PxRigidDynamic* Vehicle::createVehicleActor(const PxVehicleChassisData& chassisData, PxMaterial** wheelMaterials, PxConvexMesh** wheelConvexMeshes, const PxU32 numWheels, PxMaterial** chassisMaterials, PxConvexMesh** chassisConvexMeshes, const PxU32 numChassisMeshes, PxPhysics& physics, PxVec3 initPos) { //We need a rigid body actor for the vehicle. //Don't forget to add the actor to the scene after setting up the associated vehicle. PxRigidDynamic* vehActor = physics.createRigidDynamic(PxTransform(initPos)); vehActor->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true); //Wheel and chassis simulation filter data. PxFilterData wheelSimFilterData; wheelSimFilterData.word0 = COLLISION_FLAG_WHEEL; wheelSimFilterData.word1 = COLLISION_FLAG_WHEEL_AGAINST; PxFilterData chassisSimFilterData; chassisSimFilterData.word0 = COLLISION_FLAG_CHASSIS; chassisSimFilterData.word1 = COLLISION_FLAG_CHASSIS_AGAINST; //Wheel and chassis query filter data. //Optional: cars don't drive on other cars. PxFilterData wheelQryFilterData; wheelQryFilterData.word0 = FilterGroup::eWHEEL; setupNonDrivableSurface(wheelQryFilterData); PxFilterData chassisQryFilterData; chassisQryFilterData.word0 = FilterGroup::eVEHICLE; setupNonDrivableSurface(chassisQryFilterData); //Add all the wheel shapes to the actor. for (PxU32 i = 0; i < numWheels; i++) { PxConvexMeshGeometry geom(wheelConvexMeshes[i]); PxShape* wheelShape = vehActor->createShape(geom, *wheelMaterials[i]); wheelShape->setQueryFilterData(wheelQryFilterData); wheelShape->setSimulationFilterData(wheelSimFilterData); wheelShape->setLocalPose(PxTransform(PxIdentity)); } //Add the chassis shapes to the actor. for (PxU32 i = 0; i < numChassisMeshes; i++) { PxShape* chassisShape = vehActor->createShape (PxConvexMeshGeometry(chassisConvexMeshes[i]), *chassisMaterials[i]); chassisShape->setQueryFilterData(chassisQryFilterData); chassisShape->setSimulationFilterData(chassisSimFilterData); chassisShape->setLocalPose(PxTransform(PxIdentity)); } vehActor->setMass(chassisData.mMass); vehActor->setMassSpaceInertiaTensor(chassisData.mMOI); vehActor->setCMassLocalPose(PxTransform(chassisData.mCMOffset, PxQuat(PxIdentity))); return vehActor; }
PxShape* AttachShape_AssumesLocked(const PxGeometry& PGeom, const PxTransform& PLocalPose, const float ContactOffset, PxShapeFlags PShapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) const { const PxMaterial* PMaterial = GetDefaultPhysMaterial(); PxShape* PNewShape = bShapeSharing ? GPhysXSDK->createShape(PGeom, *PMaterial, /*isExclusive =*/ false, PShapeFlags) : PDestActor->createShape(PGeom, *PMaterial, PShapeFlags); if (PNewShape) { PNewShape->setLocalPose(PLocalPose); if (NewShapes) { NewShapes->Add(PNewShape); } PNewShape->setContactOffset(ContactOffset); const bool bSyncFlags = bShapeSharing || SceneType == PST_Sync; const FShapeFilterData& Filters = ShapeData.FilterData; const bool bComplexShape = PNewShape->getGeometryType() == PxGeometryType::eTRIANGLEMESH; PNewShape->setQueryFilterData(bComplexShape ? Filters.QueryComplexFilter : Filters.QuerySimpleFilter); PNewShape->setFlags( (bSyncFlags ? ShapeData.SyncShapeFlags : ShapeData.AsyncShapeFlags) | (bComplexShape ? ShapeData.ComplexShapeFlags : ShapeData.SimpleShapeFlags)); PNewShape->setSimulationFilterData(Filters.SimFilter); FBodyInstance::ApplyMaterialToShape_AssumesLocked(PNewShape, SimpleMaterial, ComplexMaterials, bShapeSharing); if(bShapeSharing) { PDestActor->attachShape(*PNewShape); PNewShape->release(); } } return PNewShape; }
void UDestructibleComponent::SetCollisionResponseForActor(const FCollisionResponse& ColResponse, PxRigidDynamic* Actor, int32 ChunkIdx) { // Get collision channel and response PxFilterData PQueryFilterData, PSimFilterData; uint8 MoveChannel = GetCollisionObjectType(); if(IsCollisionEnabled()) { AActor* Owner = GetOwner(); CreateShapeFilterData(MoveChannel, (Owner ? Owner->GetUniqueID() : 0), ColResponse.GetResponseContainer(), 0, ChunkIdxToBoneIdx(ChunkIdx), PQueryFilterData, PSimFilterData, BodyInstance.bUseCCD, BodyInstance.bNotifyRigidBodyCollision, false); PQueryFilterData.word3 |= EPDF_SimpleCollision | EPDF_ComplexCollision; SCOPED_SCENE_WRITE_LOCK(Actor->getScene()); TArray<PxShape*> Shapes; Shapes.AddUninitialized(Actor->getNbShapes()); int ShapeCount = Actor->getShapes(Shapes.GetTypedData(), Shapes.Num()); for (int32 i=0; i < ShapeCount; ++i) { PxShape* Shape = Shapes[i]; Shape->setQueryFilterData(PQueryFilterData); Shape->setSimulationFilterData(PSimFilterData); Shape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true); Shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, true); Shape->setFlag(PxShapeFlag::eVISUALIZATION, true); } } }
PxShape* PxCloneShape(PxPhysics &physics, const PxShape& from, bool isExclusive) { Ps::InlineArray<PxMaterial*, 64> materials; PxU16 materialCount = from.getNbMaterials(); materials.resize(materialCount); from.getMaterials(materials.begin(), materialCount); PxShape* to = physics.createShape(from.getGeometry().any(), materials.begin(), materialCount, isExclusive, from.getFlags()); to->setLocalPose(from.getLocalPose()); to->setContactOffset(from.getContactOffset()); to->setRestOffset(from.getRestOffset()); to->setSimulationFilterData(from.getSimulationFilterData()); to->setQueryFilterData(from.getQueryFilterData()); return to; }
void TCompCharacterController::SetFilterData(PxFilterData& filter) { PxRigidActor *ra = m_pActor->getActor()->isRigidActor(); m_filter = filter; if (ra) { const PxU32 numShapes = ra->getNbShapes(); PxShape **ptr; ptr = new PxShape*[numShapes]; ra->getShapes(ptr, numShapes); for (PxU32 i = 0; i < numShapes; i++) { PxShape* shape = ptr[i]; shape->setSimulationFilterData(m_filter); shape->setQueryFilterData(m_filter); } } }
void UDestructibleComponent::SetCollisionResponseForActor(PxRigidDynamic* Actor, int32 ChunkIdx, const FCollisionResponseContainer* ResponseOverride /*= NULL*/) { #if WITH_APEX if (ApexDestructibleActor == NULL) { return; } // Get collision channel and response PxFilterData PQueryFilterData, PSimFilterData; uint8 MoveChannel = GetCollisionObjectType(); if(IsCollisionEnabled()) { UDestructibleMesh* TheDestructibleMesh = GetDestructibleMesh(); AActor* Owner = GetOwner(); bool bLargeChunk = IsChunkLarge(ChunkIdx); const FCollisionResponseContainer& UseResponse = ResponseOverride == NULL ? (bLargeChunk ? LargeChunkCollisionResponse.GetResponseContainer() : SmallChunkCollisionResponse.GetResponseContainer()) : *ResponseOverride; physx::PxU32 SupportDepth = TheDestructibleMesh->ApexDestructibleAsset->getChunkDepth(ChunkIdx); const bool bEnableImpactDamage = IsImpactDamageEnabled(TheDestructibleMesh, SupportDepth); CreateShapeFilterData(MoveChannel, GetUniqueID(), UseResponse, 0, ChunkIdxToBoneIdx(ChunkIdx), PQueryFilterData, PSimFilterData, BodyInstance.bUseCCD, bEnableImpactDamage, false); PQueryFilterData.word3 |= EPDF_SimpleCollision | EPDF_ComplexCollision; SCOPED_SCENE_WRITE_LOCK(Actor->getScene()); TArray<PxShape*> Shapes; Shapes.AddUninitialized(Actor->getNbShapes()); int ShapeCount = Actor->getShapes(Shapes.GetData(), Shapes.Num()); for (int32 i=0; i < ShapeCount; ++i) { PxShape* Shape = Shapes[i]; Shape->setQueryFilterData(PQueryFilterData); Shape->setSimulationFilterData(PSimFilterData); Shape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true); Shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, true); Shape->setFlag(PxShapeFlag::eVISUALIZATION, true); } } #endif }
bool copyStaticProperties(PxRigidActor& to, const PxRigidActor& from,NxMirrorScene::MirrorFilter &mirrorFilter) { physx::shdfnd::InlineArray<PxShape*, 64> shapes; shapes.resize(from.getNbShapes()); PxU32 shapeCount = from.getNbShapes(); from.getShapes(shapes.begin(), shapeCount); physx::shdfnd::InlineArray<PxMaterial*, 64> materials; for(PxU32 i = 0; i < shapeCount; i++) { PxShape* s = shapes[i]; if ( mirrorFilter.shouldMirror(*s) ) { PxU32 materialCount = s->getNbMaterials(); materials.resize(materialCount); s->getMaterials(materials.begin(), materialCount); PxShape* shape = to.createShape(s->getGeometry().any(), materials.begin(), static_cast<physx::PxU16>(materialCount)); shape->setLocalPose( s->getLocalPose()); shape->setContactOffset(s->getContactOffset()); shape->setRestOffset(s->getRestOffset()); shape->setFlags(s->getFlags()); shape->setSimulationFilterData(s->getSimulationFilterData()); shape->setQueryFilterData(s->getQueryFilterData()); mirrorFilter.reviseMirrorShape(*shape); } } to.setActorFlags(from.getActorFlags()); to.setOwnerClient(from.getOwnerClient()); to.setDominanceGroup(from.getDominanceGroup()); if ( to.getNbShapes() ) { mirrorFilter.reviseMirrorActor(to); } return to.getNbShapes() != 0; }
void TCompCharacterController::SetCollisions(bool new_collisions) { PxRigidActor *ra = m_pActor->getActor()->isRigidActor(); if (ra) { const PxU32 numShapes = ra->getNbShapes(); PxShape **ptr; ptr = new PxShape*[numShapes]; ra->getShapes(ptr, numShapes); for (PxU32 i = 0; i < numShapes; i++) { PxShape* shape = ptr[i]; if (!new_collisions) { m_filter.word1 &= ~ItLightensFilter::eCOLLISION; m_filter.word1 &= ~ItLightensFilter::eCAN_TRIGGER; //for test only } else { m_filter.word1 |= ItLightensFilter::eCOLLISION; m_filter.word1 |= ItLightensFilter::eCAN_TRIGGER; //for test only } shape->setSimulationFilterData(m_filter); shape->setQueryFilterData(m_filter); } } }
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; }
// Creates an physics entity from an entity info structure and a starting transform void PhysicsEngine::createEntity(PhysicsEntity* entity, PhysicsEntityInfo* info, PxTransform transform) { transform.p.y += info->yPosOffset; // Set static/dynamic info for actor depending on its type PxRigidActor* actor; if (info->type == PhysicsType::DYNAMIC) { DynamicInfo* dInfo = info->dynamicInfo; PxRigidDynamic* dynamicActor = physics->createRigidDynamic(transform); dynamicActor->setLinearDamping(dInfo->linearDamping); dynamicActor->setAngularDamping(dInfo->angularDamping); dynamicActor->setMaxAngularVelocity(dInfo->maxAngularVelocity); actor = dynamicActor; } else if (info->type == PhysicsType::STATIC) { PxRigidStatic* staticActor = physics->createRigidStatic(transform); actor = staticActor; } // All shapes in actor for (auto sInfo : info->shapeInfo) { // Create material and geometry for shape and add it to actor PxGeometry* geometry; PxMaterial* material; if (sInfo->geometry == Geometry::SPHERE) { SphereInfo* sphInfo = (SphereInfo*)sInfo; geometry = new PxSphereGeometry(sphInfo->radius); } else if (sInfo->geometry == Geometry::BOX) { BoxInfo* boxInfo = (BoxInfo*)sInfo; geometry = new PxBoxGeometry(boxInfo->halfX, boxInfo->halfY, boxInfo->halfZ); } else if (sInfo->geometry == Geometry::CAPSULE) { CapsuleInfo* capInfo = (CapsuleInfo*)sInfo; geometry = new PxCapsuleGeometry(capInfo->radius, capInfo->halfHeight); } else if (sInfo->geometry == Geometry::CONVEX_MESH) { ConvexMeshInfo* cmInfo = (ConvexMeshInfo*)sInfo; PxConvexMesh* mesh = helper->createConvexMesh(cmInfo->verts.data(), cmInfo->verts.size()); geometry = new PxConvexMeshGeometry(mesh); } // Not working until index drawing is set up else if (sInfo->geometry == Geometry::TRIANGLE_MESH) { TriangleMeshInfo* tmInfo = (TriangleMeshInfo*)sInfo; PxTriangleMesh* mesh = helper->createTriangleMesh(tmInfo->verts.data(), tmInfo->verts.size(), tmInfo->faces.data(), tmInfo->faces.size()/3); geometry = new PxTriangleMeshGeometry(mesh); } material = (sInfo->isDrivable) ? drivingSurfaces[0] : physics->createMaterial(sInfo->dynamicFriction, sInfo->staticFriction, sInfo->restitution); PxShape* shape = actor->createShape(*geometry, *material); // TODO support shape flags shape->setLocalPose(sInfo->transform); material->release(); delete geometry; // Set up querry filter data for shape PxFilterData qryFilterData; qryFilterData.word3 = (sInfo->isDrivable) ? (PxU32)Surface::DRIVABLE : (PxU32)Surface::UNDRIVABLE; shape->setQueryFilterData(qryFilterData); // Set up simulation filter data for shape PxFilterData simFilterData; simFilterData.word0 = (PxU32)sInfo->filterFlag0; simFilterData.word1 = (PxU32)sInfo->filterFlag1; simFilterData.word2 = (PxU32)sInfo->filterFlag2; simFilterData.word3 = (PxU32)sInfo->filterFlag3; shape->setSimulationFilterData(simFilterData); if (info->type == PhysicsType::DYNAMIC) { DynamicInfo* dInfo = info->dynamicInfo; PxRigidBodyExt::updateMassAndInertia(*(PxRigidBody*)actor, dInfo->density, &dInfo->cmOffset); PxRigidBody* body = (PxRigidBody*)actor; } } // Add actor to scene, set actor for entity, and set user data for actor. Creates one to one between entities and phyX scene->addActor(*actor); entity->setActor(actor); actor->userData = entity; }