Motor III.Merev test animáció
Szécsi László
Letöltés
diák:www.iit.bme.hu/~szecsi/GraphGame/l08-engine3.ppt
RigidModel és RigidBodyOsztályok:RigidModel
1/m, I-1
később ütközés, légellenállásRigidBody
rigidModel hivatkozásx, L, q, P
EngineCore: RigidModelDirectoryRigidBody-k meg mehetnek az entitások közé
RigidModelclass RigidModel{friend class RigidBody;
/// Inverse of physical mass.double invMass;/// Inverse of mass moments of inertia matrix.D3DXMATRIX invAngularMass;
public:
RigidModelRigidModel( double invMass, double invAngularMassX, double invAngularMassY, double invAngularMassZ);
/// Returns 1/mass.double getInvMass();/// Returns the inverse of the moments of inertia matrix.const D3DXMATRIX& getInvAngularMass();
};
RigidModel.cppRigidModel::RigidModel( double invMass, double invAngularMassX, double invAngularMassY, double invAngularMassZ)
{this->invMass = invMass;D3DXMatrixScaling(&invAngularMass, invAngularMassX, invAngularMassY, invAngularMassZ);centreOfMass = D3DXVECTOR3(0, 0, 0);drag = D3DXVECTOR3(0, 0, 0);angularDrag = D3DXVECTOR3(0, 0, 0);
}
RigidModel.cppdouble RigidModel::getInvMass(){return invMass;
}
const D3DXMATRIX& RigidModel::getInvAngularMass()
{return invAngularMass;
}
RigidBodyclass RigidModel;
class RigidBody : public Entity{/// Physics model reference.RigidModel* rigidModel;
RigidBody/// Position. [x]D3DXVECTOR3 position;/// Orientation. [q]D3DXQUATERNION orientation;
/// Momentum. [L] (lendület)D3DXVECTOR3 momentum;/// Angular momentum. [P] (perdület)D3DXVECTOR3 angularMomentum;
RigidBody/// Force. [F]D3DXVECTOR3 force;/// Torque. [tau = r x F]D3DXVECTOR3 torque;
/// Auxiliary roataion matrix computed from orientation. [R]D3DXMATRIX rotationMatrix;
RigidBodypublic:/// Constructor.RigidBody(ShadedMesh* shadedMesh, RigidModel* rigidModel);
virtual void render(const RenderContext& context);
virtual void animate(double dt);virtual void control(const ControlContext& context);
RigidBodyvoid setPosition(const D3DXVECTOR3& position);void setAngularMomentum(const D3DXVECTOR3& am);
/// Returns model matrix to be used by lights and camera attached to the entity.virtual void getModelMatrix(D3DXMATRIX& modelMatrix);
/// Returns the inverse of the model matrix.virtual void getModelMatrixInverse(D3DXMATRIX& modelMatrixInverse);
/// Returns the inverse of the rotation matrix.virtual void getRotationMatrixInverse(D3DXMATRIX& rotationMatrixInverse);void getWorldInvMassMatrix(D3DXMATRIX& wim);
};
RigidBody.cpp#include "RigidModel.h"#include "ShadedMesh.h"#include "Camera.h"
RigidBody::RigidBody(ShadedMesh* shadedMesh, RigidModel* rigidModel)
:Entity(shadedMesh){
this->rigidModel = rigidModel;position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);orientation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f);
momentum = D3DXVECTOR3(0.0f, 0.0f, 0.0f);angularMomentum = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
force = D3DXVECTOR3(0.0f, 0.0f, 0.0f);torque = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
D3DXMatrixRotationQuaternion(&rotationMatrix, &orientation);}
RigidBody.cppvoid RigidBody::render(const RenderContext& context){
D3DXMATRIX positionMatrix;D3DXMatrixTranslation(&positionMatrix, position.x, position.y, position.z);
D3DXMATRIX bodyModelMatrix = rotationMatrix * positionMatrix;D3DXMATRIX bodyModelMatrixInverse;D3DXMatrixInverse(&bodyModelMatrixInverse, NULL, &bodyModelMatrix);
context.effect->SetMatrix("modelMatrix", &bodyModelMatrix);context.effect->SetMatrix("modelMatrixInverse", &bodyModelMatrixInverse);
D3DXMATRIX modelViewProjMatrix = bodyModelMatrix * context.camera->getViewMatrix() * context.camera->getProjMatrix();context.effect->SetMatrix("modelViewProjMatrix", &modelViewProjMatrix);
D3DXMATRIX modelViewMatrix = bodyModelMatrix * context.camera->getViewMatrix();context.effect->SetMatrix("modelViewMatrix", &modelViewMatrix);
shadedMesh->render(context);}
RigidBody.cppvoid RigidBody::animate(double dt){momentum += force * dt;D3DXVECTOR3 velocity = momentum * rigidModel->invMass;position += velocity * dt;
angularMomentum += torque * dt;
animate folyt.// compute inverse mass matrixD3DXMATRIX worldSpaceInvMassMatrix;getWorldInvMassMatrix(worldSpaceInvMassMatrix);// compute angular velocity vectorD3DXVECTOR3 angularVelocity;D3DXVec3TransformCoord(&angularVelocity,
&angularMomentum, &worldSpaceInvMassMatrix);// compute rotation happening in dt timefloat rotationsPerSecond = D3DXVec3Length(&angularVelocity);D3DXQUATERNION angularDifferenceQuaternion;D3DXQuaternionRotationAxis(
&angularDifferenceQuaternion, &angularVelocity, rotationsPerSecond * 6.28 * dt);
// append rotation to orientationorientation *= angularDifferenceQuaternion;D3DXMatrixRotationQuaternion
(&rotationMatrix, &orientation);}
RigidBody.cppVoidRigidBody::getWorldInvMassMatrix(D3DXMATRIX& wim)
{D3DXMATRIX transposedRotationMatrix;
D3DXMatrixTranspose(&transposedRotationMatrix, &rotationMatrix);wim = transposedRotationMatrix * rigidModel->invAngularMass * rotationMatrix;
}
RigidBody::controlvoid RigidBody::control(const ControlContext& context)
{force = D3DXVECTOR3(0.0, 0.0, 0.0);torque = D3DXVECTOR3(0.0, 0.0, 0.0);
//gravityif(rigidModel->invMass > 0.0)
force += D3DXVECTOR3(0.0, -10.0 / rigidModel->invMass, 0.0);
}
RigidBody.cppvoid RigidBody::setPosition(const D3DXVECTOR3& position)
{this->position = position;
}
void RigidBody::setAngularMomentum(const D3DXVECTOR3& am)
{this->angularMomentum = am;
}
RigidBody.cppvoid RigidBody::getModelMatrix(D3DXMATRIX& modelMatrix){
D3DXMATRIX positionMatrix;D3DXMatrixTranslation(&positionMatrix, position.x, position.y, position.z);
modelMatrix = rotationMatrix * positionMatrix;}
void RigidBody::getModelMatrixInverse(D3DXMATRIX& modelMatrixInverse){
D3DXMATRIX positionMatrix, rotationMatrixTransposed;D3DXMatrixTranslation(&positionMatrix, -position.x, -position.y, -position.z);D3DXMatrixTranspose(&rotationMatrixTransposed, &rotationMatrix);
modelMatrixInverse = positionMatrix * rotationMatrixTransposed;}
void RigidBody::getRotationMatrixInverse(D3DXMATRIX& rotationMatrixInverse){
D3DXMatrixTranspose(&rotationMatrixInverse, &rotationMatrix);}
XML<RigidModel name="ship" invMass="1" invAngularMassX="1" invAngularMassY="1" invAngularMassZ="1" />
<Group> <RigidBody name="flagShip" shadedMesh="steelPredator" rigidModel="ship" control="player"/>
</Group>
Directory.hclass RigidModel;typedef std::map<const std::wstring, RigidModel*> RigidModelDirectory;
EngineCoreRigidModelDirectoryrigidModelDirectory;
void loadRigidModels(XMLNode& xMainNode);
void loadRigidBodies(XMLNode& groupNode, NodeGroup* group);
loadLevelloadRigidModels(xMainNode);
// még az entitások betöltése előtt
EngineCore.cpp#include "RigidModel.h"#include "RigidBody.h"
void EngineCore::loadRigidModels(XMLNode& xMainNode){int iRigidModel = 0;XMLNode rigidModelNode;while(!(rigidModelNode=xMainNode.getChildNode(L"RigidModel",
iRigidModel)).isEmpty()){
const wchar_t* rigidModelName = rigidModelNode|L"name";double invMass = rigidModelNode.readDouble(L"invMass");double invAngularMassX = rigidModelNode.readDouble(L"invAngularMassX");double invAngularMassY = rigidModelNode.readDouble(L"invAngularMassY");double invAngularMassZ = rigidModelNode.readDouble(L"invAngularMassZ");
RigidModel* rigidModel = new RigidModel(invMass, invAngularMassX, invAngularMassY, invAngularMassZ);
rigidModelDirectory[rigidModelName] = rigidModel;iRigidModel++;
}
}
EngineCore.cppvoid EngineCore::loadRigidBodies(XMLNode& groupNode, NodeGroup* group){int iRigidBody = 0;XMLNode rigidBodyNode;while( !(rigidBodyNode =
groupNode.getChildNode(L"RigidBody", iRigidBody)).isEmpty() ){ const wchar_t* shadedMeshName = rigidBodyNode|L"shadedMesh"; ShadedMeshDirectory::iterator iShadedMesh =
shadedMeshDirectory.find(shadedMeshName); const wchar_t* rigidModelName = rigidBodyNode|L"rigidModel"; RigidModelDirectory::iterator iRigidModel =
rigidModelDirectory.find(rigidModelName); if(iShadedMesh != shadedMeshDirectory.end() &&
iRigidModel != rigidModelDirectory.end()) {
RigidBody* rigidBody =new RigidBody(iShadedMesh->second, iRigidModel->second);
rigidBody->setPosition(rigidBodyNode.readVector(L"pos"));group->add(rigidBody);const wchar_t* entityName = rigidBodyNode|L"name";if(entityName)
entityDirectory[entityName] = rigidBody; } iRigidBody++;}}
EngineCore.cppvoid EngineCore::loadGroup(XMLNode& groupNode, NodeGroup*& group)
{if(groupNode.isEmpty())
return;
group = new NodeGroup();
loadEntities(groupNode, group);loadRigidBodies(groupNode, group);
}
PróbaNem történik semmi
control-t nem hívjuk még
Új class: ControlContextHagyjuk üresen,
EngineCore:#include "ControlContext.h"
void EngineCore::animate(double dt, double t){currentCamera->second->animate(dt);sceneRoot->control(ControlContext());sceneRoot->animate(dt);
}
PróbaZuhan
Játék a RigidBody::controlban
Pl.
torque.x += 1;torque.y += 1;
VezérlésControlStatus osztály
Billentyűlenyomások, egérgombok és egérpozíció nyilvántartása
EngineCore-ba:ControlStatus status;
ControlStatusclass ControlStatus{public:
/// Array of key pressed state variables. Addressed by virtual key codes, true if key is pressed.bool keyPressed[0xff];/// Mouse pointer position in normalized screen space.D3DXVECTOR3 mousePosition;/// Pressed state variable of left, center and right mouse buttons.bool mouseButtonPressed[3];
/// Screen width. Not set by constructor.unsigned int screenWidth;/// Screen height. Not set by constructor.unsigned int screenHeight;
/// Updates input state by processing message.virtual void handleInput(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/// Constructor. Intializes input state.ControlStatus();
};
ControlStatus.cpp#include "DXUT.h"#include "ControlStatus.h"
ControlStatus::ControlStatus(){
for(unsigned int i=0; i<0xff; i++)keyPressed[i] = false;
mouseButtonPressed[0] = false;mouseButtonPressed[1] = false;mouseButtonPressed[2] = false;mousePosition = D3DXVECTOR3(0, 0, 0);
}
void ControlStatus::handleInput(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
if(uMsg == WM_KEYDOWN)keyPressed[wParam] = true;
else if(uMsg == WM_KEYUP)keyPressed[wParam] = false;
else if(uMsg == WM_KILLFOCUS){
for(unsigned int i=0; i<0xff; i++)keyPressed[i] = false;
}else if(uMsg == WM_MOUSEMOVE){
POINT pixPos;if(GetCursorPos(&pixPos))
mousePosition = D3DXVECTOR3((double)pixPos.x / screenWidth * 2.0 - 1.0, (double)pixPos.y / screenHeight * 2.0 - 1.0, 0);}
}
EngineCore::processMessage
void EngineCore::processMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
currentCamera->second->handleInput(hWnd, uMsg,
wParam, lParam);status.handleInput(hWnd, uMsg, wParam, lParam);
}
ControlContextclass ControlStatus;class Node;
class ControlContext{public: const ControlStatus& controlStatus;
/// Time step.double dt;/// Scene graph reference for interaction computations.Node* interactors;
ControlContext(const ControlStatus& controlStatus,double dt,Node* interactors):controlStatus(controlStatus)
{this->dt = dt;this->interactors = interactors;
}};
Létrehozásavoid EngineCore::animate(double dt, double t)
{currentCamera->second->animate(dt);sceneRoot->control(ControlContext(status, dt, sceneRoot));sceneRoot->animate(dt);
}
RigidBody::control játék#include "ControlContext.h"#include "ControlStatus.h"
if(context.controlStatus.keyPressed['U'])force.y += 100;