//-----------------------------------------------------------------------
		void PhysXActorExtern::_processParticle(
			ParticleTechnique* particleTechnique, 
			Particle* particle, 
			Ogre::Real timeElapsed, 
			bool firstParticle)
		{
			// Only update after a PhysX simulation step
			if (mSynchronize)
			{
				if (particle->particleType != Particle::PT_VISUAL)
					return;

				if (!particle->physicsActor)
					return;

				VisualParticle* visualParticle = static_cast<VisualParticle*>(particle);
				PhysXActor* physXActor = static_cast<PhysXActor*>(particle->physicsActor);
				NxActor* nxActor = physXActor->nxActor;
				if (nxActor)
				{
					// Synchronize both the particle and the pysicsActor with the nxActor
					particle->position = PhysXMath::convert(nxActor->getGlobalPosition());
					particle->direction = PhysXMath::convert(nxActor->getLinearVelocity());
					visualParticle->orientation = PhysXMath::convert(nxActor->getGlobalOrientationQuat());
					physXActor->position = particle->position;
					physXActor->direction = particle->direction;
					physXActor->orientation = visualParticle->orientation;

					if (nxActor->getNbShapes())
					{
						NxShape *shape = nxActor->getShapes()[0]; // Max one.
						switch(shape->getType())
						{
							case NX_SHAPE_BOX:
								(static_cast<NxBoxShape*>(shape))->setDimensions(
									PhysXMath::convert(0.5 * Ogre::Vector3(
									visualParticle->width, visualParticle->height, visualParticle->depth)));
							break;
							 case NX_SHAPE_SPHERE:
								(static_cast<NxSphereShape*>(shape))->setRadius(0.5f * visualParticle->width);
							break;
							case NX_SHAPE_CAPSULE:
							{
								(static_cast<NxCapsuleShape*>(shape))->setRadius(0.5f * visualParticle->width);
								(static_cast<NxCapsuleShape*>(shape))->setHeight(0.5f * visualParticle->height);
							}
							break;
						}
					}
				}
			}
		}
