Panda3D
physxShape.cxx
1 // Filename: physxShape.cxx
2 // Created by: enn0x (16Sep09)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "physxShape.h"
16 #include "physxManager.h"
17 #include "physxActor.h"
18 #include "physxBoxShape.h"
19 #include "physxCapsuleShape.h"
20 #include "physxPlaneShape.h"
21 #include "physxSphereShape.h"
22 #include "physxConvexShape.h"
23 #include "physxHeightFieldShape.h"
24 #include "physxTriangleMeshShape.h"
25 #include "physxWheelShape.h"
26 #include "physxGroupsMask.h"
27 #include "physxBounds3.h"
28 #include "physxSphere.h"
29 #include "physxBox.h"
30 #include "physxCapsule.h"
31 #include "physxRay.h"
32 #include "physxRaycastHit.h"
33 #include "physxCcdSkeleton.h"
34 
35 TypeHandle PhysxShape::_type_handle;
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: PhysxShape::release
39 // Access: Published
40 // Description:
41 ////////////////////////////////////////////////////////////////////
42 void PhysxShape::
43 release() {
44 
45  nassertv(_error_type == ET_ok);
46 
47  unlink();
48  ptr()->getActor().releaseShape(*ptr());
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function: PhysxShape::factory
53 // Access: Public
54 // Description:
55 ////////////////////////////////////////////////////////////////////
56 PhysxShape *PhysxShape::
57 factory(NxShapeType shapeType) {
58 
59  switch (shapeType) {
60 
61  case NX_SHAPE_PLANE:
62  return new PhysxPlaneShape();
63 
64  case NX_SHAPE_SPHERE:
65  return new PhysxSphereShape();
66 
67  case NX_SHAPE_BOX:
68  return new PhysxBoxShape();
69 
70  case NX_SHAPE_CAPSULE:
71  return new PhysxCapsuleShape();
72 
73  case NX_SHAPE_CONVEX:
74  return new PhysxConvexShape();
75 
76  case NX_SHAPE_MESH:
77  return new PhysxTriangleMeshShape();
78 
79  case NX_SHAPE_HEIGHTFIELD:
80  return new PhysxHeightFieldShape();
81 
82  case NX_SHAPE_WHEEL:
83  return new PhysxWheelShape();
84  }
85 
86  physx_cat.error() << "Unknown shape type.\n";
87  return NULL;
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: PhysxShape::get_actor
92 // Access: Published
93 // Description: Retrieves the actor which this shape is associated
94 // with.
95 ////////////////////////////////////////////////////////////////////
97 get_actor() const {
98 
99  nassertr(_error_type == ET_ok, NULL);
100  return (PhysxActor *)(ptr()->getActor().userData);
101 }
102 
103 ////////////////////////////////////////////////////////////////////
104 // Function: PhysxShape::set_name
105 // Access: Published
106 // Description: Sets a name string for this object. The name can
107 // be retrieved again with get_name().
108 // This is for debugging and is not used by the
109 // physics engine.
110 ////////////////////////////////////////////////////////////////////
111 void PhysxShape::
112 set_name(const char *name) {
113 
114  nassertv(_error_type == ET_ok);
115 
116  _name = name ? name : "";
117  ptr()->setName(_name.c_str());
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: PhysxShape::get_name
122 // Access: Published
123 // Description: Returns the name string.
124 ////////////////////////////////////////////////////////////////////
125 const char *PhysxShape::
126 get_name() const {
127 
128  nassertr(_error_type == ET_ok, "");
129  return ptr()->getName();
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function: PhysxShape::set_flag
134 // Access: Published
135 // Description: Sets the specified shape flag.
136 //
137 // The shape may be turned into a trigger by setting
138 // one or more of the TriggerFlags to true. A trigger
139 // shape will not collide with other shapes. Instead,
140 // if a shape enters the trigger's volume, a trigger
141 // event will be sent. Trigger events can be listened
142 // to by DirectObjects.
143 // The following trigger events can be sent:
144 // - physx-trigger-enter
145 // - physx-trigger-stay
146 // - physx-trigger-leave
147 ////////////////////////////////////////////////////////////////////
148 void PhysxShape::
149 set_flag(PhysxShapeFlag flag, bool value) {
150 
151  nassertv(_error_type == ET_ok);
152 
153  ptr()->setFlag((NxShapeFlag)flag, value);
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function: PhysxShape::get_flag
158 // Access: Published
159 // Description: Returns the specified shape flag.
160 ////////////////////////////////////////////////////////////////////
161 bool PhysxShape::
162 get_flag(PhysxShapeFlag flag) const {
163 
164  nassertr(_error_type == ET_ok, false);
165 
166  return (ptr()->getFlag((NxShapeFlag)flag)) ? true : false;
167 }
168 
169 ////////////////////////////////////////////////////////////////////
170 // Function: PhysxShape::set_skin_width
171 // Access: Published
172 // Description: Sets the skin width.
173 // The skin width must be non-negative.
174 ////////////////////////////////////////////////////////////////////
175 void PhysxShape::
176 set_skin_width(float skinWidth) {
177 
178  nassertv(_error_type == ET_ok);
179  nassertv(skinWidth >= 0.0f);
180 
181  ptr()->setSkinWidth(skinWidth);
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: PhysxShape::get_skin_width
186 // Access: Published
187 // Description: Returns the skin width.
188 ////////////////////////////////////////////////////////////////////
189 float PhysxShape::
190 get_skin_width() const {
191 
192  nassertr(_error_type == ET_ok, 0.0f);
193 
194  return ptr()->getSkinWidth();
195 }
196 
197 ////////////////////////////////////////////////////////////////////
198 // Function: PhysxShape::set_group
199 // Access: Published
200 // Description: Sets which collision group this shape is part of.
201 //
202 // Default group is 0. Maximum possible group is 31.
203 // Collision groups are sets of shapes which may or
204 // may not be set to collision detect with each other;
205 // this can be set using
206 // PhysxScene::set_group_collision_flag().
207 ////////////////////////////////////////////////////////////////////
208 void PhysxShape::
209 set_group(unsigned short group) {
210 
211  nassertv(_error_type == ET_ok);
212  nassertv(group < 32);
213 
214  ptr()->setGroup(group);
215 }
216 
217 ////////////////////////////////////////////////////////////////////
218 // Function: PhysxShape::get_group
219 // Access: Published
220 // Description: Retrieves the collision group set for this shape.
221 // The collision group is an integer between 0 and
222 // 31.
223 ////////////////////////////////////////////////////////////////////
224 unsigned short PhysxShape::
225 get_group() const {
226 
227  nassertr(_error_type == ET_ok, 0);
228 
229  return ptr()->getGroup();
230 }
231 
232 ////////////////////////////////////////////////////////////////////
233 // Function: PhysxShape::set_local_pos
234 // Access: Published
235 // Description: Set the position of the shape in actor space, i.e.
236 // relative to the actor it is owned by.
237 //
238 // Calling this method does NOT wake the associated
239 // actor up automatically.
240 //
241 // Calling this method does not automatically update
242 // the inertia properties of the owning actor (if
243 // applicable); use
244 // PhysxActor::update_mass_from_shapes() to do this.
245 ////////////////////////////////////////////////////////////////////
246 void PhysxShape::
247 set_local_pos(const LPoint3f &pos) {
248 
249  nassertv(_error_type == ET_ok);
250 
251  ptr()->setLocalPosition(PhysxManager::point3_to_nxVec3(pos));
252 }
253 
254 ////////////////////////////////////////////////////////////////////
255 // Function: PhysxShape::get_local_pos
256 // Access: Published
257 // Description: Retrieve the position of the shape in actor space,
258 // i.e. relative to the actor it is owned by.
259 ////////////////////////////////////////////////////////////////////
261 get_local_pos() const {
262 
263  nassertr(_error_type == ET_ok, LPoint3f::zero());
264 
265  return PhysxManager::nxVec3_to_point3(ptr()->getLocalPosition());
266 }
267 
268 ////////////////////////////////////////////////////////////////////
269 // Function: PhysxShape::set_local_mat
270 // Access: Published
271 // Description: Set the transform of the shape in actor space,
272 // i.e. relative to the actor it is owned by.
273 //
274 // Calling this method does NOT wake the associated
275 // actor up automatically.
276 //
277 // Calling this method does not automatically update
278 // the inertia properties of the owning actor (if
279 // applicable); use
280 // PhysxActor::update_mass_from_shapes() to do this.
281 ////////////////////////////////////////////////////////////////////
282 void PhysxShape::
284 
285  nassertv(_error_type == ET_ok);
286 
287  ptr()->setLocalPose(PhysxManager::mat4_to_nxMat34(mat));
288 }
289 
290 ////////////////////////////////////////////////////////////////////
291 // Function: PhysxShape::get_local_mat
292 // Access: Published
293 // Description: Retrieve the transform of the shape in actor space,
294 // i.e. relative to the actor it is owned by.
295 ////////////////////////////////////////////////////////////////////
297 get_local_mat() const {
298 
299  nassertr(_error_type == ET_ok, LMatrix4f::zeros_mat());
300 
301  return PhysxManager::nxMat34_to_mat4(ptr()->getLocalPose());
302 }
303 
304 ////////////////////////////////////////////////////////////////////
305 // Function: PhysxShape::get_material_index
306 // Access: Published
307 // Description: Returns the material index currently assigned to
308 // the shape.
309 ////////////////////////////////////////////////////////////////////
310 unsigned short PhysxShape::
312 
313  nassertr(_error_type == ET_ok, 0);
314  NxMaterialIndex index = ptr()->getMaterial();
315  return (unsigned int)index;
316 }
317 
318 ////////////////////////////////////////////////////////////////////
319 // Function: PhysxShape::set_material
320 // Access: Published
321 // Description: Assigns a material to the shape.
322 ////////////////////////////////////////////////////////////////////
323 void PhysxShape::
324 set_material(const PhysxMaterial &material) {
325 
326  nassertv(_error_type == ET_ok);
327  ptr()->setMaterial(material.ptr()->getMaterialIndex());
328 }
329 
330 ////////////////////////////////////////////////////////////////////
331 // Function: PhysxShape::set_material_index
332 // Access: Published
333 // Description: Assigns a material index to the shape.
334 //
335 // The material index can be retrieved by calling
336 // PhysxMaterial::get_material_index(). If the material
337 // index is invalid, it will still be recorded, but
338 // the default material (at index 0) will effectively
339 // be used for simulation.
340 ////////////////////////////////////////////////////////////////////
341 void PhysxShape::
342 set_material_index(unsigned short index) {
343 
344  nassertv(_error_type == ET_ok);
345  ptr()->setMaterial((NxMaterialIndex)index);
346 }
347 
348 ////////////////////////////////////////////////////////////////////
349 // Function: PhysxShape::set_groups_mask
350 // Access: Published
351 // Description: Sets 128-bit mask used for collision filtering.
352 // Does NOT wake the associated actor up
353 // automatically.
354 ////////////////////////////////////////////////////////////////////
355 void PhysxShape::
357 
358  nassertv(_error_type == ET_ok);
359  ptr()->setGroupsMask(mask.get_mask());
360 }
361 
362 ////////////////////////////////////////////////////////////////////
363 // Function: PhysxShape::get_groups_mask
364 // Access: Published
365 // Description: Gets 128-bit mask used for collision filtering.
366 ////////////////////////////////////////////////////////////////////
369 
370  PhysxGroupsMask mask;
371  nassertr(_error_type == ET_ok, mask);
372  mask.set_mask(ptr()->getGroupsMask());
373  return mask;
374 }
375 
376 ////////////////////////////////////////////////////////////////////
377 // Function: PhysxShape::get_world_bounds
378 // Access: Published
379 // Description: Returns a world space AABB enclosing this shape.
380 ////////////////////////////////////////////////////////////////////
383 
384  PhysxBounds3 bounds;
385  nassertr(_error_type == ET_ok, bounds);
386  ptr()->getWorldBounds(bounds._bounds);
387  return bounds;
388 }
389 
390 ////////////////////////////////////////////////////////////////////
391 // Function: PhysxShape::check_overlap_aabb
392 // Access: Published
393 // Description: Checks whether the shape overlaps a world-space
394 // AABB or not.
395 ////////////////////////////////////////////////////////////////////
396 bool PhysxShape::
397 check_overlap_aabb(const PhysxBounds3 &world_bounds) const {
398 
399  nassertr(_error_type == ET_ok, false);
400  return ptr()->checkOverlapAABB(world_bounds._bounds);
401 }
402 
403 ////////////////////////////////////////////////////////////////////
404 // Function: PhysxShape::check_overlap_capsule
405 // Access: Published
406 // Description: Checks whether the shape overlaps a world-space
407 // capsule or not.
408 ////////////////////////////////////////////////////////////////////
409 bool PhysxShape::
410 check_overlap_capsule(const PhysxCapsule &world_capsule) const {
411 
412  nassertr(_error_type == ET_ok, false);
413  return ptr()->checkOverlapCapsule(world_capsule._capsule);
414 }
415 
416 ////////////////////////////////////////////////////////////////////
417 // Function: PhysxShape::check_overlap_obb
418 // Access: Published
419 // Description: Checks whether the shape overlaps a world-space
420 // OBB or not.
421 ////////////////////////////////////////////////////////////////////
422 bool PhysxShape::
423 check_overlap_obb(const PhysxBox &world_box) const {
424 
425  nassertr(_error_type == ET_ok, false);
426  return ptr()->checkOverlapOBB(world_box._box);
427 }
428 
429 ////////////////////////////////////////////////////////////////////
430 // Function: PhysxShape::check_overlap_sphere
431 // Access: Published
432 // Description: Checks whether the shape overlaps a world-space
433 // sphere or not.
434 ////////////////////////////////////////////////////////////////////
435 bool PhysxShape::
436 check_overlap_sphere(const PhysxSphere &world_sphere) const {
437 
438  nassertr(_error_type == ET_ok, false);
439  return ptr()->checkOverlapSphere(world_sphere._sphere);
440 }
441 
442 ////////////////////////////////////////////////////////////////////
443 // Function: PhysxShape::raycast
444 // Access: Published
445 // Description:
446 ////////////////////////////////////////////////////////////////////
447 PhysxRaycastHit PhysxShape::
448 raycast(const PhysxRay &worldRay, bool firstHit, bool smoothNormal) const {
449 
450  NxRaycastHit hit;
451  nassertr(_error_type == ET_ok, hit);
452 
453  NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
454  if (smoothNormal == true) {
455  hints |= NX_RAYCAST_NORMAL;
456  }
457  else {
458  hints |= NX_RAYCAST_FACE_NORMAL;
459  }
460 
461  ptr()->raycast(worldRay._ray, worldRay._length, hints, hit, firstHit);
462  return PhysxRaycastHit(hit);
463 }
464 
465 ////////////////////////////////////////////////////////////////////
466 // Function: PhysxShape::set_ccd_skeleton
467 // Access: Published
468 // Description:
469 ////////////////////////////////////////////////////////////////////
470 void PhysxShape::
471 set_ccd_skeleton(PhysxCcdSkeleton *skel) {
472 
473  nassertv(_error_type == ET_ok);
474 
475  ptr()->setCCDSkeleton(skel->ptr());
476  _skel = skel;
477 }
478 
479 ////////////////////////////////////////////////////////////////////
480 // Function: PhysxShape::get_ccd_skeleton
481 // Access: Published
482 // Description:
483 ////////////////////////////////////////////////////////////////////
484 PhysxCcdSkeleton *PhysxShape::
485 get_ccd_skeleton() const {
486 
487  nassertr(_error_type == ET_ok, NULL);
488 
489  return _skel;
490 }
491 
unsigned short get_material_index() const
Returns the material index currently assigned to the shape.
Definition: physxShape.cxx:311
PhysxActor * get_actor() const
Retrieves the actor which this shape is associated with.
Definition: physxShape.cxx:97
Represents a sphere defined by its center point and radius.
Definition: physxSphere.h:28
void set_group(unsigned short group)
Sets which collision group this shape is part of.
Definition: physxShape.cxx:209
void set_local_mat(const LMatrix4f &mat)
Set the transform of the shape in actor space, i.e.
Definition: physxShape.cxx:283
bool check_overlap_obb(const PhysxBox &world_box) const
Checks whether the shape overlaps a world-space OBB or not.
Definition: physxShape.cxx:423
Represents an oriented bounding box, as a center point, extents(radii) and a rotation.
Definition: physxBox.h:32
static const LPoint3f & zero()
Returns a zero-length point.
Definition: lpoint3.h:259
static NxVec3 point3_to_nxVec3(const LPoint3f &p)
Converts from LPoint3f to NxVec3.
Definition: physxManager.I:77
unsigned short get_group() const
Retrieves the collision group set for this shape.
Definition: physxShape.cxx:225
Abstract base class for shapes.
Definition: physxShape.h:41
This class is a shape instance of a height field object of type PhysxHeightField. ...
Represention of a axis aligned bounding box.
Definition: physxBounds3.h:32
const char * get_name() const
Returns the name string.
Definition: physxShape.cxx:126
A plane collision detection primitive.
A sphere shaped collision detection primitive.
bool check_overlap_aabb(const PhysxBounds3 &world_bounds) const
Checks whether the shape overlaps a world-space AABB or not.
Definition: physxShape.cxx:397
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
void set_flag(const PhysxShapeFlag flag, bool value)
Sets the specified shape flag.
Definition: physxShape.cxx:149
A class for describing a shape&#39;s surface properties.
Definition: physxMaterial.h:51
static NxMat34 mat4_to_nxMat34(const LMatrix4f &m)
Converts from LMatrix4f to NxMat34.
Definition: physxManager.I:145
LMatrix4f get_local_mat() const
Retrieve the transform of the shape in actor space, i.e.
Definition: physxShape.cxx:297
void set_material(const PhysxMaterial &material)
Assigns a material to the shape.
Definition: physxShape.cxx:324
void set_local_pos(const LPoint3f &pos)
Set the position of the shape in actor space, i.e.
Definition: physxShape.cxx:247
This structure captures results for a single raycast query.
void set_skin_width(float skinWidth)
Sets the skin width.
Definition: physxShape.cxx:176
bool check_overlap_sphere(const PhysxSphere &world_sphere) const
Checks whether the shape overlaps a world-space sphere or not.
Definition: physxShape.cxx:436
bool check_overlap_capsule(const PhysxCapsule &world_capsule) const
Checks whether the shape overlaps a world-space capsule or not.
Definition: physxShape.cxx:410
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
float get_skin_width() const
Returns the skin width.
Definition: physxShape.cxx:190
A box shaped collision detection primitive.
Definition: physxBoxShape.h:41
Represents a capsule.
Definition: physxCapsule.h:27
A special shape used for simulating a car wheel.
Actors are the main simulation objects.
Definition: physxActor.h:48
A Convex Mesh.
static const LMatrix4f & zeros_mat()
Returns an matrix filled with zeros.
Definition: lmatrix.h:923
void set_material_index(unsigned short idx)
Assigns a material index to the shape.
Definition: physxShape.cxx:342
A shapes which is used to represent an instance of an convex mesh.
void set_name(const char *name)
Sets a name string for this object.
Definition: physxShape.cxx:112
LPoint3f get_local_pos() const
Retrieve the position of the shape in actor space, i.e.
Definition: physxShape.cxx:261
void set_groups_mask(const PhysxGroupsMask &mask)
Sets 128-bit mask used for collision filtering.
Definition: physxShape.cxx:356
static LPoint3f nxVec3_to_point3(const NxVec3 &p)
Converts from NxVec3 to LPoint3f.
Definition: physxManager.I:88
PhysxBounds3 get_world_bounds() const
Returns a world space AABB enclosing this shape.
Definition: physxShape.cxx:382
bool get_flag(const PhysxShapeFlag flag) const
Returns the specified shape flag.
Definition: physxShape.cxx:162
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
static LMatrix4f nxMat34_to_mat4(const NxMat34 &m)
Converts from NxMat34 to LMatrix4f.
Definition: physxManager.I:158
A capsule shaped collision detection primitive, also known as a line swept sphere.
PhysxGroupsMask get_groups_mask() const
Gets 128-bit mask used for collision filtering.
Definition: physxShape.cxx:368
Represents an ray as an origin and direction.
Definition: physxRay.h:28
A shapes which is used to represent an instance of an convex mesh.
128-bit bitmask class.