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; }
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; }