예제 #2
0
void AddUserDataToShapes(NxActor* actor)
{
    NxU32 i = 0;

	NxShape*const* shapes = actor->getShapes();
	NxU32 nbShapes = actor->getNbShapes();
	while (nbShapes--)
	{
		NxShape* shape = shapes[nbShapes];
        shape->userData = new ShapeUserData;
		ShapeUserData* sud = (ShapeUserData*)(shape->userData);
		sud->id = i++;
		if (shape->getType() == NX_SHAPE_CONVEX)
		{
			sud->mesh = new NxConvexMeshDesc;
			shape->isConvexMesh()->getConvexMesh().saveToDesc(*(NxConvexMeshDesc*)sud->mesh);
		}
		if (shape->getType() == NX_SHAPE_MESH)
		{
			sud->mesh = new NxTriangleMeshDesc;
			shape->isTriangleMesh()->getTriangleMesh().saveToDesc(*(NxTriangleMeshDesc*)sud->mesh);
		}
	}
}
예제 #3
0
파일: part.cpp 프로젝트: yosinski/quadrasim
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();
}
예제 #4
0
void CPhysicsActor::SetScale( Vec3& scale )
{
	// do not scale if scale is currently 1:1 or if the scale
	// has not changed
	if( scale.x == 1 && scale.y == 1 && scale.z == 1 ||
		scale == m_CurrentScale )
	{
		return;
	}

	// make sure the scale is valid
	// No 0 scales or negative scales!
	if( scale.x <= 0 && scale.y <= 0 && scale.z <= 0 )
	{
		m_ToolBox->Log( LOGWARNING, _T("CPhysicsActor::SetScale() Invalid scale!\n" ) );
		return;
	}

	NxVec3 newScale( scale.x, scale.y, scale.z );

	// unscale the old scale
	// Loop through shapes in the actor
	unsigned int numShapes = m_Actor->getNbShapes();
	NxShape*const* shapes = m_Actor->getShapes();
   	NxShape* currentShape;

	NxVec3 shapeLocalPosition;

	// for each shape type scale its dimensions
	while( numShapes-- >= 1 )
	{
		currentShape = shapes[numShapes];

		// get the shape's type
		NxShapeType type = currentShape->getType();

		switch( type )
		{
			case NX_SHAPE_BOX:
				{
					// do something
					NxBoxShape* shape = (NxBoxShape*)currentShape;
					// rescale box dimensions
					NxVec3 dimensions = shape->getDimensions();
					
					Vec3 newDimensions(dimensions.x, dimensions.y, dimensions.z);
					RescaleVector( newDimensions, scale );

					// set the shape data with the newly rescaled dimensions
					shape->setDimensions( NxVec3(newDimensions.x, newDimensions.y, newDimensions.z) );
					break;
				}
			case NX_SHAPE_SPHERE:
				{
					// do something
					NxSphereShape* shape = (NxSphereShape*)currentShape;
					float radius = shape->getRadius();
					radius /= m_CurrentScale.x;
					radius *= newScale.x;
					// set the shape data with the newly rescaled dimensions
					shape->setRadius( radius );
					break;
				}
			case NX_SHAPE_CAPSULE:
				{
					// do something
					NxCapsuleShape* shape;
					shape = (NxCapsuleShape*)currentShape;
					// rescale radius
					float radius = shape->getRadius();
					radius /= m_CurrentScale.x;
					radius *= newScale.x;
					// rescale height
					float height = shape->getHeight();
					height /= m_CurrentScale.z;
					height *= newScale.z;
					// set the shape data with the newly rescaled dimensions
					shape->setRadius( radius );
					shape->setHeight( height );
					break;
				}
			default:
				m_ToolBox->Log( LOGWARNING, _T("CPhysicsObject::SetScale() Attempting to scale on unsupported shape!\n" ) );
				return;
		}

		// get the shape's local position and rescale it
		shapeLocalPosition = currentShape->getLocalPosition();

		Vec3 newShapeLocalPosition(shapeLocalPosition.x, shapeLocalPosition.y, shapeLocalPosition.z);
		RescaleVector( newShapeLocalPosition, scale );

		currentShape->setLocalPosition( NxVec3(newShapeLocalPosition.x, newShapeLocalPosition.y, newShapeLocalPosition.z) );
	}

	// Set the current scale to the new scale so we can unscale the scale
	m_CurrentScale = scale;
}
예제 #5
0
void UpdateWheelShapeUserData()
{
    // Look for wheel shapes
    NxU32 nbActors = gScene->getNbActors();
    NxActor** actors = gScene->getActors();
    while (nbActors--)
    {
		NxU32 nbShapes = actors[nbActors]->getNbShapes();
	    NxShape*const* shapes = actors[nbActors]->getShapes();
		while (nbShapes--)
		{
			NxShape* shape = shapes[nbShapes];
			if (shape->getType() == NX_SHAPE_WHEEL)
			{
				NxWheelShape* ws = (NxWheelShape*)shape;
				ShapeUserData* sud = (ShapeUserData*)(shape->userData);
				if (sud)
				{
					// Need to save away roll angle in wheel shape user data
					NxReal rollAngle = sud->wheelShapeRollAngle;
//					rollAngle += ws->getAxleSpeed() * 1.0f/60.0f;
					rollAngle += ws->getAxleSpeed() * gDeltaTime;
					while (rollAngle > NxTwoPi)	//normally just 1x
						rollAngle -= NxTwoPi;
					while (rollAngle < -NxTwoPi)	//normally just 1x
						rollAngle += NxTwoPi;

					// We have the roll angle for the wheel now
					sud->wheelShapeRollAngle = rollAngle;


					NxMat34 pose;
					pose = ws->getGlobalPose();

					NxWheelContactData wcd;
					NxShape* s = ws->getContact(wcd);	

					NxReal r = ws->getRadius();
					NxReal st = ws->getSuspensionTravel();
					NxReal steerAngle = ws->getSteerAngle();

//					NxWheelShapeDesc state;	
//					ws->saveToDesc(state);

					NxVec3 p0;
					NxVec3 dir;
					/*
					getWorldSegmentFast(seg);
					seg.computeDirection(dir);
					dir.normalize();
					*/
					p0 = pose.t;  //cast from shape origin
					pose.M.getColumn(1, dir);
					dir = -dir;	//cast along -Y.
					NxReal castLength = r + st;	//cast ray this long

//					renderer.addArrow(p0, dir, castLength, 1.0f);
	
					//have ground contact?
					// This code is from WheelShape.cpp in SDKs/core/common/src
					// if (contactPosition != NX_MAX_REAL)  
					if (s && wcd.contactForce > -1000)
					{
//						pose.t = p0 + dir * wcd.contactPoint;
//						pose.t -= dir * state.radius;	//go from contact pos to center pos.
						pose.t = wcd.contactPoint;
						pose.t -= dir * r;	//go from contact pos to center pos.

						NxMat33 rot, axisRot;
						rot.rotY(steerAngle);
						axisRot.rotY(0);

//						NxReal rollAngle = ((ShapeUserData*)(wheel->userData))->rollAngle;

						NxMat33 rollRot;
						rollRot.rotX(rollAngle);

						pose.M = rot * pose.M * axisRot * rollRot;

						sud->wheelShapePose = pose;

					}
					else
					{
						pose.t = p0 + dir * st;
						sud->wheelShapePose = pose;
					}
				}
			}
		}
	}
}
예제 #6
0
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;
	}