Пример #1
0
/***********************************************************
	create box actor
***********************************************************/
NxActor* PhysXEngine::CreateBox(const NxVec3 & StartPosition, float dimX, float dimY, float dimZ, 
								float density, bool Pushable)
{

	// Add a single-shape actor to the scene
	NxActorDesc actorDesc;


	// The actor has one shape, a box, 1m on a side
	NxBoxShapeDesc boxDesc;
	boxDesc.dimensions.set(dimX, dimY, dimZ);
	boxDesc.localPose.t = NxVec3(0, 0, 0);

	if(Pushable)
	{
		NxBodyDesc bodyDesc;
		actorDesc.body	= &bodyDesc;
		actorDesc.density = density;
		boxDesc.group = GROUP_COLLIDABLE_PUSHABLE;
	}
	else
		boxDesc.group = GROUP_COLLIDABLE_NON_PUSHABLE;

	actorDesc.shapes.pushBack(&boxDesc);


	actorDesc.globalPose.t	= StartPosition;	
	assert(actorDesc.isValid());
	NxActor *pActor = gScene->createActor(actorDesc);	
	assert(pActor);

	return pActor;
}
Пример #2
0
// Create a static trigger
static void CreateTrigger(const NxVec3& pos, NxF32 size = 2, const NxVec3* initial_velocity=NULL, bool kinematic = 	false)
{
	// Our trigger is a cube
	NxBodyDesc triggerBody;
	NxBoxShapeDesc dummyShape;
	NxBoxShapeDesc BoxDesc;
	BoxDesc.dimensions		= NxVec3(size, size, size);
	BoxDesc.shapeFlags		|= NX_TRIGGER_ENABLE;

	NxActorDesc ActorDesc;

	if(initial_velocity || kinematic) {
		if (initial_velocity) {
			triggerBody.linearVelocity = *initial_velocity;
		}
		if (kinematic) {
			triggerBody.flags |= NX_BF_KINEMATIC;
		}
		triggerBody.mass = 1;
		ActorDesc.body = &triggerBody;
		NxF32 sizeinc = 1.01f;
		dummyShape.dimensions.set(size*sizeinc, size*sizeinc, size*sizeinc);
		dummyShape.group = 1;
		ActorDesc.shapes.pushBack(&dummyShape);
	}

	ActorDesc.shapes.pushBack(&BoxDesc);
	ActorDesc.globalPose.t = pos;
	int thisNb = ++gNbTriggers;
	gNbTouchedBodies.pushBack(0);
	NX_ASSERT(gNbTouchedBodies.size() == gNbTriggers);
	gMyPhysX.getScene()->setGroupCollisionFlag(1,0, false);
	gMyPhysX.getScene()->setGroupCollisionFlag(1,1, false);
	gMyPhysX.getScene()->setGroupCollisionFlag(1,2, true);
	ActorDesc.userData = (void*)(-thisNb);
	if (!ActorDesc.isValid()) {
		printf("Invalid ActorDesc\n");
		return;
	}
	NxActor* actor = gMyPhysX.getScene()->createActor(ActorDesc);	// This is just a quick-and-dirty way to identify the trigger for rendering
	NX_ASSERT(actor != NULL);

	if (kinematic) {
		KinematicActor k;
		k.actor = actor;
		if (initial_velocity) {
			k.vel = *initial_velocity;
		} else {
			k.vel.set(0,0,0);
		}
		gKinematicActors.pushBack(k);
	}

	gMyPhysX.getScene()->setUserTriggerReport(&myTriggerCallback);
}
Пример #3
0
/*===================================*/
void CFragment::DiscreteInit( void )
{


	NxVec3 Dimensions[CBreakWall::FragmentType] = {   NxVec3( 0.60f , 0.30f , 1.15f ) 
													, NxVec3( 0.25f , 0.15f , 1.65f )
													, NxVec3( 0.60f , 0.30f , 1.65f ) };
	
	NxBodyDesc bodyDesc;
	bodyDesc.setToDefault();
	NxActorDesc actorDesc;
	actorDesc.setToDefault();
	NxBoxShapeDesc boxDesc;
	boxDesc.setToDefault();	
	boxDesc.skinWidth = 0.0f;
	actorDesc.density = 1000000.0f;
	actorDesc.body = &bodyDesc;
	actorDesc.globalPose.t = NxVec3( m_vPos.x , m_vPos.y , m_vPos.z );
	NxMat33 Mat;
	CRandomize Rand;
	D3DXVECTOR3 Rot( (float)Rand.GetRandomize( 0.0 , 359.0 ) , (float)Rand.GetRandomize( 0.0 , 359.0 ) , (float)Rand.GetRandomize( 0.0 , 359.0 ) );
	CDPConverter::SetRot( &Mat , &Rot );
	actorDesc.globalPose.M = Mat;
	bodyDesc.angularDamping = 0.0f;
	boxDesc.dimensions = Dimensions[m_Type-1]*m_Scale;


	if( m_MaterialIndex == -1 )
	{
		// アクターのマテリアルを設定する
		NxMaterialDesc materialDesc;
		materialDesc.restitution		= 0.4f;
		materialDesc.dynamicFriction	= 3.8f;
		materialDesc.staticFriction		= 3.5f;
		m_MaterialIndex					= m_pPhysX->GetScene()->createMaterial( materialDesc )->getMaterialIndex();

		boxDesc.materialIndex = m_MaterialIndex;
	}
	else
	{
		boxDesc.materialIndex = m_MaterialIndex;
	}
	actorDesc.shapes.pushBack( &boxDesc );
	m_Actor = m_pPhysX->GetScene()->createActor( actorDesc );
	m_Actor->putToSleep();

	m_Material = m_lpXFile->GetMaterial();

}
	/**
	 * CreateSphere(float r, float xInit, float yInit, float zInit)
	 * @float r: radius of the sphere
	 * @float xInit: Initial Position on X
	 * @float yInit: Initial Position on Y
	 * @float zInit: Initial Position on Z
	 * @return
	 */
