PxRigidDynamic* createVehicleActor4W
(const PxVehicleChassisData& chassisData,
 PxConvexMesh** wheelConvexMeshes, PxConvexMesh* chassisConvexMesh, 
 PxScene& scene, PxPhysics& physics, const PxMaterial& material)
{
	//We need a rigid body actor for the vehicle.
	//Don't forget to add the actor the scene after setting up the associated vehicle.
	PxRigidDynamic* vehActor=physics.createRigidDynamic(PxTransform::createIdentity());

	//We need to add wheel collision shapes, their local poses, a material for the wheels, and a simulation filter for the wheels.
	PxConvexMeshGeometry frontLeftWheelGeom(wheelConvexMeshes[0]);
	PxConvexMeshGeometry frontRightWheelGeom(wheelConvexMeshes[1]);
	PxConvexMeshGeometry rearLeftWheelGeom(wheelConvexMeshes[2]);
	PxConvexMeshGeometry rearRightWheelGeom(wheelConvexMeshes[3]);
	const PxGeometry* wheelGeometries[4]={&frontLeftWheelGeom,&frontRightWheelGeom,&rearLeftWheelGeom,&rearRightWheelGeom};
	const PxTransform wheelLocalPoses[4]={PxTransform::createIdentity(),PxTransform::createIdentity(),PxTransform::createIdentity(),PxTransform::createIdentity()};
	const PxMaterial& wheelMaterial=material;
	PxFilterData wheelCollFilterData;
	wheelCollFilterData.word0=COLLISION_FLAG_WHEEL;
	wheelCollFilterData.word1=COLLISION_FLAG_WHEEL_AGAINST;

	//We need to add chassis collision shapes, their local poses, a material for the chassis, and a simulation filter for the chassis.
	PxConvexMeshGeometry chassisConvexGeom(chassisConvexMesh);
	const PxGeometry* chassisGeoms[1]={&chassisConvexGeom};
	const PxTransform chassisLocalPoses[1]={PxTransform::createIdentity()};
	const PxMaterial& chassisMaterial=material;
	PxFilterData chassisCollFilterData;
	chassisCollFilterData.word0=COLLISION_FLAG_CHASSIS;
	chassisCollFilterData.word1=COLLISION_FLAG_CHASSIS_AGAINST;

	//Create a query filter data for the car to ensure that cars
	//do not attempt to drive on themselves.
	PxFilterData vehQryFilterData;
	SampleVehicleSetupVehicleShapeQueryFilterData(&vehQryFilterData);

	//Set up the physx rigid body actor with shapes, local poses, and filters.
	setupActor
		(vehActor,
		vehQryFilterData,
		wheelGeometries,wheelLocalPoses,4,&wheelMaterial,wheelCollFilterData,
		chassisGeoms,chassisLocalPoses,1,&chassisMaterial,chassisCollFilterData,
		chassisData,
		&physics);

	return vehActor;
}
Example #2
0
bool CTank::CreateTankActor( CPhysX * pPhysX )
{
	if( !LoadData( "InitShader.lua" ) )
		return false;

// 	CParamTank* pParamTank = new CParamTank;
// 
// 	if( !CLua::LoadParamTank( "", &pParamTank ) )
// 	{
// 
// 	}

	if( GameObject * pBody = GetDetail( BODY ) )
	{
		if ( pBody->CreateTriangleMesh( pPhysX ) )
		{			
			pBody->Update( 0.f );
			
			PxTriangleMesh* triangleMesh = pBody->GetTriangleMesh();
			D3DXVECTOR3     Position     = pBody->GetPosition();
			//D3DXComputeBoundingBox(Vertices,  g_pMesh->GetNumVertices(),  FVFVertexSize, &pMin, &pMax);
			//PxRigidDynamic* pRigDynAct   = pPhysX->GetPhysics()->createRigidDynamic( PxTransform( physx::PxVec3( Position.x, Position.y, Position.z ) ) );
// 			PxRigidDynamic* pRigDynAct   = PxCreateDynamic( *pPhysX->GetPhysics(), PxTransform( physx::PxVec3( Position.x, Position.y, Position.z ) ), PxBoxGeometry( 14.f, 4.6f, 6.f ), *pMaterial, 1.f );
// 
// 			if( pRigDynAct && pMaterial && triangleMesh )
// 			{
// 				//pRigDynAct->createShape( PxTriangleMeshGeometry( triangleMesh ), *pMaterial );
// 				
// 				pRigDynAct->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, false);
// 				pRigDynAct->setActorFlag( PxActorFlag::eVISUALIZATION, true );
// 				pRigDynAct->setAngularDamping( 0.5f );
// 				//pRigDynAct->setMass( 10000.f );
// 				PxRigidBodyExt::updateMassAndInertia( *pRigDynAct, 10.f );
// 				
// 				if( pMaterial )
// 					pPhysX->PushMaterial( pMaterial );
// 				
// 				pPhysX->AddActorScene( pRigDynAct );
// 				m_pActor = pRigDynAct;
// 
// 				return true;
// 			}

			const int    nWheels     = 12;
			PxF32        chassisMass = 1500.f;
			const PxF32  wheelMass   = 50.f;			
			PxF32		 fShift      = -0.85f;
			PxVec3 wheelCentreOffsets[ nWheels ];

			for( int i = 0; i < nWheels/2; ++i )
			{
				wheelCentreOffsets[ i*2   ] = PxVec3( -1.2f, -0.5f,  2.1f + i * fShift );
				wheelCentreOffsets[ i*2+1 ] = PxVec3(  1.2f, -0.5f,  2.1f + i * fShift );				
			}

			// размеры корпуса
			const PxVec3 chassisDims( 2.4f, 1.f, 6.f );// = computeChassisAABBDimensions(chassisConvexMesh);

			// Начало координат находится в центре шасси сетки
			// Установить центр масс будет ниже этой точки
			const PxVec3 chassisCMOffset = PxVec3( 0.f, -chassisDims.y * 0.5f - 0.65f, 0.f );

			PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate( nWheels );
			PxVehicleWheelsSimData& wheelsData = *wheelsSimData;
			PxVehicleDriveSimData4W driveData;
			
			PxVec3 chassisMOI( (chassisDims.y*chassisDims.y + chassisDims.z * chassisDims.z) * chassisMass / 12.f,
							   (chassisDims.x*chassisDims.x + chassisDims.z * chassisDims.z) * chassisMass / 12.f,
							   (chassisDims.x*chassisDims.x + chassisDims.y * chassisDims.y) * chassisMass / 12.f);

			// структура шасси
			PxVehicleChassisData chassisData;
			
			chassisData.mMass	  = chassisMass;		// Масса транспортного средства жесткой актер тела
			chassisData.mMOI	  = chassisMOI;			// Момент инерции автомобиля жесткая актер тела.
			chassisData.mCMOffset = chassisCMOffset;	// Центр масс смещение автомобиля жесткая актер тела.

			// Немного настройки здесь.Автомобиль будет иметь более отзывчивым поворот, если мы сведем
			// у-компоненты шасси момента инерции.
			chassisMOI.y *= 0.8f;

			const PxF32 massRear  = 0.5f * chassisMass * ( chassisDims.z - 3 * chassisCMOffset.z ) / chassisDims.z;
			const PxF32 massFront = massRear;

			//Extract the wheel radius and width from the wheel convex meshes
			PxF32 wheelWidths[ nWheels ] = {0.f};
			PxF32 wheelRadii[ nWheels ]  = {0.f};
			for( PxU32 i = 0; i < nWheels; ++i )
			{
				 wheelWidths[ i ] = 0.5f;
				 wheelRadii [ i ] = 0.32f;
			}

			// Теперь вычислим колеса массы и инерции компонентов вокруг оси оси			
			PxF32 wheelMOIs[ nWheels ];
			for( PxU32 i = 0; i < nWheels; ++i )
			{
				wheelMOIs[ i ] = 0.5f * wheelMass * wheelRadii[ i ] * wheelRadii[ i ];
			}

			// Давайте создадим структуру данных колеса теперь с радиусом, массы и МВД
			PxVehicleWheelData wheels[ nWheels ];
			for(PxU32 i = 0; i < nWheels; ++i )
			{
				wheels[ i ].mRadius				= wheelRadii[ i ];		// Радиус блок, который включает в себя колеса металл плюс резиновые шины
				wheels[ i ].mMass				= wheelMass;			// Масса колеса плюс шины
				wheels[ i ].mMOI				= wheelMOIs[ i ];		// Момент инерции колеса
				wheels[ i ].mWidth				= wheelWidths[ i ];		// Максимальная ширина блок, который включает в себя колеса плюс шин
				//wheels[ i ].mMaxHandBrakeTorque = 0.f;					// Отключение стояночного тормоза от передних колес и позволяют для задних колес
				//wheels[ i ].mMaxSteer			= 0.f;					// Включить рулевого управления для передних колес и отключить для передних колес
				//wheels[ i ].mDampingRate		= 1.f;				// Скорость затухания описывает скорость, с которой свободно вращающееся колесо теряет скорость вращения
			}

			//Let's set up the tire data structures now.
			//Put slicks on the front tires and wets on the rear tires.
			PxVehicleTireData tires[ nWheels ];

			for(PxU32 i = 0; i < nWheels; ++i )
			{				
				tires[ i ].mType = 1;			// тип сцепления шин с поверхностью
			}

			// Структура данных подвески
			PxVehicleSuspensionData susps[ nWheels ];

			for( PxU32 i = 0; i < nWheels; i++ )
			{
				susps[ i ].mMaxCompression	 = 0.03f;				// Максимальное сжатие пружинной подвески
				susps[ i ].mMaxDroop		 = 0.03f;				// Максимальное удлинение пружинной подвески
				susps[ i ].mSpringStrength	 = 20000.f;	// пружинная сила подвески блока
				susps[ i ].mSpringDamperRate = 500.f;
				susps[ i ].mSprungMass		 = chassisMass / nWheels;	// Масса транспортного средства, которая поддерживается пружинная подвеска, указанных в кг.
			}
			
			PxVec3 suspTravelDirections[ nWheels ];
			PxVec3 wheelCentreCMOffsets[ nWheels ];
			PxVec3 suspForceAppCMOffsets[ nWheels ];
			PxVec3 tireForceAppCMOffsets[ nWheels ];

			for( PxU32 i = 0 ; i < nWheels; ++i )
			{
				wheelCentreCMOffsets [ i ] = wheelCentreOffsets[ i ] - chassisCMOffset;
				suspForceAppCMOffsets[ i ] = PxVec3( wheelCentreCMOffsets[ i ].x, -0.3f, wheelCentreCMOffsets[ i ].z );
				tireForceAppCMOffsets[ i ] = PxVec3( wheelCentreCMOffsets[ i ].x, -0.3f, wheelCentreCMOffsets[ i ].z );
				suspTravelDirections [ i ] = PxVec3( 0, -1, 0 );	// направление подвески
			}

			// Теперь добавьте колеса, шины и подвеска данных
			for( PxU32 i = 0; i < nWheels; ++i )
			{
				wheelsData.setWheelData( i, wheels[ i ] );								// установить данные колеса
				wheelsData.setTireData( i, tires[ i ] );								// Установите шину данных колеса
				wheelsData.setSuspensionData( i, susps[ i ] );							// Установите подвеску данные колеса
				wheelsData.setSuspTravelDirection( i, suspTravelDirections[ i ] );		// Установить направление движения подвески колес
				wheelsData.setWheelCentreOffset( i, wheelCentreCMOffsets[ i ] );		// Установить смещение от центра жесткой тело массой в центре колеса
				wheelsData.setSuspForceAppPointOffset( i, suspForceAppCMOffsets[ i ] );	// Установить приложение точкой подвески силу подвески колес
				wheelsData.setTireForceAppPointOffset( i, tireForceAppCMOffsets[ i ] );	// Установить приложение точку шин силу шинах колес
			}

			//Diff
			PxVehicleDifferential4WData diff;
			diff.mType = PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD;
			driveData.setDiffData( diff );

			//Engine
			PxVehicleEngineData engine;
			engine.mPeakTorque								= 300.f;	// максимальная скорость вращения двигателя
			engine.mMaxOmega								= 400.f;	// Максимальный крутящий момент доступен обратиться к двигателю
			engine.mDampingRateFullThrottle					= 0.15f;	// скорость затухания двигатель при полностью открытой дроссельной заслонке	
			engine.mDampingRateZeroThrottleClutchEngaged	= 8.f;		// скорость затухания двигатель при нулевой газ при включении сцепления
			engine.mDampingRateZeroThrottleClutchDisengaged	= 0.35f;	// Краткие скорость затухания двигатель при нулевой газ при выключенном сцеплении (на нейтральной передаче)

			driveData.setEngineData( engine );

			//Gears
			PxVehicleGearsData gears;
			gears.mSwitchTime = 0.5f;
			driveData.setGearsData( gears );

			// Прочность сцепления
			PxVehicleClutchData clutch;
			clutch.mStrength = PxVehicleGearsData::eMAX_NUM_GEAR_RATIOS;
			driveData.setClutchData( clutch );

			//Ackermann steer accuracy
			PxVehicleAckermannGeometryData ackermann;
			ackermann.mAccuracy		  = 0.1f;
			ackermann.mAxleSeparation = wheelCentreOffsets[ 0 ].z - wheelCentreOffsets[ nWheels - 1 ].z;	// Расстояние между центром передней оси и центром задней оси
			ackermann.mFrontWidth	  = wheelCentreOffsets[ 0 ].x - wheelCentreOffsets[ 1		    ].x;	// Расстояние между центральной точке два передних колеса
			ackermann.mRearWidth	  = wheelCentreOffsets[ nWheels - 2 ].x - wheelCentreOffsets[ nWheels - 1 ].x;	// Расстояние между центральной точке два задних колеса
			driveData.setAckermannGeometryData(ackermann);			
			
			PxTriangleMesh * pTriangleMesh = 0;
			D3DXVECTOR3      vPosition;

			if( GameObject * pRoller = GetDetail( WHEEL_LEFT_1ST ) )
			{
				if( pRoller->CreateTriangleMesh( pPhysX ) )
				{
					pRoller->Update( 0.f );					
					pTriangleMesh = pRoller->GetTriangleMesh();
					Position      = pRoller->GetPosition();
				}
			}

			// Нам нужно добавить колеса столкновения форм, их местный позы, материал для колес, и моделирование фильтра для колес
			PxTriangleMeshGeometry WheelGeom( pTriangleMesh );
			
			PxGeometry* wheelGeometries[ nWheels ] = {0};
			PxTransform wheelLocalPoses[ nWheels ];

			for( PxU32 i = 0; i < nWheels; ++i )
			{
				wheelGeometries[ i ] = &WheelGeom;
				wheelLocalPoses[ i ] = PxTransform::createIdentity();
			}
			
			PxMaterial* pMaterial = pPhysX->GetPhysics()->createMaterial( 0.5f, 0.5f, 0.1f );    //коэффициенты трения скольжения и покоя(Dynamic friction,Static friction), коэффициент упругости
			const PxMaterial& wheelMaterial	= *pMaterial;
			PxFilterData wheelCollFilterData;

			wheelCollFilterData.word0 = COLLISION_FLAG_WHEEL;
			wheelCollFilterData.word1 = COLLISION_FLAG_WHEEL_AGAINST;

			// Нам нужно добавить шасси столкновения форм, их местный позы, материала для шасси и моделирования фильтр для шасси.
			//PxBoxGeometry chassisConvexGeom( 1.5f, 0.3f, 4.f );
			PxBoxGeometry chassisConvexGeom( chassisDims.x/2, chassisDims.y/2, chassisDims.z/2 );

			const PxGeometry* chassisGeoms	    = &chassisConvexGeom;
			const PxTransform chassisLocalPoses = PxTransform::createIdentity();
			const PxMaterial& chassisMaterial	= *pMaterial;

			PxFilterData chassisCollFilterData;
			chassisCollFilterData.word0 = COLLISION_FLAG_CHASSIS;
			chassisCollFilterData.word1 = COLLISION_FLAG_CHASSIS_AGAINST;

			// Создание фильтра запроса данных для автомобилей, чтобы машины не пытайтесь ездить на себя.
			PxFilterData vehQryFilterData;			
			SampleVehicleSetupVehicleShapeQueryFilterData( &vehQryFilterData );

			PxRigidDynamic* vehActor = pPhysX->GetPhysics()->createRigidDynamic( PxTransform::createIdentity() );

			//Add all the wheel shapes to the actor.
			for( PxU32 i = 0; i < nWheels; ++i )
			{
				PxShape* wheelShape=vehActor->createShape( *wheelGeometries[ i ], wheelMaterial );
				wheelShape->setQueryFilterData( vehQryFilterData );
				wheelShape->setSimulationFilterData( wheelCollFilterData );
				wheelShape->setLocalPose( wheelLocalPoses[ i ] );
				wheelShape->setFlag( PxShapeFlag::eSIMULATION_SHAPE, true );
			}

			//Add the chassis shapes to the actor			
			PxShape* chassisShape = vehActor->createShape( *chassisGeoms, chassisMaterial );
			chassisShape->setQueryFilterData( vehQryFilterData );
			chassisShape->setSimulationFilterData( chassisCollFilterData );
			chassisShape->setLocalPose( PxTransform( physx::PxVec3( 0, 0, 0 ) ) );
			

			vehActor->setMass( chassisData.mMass );
			vehActor->setMassSpaceInertiaTensor( chassisData.mMOI );
			vehActor->setCMassLocalPose( PxTransform( chassisData.mCMOffset, PxQuat::createIdentity() ) );
			vehActor->setGlobalPose( PxTransform( physx::PxVec3( 0, 8, 0 ), PxQuat::createIdentity() ) );

			PxVehicleDriveTank* pTank = PxVehicleDriveTank::allocate( nWheels );
 			
 			pTank->setup( pPhysX->GetPhysics(), vehActor, *wheelsSimData, driveData, nWheels );			
			pPhysX->AddActorScene( vehActor );
			m_pActor = vehActor;
			pPhysX->AddTank( pTank );

			//Free the sim data because we don't need that any more.
			wheelsSimData->free();
			//pTank->setDriveModel( PxVehicleDriveTank::eDRIVE_MODEL_SPECIAL );
			pTank->setToRestState();			
			pTank->mDriveDynData.setUseAutoGears( true );

			return true;
		}
	}

	return false;
}