void MyODEGeom::notifyBodyMoved() { //dcollide::debug() << dc_funcinfo; if (mMoveNodeOnBodyMoved) { //get the new state from ODE const dReal* odeposition = dBodyGetPosition(mBody); const dReal* oderotation = dBodyGetRotation(mBody); //4x3 rotation matrix dcollide::Matrix dcMatrix; //copy the 4x3 rotation matrix, fill the last row with 0 0 0 1 //NOTE: ODE uses row-major ordering, but ODE uses colum-major ordering // simple Matrix-copying will not do the trick! //ODE rotation matrix format // 0 1 2 3 // 4 5 6 7 // 8 9 10 11 dcMatrix.setElement(0, 0, oderotation[0]); dcMatrix.setElement(0, 1, oderotation[1]); dcMatrix.setElement(0, 2, oderotation[2]); dcMatrix.setElement(1, 0, oderotation[4]); dcMatrix.setElement(1, 1, oderotation[5]); dcMatrix.setElement(1, 2, oderotation[6]); dcMatrix.setElement(2, 0, oderotation[8]); dcMatrix.setElement(2, 1, oderotation[9]); dcMatrix.setElement(2, 2, oderotation[10]); dcollide::Vector3 bodyPosition(odeposition[0], odeposition[1], odeposition[2]); //The position consists of // bodyposition = nodeposition + rotation * offset //<=> nodeposition = bodyposition - rotation * offset dcollide::Vector3 tmp; dcMatrix.transform(&tmp, mGravityOffset); dcollide::Vector3 nodePosition = bodyPosition - tmp; setPosition(nodePosition[0], nodePosition[1], nodePosition[2]); //Rotation matrix does not change setRotation(dcMatrix); // dcollide:: debug() << "dGeommoved: new body position: " <<bodyPosition<<", node position:"<<nodePosition; } }
Scene::Scene(int viewSizeX, int viewSizeY) : m_root(new Node(0)), m_camera(vEyePos, vFocus, vUp, Point(viewSizeX, viewSizeY), fov, zNear, zFar), m_light(lightDirection), m_renderer(&m_camera, &m_light), m_viewSize(viewSizeX, viewSizeY), m_cameraFolows(true), m_fpsStart(0), m_numFrames(0), m_frameTime(0.0f), fpsString() { // Here we build our scene, adding nodes to the scene graph: // // ---> terrainMeshNode // | // root ---| ---> rwingTransformNode -> rwingAnimationNode -> rwingMeshNode // | | // ---> bodyTransformNode -> bodyMeshNode --| // | // ---> lwingTransformNode -> lwingAnimationNode -> lwingMeshNode // std::vectors for raw geometry data (they will be reused) std::vector<Vertex> vertices; std::vector<unsigned int> indices; // Terrain : only mesh node CreateGrid(terrainSize, terrainResolution, vertices, indices); Mesh* terrainMesh = m_renderer.CreateMesh(vertices, indices, false); MeshNode* terrainMeshNode = new MeshNode(terrainMesh, &m_renderer); m_root->AddChild(terrainMeshNode); // Body : transform node -> mesh node TransformNode* bodyTransformNode = new TransformNode(&m_renderer); Vector3 bodyPosition(0.0f, 10.0f, 0.0f); bodyTransformNode->MoveTo(bodyPosition); bodyTransformNode->SetDirection(Vector3(1.0f, 0.0f, 0.0f)); bodyTransformNode->RotateBy(-math::PiDiv6, Vector3(0.0f, 1.0f, 0.0f)); m_root->AddChild(bodyTransformNode); vertices.clear(); indices.clear(); LoadMesh("../../meshes/teapot.obj", vertices, indices, Color(1.0f, 0.0f, 0.0f, 1.0f)); Mesh* bodyMesh = m_renderer.CreateMesh(vertices, indices); MeshNode* bodyMeshNode = new MeshNode(bodyMesh, &m_renderer); bodyTransformNode->AddChild(bodyMeshNode); m_bird = new PlayerCharacter(bodyTransformNode, &m_keyboard); // Right wing : transform node -> animation node -> mesh node TransformNode* rwingTransformNode = new TransformNode(&m_renderer); Vector3 rwingPosition(0.0f, 0.0f, 0.0f); rwingTransformNode->MoveTo(rwingPosition); bodyMeshNode->AddChild(rwingTransformNode); AnimationNode* rwingAnimationNode = new WingAnimationNode(&m_renderer); rwingTransformNode->AddChild(rwingAnimationNode); vertices.clear(); indices.clear(); LoadMesh("../../meshes/wing.obj", vertices, indices, Color(1.0f, 1.0f, 0.0f, 1.0f)); Mesh* rwingMesh = m_renderer.CreateMesh(vertices, indices); MeshNode* rwingMeshNode = new MeshNode(rwingMesh, &m_renderer); rwingAnimationNode->AddChild(rwingMeshNode); // Left wing : transform node -> animation node -> mesh node TransformNode* lwingTransformNode = new TransformNode(&m_renderer); Vector3 lwingPosition(0.0f, 0.0f, 0.0f); lwingTransformNode->MoveTo(lwingPosition); lwingTransformNode->RotateBy(math::Pi, Vector3(0.0f, 1.0f, 0.0f)); bodyMeshNode->AddChild(lwingTransformNode); AnimationNode* lwingAnimationNode = new WingAnimationNode(&m_renderer, true); lwingTransformNode->AddChild(lwingAnimationNode); vertices.clear(); indices.clear(); LoadMesh("../../meshes/wing.obj", vertices, indices, Color(1.0f, 1.0f, 0.0f, 1.0f)); Mesh* lwingMesh = m_renderer.CreateMesh(vertices, indices); MeshNode* lwingMeshNode = new MeshNode(lwingMesh, &m_renderer); lwingAnimationNode->AddChild(lwingMeshNode); m_fpsStart = glutGet(GLUT_ELAPSED_TIME); fpsString.resize(256); }