void CreateSphere(float r, float xInit, float yInit, float zInit){
	NxActorDesc actorDesc;
	NxBodyDesc bodyDesc;
	NxSphereShapeDesc sphereDesc;

	//デフォルト値で初期化 (クリア)
	actorDesc.setToDefault();
	bodyDesc.setToDefault();
	sphereDesc.setToDefault();

	bodyDesc.angularDamping = 0.5f;	//転がり摩擦係数

	sphereDesc.radius = r;									//球の半径を指定
	sphereDesc.userData = (void *)size_t(sphereDesc.radius);
	actorDesc.shapes.pushBack(&sphereDesc);	//球をアクターに追加
	actorDesc.body = &bodyDesc;	//動的情報を指定
	actorDesc.density = 100.0f;			//質量密度 (kg/m^3)
	actorDesc.globalPose.t = NxVec3(xInit, yInit, zInit);	//Scene上の位置
	//Set userData to NULL if you are not doing anyting with it.
	NxActor*pActor = pScene->createActor( actorDesc );
	pActor->userData = (void *)size_t((int)r);
}
Пример #5
0
void PhysXCapsule::createCapsule(const CapsuleInfo& info)
{
	NxCapsuleShapeDesc capsuleDesc;
	capsuleDesc.setToDefault();
	capsuleDesc.height = info.mHeight;
	capsuleDesc.radius = info.mRadius;

	NxMat33 rot0, rot1,rot2;
	rot0.rotX(info.mLocalPose.x);
	rot1.rotY(info.mLocalPose.y);
	rot2.rotZ(info.mLocalPose.z);
	rot0 = rot0 * rot1 * rot2;
	capsuleDesc.localPose.M = rot0;

	NxActorDesc actorDesc;
	actorDesc.setToDefault();
	actorDesc.shapes.pushBack(&capsuleDesc);
	actorDesc.density = 1.0;
	actorDesc.globalPose.t = info.mGlobalPose;

	mCapsule = mScene->createActor(actorDesc);
	mCapsule->userData = (void*) &mInvisible;
}
Пример #6
0
NxActor* CreateSphere(const NxVec3 &pos, int flag)
{
	// Add a single-shape actor to the scene
	NxActorDesc actorDesc;
	NxBodyDesc bodyDesc;

	// The actor has one shape, a sphere
	NxSphereShapeDesc sphereDesc;
	sphereDesc.radius		= 1.5f;
	sphereDesc.localPose.t	= NxVec3(0,2.0f,0);
	assert(sphereDesc.isValid());
	actorDesc.shapes.pushBack(&sphereDesc);

	if (0 == flag)
	{	//Dynamic actor
		bodyDesc.flags	   |= NX_BF_DISABLE_GRAVITY;
		actorDesc.body		= &bodyDesc;
		actorDesc.density	= 1.0f;
	}
	else if (1 == flag)
	{	//Static actor
		actorDesc.body		= NULL;
		actorDesc.density	= 1.0f;
	}
	else if (2 == flag)
	{	// Kinematic actor
		bodyDesc.flags	   |= NX_BF_KINEMATIC;
		actorDesc.body		= &bodyDesc;
		actorDesc.density	= 1.0f;
	}
	actorDesc.globalPose.t	= pos;	//NxVec3(-6.5f, 0, 0);
	assert(actorDesc.isValid());
	NxActor *pActor = gScene->createActor(actorDesc);
	assert(pActor);
	return pActor;
}
Пример #7
0
pRigidBody*pFactory::createBox(CK3dEntity *referenceObject,CK3dEntity *worldReferenceObject,pObjectDescr*descr,int creationFlags)
{

	pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); 
	pRigidBody*result = world->getBody(referenceObject);
	if(result)
	{
		result->destroy();
		delete result;
		result = NULL;
	}
	// we create our final body in the given world :
	result  =  createBody(referenceObject,worldReferenceObject);
	if (result)
	{
		result->setWorld(world);

		using namespace vtTools::AttributeTools;

		result->setFlags(descr->flags);
		result->setHullType(descr->hullType);
		result->setDataFlags(0x000);
		result->checkDataFlags();

		if (result->getSkinWidth()==-1.0f)
		{
			result->setSkinWidth(0.01f);
		}

		VxMatrix v_matrix ;
		VxVector position,scale;		
		VxQuaternion quat;	


		v_matrix = referenceObject->GetWorldMatrix();
		Vx3DDecomposeMatrix(v_matrix,quat,position,scale);
		VxVector box_s= BoxGetZero(referenceObject);

		NxVec3 pos = pMath::getFrom(position);
		NxQuat rot = pMath::getFrom(quat);

		float density = result->getDensity();
		float radius = referenceObject->GetRadius();
		if (referenceObject->GetRadius() < 0.001f )
		{
			radius  = 1.0f;
		}


		//////////////////////////////////////////////////////////////////////////
		//create actors description
		NxActorDesc actorDesc;actorDesc.setToDefault();
		NxBodyDesc bodyDesc;bodyDesc.setToDefault();

		//////////////////////////////////////////////////////////////////////////
		NxMaterialDesc *materialDescr = NULL;
		NxMaterial *material = NULL;
		if (isFlagOn(result->getDataFlags(),EDF_MATERIAL_PARAMETER))
		{
			NxMaterialDesc  entMatNull;entMatNull.setToDefault();
			NxMaterialDesc  *entMat  = createMaterialFromEntity(referenceObject);
			material  = world->getScene()->createMaterial(entMatNull);
			material->loadFromDesc(*entMat);
			result->setMaterial(material);
		}else{
			if (world->getDefaultMaterial())
			{
				result->setMaterial(world->getDefaultMaterial());
			}
		}
		//////////////////////////////////////////////////////////////////////////

		NxBoxShapeDesc boxShape;
		if (creationFlags & E_OFC_DIMENSION )
		{
			boxShape.dimensions = pMath::getFrom(box_s)*0.5f;
		}
		boxShape.density  = descr->density;
		boxShape.materialIndex = result->getMaterial()->getMaterialIndex();
		if (result->getSkinWidth()!=-1.0f)
			boxShape.skinWidth = result->getSkinWidth();

		actorDesc.shapes.pushBack(&boxShape);

		//////////////////////////////////////////////////////////////////////////
		//dynamic object  ? 
		if (result->getFlags() & BF_Moving){
			actorDesc.body = &bodyDesc;
		}
		else
			actorDesc.body = NULL;

		//////////////////////////////////////////////////////////////////////////
		//set transformations
		actorDesc.density  = descr->density;

		if (creationFlags & E_OFC_POSITION)
		{
			actorDesc.globalPose.t = pos;	
		}

		if (creationFlags & E_OFC_POSITION)
		{
			actorDesc.globalPose.M = rot;
		}
		
				//////////////////////////////////////////////////////////////////////////
		//create the actor

		int v = actorDesc.isValid();
		NxActor *actor  = world->getScene()->createActor(actorDesc);
		if (!actor)
		{
			xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor");
			delete result;
			return NULL;

		}


		//////////////////////////////////////////////////////////////////////////
		//set additional settings : 
		result->setActor(actor);
		actor->setName(referenceObject->GetName());
		actor->userData= result;

		if (result->getFlags() & BF_Moving)
		{
			VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&result->getMassOffset());
			actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut));
		}

		if (result->getFlags() & BF_Kinematic)
		{
			actor->raiseBodyFlag(NX_BF_KINEMATIC);
		}

		result->enableCollision((result->getFlags() & BF_Collision));
		if (result->getFlags() & BF_Moving)
		{
			if (!(result->getFlags() & BF_Gravity))
			{
				actor->raiseBodyFlag(NX_BF_DISABLE_GRAVITY);
			}
		}

		NxShape *shape  = result->getShapeByIndex();
		if (shape)
		{
			pSubMeshInfo *sInfo  = new pSubMeshInfo();
			sInfo->entID = referenceObject->GetID();
			sInfo->refObject  = (CKBeObject*)referenceObject;
			shape->userData = (void*)sInfo;
			result->setMainShape(shape);
			shape->setName(referenceObject->GetName());
		}
	}
		
	return result;
}
Пример #8
0
pRigidBody*pFactory::createRigidBody(CK3dEntity *referenceObject,pObjectDescr& oDescr)
{
	CK3dEntity *worldReferenceObject = (CK3dEntity*)GetPMan()->GetContext()->GetObject(oDescr.worlReference);

	pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); 

	if (!world)
	{
		xLogger::xLog(XL_START,ELOGWARNING,E_LI_MANAGER,"world object invalid, setting to default world");
		world  = GetPMan()->getDefaultWorld();
	}

	pRigidBody*result = world->getBody(referenceObject);

	//	create minimum object
	result  =  createBody(referenceObject,worldReferenceObject);

	if (!result)
	{
		xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"failed");
		return NULL;

	}
	result->setWorld(world);
	result->setFlags(oDescr.flags);
	result->setHullType(oDescr.hullType);

	if (oDescr.density <= 0.001f)
		oDescr.density = 1.0f;
	
	if (oDescr.skinWidth <= 0.001f)
		oDescr.skinWidth = 0.025f;

	
	result->setDensity(oDescr.density);

	bool hierarchy = (oDescr.flags & BF_Hierarchy);
	bool isDeformable = oDescr.flags & BF_Deformable;
	bool  trigger = oDescr.flags & BF_TriggerShape;


	//################################################################
	//
	// Deformable ?
	//


	pCloth *cloth = NULL;
	pClothDesc cDescr;

	if (isDeformable)
	{
		xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"deformable feature disabled in this release");
		return NULL;

		cDescr.setToDefault();
		cDescr.worldReference = worldReferenceObject->GetID();

		if ( result->getFlags() & BF_Gravity )
		{
			cDescr.flags |= PCF_Gravity;
		}

		if ( result->getFlags() & BF_Collision )
		{

		}

		if (!cloth)
		{
			cloth = pFactory::Instance()->createCloth(referenceObject,cDescr);
			if (!cloth)
			{
				xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Cannot create cloth : factory object failed !");
			}
		}
	}


	float density = oDescr.density;
	VxVector box_s= BoxGetZero(referenceObject);


	VxMatrix v_matrix ;
	VxVector position,scale;		
	VxQuaternion quat;	


	v_matrix = referenceObject->GetWorldMatrix();
	Vx3DDecomposeMatrix(v_matrix,quat,position,scale);

	NxVec3 pos = pMath::getFrom(position);
	NxQuat rot = pMath::getFrom(quat);


	//----------------------------------------------------------------
	//
	// Fill NxActorDescr
	//
	

	NxActorDesc actorDesc;actorDesc.setToDefault();
	NxBodyDesc bodyDesc;bodyDesc.setToDefault();

	//
	//	Fix parameters to default values

	
	actorDesc.density  = oDescr.density;

	//skin width
	if (oDescr.skinWidth<=0.0001f)
		oDescr.skinWidth=0.025f;


	float radius = result->GetVT3DObject()->GetRadius();
	
	//----------------------------------------------------------------
	//
	//	Create the physic mesh. Externalizing this procedure will corrupt the
	//	actor description object.
	//
	
	switch(oDescr.hullType)
	{

		//////////////////////////////////////////////////////////////////////////
	case HT_Box:
		{
			NxBoxShapeDesc shape;

			if (! (oDescr.flags & BF_Deformable) )
			{
				shape.dimensions = pMath::getFrom(box_s)*0.5f;
			}
			shape.density  = density;
			shape.skinWidth = oDescr.skinWidth;
			actorDesc.shapes.pushBack(&shape);
			break;
		}
		//////////////////////////////////////////////////////////////////////////
	case HT_Sphere:
		{
			NxSphereShapeDesc shape;
			if (! (oDescr.flags & BF_Deformable) )
			{
				shape.radius = radius;
			}
			shape.density  = density;
			shape.skinWidth = oDescr.skinWidth;
			actorDesc.shapes.pushBack(&shape);

			break;
		}
		//////////////////////////////////////////////////////////////////////////
	case HT_Mesh:
		{

			NxTriangleMeshDesc myMesh;
			myMesh.setToDefault();

			pFactory::Instance()->createMesh(result->getWorld()->getScene(),result->GetVT3DObject()->GetCurrentMesh(),myMesh);

			NxTriangleMeshShapeDesc shape;
			bool status = InitCooking();
			if (!status) {
				xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!");
				return false;
			}
			MemoryWriteBuffer buf;

			status = CookTriangleMesh(myMesh, buf);
			if (!status) {
				xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't cook mesh!");
				return false;
			}
			shape.meshData	= GetPMan()->getPhysicsSDK()->createTriangleMesh(MemoryReadBuffer(buf.data));
			shape.density  = density;
			shape.group = oDescr.collisionGroup;

			actorDesc.shapes.pushBack(&shape);
			shape.skinWidth = oDescr.skinWidth;
			CloseCooking();

			if (myMesh.points)
			{
				delete [] myMesh.points;
			}

			if (myMesh.triangles)
			{
				delete []myMesh.triangles;
			}

			break;
		}
		//////////////////////////////////////////////////////////////////////////
	case HT_ConvexMesh:
		{
		
			if (result->GetVT3DObject()->GetCurrentMesh())
			{
				if (result->GetVT3DObject()->GetCurrentMesh()->GetVertexCount()>=256 )
				{
					xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Only 256 vertices for convex meshes allowed, by Ageia!");
					return false;
				}
			}else
			{
				xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Object has no mesh!");
				return false;
			}

			NxConvexMeshDesc myMesh;
			myMesh.setToDefault();
			pFactory::Instance()->createConvexMesh(result->getWorld()->getScene(),result->GetVT3DObject()->GetCurrentMesh(),myMesh);

			NxConvexShapeDesc shape;
			bool status = InitCooking();
			if (!status) {
				xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!");
				return false;

			}
			MemoryWriteBuffer buf;

			status = CookConvexMesh(myMesh, buf);
			if (!status) {
				xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't cook convex mesh!");
				return false;


			}
			shape.meshData	= GetPMan()->getPhysicsSDK()->createConvexMesh(MemoryReadBuffer(buf.data));
			shape.density  = density;
			actorDesc.shapes.pushBack(&shape);
			if (oDescr.skinWidth!=-1.0f)
				shape.skinWidth = oDescr.skinWidth;
			int h = shape.isValid();
			CloseCooking();

			if (myMesh.points)
			{
				delete [] myMesh.points;
			}

			if (myMesh.triangles)
			{
				delete []myMesh.triangles;
			}


			break;
		}

		//////////////////////////////////////////////////////////////////////////
	case HT_ConvexCylinder:
		{
			NxConvexShapeDesc shape;
			pConvexCylinderSettings &cSettings = oDescr.convexCylinder;
			
			iAssertW( (oDescr.mask & OD_ConvexCylinder),pFactory::Instance()->findSettings(cSettings,result->GetVT3DObject()),
				"Hull type has been set to convex cylinder but there is no descriptions passed or activated in the pObjectDescr::mask.Trying object attributes....");
			
			if (cSettings.radius.reference)
				cSettings.radius.evaluate(cSettings.radius.reference);

			if (cSettings.height.reference)
				cSettings.height.evaluate(cSettings.height.reference);


			iAssertW( cSettings.isValid() , cSettings.setToDefault(),"");

			cSettings.radius.value = cSettings.radius.value > 0.0f ? (cSettings.radius.value*0.5) : (box_s.v[cSettings.radius.referenceAxis] * 0.5f);
			cSettings.height.value = cSettings.height.value > 0.0f ? cSettings.height.value : (box_s.v[cSettings.height.referenceAxis] * 0.5f);

			

			bool resultAssert = true;
			iAssertWR( pFactory::Instance()->_createConvexCylinderMesh(&shape,cSettings,result->GetVT3DObject()),"",resultAssert);
			
			shape.density  = density;
			shape.skinWidth = oDescr.skinWidth;
			actorDesc.shapes.pushBack(&shape);
			break;
		}
		//////////////////////////////////////////////////////////////////////////
	case HT_Capsule:
		{

			NxCapsuleShapeDesc shape;
			pCapsuleSettingsEx &cSettings = oDescr.capsule;
			if (!( oDescr.mask & OD_Capsule) )
			{
				// try over attribute :
				pFactory::Instance()->findSettings(cSettings,result->GetVT3DObject());
			}
			
			bool resultAssert = true;
			
			if (cSettings.radius.reference)
				cSettings.radius.evaluate(cSettings.radius.reference);

			if (cSettings.height.reference)
				cSettings.height.evaluate(cSettings.height.reference);

			iAssertWR(cSettings.isValid(),cSettings.setToDefault(),resultAssert);

			

			shape.radius = cSettings.radius.value > 0.0f ? (cSettings.radius.value*0.5) : (box_s.v[cSettings.radius.referenceAxis] * 0.5f);
			shape.height = cSettings.height.value > 0.0f ? (cSettings.height.value-( 2*shape.radius)) : (box_s.v[cSettings.height.referenceAxis]  -  ( 2*shape.radius)) ;


			shape.density  = density;
			shape.skinWidth = oDescr.skinWidth;
			actorDesc.shapes.pushBack(&shape);
			break;
		}

	case HT_Wheel:
		{

			xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Wheel shape can be sub shape only!");
			return false;
		}
	}

	if ( !isDeformable)
	{
		actorDesc.globalPose.t = pos;	
		actorDesc.globalPose.M = rot;
	}



	//----------------------------------------------------------------
	//
	// Create the final NxActor
	//

	if (oDescr.flags & BF_Moving)
		actorDesc.body = &bodyDesc;

	NxActor *actor  = world->getScene()->createActor(actorDesc);
	if (!actor)
	{
		xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor");
		delete result;
		return NULL;

	}

	//----------------------------------------------------------------
	//
	// 
	//
	result->setActor(actor);
	actor->setName(referenceObject->GetName());
	result->SetVT3DObject(referenceObject);
	actor->userData= result;


	//////////////////////////////////////////////////////////////////////////
	//Deformable : 
	if (isDeformable && cloth)
	{

		pDeformableSettings dSettings;
		dSettings.ImpulsThresold = 50.0f;
		dSettings.PenetrationDepth= 0.1f ;
		dSettings.MaxDeform = 2.0f;

		CKParameterOut *poutDS = referenceObject->GetAttributeParameter(GetPMan()->att_deformable);
		if (poutDS)
		{
			pFactory::Instance()->copyTo(dSettings,poutDS);
		}
		cloth->attachToCore(referenceObject,dSettings.ImpulsThresold,dSettings.PenetrationDepth,dSettings.MaxDeform);
		result->setCloth(cloth);
	}


	//////////////////////////////////////////////////////////////////////////
	//
	//	Extra settings : 
	//

	if (result->getFlags() & BF_Moving)
	{
		VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&oDescr.massOffsetLinear);
		actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut));
	}

	if (result->getFlags() & BF_Kinematic)
	{
		result->setKinematic(true);
	}

	if (result->getFlags() & BF_Moving )
	{
		result->enableGravity(result->getFlags() & BF_Gravity);
	}

	if (result->getFlags() & BF_Sleep )
	{
		result->setSleeping(true);
	}

	if (oDescr.worlReference == 0)
	{
		if (GetPMan()->getDefaultWorld())
		{
			oDescr.worlReference = GetPMan()->getDefaultWorld()->getReference()->GetID();
		}
	}

	//----------------------------------------------------------------
	//
	// store mesh meta info in the first main mesh
	//
	NxShape *shape  = result->getShapeByIndex();
	if (shape)
	{
		pSubMeshInfo *sInfo  = new pSubMeshInfo();
		sInfo->entID = referenceObject->GetID();
		sInfo->refObject  = (CKBeObject*)referenceObject;
		shape->userData = (void*)sInfo;
		result->setMainShape(shape);
		shape->setName(referenceObject->GetName());

	}

	result->enableCollision( (result->getFlags() & BF_Collision), referenceObject );

	//----------------------------------------------------------------
	//
	// Adjust pivot 
	//

	if ( (oDescr.mask & OD_Pivot) )
	{
		iAssertW1( oDescr.pivot.isValid(),oDescr.pivot.setToDefault());
		result->updatePivotSettings(oDescr.pivot,referenceObject);
	}else if(pFactory::Instance()->findSettings(oDescr.collision,referenceObject))
		result->updatePivotSettings(oDescr.pivot,referenceObject);
	
	//----------------------------------------------------------------
	//
	// Optimization 
	//
	if ((oDescr.mask & OD_Optimization ))
	{
		iAssertW1( oDescr.optimization.isValid(),oDescr.optimization.setToDefault());
		result->updateOptimizationSettings(oDescr.optimization);
	}
	else{
		if(pFactory::Instance()->findSettings(oDescr.optimization,referenceObject))
		{
			iAssertW1( oDescr.optimization.isValid(),oDescr.optimization.setToDefault());
			result->updateOptimizationSettings(oDescr.optimization);
		}
	}

	//----------------------------------------------------------------
	//
	// Collision
	//
	if ((oDescr.mask & OD_Collision))
		result->updateCollisionSettings(oDescr.collision,referenceObject);
	else if(pFactory::Instance()->findSettings(oDescr.collision,referenceObject))
		result->updateCollisionSettings(oDescr.collision,referenceObject);


	//----------------------------------------------------------------
	//
	// Material 
	//

	NxMaterialDesc *materialDescr = NULL;
	NxMaterial *material = NULL;

	pMaterial &bMaterial = oDescr.material;

	if (oDescr.mask & OD_Material)
	{
		result->updateMaterialSettings(bMaterial,referenceObject);
	}else
	{
		bool hasMaterial = pFactory::Instance()->findSettings(bMaterial,referenceObject);
		if (!hasMaterial)
		{
			if (world->getDefaultMaterial())
			{
				int z = (int)world->getDefaultMaterial()->userData;
				shape->setMaterial(world->getDefaultMaterial()->getMaterialIndex());
			}
		}else{
			
			iAssertW( bMaterial.isValid(),bMaterial.setToDefault(),
				"Material settings were still invalid : ");

			NxMaterialDesc nxMatDescr;
			pFactory::Instance()->copyTo(nxMatDescr,bMaterial);
			NxMaterial *nxMaterial  = world->getScene()->createMaterial(nxMatDescr);
			if (nxMaterial)
			{
				shape->setMaterial(nxMaterial->getMaterialIndex());
			}
		}
	}


	xLogger::xLog(ELOGINFO,E_LI_MANAGER,"Rigid body creation successful : %s",referenceObject->GetName());

	result->setInitialDescription(&oDescr);

	//----------------------------------------------------------------
	//
	// Hierarchy mode fix : 
	//
	if ( (oDescr.flags & BF_Hierarchy)  )
		oDescr.hirarchy = true;

	if ( oDescr.hirarchy  )
		oDescr.flags << BF_Hierarchy;


	if ( (!oDescr.hirarchy) || !(oDescr.flags & BF_Hierarchy) ) 
		return result;

	//----------------------------------------------------------------
	//
	// Parse hirarchy 
	//
	CK3dEntity* subEntity = NULL;
	while (subEntity= referenceObject->HierarchyParser(subEntity) )
	{
		pObjectDescr *subDescr  = NULL;
		int attTypePBSetup  = GetPMan()->getAttributeTypeByGuid(VTS_PHYSIC_ACTOR);
		if (subEntity->HasAttribute(attTypePBSetup))
		{
			subDescr  = new pObjectDescr();
			CKParameterOut *par =  subEntity->GetAttributeParameter(attTypePBSetup);
			IParameter::Instance()->copyTo(subDescr,par);
			subDescr->version  = pObjectDescr::E_OD_VERSION::OD_DECR_V1;
		}

		if (!subDescr)
			continue;

		if (subDescr->flags & BF_SubShape)
		{
			//////////////////////////////////////////////////////////////////////////
			//
			//			Regular Mesh : 
			//

			if (subDescr->hullType != HT_Cloth)
			{
				//result->addSubShape(NULL,*subDescr,subEntity);
				
				VxQuaternion refQuad;subEntity->GetQuaternion(&refQuad,referenceObject);
				VxVector relPos;subEntity->GetPosition(&relPos,referenceObject);
				
				shape  = pFactory::Instance()->createShape(referenceObject,*subDescr,subEntity,subEntity->GetCurrentMesh(),relPos,refQuad);
				
				//NxShape *shape = result->getSubShape(subEntity);
				if (shape)
				{
					//----------------------------------------------------------------
					//
					// check for collision setup
					//
					
					//try to get get from child attributes first
					/*
					if(pFactory::Instance()->findSettings(subDescr->collision,subEntity))
					{
						result->updateCollisionSettings(subDescr->collision,subEntity);
						continue;
					}
					if ( (subDescr->mask & OD_Optimization) )
					{
						//if (pFactory::Instance()->findSettings(subDescr->collision,subEntity))
						result->updateCollisionSettings(subDescr->collision,subEntity);
					}
					else if ( (oDescr.mask & OD_Optimization) )
					{
						result->updateCollisionSettings(oDescr.collision,subEntity);
					}else if(pFactory::Instance()->findSettings(subDescr->collision,subEntity))
					{
						result->updateCollisionSettings(subDescr->collision,subEntity);
					}
					*/
				}
				
			}
			//////////////////////////////////////////////////////////////////////////
			//
			//			Cloth Mesh : 
			//
			if (subDescr->hullType == HT_Cloth)
			{
				//pClothDesc *cloth = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute()));
			}
		}
	}

	//----------------------------------------------------------------
	//
	// Adjust mass 
	//
	
	//----------------------------------------------------------------
	//
	// Collision
	//
	if ((oDescr.mask & OD_Mass))
		result->updateMassSettings(oDescr.mass);
	else if(pFactory::Instance()->findSettings(oDescr.mass,referenceObject))
		result->updateMassSettings(oDescr.mass);


	return result;
	
		nothing:

	return result;

}
Пример #9
0
pRigidBody*pFactory::createRigidBodyFull(CK3dEntity *referenceObject, CK3dEntity *worldReferenceObject)
{


	//################################################################
	//
	// Sanity checks
	//
	pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); 
	pRigidBody*result = world->getBody(referenceObject);
	

	if(result)
	{
		result->destroy();
		delete result;
		result = NULL;
	}
	
	
	//################################################################
	//
	// Construct the result
	//
	result  =  createBody(referenceObject,worldReferenceObject);
	if (result)
	{


		result->setWorld(world);


		//----------------------------------------------------------------
		//
		// Handle different attribute types (Object or pBSetup)
		//

		int attTypeOld = GetPMan()->GetPAttribute();
		int attTypeNew = GetPMan()->getAttributeTypeByGuid(VTS_PHYSIC_ACTOR);

		pObjectDescr *oDescr = NULL;
		
		
		//----------------------------------------------------------------
		//
		// the old way : 
		//

		if (referenceObject->HasAttribute(attTypeOld))
		{
			result->retrieveSettingsFromAttribute();
			oDescr = pFactory::Instance()->createPObjectDescrFromParameter(referenceObject->GetAttributeParameter(GetPMan()->GetPAttribute()));

			

		}
		
		bool hierarchy = result->getFlags() & BF_Hierarchy;
		bool isDeformable = result->getFlags() & BF_Deformable;
		bool  trigger = (result->getFlags() & BF_TriggerShape);


		//----------------------------------------------------------------
		//
		// the new way 
		//

		if (referenceObject->HasAttribute(attTypeNew))
		{
			oDescr = new pObjectDescr();

		}

		
		result->checkDataFlags();

		
		

		/*
		pObjectDescr *oDescr = 
		if (!oDescr)
			return result;

		*/

		//################################################################
		//
		//	Older versions have the hierarchy mode settings not the body flags
		//	We migrate it :
		//

		if (oDescr->hirarchy)
		{
			result->setFlags( (result->getFlags() | BF_Hierarchy ));
		}
		if (hierarchy)
		{
			oDescr->hirarchy = hierarchy;
		}
		//################################################################
		//
		// Deformable ?
		//

		
		pCloth *cloth = NULL;
		pClothDesc cDescr;
		
		if (isDeformable)
		{
			cDescr.setToDefault();
			cDescr.worldReference = worldReferenceObject->GetID();

			if ( result->getFlags() & BF_Gravity )
			{
				cDescr.flags |= PCF_Gravity;
			}

			if ( result->getFlags() & BF_Collision )
			{

			}

			if (!cloth)
			{
				cloth = pFactory::Instance()->createCloth(referenceObject,cDescr);
				if (!cloth)
				{
					xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Cannot create cloth : factory object failed !");
				}
			}
		}

		
		//################################################################
		//
		// Some settings
		//
		if (result->getSkinWidth()==-1.0f)
		{
			result->setSkinWidth(0.01f);
		}

		float radius = referenceObject->GetRadius();
		if (referenceObject->GetRadius() < 0.001f )
		{
			radius  = 1.0f;
		}

		float density = result->getDensity();
		VxVector box_s= BoxGetZero(referenceObject);
		
		//################################################################
		//
		// Calculate destination matrix 
		//

		VxMatrix v_matrix ;
		VxVector position,scale;		
		VxQuaternion quat;	


		v_matrix = referenceObject->GetWorldMatrix();
		Vx3DDecomposeMatrix(v_matrix,quat,position,scale);
		
		NxVec3 pos = pMath::getFrom(position);
		NxQuat rot = pMath::getFrom(quat);


		//////////////////////////////////////////////////////////////////////////
		//create actors description
		NxActorDesc actorDesc;actorDesc.setToDefault();
		NxBodyDesc bodyDesc;bodyDesc.setToDefault();

		
		NxMaterialDesc *materialDescr = NULL;
		NxMaterial *material = NULL;

		

		
		switch(result->getHullType())
		{

			//////////////////////////////////////////////////////////////////////////
			case HT_Box:
			{
				NxBoxShapeDesc shape;

				if (! isDeformable )
				{
					shape.dimensions = pMath::getFrom(box_s)*0.5f;
				}
				
				shape.density  = density;
				//shape.localPose.t = pMath::getFrom(shapeOffset);
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();

				actorDesc.shapes.pushBack(&shape);

				
				break;
			}
			//////////////////////////////////////////////////////////////////////////
			case HT_Sphere:
			{
				NxSphereShapeDesc shape;
				
				
				if (! isDeformable )
				{
					shape.radius = radius;
				}
				
				shape.density  = density;
				//shape.localPose.t = pMath::getFrom(shapeOffset);
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();

				actorDesc.shapes.pushBack(&shape);
				
				break;
			}
			//////////////////////////////////////////////////////////////////////////
			case HT_Mesh:
			{

				if (! (result->getFlags() & BF_Deformable) )
				{

					//xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Can not use a mesh as de");
					//return NULL;

				}
	
				NxTriangleMeshDesc myMesh;
				myMesh.setToDefault();

				createMesh(world->getScene(),referenceObject->GetCurrentMesh(),myMesh);

				NxTriangleMeshShapeDesc shape;
				bool status = InitCooking();
				if (!status) {
						xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!");
						return NULL;
				}
				MemoryWriteBuffer buf;

				status = CookTriangleMesh(myMesh, buf);
				if (!status) {
						xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't cook mesh!");
						return NULL;
				}
				shape.meshData	= getManager()->getPhysicsSDK()->createTriangleMesh(MemoryReadBuffer(buf.data));
				shape.density  = density;
			//	shape.materialIndex = result->getMaterial()->getMaterialIndex();
				actorDesc.shapes.pushBack(&shape);
				//shape.localPose.t = pMath::getFrom(shapeOffset);
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();
				CloseCooking();

				if (myMesh.points)
				{
					delete [] myMesh.points;
				}

				if (myMesh.triangles)
				{
					delete []myMesh.triangles;
				}

				break;
			}
			//////////////////////////////////////////////////////////////////////////
			case HT_ConvexMesh:
			{
				if (referenceObject->GetCurrentMesh())
				{
					if (referenceObject->GetCurrentMesh()->GetVertexCount()>=256 )
					{
						xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Only 256 vertices for convex meshs allowed, by Ageia!");
						goto nothing;
					}
				}else
				{
					xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Object has no mesh!");
					goto nothing;


				}

				NxConvexMeshDesc myMesh;
				myMesh.setToDefault();
				createConvexMesh(world->getScene(),referenceObject->GetCurrentMesh(),myMesh);

				NxConvexShapeDesc shape;
				bool status = InitCooking();
				if (!status) {
						xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!");
						goto nothing;
						
				}
				MemoryWriteBuffer buf;

				status = CookConvexMesh(myMesh, buf);
				if (!status) {
						xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't cook convex mesh!");
						goto nothing;
				}
				shape.meshData	= getManager()->getPhysicsSDK()->createConvexMesh(MemoryReadBuffer(buf.data));
				shape.density  = density;
			//	shape.materialIndex = result->getMaterial()->getMaterialIndex();
				actorDesc.shapes.pushBack(&shape);
				//shape.localPose.t = pMath::getFrom(shapeOffset);
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();
				int h = shape.isValid();
				CloseCooking();


				if (myMesh.points)
				{
					delete [] myMesh.points;
				}

				if (myMesh.triangles)
				{
					delete []myMesh.triangles;
				}


				break;
			}

			//////////////////////////////////////////////////////////////////////////
			case HT_ConvexCylinder:
			{
				NxConvexShapeDesc shape;
				if (!_createConvexCylinder(&shape,referenceObject))
					xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't create convex cylinder mesh");

				shape.density  = density;
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();
				
				actorDesc.shapes.pushBack(&shape);
				break;
			}
			//////////////////////////////////////////////////////////////////////////
			case HT_Capsule:
			{

				NxCapsuleShapeDesc shape;

				if ( !isDeformable )
				{

					pCapsuleSettings cSettings;
					
					pFactory::Instance()->findSettings(cSettings,referenceObject);
					
					shape.radius = cSettings.radius > 0.0f ? cSettings.radius : box_s.v[cSettings.localRadiusAxis] * 0.5f;
					shape.height = cSettings.height > 0.0f ? cSettings.height : box_s.v[cSettings.localLengthAxis]  -  ( 2*shape.radius) ;
				}
				shape.density  = density;
			//	shape.materialIndex = result->getMaterial()->getMaterialIndex();
			//	shape.localPose.t = pMath::getFrom(shapeOffset);
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();
				actorDesc.shapes.pushBack(&shape);
				break;
			}

			case HT_Wheel:
			{
				//		xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't create convex cylinder mesh");


				/*
				NxWheelShapeDesc shape;
				shape.radius = box_s.z*0.5f;
				shape.density  = density;
				if (result->getSkinWidth()!=-1.0f)
					shape.skinWidth = result->getSkinWidth();

				if (referenceObject && referenceObject->HasAttribute(GetPMan()->att_wheelDescr ))
				{
					CKParameter *par = referenceObject->GetAttributeParameter(GetPMan()->att_wheelDescr );
					if (par)
					{
						pWheelDescr *wheelDescr = pFactory::Instance()->copyTo(par);
						if (wheelDescr)
						{

							float heightModifier = (wheelDescr->wheelSuspension + radius ) / wheelDescr->wheelSuspension;
							shape.suspension.damper = wheelDescr->springDamping * heightModifier;
							shape.suspension.targetValue = wheelDescr->springBias * heightModifier;
							shape.suspensionTravel = wheelDescr->wheelSuspension;

							shape.lateralTireForceFunction.stiffnessFactor *= wheelDescr->frictionToSide;
							shape.longitudalTireForceFunction.stiffnessFactor*=wheelDescr->frictionToFront;
							shape.inverseWheelMass = 0.1;
							int isValid = shape.isValid();
							

							actorDesc.shapes.pushBack(&shape);
						}
					}else
					{
						XString name = result->GetVT3DObject()->GetName();
						name << " needs to have an additional wheel attribute attached ! ";
						xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,name.CStr());
					}
				}
				*/
				break;
			}
		}

		
		//////////////////////////////////////////////////////////////////////////
		//dynamic object  ? 
		if (result->getFlags() & BF_Moving){
			actorDesc.body = &bodyDesc;
		}
		else
			actorDesc.body = NULL;

		//////////////////////////////////////////////////////////////////////////
		//set transformations
		actorDesc.density  = result->getDensity();


		if ( !isDeformable)
		{
			actorDesc.globalPose.t = pos;	
			actorDesc.globalPose.M = rot;
		}
		
		
		//////////////////////////////////////////////////////////////////////////
		//create the actor

		int v = actorDesc.isValid();
		NxActor *actor  = world->getScene()->createActor(actorDesc);
		if (!actor)
		{
			xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor");
			delete result;
			return NULL;
			
		}

		//////////////////////////////////////////////////////////////////////////
		//set additional settings : 
		result->setActor(actor);
		actor->setName(referenceObject->GetName());
		actor->userData= result;

		//////////////////////////////////////////////////////////////////////////
		//Deformable : 
		if (isDeformable && cloth)
		{

			pDeformableSettings dSettings;
			dSettings.ImpulsThresold = 50.0f;
			dSettings.PenetrationDepth= 0.1f ;
			dSettings.MaxDeform = 2.0f;

			CKParameterOut *poutDS = referenceObject->GetAttributeParameter(GetPMan()->att_deformable);
			if (poutDS)
			{
				pFactory::Instance()->copyTo(dSettings,poutDS);
			}
			cloth->attachToCore(referenceObject,dSettings.ImpulsThresold,dSettings.PenetrationDepth,dSettings.MaxDeform);
			result->setCloth(cloth);
		}


		//////////////////////////////////////////////////////////////////////////
		//
		//	Extra settings : 
		//

		if (result->getFlags() & BF_Moving)
		{
			VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&result->getMassOffset());
			actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut));
		}

		
		if (result->getFlags() & BF_Kinematic)
		{
			result->setKinematic(true);
		}

		
		
		if (result->getFlags() & BF_Moving )
		{
			result->enableGravity(result->getFlags() & BF_Gravity);
		}

		//----------------------------------------------------------------
		//
		// Special Parameters
		//

		//-	look for optimization attribute :
		result->checkForOptimization();

		

		
		//----------------------------------------------------------------
		//
		// store mesh meta info in the first main mesh
		//
		NxShape *shape  = result->getShapeByIndex();
		if (shape)
		{
			pSubMeshInfo *sInfo  = new pSubMeshInfo();
			sInfo->entID = referenceObject->GetID();
			sInfo->refObject  = (CKBeObject*)referenceObject;
			shape->userData = (void*)sInfo;
			result->setMainShape(shape);
			shape->setName(referenceObject->GetName());

			pMaterial bMaterial;
			bool hasMaterial = pFactory::Instance()->findSettings(bMaterial,referenceObject);
			if (!hasMaterial)
			{
				if (world->getDefaultMaterial())
				{
					int z = (int)world->getDefaultMaterial()->userData;
					shape->setMaterial(world->getDefaultMaterial()->getMaterialIndex());
					//pFactory::Instance()->copyTo(bMaterial,world->getDefaultMaterial());
				}
			}else{
				
				NxMaterialDesc nxMatDescr;
				pFactory::Instance()->copyTo(nxMatDescr,bMaterial);
				NxMaterial *nxMaterial  = world->getScene()->createMaterial(nxMatDescr);
				if (nxMaterial)
				{
					shape->setMaterial(nxMaterial->getMaterialIndex());
				}
			}
		}

		result->enableCollision( (result->getFlags() & BF_Collision), referenceObject );

        
		//- handle collisions setup
		if (oDescr->version == pObjectDescr::E_OD_VERSION::OD_DECR_V1)
			result->updateCollisionSettings(*oDescr,referenceObject);





		xLogger::xLog(ELOGINFO,E_LI_MANAGER,"Rigid body creation successful : %s",referenceObject->GetName());

		//----------------------------------------------------------------
		//
		// Parse hierarchy 
		//
		if (!oDescr->hirarchy)
			return result;

		CK3dEntity* subEntity = NULL;
		while (subEntity= referenceObject->HierarchyParser(subEntity) )
		{
			if (subEntity->HasAttribute(GetPMan()->GetPAttribute()))
			{
				pObjectDescr *subDescr = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute()));
				if (subDescr->flags & BF_SubShape)
				{

					//////////////////////////////////////////////////////////////////////////
					//
					//			Regular Mesh : 
					//

					if (subDescr->hullType != HT_Cloth)
					{
						result->addSubShape(NULL,*oDescr,subEntity);
					}

					//////////////////////////////////////////////////////////////////////////
					//
					//			Cloth Mesh : 
					//
					if (subDescr->hullType == HT_Cloth)
					{
						//pClothDesc *cloth = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute()));
					}
				}
			}
		}

		if (oDescr->hirarchy)
		{
		

			if (oDescr->newDensity!=0.0f || oDescr->totalMass!=0.0f )
			{
				result->updateMassFromShapes(oDescr->newDensity,oDescr->totalMass);
			}
		}


		return result;

	}
	nothing:

	

	return result;
}
		//-----------------------------------------------------------------------
		PhysicsActor* PhysXActorExtern::createPhysicsActor(PhysicsActorDesc* physicsActorDesc, PhysicsShapeDesc* physicsShapeDesc)
		{
			if (!PhysXBridge::getSingletonPtr()->getScene() || !physicsActorDesc || !physicsShapeDesc)
				return 0;

			NxBodyDesc bodyDesc;
			bodyDesc.setToDefault();
			NxReal angularDamping = bodyDesc.angularDamping;
			NxVec3 angularVelocity = bodyDesc.angularVelocity;
			NxVec3 linearVelocity = bodyDesc.linearVelocity;
			bodyDesc.angularDamping = physicsShapeDesc->mAngularDamping;
			bodyDesc.angularVelocity = PhysXMath::convert(physicsShapeDesc->mAngularVelocity);
			bodyDesc.linearVelocity = PhysXMath::convert(physicsActorDesc->direction);

			NxActorDesc actorDesc;
			NxActorDesc defaultActorDesc;
			actorDesc.setToDefault();
			defaultActorDesc.setToDefault();
			switch (physicsShapeDesc->mPhysicsShapeType)
			{
				case ST_BOX:
				{
					PhysicsBoxDesc* physicsBoxDesc = static_cast<PhysicsBoxDesc*>(physicsShapeDesc);
					NxBoxShapeDesc boxDesc;
					boxDesc.setToDefault();
					boxDesc.dimensions = PhysXMath::convert(physicsBoxDesc->mDimensions);
					boxDesc.group = physicsBoxDesc->mCollisionGroup;
					boxDesc.groupsMask = PhysXMath::convert(physicsBoxDesc->mGroupMask);
					boxDesc.materialIndex = physicsBoxDesc->mMaterialIndex;
					actorDesc.density = NxComputeBoxDensity(2 * boxDesc.dimensions, physicsActorDesc->mass);
					actorDesc.shapes.pushBack(&boxDesc);
				}
				break;

				case ST_SPHERE:
				{
					PhysicsSphereDesc* physicsSphereDesc = static_cast<PhysicsSphereDesc*>(physicsShapeDesc);
					NxSphereShapeDesc sphereDec;
					sphereDec.setToDefault();
					sphereDec.radius = physicsSphereDesc->mRadius;
					sphereDec.group = physicsSphereDesc->mCollisionGroup;
					sphereDec.groupsMask = PhysXMath::convert(physicsSphereDesc->mGroupMask);
					sphereDec.materialIndex = physicsSphereDesc->mMaterialIndex;
					actorDesc.density = NxComputeSphereDensity(sphereDec.radius, physicsActorDesc->mass);
					actorDesc.shapes.pushBack(&sphereDec);
				}
				break;

				case ST_CAPSULE:
				{
					PhysicsCapsuleDesc* physicsCapsuleDesc = static_cast<PhysicsCapsuleDesc*>(physicsShapeDesc);
					NxCapsuleShapeDesc capsuleDec;
					capsuleDec.setToDefault();
					capsuleDec.radius = physicsCapsuleDesc->mRadius;
					capsuleDec.height = physicsCapsuleDesc->mHeight;
					capsuleDec.group = physicsCapsuleDesc->mCollisionGroup;
					capsuleDec.groupsMask = PhysXMath::convert(physicsCapsuleDesc->mGroupMask);
					capsuleDec.materialIndex = physicsCapsuleDesc->mMaterialIndex;
					actorDesc.density = NxComputeCylinderDensity(capsuleDec.radius, capsuleDec.height, physicsActorDesc->mass);
					actorDesc.shapes.pushBack(&capsuleDec);
				}
				break;
			}
			actorDesc.globalPose.t = PhysXMath::convert(physicsActorDesc->position);
			actorDesc.body = &bodyDesc;
			actorDesc.group = physicsActorDesc->collisionGroup;
			PhysXActor* physXActor = 0;
			if (!actorDesc.isValid())
			{
				actorDesc = defaultActorDesc;
				Ogre::LogManager::getSingleton().logMessage("ParticleUniverse PhysXActor: Cannot create actor; use default attributes.");
			}
			NxActor* nxActor = PhysXBridge::getSingletonPtr()->getScene()->createActor(actorDesc);

			if (nxActor)
			{
				physXActor = OGRE_NEW_T(PhysXActor, Ogre::MEMCATEGORY_SCENE_OBJECTS)();
				physXActor->position = PhysXMath::convert(nxActor->getGlobalPosition());
				physXActor->direction = PhysXMath::convert(nxActor->getLinearVelocity());
				nxActor->setGlobalOrientationQuat(PhysXMath::convert(physicsActorDesc->orientation));
				physXActor->orientation = physicsActorDesc->orientation;
				physXActor->mass = nxActor->getMass();
				physXActor->collisionGroup = nxActor->getGroup();
				physXActor->nxActor = nxActor;
			}
			return physXActor;
		}
