void Part::render() { assert(act && "partrender: physics equivalent invalid"); glPushMatrix(); float glMat[16]; NxActor* actor; actor=act; if(NULL==actor) return; actor->getGlobalPose().getColumnMajor44(glMat); glMultMatrixf(glMat); if(actor->userData!=NULL && gRenderUserData) { glPushMatrix(); ((GraphicsObject*)actor->userData)->render(); glPopMatrix(); } else { //render according to shape descriptions in actor for(unsigned s=0; s < actor->getNbShapes(); s++) { NxShape *shape = actor->getShapes()[s]; glPushMatrix(); shape->getLocalPose().getColumnMajor44(glMat); glMultMatrixf(glMat); //render shapes if(shape->getFlag(NX_TRIGGER_ENABLE)) { //do nothing, triggers are not to be rendered and have different userdata } else if(shape->userData!=NULL) { ((GraphicsObject*)shape->userData)->render(); } else { NxShapeType type=shape->getType(); if(NX_SHAPE_BOX==type) { NxBoxShape *sh=(NxBoxShape *)shape; NxVec3 dim=sh->getDimensions(); BoxGraphicsObject g(dim.x,dim.z,dim.y); //wrond dimensions g.render(); } else if(NX_SHAPE_CAPSULE==type) { NxCapsuleShape *sh=(NxCapsuleShape *)shape; float radius=sh->getRadius(); float height=sh->getHeight(); CapsuleGraphicsObject g(radius,height); g.render(); } else if(NX_SHAPE_SPHERE==type) { NxSphereShape *sh=(NxSphereShape *)shape; float radius=sh->getRadius(); SphereGraphicsObject g(radius); g.render(); } else { //render a default sphere if shape type unknown SphereGraphicsObject sg(1); sg.render(); } } glPopMatrix(); } } glPopMatrix(); }
bool FindTouchedGeometry( void* user_data, const NxExtendedBounds3& worldBounds, // ### we should also accept other volumes TriArray& world_triangles, TriArray* world_edge_normals, IntArray& edge_flags, IntArray& geom_stream, NxU32 group_flags, bool static_shapes, bool dynamic_shapes, const NxGroupsMask* groupsMask) { NX_ASSERT(user_data); NxScene* scene = (NxScene*)user_data; NxExtendedVec3 Origin; // Will be TouchedGeom::mOffset worldBounds.getCenter(Origin); // Reserve a stack buffer big enough to hold all shapes in the world. This is a lazy approach that is // acceptable here since the total number of shapes is limited to 64K anyway, which would "only" consume // 256 Kb on the stack (hence, stack overflow is unlikely). // ### TODO: the new callback mechanism would allow us to use less memory here // NxU32 total = scene->getNbStaticShapes() + scene->getNbDynamicShapes(); NxU32 total = scene->getTotalNbShapes(); NxShape** buffer = (NxShape**)NxAlloca(total*sizeof(NxShape*)); // Find touched *boxes* i.e. touched objects' AABBs in the world // We collide against dynamic shapes too, to get back dynamic boxes/etc // TODO: add active groups in interface! NxU32 Flags = 0; if(static_shapes) Flags |= NX_STATIC_SHAPES; if(dynamic_shapes) Flags |= NX_DYNAMIC_SHAPES; // ### this one is dangerous NxBounds3 tmpBounds; // LOSS OF ACCURACY tmpBounds.min.x = (float)worldBounds.min.x; tmpBounds.min.y = (float)worldBounds.min.y; tmpBounds.min.z = (float)worldBounds.min.z; tmpBounds.max.x = (float)worldBounds.max.x; tmpBounds.max.y = (float)worldBounds.max.y; tmpBounds.max.z = (float)worldBounds.max.z; NxU32 nbTouchedBoxes = scene->overlapAABBShapes(tmpBounds, NxShapesType(Flags), total, buffer, NULL, group_flags, groupsMask); // Early exit if no AABBs found if(!nbTouchedBoxes) return false; NX_ASSERT(nbTouchedBoxes<=total); // Else we just trashed some stack memory // Loop through touched world AABBs NxShape** touched = buffer; while(nbTouchedBoxes--) { // Get current shape NxShape* shape = *touched++; // Filtering // Discard all CCT shapes, i.e. kinematic actors we created ourselves. We don't need to collide with them since they're surrounded // by the real CCT volume - and collisions with those are handled elsewhere. We use the userData field for filtering because that's // really our only valid option (filtering groups are already used by clients and we don't have control over them, clients might // create other kinematic actors that we may want to keep here, etc, etc) if(size_t(shape->userData)=='CCTS') continue; // Discard if not collidable // PT: this shouldn't be possible at this point since: // - the SF flag is only used for compounds // - the AF flag is already tested in scene query // - we shouldn't get compound shapes here if(shape->getFlag(NX_SF_DISABLE_COLLISION)) continue; // Ubi (EA) : Discarding Triggers : if ( shape->getFlag(NX_TRIGGER_ENABLE) ) continue; // PT: here you might want to disable kinematic objects. // Output shape to stream NxShapeType type = shape->getType(); if(type==NX_SHAPE_SPHERE) outputSphereToStream((NxSphereShape*)shape, shape, geom_stream, Origin); else if(type==NX_SHAPE_CAPSULE) outputCapsuleToStream((NxCapsuleShape*)shape, shape, geom_stream, Origin); else if(type==NX_SHAPE_BOX) outputBoxToStream((NxBoxShape*)shape, shape, geom_stream, Origin); else if(type==NX_SHAPE_MESH) outputMeshToStream((NxTriangleMeshShape*)shape, shape, geom_stream, world_triangles, world_edge_normals, edge_flags, Origin, tmpBounds); else if(type==NX_SHAPE_HEIGHTFIELD) outputHeightFieldToStream((NxHeightFieldShape*)shape, shape, geom_stream, world_triangles, world_edge_normals, edge_flags, Origin, tmpBounds); else if(type==NX_SHAPE_CONVEX) outputConvexToStream((NxConvexShape*)shape, shape, geom_stream, world_triangles, world_edge_normals, edge_flags, Origin, tmpBounds); } return true; }