Esempio n. 1
0
//设置位置 (游戏世界坐标)
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
}
Esempio n. 2
0
//------------------------------------------------------------------------------
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 );
        }
    }
}
Esempio n. 3
0
	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);
	}
Esempio n. 4
0
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;
}
Esempio n. 5
0
// ----------------------------------------------------------------
// 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();
}
Esempio n. 7
0
  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;
  }
Esempio n. 8
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;
}
Esempio n. 9
0
    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();
        }
    }
Esempio n. 10
0
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");
}
Esempio n. 12
0
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;


}
Esempio n. 14
0
	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);
	}
Esempio n. 15
0
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);
}
Esempio n. 16
0
// 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);
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
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();}

 
}
Esempio n. 20
0
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 );
  
}

}
Esempio n. 21
0
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 );
  
}
Esempio n. 22
0
		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);*/
		}
Esempio n. 23
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;	
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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());
}
Esempio n. 27
0
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);
    }
}
Esempio n. 28
0
	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);
}
Esempio n. 30
0
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;
}