Пример #11
0
NxActor* CreateConvex(const NxVec3 &pos, int flag)
{
   NxActorDesc actorDesc;
    NxBodyDesc bodyDesc;
	
	NxVec3 boxDim(1,0.8,1.5);
    // Pyramid
     NxVec3 verts[8] =	{	NxVec3(boxDim.x,      -boxDim.y, -boxDim.z), 
							NxVec3(-boxDim.x,     -boxDim.y, -boxDim.z), 
							NxVec3(-boxDim.x,     -boxDim.y, boxDim.z),
							NxVec3(boxDim.x,      -boxDim.y, boxDim.z), 
							NxVec3(boxDim.x*0.5,  boxDim.y,  -boxDim.z*0.5), 
							NxVec3(-boxDim.x*0.5, boxDim.y,  -boxDim.z*0.5),
							NxVec3(-boxDim.x*0.5, boxDim.y,  boxDim.z*0.5), 
							NxVec3(boxDim.x*0.5,  boxDim.y,  boxDim.z*0.5)
						};


	// Create descriptor for convex mesh
	 if (!convexDesc)
	 {
		convexDesc = new  NxConvexMeshDesc();
		assert(convexDesc);
	 }

    convexDesc->numVertices			= 8;
    convexDesc->pointStrideBytes	= sizeof(NxVec3);
    convexDesc->points				= verts;
	convexDesc->flags				= NX_CF_COMPUTE_CONVEX;

	NxConvexShapeDesc convexShapeDesc;
	convexShapeDesc.localPose.t		= NxVec3(0, 2.0f, boxDim.z * 0.4);
	convexShapeDesc.userData		= convexDesc;
 
	NxInitCooking();
	// Cooking from memory
    MemoryWriteBuffer buf;
    bool status = NxCookConvexMesh(*convexDesc, buf);
	//
	// Please note about the created Convex Mesh, user needs to release it when no one uses it to save memory. It can be detected
	// by API "meshData->getReferenceCount() == 0". And, the release API is "gPhysicsSDK->releaseConvexMesh(*convexShapeDesc.meshData);"
	//
	NxConvexMesh *pMesh			= gPhysicsSDK->createConvexMesh(MemoryReadBuffer(buf.data));
	assert(pMesh);
    convexShapeDesc.meshData	= pMesh;
	NxCloseCooking();

    if (pMesh)
    {
        // Save mesh in userData for drawing.
		pMesh->saveToDesc(*convexDesc);
		//
		NxActorDesc actorDesc;
		assert(convexShapeDesc.isValid());
		actorDesc.shapes.pushBack(&convexShapeDesc);
		if (0 == flag)
		{	//Dynamic actor
			bodyDesc.flags	   |= NX_BF_DISABLE_GRAVITY;
			actorDesc.body		= &bodyDesc;
			actorDesc.density	= 1.0f;
		}
		else if (1 == flag)
		{	//Static actor
			actorDesc.body		= NULL;
			actorDesc.density	= 1.0f;
		}
		else if (2 == flag)
		{	// Kinematic actor
			bodyDesc.flags	   |= NX_BF_KINEMATIC;
			actorDesc.body		= &bodyDesc;
			actorDesc.density	= 1.0f;
		}

		actorDesc.globalPose.t  = pos; //NxVec3(6.5f, 0.0f, 0.0f);
		assert(actorDesc.isValid());
		NxActor* actor = gScene->createActor(actorDesc);
		assert(actor);	
		return actor;
    }

    return NULL;
}
Пример #12
0
NxActor* CreateLander(NxVec3 position)
{
	NxActor* actor=NULL;
	switch (gLanderType)
	{
		case CAPSULE_LANDER:
			actor = CreateCapsuleGrain(position,gLanderMass/pow(gLanderSize.x,3.0f),gLanderSize.x);
			break;
		case SPHERE_LANDER:
			actor = CreateSphericalGrain(position,gLanderMass/pow(gLanderSize.x,3.0f),gLanderSize.x);
			break;
		case ROLY_POLY:
			{// Two slightly offset spheres, one heavy, one slightly smaller, and hollow
				NxActorDesc actorDesc;
				NxBodyDesc bodyDesc;
				NxReal radius=gLanderSize.x;

				// The bottom "roly"
				NxSphereShapeDesc rolyDesc;
				rolyDesc.radius=radius*gLanderSize.z; // relative to top hemisphere
				rolyDesc.localPose.t=NxVec3(0.0f,radius,0.0f);
				rolyDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); // note: both hemispheres use "down" material
				rolyDesc.mass=1; // relative to top hemisphere
				rolyDesc.skinWidth=radius/60;
				rolyDesc.name="downside";
				actorDesc.shapes.pushBack(&rolyDesc);

				// The top "poly"
				NxSphereShapeDesc polyDesc;
				polyDesc.radius=radius;
				polyDesc.localPose.t=NxVec3(0.0f,radius+gLanderSize.y,0.0f);
				polyDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); // note: both hemispheres use "down" material
				polyDesc.mass=1;
				polyDesc.skinWidth=radius/60;
				polyDesc.name="upside";
				actorDesc.shapes.pushBack(&polyDesc);

				// The weight
				NxSphereShapeDesc wDesc;
				wDesc.radius=radius/10;
				wDesc.localPose.t=NxVec3(0.0f,wDesc.radius,0.0f);
				wDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); // note: this is irrelevant
				wDesc.mass=gRPWeight; // relative to top hemisphere
				wDesc.skinWidth=radius/120;
				wDesc.name="weight";
				actorDesc.shapes.pushBack(&wDesc);

				// the lander
				bodyDesc.mass=gLanderMass;
				actorDesc.body=&bodyDesc;
				actorDesc.globalPose.t=position;
				assert(actorDesc.isValid());
				actor=gScene->createActor(actorDesc);
				assert(actor);
				actor->setName("~lander");
				//actor->raiseBodyFlag(NX_BF_KINEMATIC);

				break;
			}
		case SHAPED_CHARGE:
			{// Two flat plates, like a two-layer ruler, one heavy and absorbing, one hollow and elastic
				NxActorDesc actorDesc;
				NxBodyDesc bodyDesc;
				NxVec3 boxDim=gLanderSize/2; // remember NxShapeDesc.dimension is the "radius"
				boxDim.y/=2; // remember we're going to stack two of these

				// The down side
				NxBoxShapeDesc downsideDesc;
				downsideDesc.dimensions.set(boxDim);
				downsideDesc.localPose.t=NxVec3(0.0f,boxDim.y,0.0f);
				downsideDesc.materialIndex=gLanderDownMaterial->getMaterialIndex();
				downsideDesc.density=gLanderMassRatio;
				downsideDesc.skinWidth=boxDim.y/60;
				downsideDesc.name="downside";
				actorDesc.shapes.pushBack(&downsideDesc);

				// The up side
				NxBoxShapeDesc upsideDesc;
				upsideDesc.dimensions.set(boxDim);
				upsideDesc.localPose.t=NxVec3(0.0f,3.0*boxDim.y,0.0f);
				upsideDesc.materialIndex=gLanderUpMaterial->getMaterialIndex();
				upsideDesc.density=1;
				upsideDesc.skinWidth=boxDim.y/60;
				upsideDesc.name="upside";
				actorDesc.shapes.pushBack(&upsideDesc);

				// The Lander
				bodyDesc.mass=gLanderMass;
				actorDesc.body = &bodyDesc;
				actorDesc.globalPose.t	= position;
				assert(actorDesc.isValid());
				actor = gScene->createActor(actorDesc);	
				assert(actor);
				actor->setName("~lander");

				break;
			}
		case CUBESAT:
			{// JPL's new fad, comes in units of 10x10x10 cm
				NxActorDesc actorDesc;
				NxBodyDesc bodyDesc;
				NxVec3 boxDim(0.05); // remember NxShapeDesc.dimension is the "radius"

				// U1 - the dead weight
				NxBoxShapeDesc U1Desc;
				U1Desc.dimensions.set(boxDim);
				U1Desc.localPose.t=NxVec3(0.0f,boxDim.y,0.0f);
				U1Desc.materialIndex=gLanderDownMaterial->getMaterialIndex();
				U1Desc.mass=10*gLanderMass;
				U1Desc.skinWidth=boxDim.y/60;
				U1Desc.name="U1";
				actorDesc.shapes.pushBack(&U1Desc);

				// U2
				NxBoxShapeDesc U2Desc;
				U2Desc.dimensions.set(boxDim);
				U2Desc.localPose.t=NxVec3(0.0f,3.0*boxDim.y,0.0f);
				U2Desc.materialIndex=gLanderUpMaterial->getMaterialIndex();
				U2Desc.mass=gLanderMass;
				U2Desc.skinWidth=boxDim.y/60;
				U2Desc.name="U2";
				actorDesc.shapes.pushBack(&U2Desc);

				// U3
				NxBoxShapeDesc U3Desc;
				U3Desc.dimensions.set(boxDim);
				U3Desc.localPose.t=NxVec3(0.0f,5.0*boxDim.y,0.0f);
				U3Desc.materialIndex=gLanderUpMaterial->getMaterialIndex();
				U3Desc.mass=gLanderMass;
				U3Desc.skinWidth=boxDim.y/60;
				U3Desc.name="U3";
				actorDesc.shapes.pushBack(&U3Desc);

				// The Cubesat
				bodyDesc.mass=gLanderMass;
				actorDesc.body = &bodyDesc;
				actorDesc.globalPose.t	= position;
				assert(actorDesc.isValid());
				actor = gScene->createActor(actorDesc);	
				assert(actor);
				actor->setName("~lander");
				break;
			}
		default:
			printf("Error: unknown lander type\n");
			break;
	}

	return actor;
}
Пример #13
0
static bool InitNx()
	{

	if (!gAllocator)
		gAllocator = new UserAllocator;

	// Initialize PhysicsSDK
	NxPhysicsSDKDesc desc;
	NxSDKCreateError errorCode = NXCE_NO_ERROR;
	gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, gAllocator, &gErrorStream, desc, &errorCode);
	if(gPhysicsSDK == NULL) 
		{
		printf("\nSDK create error (%d - %s).\nUnable to initialize the PhysX SDK, exiting the sample.\n\n", errorCode, getNxSDKCreateError(errorCode));
		return false;
		}
