physx aut ó
DESCRIPTION
PhysX aut ó. Sz écsi László. Let öltés. di ák: bagira .iit.bme.hu /~szecsi/GraphGame / l12-car. ppt modell: bagira .iit.bme.hu /~szecsi/GraphGame / pickup.zip. Új class: PhysicsEntityWheel. class ShadedMesh; class RenderContext; class PhysicsEntityWheel { ShadedMesh* shadedMesh; - PowerPoint PPT PresentationTRANSCRIPT
PhysX autó
Szécsi László
Letöltés
diák:
bagira.iit.bme.hu/~szecsi/GraphGame
/l12-car.ppt
modell:
bagira.iit.bme.hu/~szecsi/GraphGame
/pickup.zip
Új class: PhysicsEntityWheelclass ShadedMesh;class RenderContext;
class PhysicsEntityWheel {ShadedMesh* shadedMesh;NxWheelShape* shape;double rollAngle;
public:PhysicsEntityWheel(ShadedMesh* shadedMesh);void render(const RenderContext& context);void animate(double dt);void setShape(NxWheelShape* shape);
};
PhysicsEntityWheel.cpp
#include "ShadedMesh.h"
#include "RenderContext.h"
#include "Camera.h"
PhysicsEntityWheel::
PhysicsEntityWheel(
ShadedMesh* shadedMesh){
this->shadedMesh = shadedMesh;
rollAngle = 0.0;
}
PhysicsEntityWheel.cpp
void PhysicsEntityWheel::animate(double dt)
{
rollAngle += dt * shape->getAxleSpeed();
}
void PhysicsEntityWheel::setShape(
NxWheelShape* shape)
{
this->shape = shape;
}
PhysicsEntityWheel.cppvoid PhysicsEntityWheel::render(const RenderContext&
context){D3DXMATRIX modelMatrix, rollMatrix;D3DXMatrixRotationX(&rollMatrix, rollAngle);NxMat34 pose = shape->getGlobalPose();pose.getColumnMajor44((NxF32*)&modelMatrix);
D3DXMatrixMultiply(&modelMatrix,&rollMatrix, &modelMatrix);
D3DXMATRIX modelMatrixInverse;D3DXMatrixInverse(&modelMatrixInverse, NULL, &modelMatrix);context.effect->SetMatrix("modelMatrix", &modelMatrix);context.effect->SetMatrix("modelMatrixInverse", &modelMatrixInverse);D3DXMATRIX modelViewProjMatrix = modelMatrix * context.camera->getViewMatrix() *
context.camera->getProjMatrix();context.effect->SetMatrix("modelViewProjMatrix", &modelViewProjMatrix);D3DXMATRIX modelViewMatrix = modelMatrix * context.camera->getViewMatrix();context.effect->SetMatrix("modelViewMatrix", &modelViewMatrix);
shadedMesh->render(context);}
PhysicsEntity osztályba
class PhysicsEntityWheel;
//…
std::vector<PhysicsEntityWheel*> wheels;
public:
void animate(double dt);
void addWheel(
PhysicsEntityWheel* wheel);
void finishWheels();
PhysicsEntity.cpp
#include "PhysicsEntityWheel.h"
PhysicsEntity.cpp
void PhysicsEntity::render(const RenderContext& context){// …shadedMesh->render(context);
std::vector<PhysicsEntityWheel*>::iterator wii = wheels.begin();while(wii != wheels.end()) {
(*wii)->render(context);wii++;
}}
PhysicsEntity.cpp
void PhysicsEntity::addWheel(
PhysicsEntityWheel* wheel)
{
wheels.push_back(wheel);
}
PhysicsEntity.cppvoid PhysicsEntity::finishWheels() {
NxShape*const* nxShapes = nxActor->getShapes();unsigned int nNxShapes = nxActor->getNbShapes();std::vector<PhysicsEntityWheel*>::iterator wii = wheels.begin();unsigned int iNxShapes=0;while(wii != wheels.end() && iNxShapes < nNxShapes) {
if(nxShapes[iNxShapes]->getType() == NX_SHAPE_WHEEL){
(*wii)->setShape((NxWheelShape*)nxShapes[iNxShapes]);
wii++;}iNxShapes++;
}}
PhysicsEntity.cpp
void PhysicsEntity::animate(double dt){
std::vector<PhysicsEntityWheel*>::iterator wii = wheels.begin();while(wii != wheels.end()){
(*wii)->animate(dt);wii++;
}}
EntityCore
void loadNxWheelShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel);
void loadPhysicsEntityWheels(XMLNode& physicsEntityNode, PhysicsEntity* physicsEntity);
EngineCore.cpp
#include "PhysicsEntityWheel.h"
EnginePhysics::loadPhysicsModels
loadNxSphereShapes(physicsModelNode, physicsModel);
loadNxWheelShapes(physicsModelNode, physicsModel);
physicsModelDirectory
[physicsModelName] = physicsModel;
EngineCore.cppvoid EngineCore::loadNxWheelShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel){int iShape = 0;XMLNode shapeNode;while( !(shapeNode = physicsModelNode.getChildNode(L"NxWheelShape", iShape)).isEmpty() )
{NxWheelShapeDesc* nxWheelShapeDesc = new NxWheelShapeDesc();loadShapeDesc(shapeNode, nxWheelShapeDesc, D3DXVECTOR3(0, 0, 1));
nxWheelShapeDesc->radius = shapeNode.readDouble(L"radius", 0.5);nxWheelShapeDesc->suspensionTravel = shapeNode.readDouble(L"suspension", 0.2); nxWheelShapeDesc->suspension.spring = shapeNode.readDouble(L"springRestitution",7000.0);nxWheelShapeDesc->suspension.damper = shapeNode.readDouble(L"springDamping", 800);nxWheelShapeDesc->suspension.targetValue = shapeNode.readDouble(L"springBias", 0.0);nxWheelShapeDesc->inverseWheelMass = shapeNode.readDouble(L"inverseMass", 0.1);
const wchar_t* physicsMaterialName = shapeNode|L"material";PhysicsMaterialDirectory::iterator iPhysicsMaterial =
physicsMaterialDirectory.find(physicsMaterialName);if(iPhysicsMaterial != physicsMaterialDirectory.end())
nxWheelShapeDesc->materialIndex = iPhysicsMaterial->second->getMaterialIndex();
physicsModel->addShape(nxWheelShapeDesc);iShape++;
}}
EnginePhysics::loadPhysicsEntities
PhysicsEntity* physicsEntity = new PhysicsEntity(iShadedMesh->second, iPhysicsModel->second, nxScene, position);
loadPhysicsEntityWheels(
physicsEntityNode, physicsEntity);
group->add(physicsEntity);
EngineCore.cppvoid EngineCore::loadPhysicsEntityWheels(XMLNode&
physicsEntityNode, PhysicsEntity* physicsEntity) {int iWheel = 0;XMLNode wheelNode;while( !(wheelNode = physicsEntityNode.getChildNode(L"Wheel", iWheel)).isEmpty() ){
const wchar_t* shadedMeshName = wheelNode|L"shadedMesh";
ShadedMeshDirectory::iterator iShadedMesh = shadedMeshDirectory.find(shadedMeshName);
if(iShadedMesh != shadedMeshDirectory.end()){
PhysicsEntityWheel* wheel = new PhysicsEntityWheel(iShadedMesh->second);
physicsEntity->addWheel(wheel);}iWheel++;
}physicsEntity->finishWheels();
}
XML
<Mesh name="wheel" xFileName="media\\wheel.x" />
XML <PhysicsModel name="pickup"> <NxBoxShape position.y="9" dimension.x="16.5" dimension.y="3" dimension.z="6.7" /> <NxBoxShape position.y="14" dimension.x="4" dimension.y="2" dimension.z="6.2" /> <NxWheelShape material="wheel" position.x="-10" position.y="4" position.z="-7"
axis.x="1" approximation="10" radius="4.0" width="2" suspension="0.2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.99"/> <NxWheelShape material="wheel" position.x="-10" position.y="4" position.z="7"
axis.x="-1" approximation="10" radius="4.0" width="2" suspension="0.2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.99"/> <NxWheelShape material="wheel" position.x="12" position.y="4" position.z="-7"
axis.x="1" approximation="10" radius="4.0" width="2" suspension="0.2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.99"/> <NxWheelShape material="wheel" position.x="12" position.y="4" position.z="7"
axis.x="-1" approximation="10" radius="4.0" width="2" suspension="0.2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.99"/> </PhysicsModel>
XML <PhysicsEntity name="pickup" shadedMesh="pickup"
physicsModel="pickup" position.y="30" > <Wheel shadedMesh="wheel" /> <Wheel shadedMesh="wheel" /> <Wheel shadedMesh="wheel" /> <Wheel shadedMesh="wheel" /> </PhysicsEntity> <PhysicsEntity name="nmi" shadedMesh="pickup"
physicsModel="pickup" position.x="6" position.y="50" position.z="6" >
<Wheel shadedMesh="wheel" /> <Wheel shadedMesh="wheel" /> <Wheel shadedMesh="wheel" /> <Wheel shadedMesh="wheel" /> </PhysicsEntity>
Kerék rugózása
suspensionOffsetDirection
contactPoint
toContactalong
across
eredeti pozíció
Kerék rugózása
suspensionOffsetDirection
contactPoint
racross
új pozíció
pullBack
Kereket a rugózott pozícióba rajzolni
void PhysicsEntityWheel::render(const RenderContext& context){
NxMat34 pose = shape->getGlobalPose();
NxWheelContactData wcd; // hozzáérünk-e?
NxShape* contactShape = shape->getContact(wcd);
// merre mozoghat a kerék
NxVec3 suspensionOffsetDirection;
pose.M.getColumn(1, suspensionOffsetDirection);
suspensionOffsetDirection =
-suspensionOffsetDirection;
// folyt.
Elmozdítás az érintkezéshezif (contactShape && wcd.contactForce > -1000){
NxVec3 toContact = wcd.contactPoint - pose.t;double alongLength =
suspensionOffsetDirection.dot(toContact);NxVec3 across = toContact - alongLength *
suspensionOffsetDirection;double r = shape->getRadius();double pullBack = sqrt(r*r - across.dot(across));pose.t += (alongLength - pullBack) *
suspensionOffsetDirection;} else {
pose.t += shape->getSuspensionTravel() *suspensionOffsetDirection;
}
Felborulás ellen
tegyük lejjebb a súlypontot
nehéz fémlap alulra, többi doboz legyen könnyű
sűrűség betölése a shape-ekbe
void EngineCore::loadShapeDesc(XMLNode& shapeNode, NxShapeDesc* shapeDesc, D3DXVECTOR3 originalAxis) {shapeDesc->localPose.t = shapeNode.readNxVec3(L"position");D3DXVECTOR3 axis = shapeNode.readVector(L"axis");
if( D3DXVec3Length(&axis) < 0.001 )axis = originalAxis;
D3DXVECTOR3 turnAxis;D3DXVec3Cross(&turnAxis, &axis, &originalAxis);D3DXVec3Normalize(&axis, &axis);D3DXMATRIX turnMatrix;D3DXMatrixRotationAxis(&turnMatrix, &turnAxis,
acos(D3DXVec3Dot(&axis, &originalAxis)));shapeDesc->localPose.M.setColumnMajorStride4((NxF32*)&turnMatrix);
shapeDesc->density = shapeNode.readDouble(L"density");
}
XML - finomhangolás
<PhysicsModel name="pickup">
<NxBoxShape density="0.1" position.y="9" dimension.x="16.5" dimension.y="3" dimension.z="6.7" />
<NxBoxShape density="0.1" position.y="14" dimension.x="4" dimension.y="2" dimension.z="6.2" />
<NxBoxShape density="300" position.y="2.2" dimension.x="4" dimension.y="0.1" dimension.z="6" />
XML Folyt. <NxWheelShape material="wheel"
position.x="-10" position.y="6" position.z="-7" axis.x="1" approximation="10" radius="4.0" width="2" suspension="2" springRestitution="7000" springDamping="800" springBias="0" maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.6"/>
<NxWheelShape material="wheel" position.x="-10" position.y="6" position.z="7" axis.x="-1" approximation="10" radius="4.0" width="2" suspension="2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.6"/> <NxWheelShape material="wheel" position.x="12" position.y="6" position.z="-7"
axis.x="1" approximation="10" radius="4.0" width="2" suspension="2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.6"/> <NxWheelShape material="wheel" position.x="12" position.y="6" position.z="7" axis.x="-
1" approximation="10" radius="4.0" width="2" suspension="2" springRestitution="7000" springDamping="800" springBias="0"
maxBrakeForce="1" frictionToFront="0.1" frictionToSide="0.6"/>
</PhysicsModel>
Csináljunk vezérlést
Wheel-be vezérlő-referencia
WheelController vezérlő
(RigidBodyControl mintájára)
PhysicsEntityWheel
friend class WheelController;
WheelController* controller;
double torque;
double steerAngle;
public:
void control(const ControlContext& context);
void setController(WheelController* controller);
PhysicsEntityWheel.cpp
PhysicsEntityWheel::
PhysicsEntityWheel(ShadedMesh* shadedMesh){
this->shadedMesh = shadedMesh;
rollAngle = 0.0;
torque = 0.0;
steerAngle = 0.0;
controller = NULL;
}
PhysicsEntityWheel.cpp
void PhysicsEntityWheel::animate(
double dt)
{
rollAngle += dt *
shape->getAxleSpeed();
shape->setMotorTorque(torque);
shape->setSteerAngle(steerAngle);
}
PhysicsEntityWheel.cpp
#include "WheelController.h"void PhysicsEntityWheel::control(
const ControlContext& context){torque = 0.0;steerAngle = 0.0;if(controller)
controller->apply(this, context);}void PhysicsEntityWheel::setController(
WheelController* controller) {this->controller = controller;
}
új class: WheelControllerclass Motor;class Steer;class PhysicsEntityWheel;class ControlContext;
class WheelController {std::vector<Motor*> motors;std::vector<Steer*> steers;
public:WheelController(void);~WheelController(void);void addMotor(Motor* motor);void addSteer(Steer* steer);void apply(PhysicsEntityWheel* wheel, const ControlContext& context);
};
WheelController.cpp
#include "DXUT.h"#include "WheelController.h"#include "PhysicsEntityWheel.h"#include "Motor.h"#include "Steer.h"#include "ControlStatus.h"#include "ControlContext.h"
WheelController::WheelController(void){}
WheelController.cppWheelController::~WheelController(void){std::vector<Motor*>::iterator i = motors.begin();while(i != motors.end()){
delete *i;i++;
}std::vector<Steer*>::iterator si = steers.begin();while(si != steers.end()) {
delete *si;si++;
}}
WheelController.cpp
void WheelController::addMotor(
Motor* motor){
motors.push_back(motor);
}
void WheelController::addSteer(
Steer* steer){
steers.push_back(steer);
}
WheelController.cppvoid WheelController::apply(
PhysicsEntityWheel* wheel, const ControlContext& context){std::vector<Motor*>::iterator i = motors.begin();while(i != motors.end()){
Motor* motor = *i;if(context.controlStatus.keyPressed[motor->key]){
wheel->torque += motor->torque.x;}i++;
}std::vector<Steer*>::iterator si = steers.begin();while(si != steers.end()){
Steer* steer= *si;if(context.controlStatus.keyPressed[steer->key])
wheel->steerAngle = steer->turn.x;si++;
}}
Steer (motor már van)
class Steer{
friend class WheelController;
unsigned int key;
D3DXVECTOR3 turn;
public:
Steer(unsigned int key,
const D3DXVECTOR3& turn);
};
Steer.cpp
#include "DXUT.h"
#include "Steer.h"
Steer::Steer(unsigned int key, const D3DXVECTOR3& turn)
{
this->key = key;
this->turn = turn;
}
a régi Motor jó, de:
class Motor
{
friend class MotorControl;
friend class WheelController;
EngineCore
WheelControllerDirectory wheelControllerDirectory;
void loadWheelControllers(XMLNode& xMainNode);
void loadWheelMotors(XMLNode& controllerNode, WheelController* controller);
void loadWheelSteers(XMLNode& controllerNode, WheelController* controller);
EngineCore.cpp
#include "WheelController.h"
#include "Steer.h"
EngineCore.cpp
void EngineCore::loadLevel(){
loadWheelControllers(propsNode);
loadGroup(…
EngineCore::releaseManagedResources
{
WheelControllerDirectory::iterator i =
wheelControllerDirectory.begin();
while(i !=
wheelControllerDirectory.end()){
delete i->second;
i++;
}
}
EngineCore.cppvoid EngineCore::loadWheelControllers(XMLNode& xMainNode){
int iWheelController = 0;XMLNode wheelControllerNode;while( !(wheelControllerNode = xMainNode.getChildNode(L"WheelController",
iWheelController)).isEmpty() ) { const wchar_t* name = wheelControllerNode|L"name"; if(name) { WheelController* wheelController = new WheelController(); wheelControllerDirectory[name] = wheelController; loadWheelMotors(wheelControllerNode, wheelController); loadWheelSteers(wheelControllerNode, wheelController);}iWheelController++;}
}
EngineCore.cppvoid EngineCore::loadWheelMotors(
XMLNode& controllerNode, WheelController* controller){int iMotor = 0; XMLNode motorNode;while( !(motorNode = controllerNode.getChildNode(L“Motor",
iMotor)).isEmpty() ) { NxVec3 force = motorNode.readNxVec3(L"force");NxVec3 torque = motorNode.readNxVec3(L"torque"); unsigned int keyCode = mtorNode.readLong(L"key"); const wchar_t* codeTypeString = motorNode|L"codeType"; if(codeTypeString
&& wcscmp(codeTypeString, L"numpad") == 0) keyCode += VK_NUMPAD0; motorController->addMotor(
new Motor(keyCode, force, torque)); iMotor++;}
}
EngineCore.cppvoid EngineCore::loadWheelSteers(
XMLNode& controllerNode, WheelController* controller){int iSteer = 0; XMLNode steerNode;while( !(steerNode = controllerNode.getChildNode(L"Steer",
iSteer)).isEmpty() ) { D3DXVECTOR3 turn = steerNode.readVector(L"turn"); unsigned int keyCode = steerNode.readLong(L"key"); const wchar_t* codeTypeString = steerNode|L"codeType"; if(codeTypeString
&& wcscmp(codeTypeString, L"numpad") == 0) keyCode += VK_NUMPAD0; controller->addSteer(new Steer(keyCode, turn)); iSteer++;}
}
EngineCore::loadPhysicsEntityWheels
physicsEntity->addWheel(wheel);const wchar_t* controllerName = wheelNode|L"controller";
if(controllerName){WheelControllerDirectory::iterator
iWheelController =wheelControllerDirectory.find(
controllerName);if(iWheelController !=
wheelControllerDirectory.end())wheel->setController(
iWheelController->second);}
XML <WheelController name="frontLeftWheel"> <Motor key="85" torque.x="-50" /> <Motor key="74" torque.x="50" /> </WheelController> <WheelController name="rearLeftWheel"> <Motor key="85" torque.x="-450" /> <Motor key="74" torque.x="450" /> <Steer key="72" turn.x="-0.5" /> <Steer key="75" turn.x="0.5" /> </WheelController> <WheelController name="frontRightWheel"> <Motor key="85" torque.x="50" /> <Motor key="74" torque.x="-50" /> </WheelController> <WheelController name="rearRightWheel"> <Motor key="85" torque.x="450" /> <Motor key="74" torque.x="-450" /> <Steer key="72" turn.x="-0.5" /> <Steer key="75" turn.x="0.5" /> </WheelController>
XML<PhysicsEntity name="pickup" shadedMesh="pickup"
physicsModel="pickup" position.y="30" >
<Wheel shadedMesh="wheel" controller="frontLeftWheel" />
<Wheel shadedMesh="wheel" controller="frontRightWheel" />
<Wheel shadedMesh="wheel" controller="rearLeftWheel" />
<Wheel shadedMesh="wheel" controller="rearRightWheel" />
</PhysicsEntity>
PhysicsEntity
void control(const ControlContext& context);
PhysicsEntity.cpp
void PhysicsEntity::control(
const ControlContext& context){
std::vector<PhysicsEntityWheel*>::
iterator wii = wheels.begin();
while(wii != wheels.end()){
(*wii)->control(context);
wii++;
}
}
Steer in render
D3DXMATRIX modelMatrix, rollMatrix, steerMatrix;
D3DXMatrixRotationX(&rollMatrix, rollAngle);
pose.getColumnMajor44((NxF32*)&modelMatrix);
D3DXMatrixRotationY(&steerMatrix,
shape->getSteerAngle());
D3DXMatrixMultiply(&modelMatrix, &steerMatrix,
&modelMatrix);
D3DXMatrixMultiply(&modelMatrix, &rollMatrix, &modelMatrix);