//设置位置 (游戏世界坐标) VOID CEffectObject::SetPosition(const fVector3& vPos) { //坐标转换 fVector3 fvGfx; CRenderSystem::GetMe()->Axis_Trans(CRenderSystem::AX_GAME, vPos, CRenderSystem::AX_GFX, fvGfx); std::list< std::pair< Fairy::Effect*, Ogre::SceneNode* > >::iterator it; for(it=m_listEffectImpl.begin(); it!=m_listEffectImpl.end(); it++) { it->second->setPosition(Ogre::Vector3(fvGfx.x, fvGfx.y, fvGfx.z)); } #if 0 Ogre::Matrix4 mxPosition = Ogre::Matrix4::IDENTITY; mxPosition.makeTrans(fvGfx.x, fvGfx.y, fvGfx.z); Ogre::MatrixList vMatrix; vMatrix.push_back(mxPosition); std::list< Ogre::Effect* >::iterator it; for(it=m_listEffectImpl.begin(); it!=m_listEffectImpl.end(); it++) { (*it)->execute(0, vMatrix); } #endif }
//------------------------------------------------------------------------------ void Background2D::renderQueueEnded( Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation ) { if( cv_show_background2d.GetB() == false ) { return; } if( queueGroupId == Ogre::RENDER_QUEUE_MAIN ) { m_RenderSystem->_setWorldMatrix( Ogre::Matrix4::IDENTITY ); m_RenderSystem->_setProjectionMatrix( Ogre::Matrix4::IDENTITY ); Ogre::Viewport *viewport( CameraManager::getSingleton().getViewport() ); float width = viewport->getActualWidth(); float height = viewport->getActualHeight(); Ogre::Matrix4 view; view.makeTrans( Ogre::Vector3( m_PositionReal.x * 2 / width, -m_PositionReal.y * 2 / height, 0 ) ); m_RenderSystem->_setViewMatrix( view ); if( m_AlphaRenderOp.vertexData->vertexCount != 0 ) { m_SceneManager->_setPass( m_AlphaMaterial->getTechnique( 0 )->getPass( 0 ), true, false ); m_RenderSystem->_render( m_AlphaRenderOp ); } if( m_AddRenderOp.vertexData->vertexCount != 0 ) { m_SceneManager->_setPass( m_AddMaterial->getTechnique( 0 )->getPass( 0 ), true, false ); m_RenderSystem->_render( m_AddRenderOp ); } } }
const Ogre::Vector3 Mesh::getWorldSpacePosition(const Ogre::Vector3& ObjectSpacePosition) const { Ogre::Matrix4 mWorldMatrix; if (mCreated) { #if OGRE_VERSION_MAJOR >= 1 && OGRE_VERSION_MINOR >= 7 mWorldMatrix = mEntity->getParentSceneNode()->_getFullTransform(); #else mEntity->getParentSceneNode()->getWorldTransforms(&mWorldMatrix); #endif } else { Ogre::SceneNode *mTmpSN = new Ogre::SceneNode(0); mTmpSN->setPosition(mHydrax->getPosition()); #if OGRE_VERSION_MAJOR >= 1 && OGRE_VERSION_MINOR >= 7 mWorldMatrix = mTmpSN->_getFullTransform(); #else mTmpSN->getWorldTransforms(&mWorldMatrix); #endif delete mTmpSN; } return mWorldMatrix.transformAffine(ObjectSpacePosition); }
bool Panel::injectMouseMoved(const Ogre::Ray& ray) { Ogre::Matrix4 transform; transform.makeTransform(mNode->getPosition(), mNode->getScale(), mNode->getOrientation()); Ogre::AxisAlignedBox aabb = mScreenRenderable->getBoundingBox(); aabb.transform(transform); pair<bool, Ogre::Real> result = Ogre::Math::intersects(ray, aabb); if (result.first == false) { unOverAllElements(); return false; } Ogre::Vector3 a,b,c,d; Ogre::Vector2 halfSize = (mSize/100) * 0.5f; a = transform * Ogre::Vector3(-halfSize.x,-halfSize.y,0); b = transform * Ogre::Vector3( halfSize.x,-halfSize.y,0); c = transform * Ogre::Vector3(-halfSize.x, halfSize.y,0); d = transform * Ogre::Vector3( halfSize.x, halfSize.y,0); result = Ogre::Math::intersects(ray, c, b, a); if (result.first == false) result = Ogre::Math::intersects(ray, c, d, b); if (result.first == false) { unOverAllElements(); return false; } if (result.second > mDistanceFromPanelToInteractWith) { unOverAllElements(); return false; } Ogre::Vector3 hitPos = (ray.getOrigin() + (ray.getDirection() * result.second)); Ogre::Vector3 localPos = transform.inverse() * hitPos; localPos.x += halfSize.x; localPos.y -= halfSize.y; localPos.x *= 100; localPos.y *= 100; // Cursor clip localPos.x = Ogre::Math::Clamp<Ogre::Real>(localPos.x, 0, mSize.x - 10); localPos.y = Ogre::Math::Clamp<Ogre::Real>(-localPos.y, 0, mSize.y - 18); mInternalMousePos = Ogre::Vector2(localPos.x, localPos.y); mMousePointer->position(mInternalMousePos); // Let's actualize the "over" for each elements for (size_t i=0; i < mPanelElements.size(); i++) mPanelElements[i]->isOver(mInternalMousePos); return true; }
// ---------------------------------------------------------------- // gets the location of the specified eye // ---------------------------------------------------------------- Ogre::Matrix4 OgreOpenVR::getHMDMatrixPoseEye(vr::Hmd_Eye nEye) { if (!m_pHMD) return Ogre::Matrix4(); vr::HmdMatrix34_t matEye = m_pHMD->GetEyeToHeadTransform(nEye); Ogre::Matrix4 eyeTransform = convertSteamVRMatrixToOgreMatrix4(matEye); return eyeTransform.inverse(); }
int IcoSphere::addToVertices(std::list<VertexPair> *target, const Ogre::Vector3 &position, const Ogre::ColourValue &colour, float scale) { Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY; transform.setTrans(position); transform.setScale(Ogre::Vector3(scale, scale, scale)); for (int i = 0; i < (int)vertices.size(); i++) target->push_back(VertexPair(transform * vertices[i], colour)); return vertices.size(); }
Button* check(const Ogre::Ray& ray, bool& isOver) { isOver = false; Ogre::Matrix4 transform; transform.makeTransform(mNode->getPosition(), mNode->getScale(), mNode->getOrientation()); Ogre::AxisAlignedBox aabb = mScreen->getBoundingBox(); aabb.transform(transform); std::pair<bool, Ogre::Real> result = Ogre::Math::intersects(ray, aabb); if (result.first == false) return 0; Ogre::Vector3 a,b,c,d; Ogre::Vector2 halfSize = mSize * 0.5f; a = transform * Ogre::Vector3(-halfSize.x,-halfSize.y,0); b = transform * Ogre::Vector3( halfSize.x,-halfSize.y,0); c = transform * Ogre::Vector3(-halfSize.x, halfSize.y,0); d = transform * Ogre::Vector3( halfSize.x, halfSize.y,0); result = Ogre::Math::intersects(ray, c, b, a); if (result.first == false) result = Ogre::Math::intersects(ray, c, d, b); if (result.first == false) return 0; if (result.second > 6.0f) return 0; isOver = true; Ogre::Vector3 hitPos = ( ray.getOrigin() + (ray.getDirection() * result.second) ); Ogre::Vector3 localPos = transform.inverse() * hitPos; localPos.x += halfSize.x; localPos.y -= halfSize.y; localPos.x *= 100; localPos.y *= 100; // Cursor clip localPos.x = Ogre::Math::Clamp<Ogre::Real>(localPos.x, 0, (mSize.x * 100) - 10); localPos.y = Ogre::Math::Clamp<Ogre::Real>(-localPos.y, 0, (mSize.y * 100) - 18); mMousePointer->position(localPos.x, localPos.y); for (size_t i=0;i < mButtons.size();i++) { if (mButtons[i]->isOver(mMousePointer->position())) return mButtons[i]; } return 0; }
Ogre::AxisAlignedBox AACamera::GetBoundingBox(bool transformed) const { Ogre::AxisAlignedBox box = Box; if (!transformed) return box; Ogre::Matrix4 transforms; //Node->getWorldTransforms(&transforms); transforms.makeTransform(Node->getPosition(),Node->getScale(),Node->getOrientation()); box.transform(transforms); return box; }
void BoxCenterMovable::getBoundingBoxCenter() { if(object.lock()->hasProperty("bounding box") && object.lock()->hasProperty("position")) { Ogre::AxisAlignedBox aabb = VariantCast<Ogre::AxisAlignedBox>(object.lock()->getProperty("bounding box")); /*Ogre::Vector3 position = VariantCast<Ogre::Vector3>(object.lock()->getProperty("position")); Ogre::Matrix4 matTrans; matTrans.makeTrans( position ); aabb.transformAffine(matTrans);*/ Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY; Ogre::Matrix3 rot3x3; if (object.lock()->hasProperty("orientation")) { Ogre::Quaternion orientation = VariantCast<Ogre::Quaternion>(object.lock()->getProperty("orientation")); orientation.ToRotationMatrix(rot3x3); } else { rot3x3 = Ogre::Matrix3::IDENTITY; } Ogre::Matrix3 scale3x3; if (object.lock()->hasProperty("scale")) { Ogre::Vector3 scale = VariantCast<Ogre::Vector3>(object.lock()->getProperty("scale")); scale3x3 = Ogre::Matrix3::ZERO; scale3x3[0][0] = scale.x; scale3x3[1][1] = scale.y; scale3x3[2][2] = scale.z; } else { scale3x3 = Ogre::Matrix3::IDENTITY; } transform = rot3x3 * scale3x3; if (object.lock()->hasProperty("position")) { Ogre::Vector3 position = VariantCast<Ogre::Vector3>(object.lock()->getProperty("position")); transform.setTrans(position); } aabb.transformAffine(transform); mCenterPosWC = aabb.getCenter(); } }
void PlayerCameraOgre::onRightButtonPressed() { if (!mRightButtonPressedLastFrame) mMousePosLastFrame = mMouse->getPosition(); mp::Vector2i diff = mMouse->getPosition() - mMousePosLastFrame; const mp::Vector3f &playerPos = mPlayer->model()->getPosition(); Ogre::Vector3 pivotPoint(playerPos.getX(), playerPos.getY() + mPivotHeight, playerPos.getZ()); float yaw = (float)diff.getX() * CAMERA_SPEED; float pitch = (float)-diff.getY() * CAMERA_SPEED; Ogre::Quaternion yawQuat; yawQuat.FromAngleAxis(Ogre::Radian(yaw), Ogre::Vector3::UNIT_Y); Ogre::Matrix3 yawMat; yawQuat.ToRotationMatrix(yawMat); Ogre::Vector3 pivotToPos = Ogre::Vector3(mRealPosition.getX(), mRealPosition.getY(), mRealPosition.getZ()) - pivotPoint; Ogre::Matrix4 pos(1, 0, 0, pivotToPos.x, 0, 1, 0, pivotToPos.y, 0, 0, 1, pivotToPos.z, 0, 0, 0, 1); Ogre::Vector3 xz(pivotToPos.x, 0, pivotToPos.z); Ogre::Vector3 norm(-xz.z, 0, xz.x); Ogre::Quaternion pitchQuat; pitchQuat.FromAngleAxis(Ogre::Radian(pitch), norm); Ogre::Matrix3 pitchMat; pitchQuat.ToRotationMatrix(pitchMat); Ogre::Matrix4 toPivot(1, 0, 0, pivotPoint.x, 0, 1, 0, pivotPoint.y, 0, 0, 1, pivotPoint.z, 0, 0, 0, 1); Ogre::Matrix4 newPosMat = pos * pitchMat * yawMat * toPivot; newPosMat = newPosMat.inverse(); Ogre::Vector3 newPos = newPosMat.getTrans(); mRealPosition.set(-newPos.x, -newPos.y, -newPos.z); setPosition(mRealPosition); lookAt(pivotPoint.x, pivotPoint.y, pivotPoint.z); adjustDistance(); mMousePosLastFrame = mMouse->getPosition(); mRightButtonPressedLastFrame = true; }
void OgreCollada::MeshWriter::pass1Finish() { // build scene graph and record transformations for each geometry instantiation // determine initial transformation Ogre::Matrix4 xform; xform.makeTransform(Ogre::Vector3::ZERO, // no translation Ogre::Vector3(m_ColladaScale.x, m_ColladaScale.y, m_ColladaScale.z), Ogre::Quaternion(m_ColladaRotation.w, m_ColladaRotation.x, m_ColladaRotation.y, m_ColladaRotation.z)); // recursively find geometry instances and their transforms for (size_t i = 0; i < m_vsRootNodes.size(); ++i) { createSceneDFS(m_vsRootNodes[i], xform); } // create manualobject for use by pass2 writeGeometry calls m_manobj = new Ogre::ManualObject(m_vsRootNodes[0]->getName() + "_mobj"); }
void EditorNode::setTransform(Ogre::Matrix4 transform) { Ogre::Vector3 position, scale; Ogre::Quaternion orientation; transform.decomposition(position, scale, orientation); scene_node->setPosition(position); scene_node->setScale(scale); scene_node->setOrientation(orientation); }
// // 根据输入的平移, 旋转, 缩放分量创建出位置变换矩阵. // void FairyEditorFrame::BuildTransformMatrix(Ogre::Matrix4& Matrix, const Ogre::Vector3& position, const Ogre::Quaternion rotate, const Ogre::Vector3 scale) { Ogre::Matrix4 posMatrix; Ogre::Matrix4 scaleMatrix; Ogre::Matrix4 rotateMatrix(rotate); posMatrix = Ogre::Matrix4::IDENTITY; posMatrix.setTrans(position); scaleMatrix = Ogre::Matrix4::IDENTITY; scaleMatrix.setScale(scale); // 最终的变换矩阵. Matrix = posMatrix * rotateMatrix * scaleMatrix; }
const Ogre::Vector3 Mesh::getWorldSpacePosition(const Ogre::Vector3& ObjectSpacePosition) const { Ogre::Matrix4 mWorldMatrix; if (mCreated) { mWorldMatrix = mEntity->getParentSceneNode()->_getFullTransform(); } else { Ogre::SceneNode *mTmpSN = new Ogre::SceneNode(0); mTmpSN->setPosition(mHydrax->getPosition()); mWorldMatrix = mTmpSN->_getFullTransform(); delete mTmpSN; } return mWorldMatrix.transformAffine(ObjectSpacePosition); }
float3 EC_WaterPlane::GetPointOnPlane(const float3 &point) const { if (node_ == 0) return float3::nan; Ogre::Quaternion rot = node_->_getDerivedOrientation(); Ogre::Vector3 trans = node_->_getDerivedPosition(); Ogre::Vector3 scale = node_->_getDerivedScale(); Ogre::Matrix4 worldTM; worldTM.makeTransform(trans, scale, rot); // In Ogre 1.7.1 we could simply use the following line, but since we're also supporting Ogre 1.6.4 for now, the above // lines are used instead, which work in both. // Ogre::Matrix4 worldTM = node_->_getFullTransform(); // local->world. Ogre::Matrix4 inv = worldTM.inverse(); // world->local Ogre::Vector4 local = inv * Ogre::Vector4(point.x, point.y, point.z, 1.f); local.y = 0; Ogre::Vector4 world = worldTM * local; return float3(world.x, world.y, world.z); }
// Called by Rocket when it wants to render application-compiled geometry. void RenderInterfaceOgre3D::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation) { Ogre::Matrix4 transform; transform.makeTrans(translation.x, translation.y, 0); render_system->_setWorldMatrix(transform); render_system = Ogre::Root::getSingleton().getRenderSystem(); RocketOgre3DCompiledGeometry* ogre3d_geometry = (RocketOgre3DCompiledGeometry*) geometry; if (ogre3d_geometry->texture != NULL) { render_system->_setTexture(0, true, ogre3d_geometry->texture->texture); // Ogre can change the blending modes when textures are disabled - so in case the last render had no texture, // we need to re-specify them. render_system->_setTextureBlendMode(0, colour_blend_mode); render_system->_setTextureBlendMode(0, alpha_blend_mode); } else render_system->_disableTextureUnit(0); render_system->_render(ogre3d_geometry->render_operation); }
void RocketInterface::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometryHandle, const Rocket::Core::Vector2f& translation) { RocketOgreGeometry* geometry = reinterpret_cast<RocketOgreGeometry*>(geometryHandle); // Build world matrix Ogre::Matrix4 world; world.makeTrans(translation.x, translation.y, 0); // Draw UI element Ogre::Pass* pass; if (geometry->texture) { pass = mUIMaterial->getTechnique("Texture")->getPass(0); pass->getTextureUnitState(0)->setTexture(geometry->texture->texture); } else { pass = mUIMaterial->getTechnique("NoTexture")->getPass(0); } mSceneMgr->manualRender(&geometry->renderOp, pass, nullptr, world, Ogre::Matrix4::IDENTITY, mProjection); }
HavokNode::HavokNode(string name, hkGeometry *geometry, LibGens::Matrix4 transform, Ogre::SceneManager *scene_manager) { type = EDITOR_NODE_HAVOK; scene_node = scene_manager->getRootSceneNode()->createChildSceneNode(); havok_name = name; buildHavokMesh(scene_node, havok_name, geometry, scene_manager, EDITOR_NODE_QUERY_HAVOK, GENERAL_MESH_GROUP); Ogre::Matrix4 matrix = Ogre::Matrix4(transform.m[0][0], transform.m[0][1], transform.m[0][2], transform.m[0][3], transform.m[1][0], transform.m[1][1], transform.m[1][2], transform.m[1][3], transform.m[2][0], transform.m[2][1], transform.m[2][2], transform.m[2][3], transform.m[3][0], transform.m[3][1], transform.m[3][2], transform.m[3][3]); matrix.decomposition(position, scale, rotation); scene_node->setPosition(position); scene_node->setScale(scale); scene_node->setOrientation(rotation); scene_node->getUserObjectBindings().setUserAny(EDITOR_NODE_BINDING, Ogre::Any((EditorNode *)this)); selected = false; }
void processDirectionElement(VertexData* vertexData, const VertexElement* vertexElem ) { Ogre::Quaternion rotation = mTransform.extractQuaternion(); rotation.normalise(); int nMaxVert= vertexData->vertexCount ; //const Ogre::VertexElement* VertexEle_POS = vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION ); // get vertex buffer info via the input element Ogre::HardwareVertexBufferSharedPtr VertexBufPOS = vertexData->vertexBufferBinding->getBuffer( vertexElem->getSource() ); //LOCK BUFFER unsigned char* VertexPtrPOS = static_cast<unsigned char*>( VertexBufPOS->lock( Ogre::HardwareBuffer::HBL_NORMAL ) ); int VertSizePOS=VertexBufPOS->getVertexSize(); float * pElementPOS=NULL; //A vector of every vertices position std::vector<Ogre::Vector3> positions(nMaxVert); //Copy each position into position vector for(int nVert=0 ; nVert<nMaxVert ; nVert++) { vertexElem->baseVertexPointerToElement( VertexPtrPOS, &pElementPOS ); Ogre::Vector3 vertex(pElementPOS); vertex = rotation * vertex; if (mNormaliseNormals) { vertex.normalise(); } pElementPOS[0] = vertex.x; pElementPOS[1] = vertex.y; pElementPOS[2] = vertex.z; //mBoundingBox.merge(vertex); VertexPtrPOS+=VertSizePOS ; } //UNLOCK BUFFER if(VertexBufPOS->isLocked()){VertexBufPOS->unlock();} }
namespace Nx { bool mFlipVertexWinding = false; Ogre::Matrix4 mTransform ; AxisAlignedBox mBoundingBox; bool mNormaliseNormals = false; bool mUpdateBoundingBox = true; void processIndexData(IndexData* indexData) { if (!mFlipVertexWinding) { // Nothing to do. return; } if (indexData->indexCount % 3 != 0) { printf("Index number is not a multiple of 3, no vertex winding flipping possible. Skipped."); return; } //print("Flipping index order for vertex winding flipping.", V_HIGH); Ogre::HardwareIndexBufferSharedPtr buffer = indexData->indexBuffer; unsigned char* data = static_cast<unsigned char*>(buffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); if(buffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT) { // 16 bit //print("using 16bit indices", V_HIGH); for (size_t i = 0; i < indexData->indexCount; i+=3) { Ogre::uint16 * i0 = (Ogre::uint16*)(data+0 * buffer->getIndexSize()); Ogre::uint16* i2 = (Ogre::uint16*)(data+2 * buffer->getIndexSize()); // flip Ogre::uint16 tmp = *i0; *i0 = *i2; *i2 = tmp; data += 3 * buffer->getIndexSize(); } } else { // 32 bit //print("using 32bit indices", V_HIGH); for (size_t i = 0; i < indexData->indexCount; i+=3) { Ogre::uint32* i0 = (Ogre::uint32*)(data+0 * buffer->getIndexSize()); Ogre::uint32* i2 = (Ogre::uint32*)(data+2 * buffer->getIndexSize()); // flip Ogre::uint32 tmp = *i0; *i0 = *i2; *i2 = tmp; data += 3 * buffer->getIndexSize(); } } buffer->unlock(); } void processPositionElement( VertexData* vertexData, const VertexElement* vertexElem ) { int nMaxVert= vertexData->vertexCount ; //const Ogre::VertexElement* VertexEle_POS = vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION ); // get vertex buffer info via the input element Ogre::HardwareVertexBufferSharedPtr VertexBufPOS = vertexData->vertexBufferBinding->getBuffer( vertexElem->getSource() ); //LOCK BUFFER unsigned char* VertexPtrPOS = static_cast<unsigned char*>( VertexBufPOS->lock( Ogre::HardwareBuffer::HBL_NORMAL) ); int VertSizePOS=VertexBufPOS->getVertexSize(); float * pElementPOS=NULL; //A vector of every vertices position std::vector<Ogre::Vector3> positions(nMaxVert); //Copy each position into position vector for(int nVert=0 ; nVert<nMaxVert ; nVert++) { vertexElem->baseVertexPointerToElement( VertexPtrPOS, &pElementPOS ); Ogre::Vector3 vertex(pElementPOS); vertex = mTransform * vertex; pElementPOS[0] = vertex.x; pElementPOS[1] = vertex.y; pElementPOS[2] = vertex.z; mBoundingBox.merge(vertex); VertexPtrPOS+=VertSizePOS ; } //UNLOCK BUFFER if(VertexBufPOS->isLocked()){VertexBufPOS->unlock();} } void processDirectionElement(VertexData* vertexData, const VertexElement* vertexElem ) { Ogre::Quaternion rotation = mTransform.extractQuaternion(); rotation.normalise(); int nMaxVert= vertexData->vertexCount ; //const Ogre::VertexElement* VertexEle_POS = vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION ); // get vertex buffer info via the input element Ogre::HardwareVertexBufferSharedPtr VertexBufPOS = vertexData->vertexBufferBinding->getBuffer( vertexElem->getSource() ); //LOCK BUFFER unsigned char* VertexPtrPOS = static_cast<unsigned char*>( VertexBufPOS->lock( Ogre::HardwareBuffer::HBL_NORMAL ) ); int VertSizePOS=VertexBufPOS->getVertexSize(); float * pElementPOS=NULL; //A vector of every vertices position std::vector<Ogre::Vector3> positions(nMaxVert); //Copy each position into position vector for(int nVert=0 ; nVert<nMaxVert ; nVert++) { vertexElem->baseVertexPointerToElement( VertexPtrPOS, &pElementPOS ); Ogre::Vector3 vertex(pElementPOS); vertex = rotation * vertex; if (mNormaliseNormals) { vertex.normalise(); } pElementPOS[0] = vertex.x; pElementPOS[1] = vertex.y; pElementPOS[2] = vertex.z; //mBoundingBox.merge(vertex); VertexPtrPOS+=VertSizePOS ; } //UNLOCK BUFFER if(VertexBufPOS->isLocked()){VertexBufPOS->unlock();} } void processVertexData(VertexData* vertexData) { const VertexElement* position = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); if (position != NULL) { processPositionElement(vertexData, position); }else { LogMsg("processVertexData : CANT Process POSITION"); } const VertexElement* normal = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL); if (normal != NULL) { processDirectionElement(vertexData, normal); } const VertexElement* binormal = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_BINORMAL); if (binormal != NULL) { processDirectionElement(vertexData, binormal); } const VertexElement* tangent = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_TANGENT); if (tangent != NULL) { processDirectionElement(vertexData, tangent); } } AxisAlignedBox getVertexDataAabb( VertexData* vd, const Ogre::Matrix4& transform) { AxisAlignedBox aabb; const VertexElement* ve = vd->vertexDeclaration->findElementBySemantic(VES_POSITION); HardwareVertexBufferSharedPtr vb = vd->vertexBufferBinding->getBuffer(ve->getSource()); unsigned char* data = static_cast<unsigned char*>( vb->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); for (size_t i = 0; i < vd->vertexCount; ++i) { float* v; ve->baseVertexPointerToElement(data, &v); aabb.merge(transform * Ogre::Vector3(v[0], v[1], v[2])); data += vb->getVertexSize(); } vb->unlock(); return aabb; } AxisAlignedBox getMeshAabb(Mesh* mesh, const Ogre::Matrix4& transform) { AxisAlignedBox aabb; if (mesh->sharedVertexData != 0) { aabb.merge(getVertexDataAabb(mesh->sharedVertexData, transform)); } for (unsigned int i = 0; i < mesh->getNumSubMeshes(); ++i) { SubMesh* sm = mesh->getSubMesh(i); if (sm->vertexData != 0) { aabb.merge(getVertexDataAabb(sm->vertexData, transform)); } } return aabb; } AxisAlignedBox getMeshAabb(MeshPtr mesh, const Nx::Matrix4& transform) { Ogre::Matrix4 mat1; NxMat4toOgre( mat1, transform ); return getMeshAabb(mesh.get(), mat1); } void NxMeshManager::SetPivotTransform( Ogre::MeshPtr mesh, const Nx::Vector3 & Position, const Nx::Quaternion & Rotation, const Nx::Vector3 & Scale ) { //from mesh magick / mit licence Nx::Matrix4 transform = Nx::Matrix4::IDENTITY; Nx::Vector3 translate = Nx::Vector3::ZERO; // Apply current transform to the mesh, to get the bounding box to // base te translation on. AxisAlignedBox aabb = getMeshAabb( mesh, transform); //if (alignment == "left") //{ // translate = Vector3(-aabb.getMinimum().x, 0, 0); //} //else if (alignment == "center") //{ // translate = Vector3(-aabb.getCenter().x, 0, 0); //} //else if (alignment == "right") //{ // translate = Vector3(-aabb.getMaximum().x, 0, 0); //} //Position .. only support pivot down / centered //translate = Vector3(0, -aabb.getMinimum().y, 0);// pivot down translate = Position; transform = Nx::Matrix4::getTrans(translate) * transform; //rotation transform = Nx::Matrix4(Rotation) * transform; //scale transform = Nx::Matrix4::getScale(Scale) * transform; // Check whether we have to flip vertex winding. // We do have to, if we changed our right hand base. // We can test it by using the cross product from X and Y and see, if it is a non-negative // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet, // but the test is cheap either way. Nx::Matrix3 m3; transform.extract3x3Matrix(m3); if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) { LogMsg("SetPivotPosition : Flipping vertex winding ... " ); mFlipVertexWinding = true; } //mTransform = transform; NxMat4toOgre( mTransform, transform ) ; mBoundingBox.setNull(); if( mesh->sharedVertexData != NULL) { processVertexData( mesh->sharedVertexData); }else { LogMsg("mesh->sharedVertexData NULL"); } for( int i = 0; i < mesh->getNumSubMeshes(); i++ ) { SubMesh* submesh = mesh->getSubMesh(i); if( submesh->vertexData != NULL ) { LogMsg("SetPivotPosition : Processing vertex data ... " ); processVertexData(submesh->vertexData); }else { LogMsg("submesh->vertexData NULL"); } if (submesh->indexData != NULL) { LogMsg("SetPivotPosition : Processing Index data .." ); processIndexData(submesh->indexData); }else { LogMsg("submesh->indexData NULL"); } } //process pose for( unsigned short i = 0; i < mesh->getPoseCount(); ++i ) { Ogre::Pose * pose = mesh->getPose(i); Ogre::Matrix3 m3x3; mTransform.extract3x3Matrix(m3x3); Pose::VertexOffsetIterator it = pose->getVertexOffsetIterator(); while (it.hasMoreElements()) { Ogre::Vector3 offset = it.peekNextValue(); Ogre::Vector3 newOffset = m3x3 * offset; *it.peekNextValuePtr() = newOffset; it.moveNext(); } } mesh->_setBounds( mBoundingBox, false ); } }
void NxMeshManager::SetPivotTransform( Ogre::MeshPtr mesh, const Nx::Vector3 & Position, const Nx::Quaternion & Rotation, const Nx::Vector3 & Scale ) { //from mesh magick / mit licence Nx::Matrix4 transform = Nx::Matrix4::IDENTITY; Nx::Vector3 translate = Nx::Vector3::ZERO; // Apply current transform to the mesh, to get the bounding box to // base te translation on. AxisAlignedBox aabb = getMeshAabb( mesh, transform); //if (alignment == "left") //{ // translate = Vector3(-aabb.getMinimum().x, 0, 0); //} //else if (alignment == "center") //{ // translate = Vector3(-aabb.getCenter().x, 0, 0); //} //else if (alignment == "right") //{ // translate = Vector3(-aabb.getMaximum().x, 0, 0); //} //Position .. only support pivot down / centered //translate = Vector3(0, -aabb.getMinimum().y, 0);// pivot down translate = Position; transform = Nx::Matrix4::getTrans(translate) * transform; //rotation transform = Nx::Matrix4(Rotation) * transform; //scale transform = Nx::Matrix4::getScale(Scale) * transform; // Check whether we have to flip vertex winding. // We do have to, if we changed our right hand base. // We can test it by using the cross product from X and Y and see, if it is a non-negative // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet, // but the test is cheap either way. Nx::Matrix3 m3; transform.extract3x3Matrix(m3); if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) { LogMsg("SetPivotPosition : Flipping vertex winding ... " ); mFlipVertexWinding = true; } //mTransform = transform; NxMat4toOgre( mTransform, transform ) ; mBoundingBox.setNull(); if( mesh->sharedVertexData != NULL) { processVertexData( mesh->sharedVertexData); }else { LogMsg("mesh->sharedVertexData NULL"); } for( int i = 0; i < mesh->getNumSubMeshes(); i++ ) { SubMesh* submesh = mesh->getSubMesh(i); if( submesh->vertexData != NULL ) { LogMsg("SetPivotPosition : Processing vertex data ... " ); processVertexData(submesh->vertexData); }else { LogMsg("submesh->vertexData NULL"); } if (submesh->indexData != NULL) { LogMsg("SetPivotPosition : Processing Index data .." ); processIndexData(submesh->indexData); }else { LogMsg("submesh->indexData NULL"); } } //process pose for( unsigned short i = 0; i < mesh->getPoseCount(); ++i ) { Ogre::Pose * pose = mesh->getPose(i); Ogre::Matrix3 m3x3; mTransform.extract3x3Matrix(m3x3); Pose::VertexOffsetIterator it = pose->getVertexOffsetIterator(); while (it.hasMoreElements()) { Ogre::Vector3 offset = it.peekNextValue(); Ogre::Vector3 newOffset = m3x3 * offset; *it.peekNextValuePtr() = newOffset; it.moveNext(); } } mesh->_setBounds( mBoundingBox, false ); }
void BoneAim::update(float time){ if (mBone == NULL){ mBone = mGo->getEntity()->getSkeleton()->getBone(mBoneName); mTarget = Level::getSingleton()->getCurrentSegment()->getObjectByName(mTargetName); if (mTarget == NULL){ throw("No such object : "+mTargetName); } } //Ogre::Entity* entity; //mTarget = Level::getSingleton()->getPlayerShip(); Ogre::Matrix4 matrixA = mGo->getNode()->_getFullTransform()*mBone->_getFullTransform(); Ogre::Matrix4 matrix = matrixA; Ogre::Matrix4 transform = matrix.inverse()*mTarget->getNode()->_getFullTransform(); Ogre::Vector3 v = transform.getTrans(); /*Util::Log( "Bone:"+ts(matrixA.getTrans())+ " Ship:"+ts(mTarget->getNode()->_getFullTransform().getTrans())+ " Diff:"+ts(v) ,0 );*/ //targetMatrix = Ogre::Matrix4::IDENTITY; //matrix.setTrans(mTarget->getNode()->_getFullTransform()); //Ogre::Quaternion q = transform.extractQuaternion(); Ogre::Quaternion q; switch (mAxis){ case AXIS_X: q.FromAngleAxis(Ogre::Math::ATan2(v.y, v.z),Ogre::Vector3(-1,0,0)); break; case AXIS_Y: q.FromAngleAxis(Ogre::Math::ATan2(v.x, v.z),Ogre::Vector3(0,1,0)); break; case AXIS_Z: q.FromAngleAxis(Ogre::Math::ATan2(v.x, v.y),Ogre::Vector3(0,0,1)); break; case AXIS_ALL: //q.FromAngleAxis(Ogre::Radian(0),v); q = transform.extractQuaternion();// - matrixA.extractQuaternion(); //q = transform.extractQuaternion() - matrixA.extractQuaternion(); break; } mBone->setManuallyControlled(true); //mBone->setOrientation(q); float slerp = time*mStrength; if (slerp > 1){ slerp = 1; } Ogre::Quaternion r = Quaternion::Slerp(slerp, Ogre::Quaternion::IDENTITY, q); //Level::getSingleton()->getTimeDelta() mBone->rotate(r); /*mBone->yaw(Ogre::Radian(Ogre::Math::RangeRandom(-Math::PI, Math::PI))); mBone->pitch(Ogre::Radian(Ogre::Math::RangeRandom(-Math::PI, Math::PI))); mBone->roll(Ogre::Radian(Ogre::Math::RangeRandom(-Math::PI, Math::PI)));*/ //mBone->_update(true, true); Parent::update(time); //mSpeed += .6*time; //mGo->getNode()->translate(0, 0-mSpeed, 0);*/ }
void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape) { const Nif::NiTriShapeData *data = shape->data.getPtr(); const Nif::NiSkinInstance *skin = (shape->skin.empty() ? NULL : shape->skin.getPtr()); std::vector<Ogre::Vector3> srcVerts = data->vertices; std::vector<Ogre::Vector3> srcNorms = data->normals; Ogre::HardwareBuffer::Usage vertUsage = Ogre::HardwareBuffer::HBU_STATIC; bool vertShadowBuffer = false; bool geomMorpherController = false; if(!shape->controller.empty()) { Nif::ControllerPtr ctrl = shape->controller; do { if(ctrl->recType == Nif::RC_NiGeomMorpherController) { vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY; vertShadowBuffer = true; geomMorpherController = true; break; } } while(!(ctrl=ctrl->next).empty()); } if(skin != NULL) { vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY; vertShadowBuffer = true; // Only set a skeleton when skinning. Unskinned meshes with a skeleton will be // explicitly attached later. mesh->setSkeletonName(mName); // Convert vertices and normals to bone space from bind position. It would be // better to transform the bones into bind position, but there doesn't seem to // be a reliable way to do that. std::vector<Ogre::Vector3> newVerts(srcVerts.size(), Ogre::Vector3(0.0f)); std::vector<Ogre::Vector3> newNorms(srcNorms.size(), Ogre::Vector3(0.0f)); const Nif::NiSkinData *data = skin->data.getPtr(); const Nif::NodeList &bones = skin->bones; for(size_t b = 0;b < bones.length();b++) { Ogre::Matrix4 mat; mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale), Ogre::Quaternion(data->bones[b].trafo.rotation)); mat = bones[b]->getWorldTransform() * mat; const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights; for(size_t i = 0;i < weights.size();i++) { size_t index = weights[i].vertex; float weight = weights[i].weight; newVerts.at(index) += (mat*srcVerts[index]) * weight; if(newNorms.size() > index) { Ogre::Vector4 vec4(srcNorms[index][0], srcNorms[index][1], srcNorms[index][2], 0.0f); vec4 = mat*vec4 * weight; newNorms[index] += Ogre::Vector3(&vec4[0]); } } } srcVerts = newVerts; srcNorms = newNorms; } else { Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr(); if(skelMgr->getByName(mName).isNull()) { // No skinning and no skeleton, so just transform the vertices and // normals into position. Ogre::Matrix4 mat4 = shape->getWorldTransform(); for(size_t i = 0;i < srcVerts.size();i++) { Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f); vec4 = mat4*vec4; srcVerts[i] = Ogre::Vector3(&vec4[0]); } for(size_t i = 0;i < srcNorms.size();i++) { Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f); vec4 = mat4*vec4; srcNorms[i] = Ogre::Vector3(&vec4[0]); } } } // Set the bounding box first BoundsFinder bounds; bounds.add(&srcVerts[0][0], srcVerts.size()); if(!bounds.isValid()) { float v[3] = { 0.0f, 0.0f, 0.0f }; bounds.add(&v[0], 1); } mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f, bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f)); mesh->_setBoundingSphereRadius(bounds.getRadius()); // This function is just one long stream of Ogre-barf, but it works // great. Ogre::HardwareBufferManager *hwBufMgr = Ogre::HardwareBufferManager::getSingletonPtr(); Ogre::HardwareVertexBufferSharedPtr vbuf; Ogre::HardwareIndexBufferSharedPtr ibuf; Ogre::VertexBufferBinding *bind; Ogre::VertexDeclaration *decl; int nextBuf = 0; Ogre::SubMesh *sub = mesh->createSubMesh(); // Add vertices sub->useSharedVertices = false; sub->vertexData = new Ogre::VertexData(); sub->vertexData->vertexStart = 0; sub->vertexData->vertexCount = srcVerts.size(); decl = sub->vertexData->vertexDeclaration; bind = sub->vertexData->vertexBufferBinding; if(srcVerts.size()) { vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), srcVerts.size(), vertUsage, vertShadowBuffer); vbuf->writeData(0, vbuf->getSizeInBytes(), &srcVerts[0][0], true); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); bind->setBinding(nextBuf++, vbuf); } // Vertex normals if(srcNorms.size()) { vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), srcNorms.size(), vertUsage, vertShadowBuffer); vbuf->writeData(0, vbuf->getSizeInBytes(), &srcNorms[0][0], true); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); bind->setBinding(nextBuf++, vbuf); } // Vertex colors const std::vector<Ogre::Vector4> &colors = data->colors; if(colors.size()) { Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem(); std::vector<Ogre::RGBA> colorsRGB(colors.size()); for(size_t i = 0;i < colorsRGB.size();i++) { Ogre::ColourValue clr(colors[i][0], colors[i][1], colors[i][2], colors[i][3]); rs->convertColourValue(clr, &colorsRGB[i]); } vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR), colorsRGB.size(), Ogre::HardwareBuffer::HBU_STATIC); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB[0], true); decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); bind->setBinding(nextBuf++, vbuf); } // Texture UV coordinates size_t numUVs = data->uvlist.size(); if (numUVs) { size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); for(size_t i = 0; i < numUVs; i++) decl->addElement(nextBuf, elemSize*i, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i); vbuf = hwBufMgr->createVertexBuffer(decl->getVertexSize(nextBuf), srcVerts.size(), Ogre::HardwareBuffer::HBU_STATIC); std::vector<Ogre::Vector2> allUVs; allUVs.reserve(srcVerts.size()*numUVs); for (size_t vert = 0; vert<srcVerts.size(); ++vert) for(size_t i = 0; i < numUVs; i++) allUVs.push_back(data->uvlist[i][vert]); vbuf->writeData(0, elemSize*srcVerts.size()*numUVs, &allUVs[0], true); bind->setBinding(nextBuf++, vbuf); } // Triangle faces const std::vector<short> &srcIdx = data->triangles; if(srcIdx.size()) { ibuf = hwBufMgr->createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, srcIdx.size(), Ogre::HardwareBuffer::HBU_STATIC); ibuf->writeData(0, ibuf->getSizeInBytes(), &srcIdx[0], true); sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = srcIdx.size(); sub->indexData->indexStart = 0; } // Assign bone weights for this TriShape if(skin != NULL) { Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(mName); const Nif::NiSkinData *data = skin->data.getPtr(); const Nif::NodeList &bones = skin->bones; for(size_t i = 0;i < bones.length();i++) { Ogre::VertexBoneAssignment boneInf; boneInf.boneIndex = skel->getBone(bones[i]->name)->getHandle(); const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[i].weights; for(size_t j = 0;j < weights.size();j++) { boneInf.vertexIndex = weights[j].vertex; boneInf.weight = weights[j].weight; sub->addBoneAssignment(boneInf); } } } const Nif::NiTexturingProperty *texprop = NULL; const Nif::NiMaterialProperty *matprop = NULL; const Nif::NiAlphaProperty *alphaprop = NULL; const Nif::NiVertexColorProperty *vertprop = NULL; const Nif::NiZBufferProperty *zprop = NULL; const Nif::NiSpecularProperty *specprop = NULL; const Nif::NiWireframeProperty *wireprop = NULL; bool needTangents = false; shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop); std::string matname = NIFMaterialLoader::getMaterial(data, mesh->getName(), mGroup, texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop, needTangents); if(matname.length() > 0) sub->setMaterialName(matname); // build tangents if the material needs them if (needTangents) { unsigned short src,dest; if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src,dest)) mesh->buildTangentVectors(Ogre::VES_TANGENT, src,dest); } // Create a dummy vertex animation track if there's a geom morpher controller // This is required to make Ogre create the buffers we will use for software vertex animation if (srcVerts.size() && geomMorpherController) mesh->createAnimation("dummy", 0)->createVertexTrack(1, sub->vertexData, Ogre::VAT_MORPH); }
OgreNewt::ConvexCollisionPtr PhysicsRagDoll::RagBone::_makeConvexHull(OgreNewt::World* world, Ogre::MeshPtr mesh, Ogre::Real minWeight) { std::vector< Ogre::Vector3 > vertexVector; // for this bone, gather all of the vertices linked to it, and make an individual convex hull. std::string boneName = mOgreBone->getName(); unsigned int boneIndex = mOgreBone->getHandle(); Ogre::Matrix4 invMatrix; invMatrix.makeInverseTransform(-mOgreBone->_getBindingPoseInversePosition(), Ogre::Vector3::UNIT_SCALE / mOgreBone->_getBindingPoseInverseScale(), mOgreBone->_getBindingPoseInverseOrientation().Inverse()); unsigned int num_sub = mesh->getNumSubMeshes(); for (unsigned int i = 0; i < num_sub; i++) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::SubMesh::BoneAssignmentIterator bai = submesh->getBoneAssignmentIterator(); Ogre::VertexDeclaration* v_decl; const Ogre::VertexElement* p_elem; float* v_Posptr; size_t v_count; Ogre::VertexData* v_data = NULL; if (submesh->useSharedVertices) { v_data = mesh->sharedVertexData; v_count = v_data->vertexCount; v_decl = v_data->vertexDeclaration; p_elem = v_decl->findElementBySemantic(Ogre::VES_POSITION); } else { v_data = submesh->vertexData; v_count = v_data->vertexCount; v_decl = v_data->vertexDeclaration; p_elem = v_decl->findElementBySemantic(Ogre::VES_POSITION); } size_t start = v_data->vertexStart; //pointer Ogre::HardwareVertexBufferSharedPtr v_sptr = v_data->vertexBufferBinding->getBuffer(p_elem->getSource()); unsigned char* v_ptr = static_cast<unsigned char*>(v_sptr->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned char* v_offset; while (bai.hasMoreElements()) { Ogre::VertexBoneAssignment vba = bai.getNext(); if (vba.boneIndex == boneIndex) { //found a vertex that is attached to this bone. if (vba.weight >= minWeight) { //get offset to Position data! v_offset = v_ptr + (vba.vertexIndex * v_sptr->getVertexSize()); p_elem->baseVertexPointerToElement(v_offset, &v_Posptr); Ogre::Vector3 vert; vert.x = *v_Posptr; v_Posptr++; vert.y = *v_Posptr; v_Posptr++; vert.z = *v_Posptr; // apply transformation in to local space. vert = invMatrix * vert; vertexVector.push_back(vert); Ogre::LogManager::getSingletonPtr()->logMessage(" vertex found! id:"+Ogre::StringConverter::toString(vba.vertexIndex)); } } } v_sptr->unlock(); } // okay, we have gathered all verts for this bone. make a convex hull! unsigned int numVerts = vertexVector.size(); Ogre::Vector3* verts = new Ogre::Vector3[ numVerts ]; unsigned int j = 0; while (!vertexVector.empty()) { verts[j] = vertexVector.back(); vertexVector.pop_back(); j++; } ////////////////////////////////////////////////////////////////////////////////// OgreNewt::ConvexCollisionPtr col; if (numVerts > 0) col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::ConvexHull(world, verts, numVerts, 0)); delete []verts; return col; }
bool Oculus::setupOgre(Ogre::SceneManager *sm, Ogre::RenderWindow *win, Ogre::SceneNode *parent) { m_window = win; m_sceneManager = sm; Ogre::LogManager::getSingleton().logMessage("Oculus: Setting up Ogre"); if(parent) m_cameraNode = parent->createChildSceneNode("StereoCameraNode"); else m_cameraNode = sm->getRootSceneNode()->createChildSceneNode("StereoCameraNode"); m_cameras[0] = sm->createCamera("CameraLeft"); m_cameras[1] = sm->createCamera("CameraRight"); Ogre::MaterialPtr matLeft = Ogre::MaterialManager::getSingleton().getByName("Ogre/Compositor/Oculus"); Ogre::MaterialPtr matRight = matLeft->clone("Ogre/Compositor/Oculus/Right"); Ogre::GpuProgramParametersSharedPtr pParamsLeft = matLeft->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); Ogre::GpuProgramParametersSharedPtr pParamsRight = matRight->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); Ogre::Vector4 hmdwarp; if(m_stereoConfig) { hmdwarp = Ogre::Vector4(m_stereoConfig->GetDistortionK(0), m_stereoConfig->GetDistortionK(1), m_stereoConfig->GetDistortionK(2), m_stereoConfig->GetDistortionK(3)); } else { hmdwarp = Ogre::Vector4(g_defaultDistortion[0], g_defaultDistortion[1], g_defaultDistortion[2], g_defaultDistortion[3]); } pParamsLeft->setNamedConstant("HmdWarpParam", hmdwarp); pParamsRight->setNamedConstant("HmdWarpParam", hmdwarp); pParamsLeft->setNamedConstant("LensCentre", 0.5f+(m_stereoConfig->GetProjectionCenterOffset()/2.0f)); pParamsRight->setNamedConstant("LensCentre", 0.5f-(m_stereoConfig->GetProjectionCenterOffset()/2.0f)); Ogre::CompositorPtr comp = Ogre::CompositorManager::getSingleton().getByName("OculusRight"); comp->getTechnique(0)->getOutputTargetPass()->getPass(0)->setMaterialName("Ogre/Compositor/Oculus/Right"); for(int i=0;i<2;++i) { m_cameraNode->attachObject(m_cameras[i]); if(m_stereoConfig) { // Setup cameras. m_cameras[i]->setNearClipDistance(m_stereoConfig->GetEyeToScreenDistance()); m_cameras[i]->setFarClipDistance(g_defaultFarClip); m_cameras[i]->setPosition((i * 2 - 1) * m_stereoConfig->GetIPD() * 0.5f, 0, 0); m_cameras[i]->setAspectRatio(m_stereoConfig->GetAspect()); m_cameras[i]->setFOVy(Ogre::Radian(m_stereoConfig->GetYFOVRadians())); // Oculus requires offset projection, create a custom projection matrix Ogre::Matrix4 proj = Ogre::Matrix4::IDENTITY; float temp = m_stereoConfig->GetProjectionCenterOffset(); proj.setTrans(Ogre::Vector3(-m_stereoConfig->GetProjectionCenterOffset() * (2 * i - 1), 0, 0)); m_cameras[i]->setCustomProjectionMatrix(true, proj * m_cameras[i]->getProjectionMatrix()); } else { m_cameras[i]->setNearClipDistance(g_defaultNearClip); m_cameras[i]->setFarClipDistance(g_defaultFarClip); m_cameras[i]->setPosition((i*2-1) * g_defaultIPD * 0.5f, 0, 0); } m_viewports[i] = win->addViewport(m_cameras[i], i, 0.5f*i, 0, 0.5f, 1.0f); m_viewports[i]->setBackgroundColour(g_defaultViewportColour); m_compositors[i] = Ogre::CompositorManager::getSingleton().addCompositor(m_viewports[i],i==0?"OculusLeft":"OculusRight"); m_compositors[i]->setEnabled(true); } m_ogreReady = true; Ogre::LogManager::getSingleton().logMessage("Oculus: Oculus setup completed successfully"); return true; }
void MapCloudDisplay::update( float wall_dt, float ros_dt ) { rviz::PointCloud::RenderMode mode = (rviz::PointCloud::RenderMode) style_property_->getOptionInt(); if (needs_retransform_) { retransform(); needs_retransform_ = false; } { boost::mutex::scoped_lock lock(new_clouds_mutex_); if( !new_cloud_infos_.empty() ) { float size; if( mode == rviz::PointCloud::RM_POINTS ) { size = point_pixel_size_property_->getFloat(); } else { size = point_world_size_property_->getFloat(); } std::map<int, CloudInfoPtr>::iterator it = new_cloud_infos_.begin(); std::map<int, CloudInfoPtr>::iterator end = new_cloud_infos_.end(); for (; it != end; ++it) { CloudInfoPtr cloud_info = it->second; cloud_info->cloud_.reset( new rviz::PointCloud() ); cloud_info->cloud_->addPoints( &(cloud_info->transformed_points_.front()), cloud_info->transformed_points_.size() ); cloud_info->cloud_->setRenderMode( mode ); cloud_info->cloud_->setAlpha( alpha_property_->getFloat() ); cloud_info->cloud_->setDimensions( size, size, size ); cloud_info->cloud_->setAutoSize(false); cloud_info->manager_ = context_->getSceneManager(); cloud_info->scene_node_ = scene_node_->createChildSceneNode(); cloud_info->scene_node_->attachObject( cloud_info->cloud_.get() ); cloud_info->scene_node_->setVisible(false); cloud_infos_.insert(*it); } new_cloud_infos_.clear(); } } { boost::recursive_mutex::scoped_try_lock lock( transformers_mutex_ ); if( lock.owns_lock() ) { if( new_xyz_transformer_ || new_color_transformer_ ) { M_TransformerInfo::iterator it = transformers_.begin(); M_TransformerInfo::iterator end = transformers_.end(); for (; it != end; ++it) { const std::string& name = it->first; TransformerInfo& info = it->second; setPropertiesHidden( info.xyz_props, name != xyz_transformer_property_->getStdString() ); setPropertiesHidden( info.color_props, name != color_transformer_property_->getStdString() ); } } } new_xyz_transformer_ = false; new_color_transformer_ = false; } int totalPoints = 0; int totalNodesShown = 0; { // update poses boost::mutex::scoped_lock lock(current_map_mutex_); if(!current_map_.empty()) { for (std::map<int, rtabmap::Transform>::iterator it=current_map_.begin(); it != current_map_.end(); ++it) { std::map<int, CloudInfoPtr>::iterator cloudInfoIt = cloud_infos_.find(it->first); if(cloudInfoIt != cloud_infos_.end()) { totalPoints += cloudInfoIt->second->transformed_points_.size(); cloudInfoIt->second->pose_ = it->second; Ogre::Vector3 framePosition; Ogre::Quaternion frameOrientation; if (context_->getFrameManager()->getTransform(cloudInfoIt->second->message_->header, framePosition, frameOrientation)) { // Multiply frame with pose Ogre::Matrix4 frameTransform; frameTransform.makeTransform( framePosition, Ogre::Vector3(1,1,1), frameOrientation); const rtabmap::Transform & p = cloudInfoIt->second->pose_; Ogre::Matrix4 pose(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], 0, 0, 0, 1); frameTransform = frameTransform * pose; Ogre::Vector3 posePosition = frameTransform.getTrans(); Ogre::Quaternion poseOrientation = frameTransform.extractQuaternion(); poseOrientation.normalise(); cloudInfoIt->second->scene_node_->setPosition(posePosition); cloudInfoIt->second->scene_node_->setOrientation(poseOrientation); cloudInfoIt->second->scene_node_->setVisible(true); ++totalNodesShown; } else { ROS_ERROR("MapCloudDisplay: Could not update pose of node %d", it->first); } } } //hide not used clouds for(std::map<int, CloudInfoPtr>::iterator iter = cloud_infos_.begin(); iter!=cloud_infos_.end(); ++iter) { if(current_map_.find(iter->first) == current_map_.end()) { iter->second->scene_node_->setVisible(false); } } } } this->setStatusStd(rviz::StatusProperty::Ok, "Points", tr("%1").arg(totalPoints).toStdString()); this->setStatusStd(rviz::StatusProperty::Ok, "Nodes", tr("%1 shown of %2").arg(totalNodesShown).arg(cloud_infos_.size()).toStdString()); }
void PhysicalCamera::moveRelative(const opal::Vec3r& dir, opal::real dt) { // Construct the actual velocity vector. opal::Vec3r velocity = dir; if (!opal::areEqual(velocity.lengthSquared(), 0)) { velocity.normalize(); } velocity *= mTranslateSpeed; switch(mType) { case PHYSICAL: { assert(mSolid); // TODO: handle things differently if we're in midair. Ogre::Matrix4 camTransform; mOgreCamera->getParentSceneNode()->getWorldTransforms( &camTransform); Ogre::Vector3 localDir(velocity[0], velocity[1], velocity[2]); // Convert the local direction vector to a global direction // vector. Subtract out the camera's position. Ogre::Vector3 globalDir = camTransform * localDir; globalDir -= camTransform.getTrans(); opal::Vec3r opalVec(globalDir[0], globalDir[1], globalDir[2]); // Keep from flying. if (opalVec[1] > 0) { opalVec[1] = 0; } // Don't use the dt in this case; let Opal take care of the // velocity. mSolid->setGlobalLinearVel(opalVec); break; } case NON_CLIPPING: { Ogre::Vector3 posChange(velocity[0] * dt, velocity[1] * dt, velocity[2] * dt); mOgreCamera->getParentSceneNode()->translate(posChange, Ogre::Node::TS_LOCAL); break; } case NON_CLIPPING_ORBIT: { Ogre::Vector3 posChange(velocity[0] * dt, velocity[1] * dt, velocity[2] * dt); mOgreCamera->getParentSceneNode()->translate(posChange, Ogre::Node::TS_LOCAL); lookAt(mOrbitCenter); break; } default: assert(false); } }
void SimpleGrid::update(const Ogre::Real &timeSinceLastFrame) { if (!isCreated()) { return; } Module::update(timeSinceLastFrame); // Update heigths int i = 0, v, u; if (getNormalMode() == MaterialManager::NM_VERTEX) { Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices); if (mOptions.ChoppyWaves) { for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++) { Vertices[i] = mVerticesChoppyBuffer[i]; Vertices[i].y = mNoise->getValue(Vertices[i].x, Vertices[i].z) * mOptions.Strength; } } else { for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++) { Vertices[i].y = mNoise->getValue(Vertices[i].x, Vertices[i].z) * mOptions.Strength; } } } else if (getNormalMode() == MaterialManager::NM_RTT) { Mesh::POS_VERTEX* Vertices = static_cast<Mesh::POS_VERTEX*>(mVertices); // For object-space to world-space conversion // RTT normals calculation needs world-space coords Ogre::Vector3 p = Ogre::Vector3(0,0,0); Ogre::Matrix4 mWorldMatrix; mHydrax->getMesh()->getEntity()->getParentSceneNode()->getWorldTransforms(&mWorldMatrix); for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++) { p.x = Vertices[i].x; p.y = 0; p.z = Vertices[i].z; // Calculate the world-space position mWorldMatrix.transformAffine(p); Vertices[i].y = mNoise->getValue(p.x, p.z) * mOptions.Strength; } } // Smooth the heightdata if (mOptions.Smooth) { if (getNormalMode() == MaterialManager::NM_VERTEX) { Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices); for(v=1; v<(mOptions.Complexity-1); v++) { for(u=1; u<(mOptions.Complexity-1); u++) { Vertices[v*mOptions.Complexity + u].y = 0.2f * (Vertices[v *mOptions.Complexity + u ].y + Vertices[v *mOptions.Complexity + (u+1)].y + Vertices[v *mOptions.Complexity + (u-1)].y + Vertices[(v+1)*mOptions.Complexity + u ].y + Vertices[(v-1)*mOptions.Complexity + u ].y); } } } else if (getNormalMode() == MaterialManager::NM_RTT) { Mesh::POS_VERTEX* Vertices = static_cast<Mesh::POS_VERTEX*>(mVertices); for(v=1; v<(mOptions.Complexity-1); v++) { for(u=1; u<(mOptions.Complexity-1); u++) { Vertices[v*mOptions.Complexity + u].y = 0.2f * (Vertices[v *mOptions.Complexity + u ].y + Vertices[v *mOptions.Complexity + (u+1)].y + Vertices[v *mOptions.Complexity + (u-1)].y + Vertices[(v+1)*mOptions.Complexity + u ].y + Vertices[(v-1)*mOptions.Complexity + u ].y); } } } } // Update normals _calculeNormals(); // Perform choppy waves _performChoppyWaves(); // Upload geometry changes mHydrax->getMesh()->updateGeometry(mOptions.Complexity*mOptions.Complexity, mVertices); }
//----------------------------------------------------------------------------// void OgreRenderTarget::unprojectPoint(const GeometryBuffer& buff, const Vector2& p_in, Vector2& p_out) const { if (!d_matrixValid) updateMatrix(); const OgreGeometryBuffer& gb = static_cast<const OgreGeometryBuffer&>(buff); const Ogre::Real midx = d_area.getWidth() * 0.5f; const Ogre::Real midy = d_area.getHeight() * 0.5f; // viewport matrix const Ogre::Matrix4 vpmat( midx, 0, 0, d_area.d_left + midx, 0, -midy, 0, d_area.d_top + midy, 0, 0, 1, 0, 0, 0, 0, 1 ); // matrices used for projecting and unprojecting points const Ogre::Matrix4 proj(gb.getMatrix() * d_matrix * vpmat); const Ogre::Matrix4 unproj(proj.inverse()); Ogre::Vector3 in; // unproject the ends of the ray in.x = midx; in.y = midy; in.z = -d_viewDistance; const Ogre::Vector3 r1(unproj * in); in.x = p_in.d_x; in.y = p_in.d_y; in.z = 0; // calculate vector of picking ray const Ogre::Vector3 rv(r1 - unproj * in); // project points to orientate them with GeometryBuffer plane in.x = 0.0; in.y = 0.0; const Ogre::Vector3 p1(proj * in); in.x = 1.0; in.y = 0.0; const Ogre::Vector3 p2(proj * in); in.x = 0.0; in.y = 1.0; const Ogre::Vector3 p3(proj * in); // calculate the plane normal const Ogre::Vector3 pn((p2 - p1).crossProduct(p3 - p1)); // calculate distance from origin const Ogre::Real plen = pn.length(); const Ogre::Real dist = -(p1.x * (pn.x / plen) + p1.y * (pn.y / plen) + p1.z * (pn.z / plen)); // calculate intersection of ray and plane const Ogre::Real pn_dot_rv = pn.dotProduct(rv); const Ogre::Real tmp = pn_dot_rv != 0.0 ? (pn.dotProduct(r1) + dist) / pn_dot_rv : 0.0; p_out.d_x = static_cast<float>(r1.x - rv.x * tmp); p_out.d_y = static_cast<float>(r1.y - rv.y * tmp); }
std::pair<bool, Real> rayCollide(const Ogre::Ray& ray, Ogre::MovableObject* movable, bool accurate, CullingMode cullingMode, bool allowAnimable) { // Get local space axis aligned bounding box const Ogre::AxisAlignedBox& aabb = movable->getBoundingBox(); // Matrix4 to transform local space to world space const Ogre::Matrix4& localToWorld = movable->_getParentNodeFullTransform(); // Matrix4 to transform world space to local space Ogre::Matrix4 worldToLocal = localToWorld.inverse(); // Matrix3 to transform world space normal to local space Ogre::Matrix3 worldToLocalN; worldToLocal.extract3x3Matrix(worldToLocalN); // Convert world space ray to local space ray // Note: // By preserving the scale between world space and local space of the // direction, we don't need to recalculate the distance later. Ogre::Ray localRay; localRay.setOrigin(worldToLocal * ray.getOrigin()); localRay.setDirection(worldToLocalN * ray.getDirection()); // Intersect with axis aligned bounding box, but because we transformed // ray to local space of the bounding box, so this test just like test // with oriented bounding box. std::pair<bool, Real> ret = localRay.intersects(aabb); // Do accurate test if hitted bounding box and user required. if (ret.first && accurate) { if (movable->getMovableType() == Ogre::EntityFactory::FACTORY_TYPE_NAME || allowAnimable && movable->getMovableType() == Ogre::AutoAnimationEntityFactory::FACTORY_TYPE_NAME) { Ogre::Entity* entity = static_cast<Ogre::Entity*>(movable); if (!entity->_isAnimated()) { // Static entity // Get the entity mesh const Ogre::MeshPtr& mesh = entity->getMesh(); // Get the collision mode CollisionModelPtr collisionModel = CollisionModelManager::getSingleton().getCollisionModel(mesh); ret = doPicking(localRay, *collisionModel, cullingMode); } else if (allowAnimable) { // Animation entity bool addedSoftwareAnimation = false; if (entity->getSoftwareAnimationRequests() <= 0) { entity->addSoftwareAnimationRequest(false); entity->_updateAnimation(); addedSoftwareAnimation = true; } CollisionModel collisionModel; collisionModel.addEntity(entity); collisionModel.build(true); ret = doPicking(localRay, collisionModel, cullingMode); if (addedSoftwareAnimation) { entity->removeSoftwareAnimationRequest(false); } } } } return ret; }