#if SAMPLES_USE_VRD
	// The settings for the VRD host and port are found in SampleCommonCode/SamplesVRDSettings.h
	if (gPhysicsSDK->getFoundationSDK().getRemoteDebugger() && !gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->isConnected())
		gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect(SAMPLES_VRD_HOST, SAMPLES_VRD_PORT, SAMPLES_VRD_EVENTMASK);
#endif

	gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.025f);
	//enable visualisation
	gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1.0f);
	gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1.0f);
		
	// Create a scene
	NxSceneDesc sceneDesc;
	sceneDesc.gravity				= gDefaultGravity;
	gScene = gPhysicsSDK->createScene(sceneDesc);
	if(gScene == NULL) 
		{
		printf("\nError: Unable to create a PhysX scene, exiting the sample.\n\n");
		return false;
		}

	//create some materials -- note that we reuse the same NxMaterialDesc every time,
	//as it gets copied to the SDK with every call, not just referenced.
	NxMaterialDesc	material;
	
	//default material
	material.restitution		= 0.0f;
	material.staticFriction		= 0.5f;
	material.dynamicFriction	= 0.5f;
	defaultMaterialIndex = 0;
	gScene->getMaterialFromIndex(defaultMaterialIndex)->loadFromDesc(material);//we redefine the default material in slot 0
	
	
	//somewhat bouncy material
	material.restitution		= 0.75f;
	material.staticFriction		= 0.5f;
	material.dynamicFriction	= 0.5f;
	somewhatBouncyMaterialIndex = gScene->createMaterial(material)->getMaterialIndex();
	
	//very bouncy material
	material.restitution		= 1.0f;
	material.staticFriction		= 0.5f;
	material.dynamicFriction	= 0.5f;
	veryBouncyMaterialIndex = gScene->createMaterial(material)->getMaterialIndex();
	
	//almost frictionless material
	material.restitution		= 0.0f;
	material.staticFriction		= 0.01f;
	material.dynamicFriction	= 0.01f;
	frictionlessMaterialIndex = gScene->createMaterial(material)->getMaterialIndex();
	
	//really high friction material
	material.restitution		= 0.0f;
	material.staticFriction		= 20.0f;//static friction can be higher than 1.
	material.dynamicFriction	= 1.0f;	//dynamic friction should not be higher than 1.
	highFrictionMaterialIndex = gScene->createMaterial(material)->getMaterialIndex();
	
	//anisotropic friction material
	material.restitution		= 0.0f;
	material.staticFriction		= 0.1f;
	material.dynamicFriction	= 0.1f;	
	material.dynamicFrictionV	= 0.8f;
	material.staticFrictionV	= 1.0f;
	material.dirOfAnisotropy.set(1.5,0,1);	//this will be used on one of the ramps so that boxes slide off at an angle
	material.dirOfAnisotropy.normalize();
	material.flags				= NX_MF_ANISOTROPIC;
	anisoMaterialIndex = gScene->createMaterial(material)->getMaterialIndex();
	material.setToDefault();		//turn off aniso on our material object in case we want to use it again.
	

	
	// Create ground plane
	NxPlaneShapeDesc planeDesc;
	planeDesc.materialIndex = frictionlessMaterialIndex;
	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&planeDesc);
	gScene->createActor(actorDesc);

	//create some ramps
	NxBoxShapeDesc anisoBoxDesc;
	anisoBoxDesc.dimensions		= NxVec3(float(20), float(2), float(30));
	anisoBoxDesc.materialIndex	= anisoMaterialIndex;
	
	actorDesc.setToDefault();
	actorDesc.shapes.pushBack(&anisoBoxDesc);
	actorDesc.globalPose.t.set(0,20.0f,0);
	float angle = NxMath::degToRad(30.0f);
	actorDesc.globalPose.M(0,0) = 1;		actorDesc.globalPose.M(0,1) = 0;		actorDesc.globalPose.M(0,2) = 0;
	actorDesc.globalPose.M(1,0) = 0;		actorDesc.globalPose.M(1,1) = cos(angle);		actorDesc.globalPose.M(1,2) = -sin(angle);
	actorDesc.globalPose.M(2,0) = 0;		actorDesc.globalPose.M(2,1) = sin(angle);		actorDesc.globalPose.M(2,2) = cos(angle);
	gScene->createActor(actorDesc);

	NxBoxShapeDesc frictlessBoxDesc;
	frictlessBoxDesc.dimensions		= NxVec3(float(20), float(2), float(30));
	frictlessBoxDesc.materialIndex	= frictionlessMaterialIndex;

	actorDesc.setToDefault();
	actorDesc.shapes.clear();
	actorDesc.shapes.pushBack(&frictlessBoxDesc);
	actorDesc.globalPose.t.set(-40,20.0f,0);
	actorDesc.globalPose.M(0,0) = 1;		actorDesc.globalPose.M(0,1) = 0;		actorDesc.globalPose.M(0,2) = 0;
	actorDesc.globalPose.M(1,0) = 0;		actorDesc.globalPose.M(1,1) = cos(angle);		actorDesc.globalPose.M(1,2) = -sin(angle);
	actorDesc.globalPose.M(2,0) = 0;		actorDesc.globalPose.M(2,1) = sin(angle);		actorDesc.globalPose.M(2,2) = cos(angle);
	gScene->createActor(actorDesc);

	NxBoxShapeDesc hiFrictBoxDesc;
	hiFrictBoxDesc.dimensions		= NxVec3(float(20), float(2), float(30));
	hiFrictBoxDesc.materialIndex	= highFrictionMaterialIndex;

	actorDesc.setToDefault();
	actorDesc.shapes.clear();
	actorDesc.shapes.pushBack(&hiFrictBoxDesc);
	actorDesc.globalPose.t.set(40,20.0f,0);
	actorDesc.globalPose.M(0,0) = 1;		actorDesc.globalPose.M(0,1) = 0;		actorDesc.globalPose.M(0,2) = 0;
	actorDesc.globalPose.M(1,0) = 0;		actorDesc.globalPose.M(1,1) = cos(angle);		actorDesc.globalPose.M(1,2) = -sin(angle);
	actorDesc.globalPose.M(2,0) = 0;		actorDesc.globalPose.M(2,1) = sin(angle);		actorDesc.globalPose.M(2,2) = cos(angle);
	gScene->createActor(actorDesc);

	return true;
	}