Beispiel #1
0
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;
	}