280 likes | 396 Vues
GraphGame gg017-PhysXVehicle. PhysX járművek Szécsi Lászl ó Bendefy Zoltán. Járművek a PhysX-ben. Include és lib a laborgépeken. Assimp Include könyvtár: C:Program Files Assimp Include Lib könyvtár: C: Program Files Assimp lib x86 Boost Include könyvtár:
E N D
GraphGamegg017-PhysXVehicle PhysX járművek SzécsiLászló Bendefy Zoltán
Include és lib a laborgépeken • Assimp • Include könyvtár: • C:\Program Files\Assimp\Include • Lib könyvtár: • C:\Program Files\Assimp\lib\x86 • Boost • Include könyvtár: • C:\Program Files\boost\boost_1_52_0 • PhysX SDK 3.2 • Include könyvtár: • C:\Program Files\NVIDIA Corporation\PhysX SDK 3.2\Include • Lib könyvtár: • C:\Program Files\NVIDIA Corporation\PhysX SDK 3.2\Lib\win32
Első teszt • Futtassuk a projektet:
VehicleEntity.h::VehicleEntity() • Ez az osztály konstruktora, itt épül fel a jármű. • Első lépésként hozzuk létre az 5 entitást (StaticPartEntity), amelyekből felépül az autó. A StaticPartEntity osztály egy wrappert képez a multimesh köré. chassis = StaticPartEntity::create(echassis); wheel1 = StaticPartEntity::create(ewheel); wheel2 = StaticPartEntity::create(ewheel); wheel3 = StaticPartEntity::create(ewheel); wheel4 = StaticPartEntity::create(ewheel);
VehicleEntity.h::VehicleEntity() • Írjuk bele egy wheelOffsets nevű tömbbe, hogy az autón belül hol legyenek a kerekek. wheelOffsets[0] = PxVec3(-3,-3, 6); //Front Left wheel wheelOffsets[1] = PxVec3( 3,-3, 6); //Front Right wheel wheelOffsets[2] = PxVec3(-3,-3,-5); //Rear left wheel wheelOffsets[3] = PxVec3( 3,-3,-5); //Rear right wheel
VehicleEntity.h::VehicleEntity() • Készítsük el a jármű viselkedését leíró szimulációs osztálypéldányokat! • Megyjegyzés: érdemes megnézni a createVehicle4WSimulationData() függvényben, hogy mennyi paramétert enged a PhysX állítani! PxVehicleWheelsSimData* wheelsSimData=PxVehicleWheelsSimData::allocate(4); PxVehicleDriveSimData4W driveSimData; PxVehicleChassisDatachassisData; createVehicle4WSimulationData (chassisWeight, chassisConvexMesh, wheelWeight,wheelConvexMeshes, wheelOffsets, *wheelsSimData,driveSimData,chassisData);
VehicleEntity.h::VehicleEntity() • Ez a függvény készíti el az actort, később majd ezt a függvényt is meg kell írnunk. actor = createVehicleActor4W(chassisData,wheelConvexMeshes,chassisConvexMesh,*scene,(scene->getPhysics()),*physicsMaterial);
VehicleEntity.h::VehicleEntity() • Ez a függvény készíti el az actort, később majd ezt a függvényt is meg kell írnunk. Ez elkészíti a geometriákat is. • Elkészítjük a PxVehicleDrive4W példányunkat actor = createVehicleActor4W(chassisData,wheelConvexMeshes,chassisConvexMesh,*scene,(scene->getPhysics()),*physicsMaterial); PxU32 n = actor->getNbShapes(); car = PxVehicleDrive4W::allocate(4); car->setup(&(scene->getPhysics()),actor,*wheelsSimData,driveSimData,0); //we won't need this anymore wheelsSimData->free();
VehicleEntity.h::VehicleEntity() • A talaj és a gumik közti súrlódási tényező beállítása az egyes PhysXMaterial-okra: int materialCount = scene->getPhysics().getNbMaterials(); PxMaterial** materials = new PxMaterial*[materialCount]; scene->getPhysics().getMaterials(materials, materialCount); // Specifying which materials will be drivable. A specific friction value can be applied using mSurfaceTirePairs->setTypePairFriction; PxMaterial** drivableSurfaceMaterials = new PxMaterial*[materialCount]; for(int i = 0; i < materialCount; i++) { drivableSurfaceMaterials[i] = materials[i]; mVehicleDrivableSurfaceTypes[i].mType = i; } mSurfaceTirePairs=PxVehicleDrivableSurfaceToTireFrictionPairs::create(1, materialCount,(constPxMaterial**)drivableSurfaceMaterials,mVehicleDrivableSurfaceTypes); // You can specify the friction between each tire type, and each PxMaterial. for(int i = 0; i < materialCount; i++) { mSurfaceTirePairs->setTypePairFriction(i,0,1.0f); }
VehicleEntity.h::VehicleEntity() • Végül hozzáadjuk az actort a fizikai világhoz, és elvégezzük az utolsó simításokat. scene->addActor(*actor); PxVehicleDrive4W* vehDrive4W=(PxVehicleDrive4W*)car; vehDrive4W->setToRestState(); vehDrive4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST); actor->setGlobalPose(PxTransform(~(position))); //sets Automatic or Manual gear switching car->mDriveDynData.setUseAutoGears(true);
VehicleEntity.cpp::createVehicleActor4W() • PhysXActor elkészítését végzi //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::createIdentity());
VehicleEntity.cpp::createVehicleActor4W() • Elkészítjük a kerekekhez tartozó konvex héj geometriát,, majd betöltjük ezeket, és egyéb adatokat egy-egy 4 elemű tömbbe. PxConvexMeshGeometryfrontLeftWheelGeom(wheelConvexMeshes[0]); PxConvexMeshGeometryfrontRightWheelGeom(wheelConvexMeshes[1]); PxConvexMeshGeometryrearLeftWheelGeom(wheelConvexMeshes[2]); PxConvexMeshGeometryrearRightWheelGeom(wheelConvexMeshes[3]); constPxGeometry* wheelGeometries[WHEEL_NUM]={&frontLeftWheelGeom,&frontRightWheelGeom,&rearLeftWheelGeom,&rearRightWheelGeom}; constPxTransformwheelLocalPoses[WHEEL_NUM]={PxTransform(wheelOffsets[0]),PxTransform(wheelOffsets[1]),PxTransform(wheelOffsets[2]),PxTransform(wheelOffsets[3])}; constPxMaterial&wheelMaterial=material; PxFilterDatawheelCollFilterData; wheelCollFilterData.word0=COLLISION_FLAG_WHEEL; wheelCollFilterData.word1=COLLISION_FLAG_WHEEL_AGAINST;
VehicleEntity.cpp::createVehicleActor4W() • Elkészítjük a karosszériához tartozó konvex héj geometriát, majd betöltjük ezt, és egyéb adatokat egy-egy 1 elemű tömbbe. PxConvexMeshGeometrychassisConvexGeom(chassisConvexMesh); constPxGeometry* chassisGeoms[1]={&chassisConvexGeom}; constPxTransformchassisLocalPoses[1]={PxTransform::createIdentity()}; constPxMaterial&chassisMaterial=material; PxFilterDatachassisCollFilterData; chassisCollFilterData.word0= COLLISION_FLAG_CHASSIS; chassisCollFilterData.word1= COLLISION_FLAG_CHASSIS_AGAINST;
VehicleEntity.cpp::createVehicleActor4W() • Beállítjuk a raycastokhoz tartozó szűrési feltételeket. //Create a query filter data for the car to ensure that cars //do not attempt to drive on themselves. PxFilterDatavehQryFilterData; SampleVehicleSetupVehicleShapeQueryFilterData(&vehQryFilterData);
VehicleEntity.cpp::createVehicleActor4W() • Beállítjuk az actort a setupActor nevű függvény meghívásával. Ez lényegében inicializálja az actort, és hozzáveszi az actorhoz a 4 kerék és a karosszéria geometriáját. //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); returnvehActor;
Filter shader beállítása • VehicleApp.cpp::initializePhysX(): • VehicleApp.h::VehicleFilterShader(): // TODO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(!sceneDesc.filterShader) sceneDesc.filterShader = VehicleFilterShader; //gDefaultFilterShader; //TODO END ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // TODO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ((filterData0.word0 != 0 && filterData1.word0 != 0) && !(filterData0.word0&filterData1.word1 || filterData1.word0&filterData0.word1)) returnPxFilterFlag::eSUPPRESS; //TODO END ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VehicleEntity.cpp::Render() • Kirajzoljuk az 5 multimesht wheel1->render(renderParameters); wheel2->render(renderParameters); wheel3->render(renderParameters); wheel4->render(renderParameters); chassis->render(renderParameters);
VehicleEntity.cpp::Animate() • Létrehozunk egy PxVehicleDrive4WRawInputData példányt, és feltöltjük a billentyűzet jelenlegi állásával, végül beadjuk a járműnek. PxVehicleDrive4WRawInputData rawInputData; rawInputData.setDigitalAccel(control_accel); rawInputData.setDigitalBrake(control_brake); rawInputData.setDigitalSteerLeft(control_steerleft); rawInputData.setDigitalSteerRight(control_steerright); rawInputData.setGearUp(control_gearup); rawInputData.setGearDown(control_geardown); PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs(gKeySmoothingData,gSteerVsForwardSpeedTable,rawInputData,dt,*car);
VehicleEntity.cpp::Animate() • Elvégeztetjük a raycastokat, majd szólunk a PhysX-nek, hogy frissítse a járművet az eltelt idővel. if(NULL==mSqWheelRaycastBatchQuery) { mSqWheelRaycastBatchQuery= mSqData->setUpBatchedSceneQuery(actor->getScene()); } PxVehicleSuspensionRaycasts(mSqWheelRaycastBatchQuery,1,vehicles,mSqData->getRaycastQueryResultBufferSize(),mSqData->getRaycastQueryResultBuffer()); PxVehicleUpdates(dt,actor->getScene()->getGravity(),*mSurfaceTirePairs,1,vehicles);
VehicleEntity.cpp::Animate() • Frissítjük a multimeshek pozícióját és irányát, a hozzájuk tartozó PxShape-ből. const int numShapes=actor->getNbShapes(); PxShape* carShapes[WHEEL_NUM + 1]; //4 wheels + chassis actor->getShapes(carShapes,numShapes); if(~PxShapeExt::getGlobalPose(*carShapes[0]).isSane() && ~PxShapeExt::getGlobalPose(*carShapes[0]).isFinite()) {//1. kerék multimesh frissítése wheel1->setPosition(~PxShapeExt::getGlobalPose(*carShapes[0]).p); wheel1->setRotation(~PxShapeExt::getGlobalPose(*carShapes[0]).q); } //(…) Ez csak a wheel1 frissítése, a wheel2-4-ig is meg kell csinálni!… if (~PxShapeExt::getGlobalPose(*carShapes[4]).isSane() && ~PxShapeExt::getGlobalPose(*carShapes[4]).isFinite()) { //Karosszéria multimesh frissítése chassis->setPosition(~PxShapeExt::getGlobalPose(*carShapes[4]).p); chassis->setRotation(~PxShapeExt::getGlobalPose(*carShapes[4]).q); }
vehicleScene.lua • Jármű berakása luaszkriptből: • (A luaszkriptaProjects/gg017-Vehicle/Media mappában található) O:spawnVehicle(_, {name='GraphGameVehicle', controlState=clone(vehicleControlState), chassismultimesh='chassis', wheelmultimesh='wheel', material='default', wheelphysxmodel='pickup/wheel_physx.obj', chassisphysxmodel='pickup/pickup_physx.obj', position = {x=0, y=40, z=0}}, function(_) end )
Végeredmény: Irányítás: numpadon 8: gáz 5: fék 4,6: balra/jobbra kanyarodás 1,3: le/felfelé váltás (auto) 7: jármű alaphelyzetbe állítása
vehicleScene.lua • Járművet követő kamera: • ELŐSZÖR KIKOMMENTEZNI EZT A SORT: • Majd beírni ezt a sort: (nem lehet két kamera egyszerre) --O:FirstPersonCam(_, {name='default', position={x=50, y=50, z=50} } ) O:FixedCam(_, {name='default', attachTo='GraphGameVehicle', pos ={x=6, y=12, z=-24} } )
vehicleScene.lua • Ugrató betevése: O:PhysicsEntity(_, {name='ramp', multiMesh='ramp', position={x=-50 , y=9.8, z=0 }}, function(_) O:Shape(_, {geometryType='eBOX', material='default', orientationAngle=0.17453289, orientationAxis={x=0, y=0, z=1}, halfExtents = {x=32.0, y=0.4, z=20}, position = { x=0, y=0, z=0 } } ) O:Drivable(_, {drivable = 1}) end)
vehicleScene.lua • Zsiráfok betevése: for j=1,5 do for i=1,20 do for k=1,1do O:PhysicsEntity(_, {name='giraffe'..i..'_'..j..'_'..k, multiMesh='giraffe', position={x=i*20 , y=k*14, z=20 + j*20 }}, function(_) O:Shape(_, {geometryType='eBOX', material='default', orientationAngle=0, orientationAxis={x=0, y=1, z=0}, halfExtents = {x=2.8, y=7, z=1.4}, position = { x=0, y=0, z=0 } } ) O:Dynamics(_, {density=0.2} ) --Drivable must be usedtospecify a surfacedrivableorundrivable --Thismethod must be calledaftercallingShape() and Dynamics() methods. O:Drivable(_, {drivable = 0}) end) end end end
vehicleScene.lua • Labdák betevése: • Önálló feladat! • Elérhető egy labda objektum ( sphere.obj )