老代码, 第二部分

来源:互联网 发布:美工刀片材质 编辑:程序博客网 时间:2024/04/20 05:59

// ################################################

// ArrowDrawable.cpp

#include "ArrowDrawable.h"
#include "Ogre.h"
using namespace Ogre;

const Ogre::String ArrowDrawable::mType("ArrowDrawable");

ArrowDrawable::ArrowDrawable(const Ogre::Vector3& from , const Ogre::Vector3& to)
{
 mRenderOp.indexData = new Ogre::IndexData;
 mRenderOp.vertexData = new Ogre::VertexData;

 mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST;

 mRenderOp.useIndexes = true;

 mRenderOp.vertexData->vertexCount = 5;
 mRenderOp.vertexData->vertexStart = 0;
 Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
 decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

 HardwareBufferManager& mgr = HardwareBufferManager::getSingleton();

 mIndexHardwareBuf = mgr.createIndexBuffer(HardwareIndexBuffer::IT_32BIT, 8, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
 mVertexHardwareBuf = mgr.createVertexBuffer( sizeof(Vector3), 5,  HardwareBuffer::HBU_STATIC_WRITE_ONLY);

 
 mRenderOp.indexData->indexCount = 8;
 mRenderOp.indexData->indexStart = 0;
 mRenderOp.indexData->indexBuffer = mIndexHardwareBuf;

 mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mVertexHardwareBuf);

 setArrow(from, to);
}

ArrowDrawable::~ArrowDrawable()
{
 delete mRenderOp.indexData;
 delete mRenderOp.vertexData;
}

Ogre::Real ArrowDrawable::getBoundingRadius() const
{
 return mBox.getHalfSize().length();
}

void ArrowDrawable::getRenderOperation(RenderOperation& rend)
{
 rend = mRenderOp;
}

void ArrowDrawable::setArrow(const Ogre::Vector3 & from , const Ogre::Vector3& to)
{
 Vector3 dir = to - from;
 float scale = dir.normalise();
 Quaternion q = Ogre::Vector3::UNIT_X.getRotationTo(dir);

 Vector3 p1(1 - 0.1*Math::Cos(Math::PI/12), 0.1*Math::Sin(Math::PI/12), 0);

 Quaternion q2;
 q2.FromAngleAxis(Radian(Math::PI*2/3), Vector3::UNIT_X);

 Vector3 p2 = q2*p1;
 Vector3 p3 = q2*p2;

 mPoints[0] = from;
 mPoints[1] = to;
 mPoints[2] = q*(scale*p1) + from;
 mPoints[3] = q*(scale*p2) + from;
 mPoints[4] = q*(scale*p3) + from;

 uint32 array[8] = { 0, 1, 1, 2, 1, 3, 1, 4};

 mIndexHardwareBuf->writeData(0, mIndexHardwareBuf->getSizeInBytes(), array);
 mVertexHardwareBuf->writeData(0, mVertexHardwareBuf->getSizeInBytes(), mPoints);

 mBox.setNull();
 for(int i=0;i<5;++i)
  mBox.merge(mPoints[i]);
}

Ogre::Real ArrowDrawable::getSquaredViewDepth(const Camera* cam) const
{
 return mParentNode->getSquaredViewDepth( cam );
}

 

//##########################################################

/////////////////////////////////////////////////////////

//   Author   tony 
//   Created  2010/08/06 14:36
//
//
/////////////////////////////////////////////////////////

#ifndef __ArrowDrawable_H__
#define __ArrowDrawable_H__
#include <OgreSimpleRenderable.h>
#include <OgreHardwareVertexBuffer.h>
#include <OgreHardwareIndexBuffer.h>
#include <OgrePrerequisites.h>

class ArrowDrawable : public Ogre::SimpleRenderable
{
public:

 ArrowDrawable(const Ogre::Vector3& from , const Ogre::Vector3& to);

 ~ArrowDrawable();

 //virtual uint32 getTypeFlags();

 /**
 创建一个renderable, 并显示它
 **/
 virtual void getRenderOperation(Ogre::RenderOperation& rend);

 //重载renderable及Moveable方法
 Ogre::Real getBoundingRadius() const;

 Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam) const;

 static const Ogre::String mType;

 virtual const Ogre::String& getMovableType(void) const { return mType; };
 
 void getWorldTransforms( Ogre::Matrix4* xform ) const{ *xform=Ogre::Matrix4::IDENTITY; };

 void setArrow(const Ogre::Vector3 & from , const Ogre::Vector3& to);

private:

 Ogre::HardwareVertexBufferSharedPtr mVertexHardwareBuf;

 Ogre::Vector3 mPoints[5];

 Ogre::HardwareIndexBufferSharedPtr  mIndexHardwareBuf;

 Ogre::uint32 mIndices[8];

};
 

#endif

 

 

//#################################################################

// MeshTriangleData.cpp

 

 

#include "MeshTriangleData.h"

#include <ogre/Ogre.h>

using namespace Ogre;

namespace demo
{

MeshTriangleData::MeshTriangleData(const Ogre::Mesh* const mesh)
{
 getMeshInformation(mesh, mVertexCount, mVertices, mNormals, mIndexCount, mIndices);
}

MeshTriangleData::~MeshTriangleData()
{
 if(mVertices)
 {
  delete[] mVertices;
 }
 if(mIndices)
 {
  delete[] mIndices;
 }
 if(mNormals)
 {
  delete[] mNormals;
 }
}

void MeshTriangleData::getMeshInformation(const Ogre::Mesh* const mesh, size_t &vertex_count, Ogre::Vector3* &vertices,
            Ogre::Vector3* &normals, size_t &index_count, unsigned long* &indices,
            const Ogre::Vector3 &position/* =Ogre::Vector3::ZERO */,
            const Ogre::Quaternion &orient/* =Ogre::Quaternion::IDENTITY */,
            const Ogre::Vector3 &scale/* =Ogre::Vector3::UNIT_SCALE */)
{
 bool added_shared = false;
 size_t current_offset = 0;
 size_t shared_offset = 0;
 size_t next_offset = 0;
 size_t index_offset = 0;


 vertex_count = index_count = 0;

 // Calculate how many vertices and indices we're going to need
 for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
 {
  Ogre::SubMesh* submesh = mesh->getSubMesh( i );

  // We only need to add the shared vertices once
  if(submesh->useSharedVertices)
  {
   if( !added_shared )
   {
    vertex_count += mesh->sharedVertexData->vertexCount;
    added_shared = true;
   }
  }
  else
  {
   vertex_count += submesh->vertexData->vertexCount;
  }

  // Add the indices
  index_count += submesh->indexData->indexCount;
 }


 // Allocate space for the vertices and indices
 vertices = new Ogre::Vector3[vertex_count];
 normals  = new Ogre::Vector3[vertex_count];
 indices = new unsigned long[index_count];

 added_shared = false;

 // Run through the submeshes again, adding the data into the arrays
 for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
 {
  Ogre::SubMesh* submesh = mesh->getSubMesh(i);

  Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

  if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
  {
   if(submesh->useSharedVertices)
   {
    added_shared = true;
    shared_offset = current_offset;
   }

   const Ogre::VertexElement* posElem =
    vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

   Ogre::HardwareVertexBufferSharedPtr vbuf =
    vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

   unsigned char* vertex =
    static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

   // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
   //  as second argument. So make it float, to avoid trouble when Ogre::Real will
   //  be comiled/typedefed as double:
   //      Ogre::Real* pReal;
   float* pReal;

   for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
   {
    posElem->baseVertexPointerToElement(vertex, &pReal);

    Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);

    vertices[current_offset + j] = (orient * (pt * scale)) + position;
   }

   vbuf->unlock();

 

   const Ogre::VertexElement* posElem1 =
    vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL);

   Ogre::HardwareVertexBufferSharedPtr vbuf1 =
    vertex_data->vertexBufferBinding->getBuffer(posElem1->getSource());

   unsigned char* vertex1 =
    static_cast<unsigned char*>(vbuf1->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

   // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
   //  as second argument. So make it float, to avoid trouble when Ogre::Real will
   //  be comiled/typedefed as double:
   //      Ogre::Real* pReal;
   float* pReal1;

   for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex1 += vbuf1->getVertexSize())
   {
    posElem1->baseVertexPointerToElement(vertex1, &pReal1);

    Ogre::Vector3 pt(pReal1[0], pReal1[1], pReal1[2]);

    normals[current_offset + j] = (orient * (pt * scale)) + position;
    normals[current_offset + j].normalise();
   }

   vbuf1->unlock();


   next_offset += vertex_data->vertexCount;
  }


  Ogre::IndexData* index_data = submesh->indexData;
  size_t numTris = index_data->indexCount / 3;
  Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

  bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

  unsigned long*  pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
  unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);


  size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;

  if ( use32bitindexes )
  {
   for ( size_t k = 0; k < numTris*3; ++k)
   {
    indices[index_offset++] = pLong[k + index_data->indexStart] + static_cast<unsigned long>(offset);
   }
  }
  else
  {
   for ( size_t k = 0; k < numTris*3; ++k)
   {
    indices[index_offset++] = static_cast<unsigned long>(pShort[k + index_data->indexStart]) +
     static_cast<unsigned long>(offset);
   }
  }

  ibuf->unlock();
  current_offset = next_offset;
 }
}

bool MeshTriangleData::collide(Ogre::Ray* ray, const Ogre::Matrix4& transform, Ogre::Vector3&a,Ogre::Vector3&b, Ogre::Vector3&c)
{
 static const Real INF_FAR=1e+10;
 Ogre::Matrix4 inverseTrans=transform.inverse();
 Vector4 dir(ray->getDirection());
 dir.w=0;
 dir = inverseTrans*dir;
 Ogre::Ray     rayInModel(inverseTrans*ray->getOrigin(), Vector3(dir.x, dir.y, dir.z));
 Real nearestDist=INF_FAR;
 unsigned long triIndex=0;
 for(int i=0;i<mIndexCount;i+=3)
 {
  Vector3& a=mVertices[mIndices[i]],&b=mVertices[mIndices[i+1]],&c=mVertices[mIndices[i+2]];
  std::pair<bool, Real> res=Math::intersects(rayInModel,a, b, c, true, false);
  if(res.first && nearestDist>res.second)
  {
   triIndex=i;
   nearestDist=res.second;
  }
 }
 if(nearestDist<INF_FAR)
 {
  a=transform*mVertices[mIndices[triIndex]];
  b=transform*mVertices[mIndices[triIndex+1]];
  c=transform*mVertices[mIndices[triIndex+2]];
  return true;
 }
 return false;
}
}

 

//#######################################################################

#ifndef __MeshTriangleData_H__
#define __MeshTriangleData_H__

#include<ogre/OgreVector3.h>
#include <ogre/OgreQuaternion.h>
#include <ogre/OgreMatrix4.h>
namespace Ogre{ class Mesh;  class Ray; }

namespace demo
{

class MeshTriangleData
{
public:

 MeshTriangleData(const Ogre::Mesh* const mesh);
 
 ~MeshTriangleData();

 bool collide(Ogre::Ray* ray,const Ogre::Matrix4& transform,
  Ogre::Vector3&a,Ogre::Vector3&b, Ogre::Vector3&c);

private:
 void getMeshInformation(
  const Ogre::Mesh* const mesh,
  size_t &vertex_count,
  Ogre::Vector3* &vertices,
  Ogre::Vector3* &normals,
  size_t &index_count,
  unsigned long* &indices,
  const Ogre::Vector3 &position=Ogre::Vector3::ZERO,
  const Ogre::Quaternion &orient=Ogre::Quaternion::IDENTITY,
  const Ogre::Vector3 &scale=Ogre::Vector3::UNIT_SCALE);

private:
 
 size_t               mVertexCount;
 size_t               mIndexCount;
 Ogre::Vector3*       mVertices;
 Ogre::Vector3*       mNormals;
 unsigned long*       mIndices;

};

}

#endif

 

//#######################################################################

#include "MeshTriangleDataManager.h"
#include "MeshTriangleData.h"
#include <ogre/OgreMesh.h>
#include <ogre/OgreMeshManager.h>
using namespace Ogre;

namespace Ogre {
 demo::MeshTriangleDataManager* demo::MeshTriangleDataManager::ms_Singleton=0;
}

namespace demo
{
 
MeshTriangleDataManager::MeshTriangleDataManager()
{

}

MeshTriangleDataManager::~MeshTriangleDataManager()
{
 std::map<Ogre::String, MeshTriangleData*>::iterator i,iend=mDataMap.end();
 for(i=mDataMap.begin();i!=iend;++i)
 {
  delete i->second;
 }
 mDataMap.clear();
}

MeshTriangleData* MeshTriangleDataManager::loadTriangleData( const Ogre::String& meshName )
{
 std::map<Ogre::String, MeshTriangleData*>::iterator it=mDataMap.find(meshName);
 if(it!=mDataMap.end()) return it->second;
 MeshPtr mesh=MeshManager::getSingleton().load(meshName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
 return  mDataMap[meshName]=new MeshTriangleData(mesh.get());
}

}

 

//########################################################################

#ifndef __MeshTriangleDataManager_H__
#define __MeshTriangleDataManager_H__
#include <ogre/OgreSingleton.h>
#include <map>

namespace demo
{
class MeshTriangleData;
class MeshTriangleDataManager : public Ogre::Singleton<MeshTriangleDataManager>
{

public:

 MeshTriangleDataManager();
 
 ~MeshTriangleDataManager();

 MeshTriangleData* loadTriangleData( const Ogre::String& meshName );

private:
 
 std::map<Ogre::String, MeshTriangleData*> mDataMap;


};
}

#endif

 

//A########################################################################

#include"TriangleRenderable.h"
#include<ogre/OgreRenderOperation.h>
#include<ogre/OgreVertexIndexData.h>
#include <ogre/OgreHardwareBufferManager.h>
#include<ogre/OgreNode.h>
namespace Ogre
{

const String TriangleRenderable::mType("Demo_TriangleRenderable");

uint32 TriangleRenderable::getTypeFlags()
{
 return 0xffffffff;
}

TriangleRenderable::TriangleRenderable(const Vector3& a, const Vector3& b, const Vector3& c)
{
 setMaterial("SimpleTriangle");

 mRenderOp.vertexData = new Ogre::VertexData;
 mRenderOp.useIndexes=false;
 mRenderOp.operationType=RenderOperation::OT_TRIANGLE_LIST;
 mRenderOp.vertexData->vertexCount=3;
 mRenderOp.vertexData->vertexStart=0;
 
 HardwareVertexBufferSharedPtr vb=HardwareBufferManager::getSingleton()
  .createVertexBuffer(24, 3, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

 VertexDeclaration *decl=mRenderOp.vertexData->vertexDeclaration;
 decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
 decl->addElement(0, 12, VET_FLOAT3, VES_NORMAL);

 Vector3 n=(b-a).crossProduct(c-a);
 n.normalise();
 Vector3 vt[6]={a,n,b,n,c,n};
 vb->writeData(0, vb->getSizeInBytes(),&vt[0], true);

 VertexBufferBinding *binding=mRenderOp.vertexData->vertexBufferBinding;
 binding->setBinding(0, vb);

 mBox.setNull();
 mBox.merge(a);
 mBox.merge(b);
 mBox.merge(c);
 mVB=vb;

}

TriangleRenderable::~TriangleRenderable()
{
 if(mRenderOp.vertexData)
 {
  delete mRenderOp.vertexData;
  mRenderOp.vertexData=0;
 }
}

Real TriangleRenderable::getBoundingRadius()const
{
 return mBox.getHalfSize().length();
}
Real TriangleRenderable::getSquaredViewDepth(const Camera* cam) const
{
 return mParentNode->getSquaredViewDepth(cam);
}
void TriangleRenderable::getRenderOperation(RenderOperation& rend)
{
 rend=mRenderOp;
}
void TriangleRenderable::modifyTriangle(const Vector3& a, const Vector3& b, const Vector3& c)
{
 Vector3 n=(b-a).crossProduct(c-a);
 n.normalise();
 Vector3 vt[6]={a,n,b,n,c,n};
 mVB->writeData(0, mVB->getSizeInBytes(),&vt[0], true);
 mBox.setNull();
 mBox.merge(a);
 mBox.merge(b);
 mBox.merge(c);
}
void TriangleRenderable::getWorldTransforms( Matrix4* xform ) const
{
 *xform=Matrix4::IDENTITY;
}

}

 

//############################################################

#ifndef __TriangleRenderable_H__
#define __TriangleRenderable_H__

#include <ogre/OgreSimpleRenderable.h>
#include <ogre/OgreVector3.h>
#include <ogre/OgrePrerequisites.h>
#include <ogre/OgreString.h>
namespace Ogre
{
class HardwareVertexBufferSharedPtr;
class TriangleRenderable: public SimpleRenderable
{
public:
 TriangleRenderable(const Vector3& a, const Vector3& b, const Vector3& c);
 ~TriangleRenderable();

 virtual uint32 getTypeFlags();

 /**
 创建一个renderable, 并显示它
 **/
 virtual void getRenderOperation(RenderOperation& rend);

 //重载renderable及Moveable方法
 Real getBoundingRadius() const;

 Real getSquaredViewDepth(const Camera* cam) const;

 static const String mType;

 virtual const String& getMovableType(void) const { return mType; };

 void modifyTriangle(const Vector3& a, const Vector3& b, const Vector3& c);

 void getWorldTransforms( Matrix4* xform ) const;

private:

 HardwareVertexBufferSharedPtr mVB;
};
}

#endif

 

/////////////////////////////////////////////////////////////////////////////

#ifndef __RTTManager_H__
#define __RTTManager_H__
#include <ogre/OgrePrerequisites.h>
#include <ogre/OgreRenderTargetListener.h>
#include <ogre/OgreTexture.h>

namespace demo
{
 class RTTManager : public Ogre::RenderTargetListener
 {
 public:

  RTTManager(Ogre::SceneManager* mgr);
  
  ~RTTManager();

  virtual void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);

  virtual void postRenderTargetUpdate(const  Ogre::RenderTargetEvent& evt);

  Ogre::Matrix4 getLightViewProjMatrix() const;

  void         addShadowCaster(Ogre::Entity* caster);

  void         addShadowReceiver(Ogre::Entity* receiver);

  void         update();

 protected:

  void         _init();

  void         _destroy();

  Ogre::SceneManager*  mSceneManager;

  Ogre::Camera*        mLightPosCamera;
  
  Ogre::TexturePtr     mRenderTexture;

  Ogre::RenderTexture* mRenderTarget;
 
  std::vector<Ogre::Entity*> mShadowReceivers;
  
  std::vector<Ogre::Entity*> mShadowCasters;

  std::vector<std::vector<Ogre::String> > mShadowCasterOldMaterials;

 };
}

#endif

 

/////////////////////////////////////////////////

#include "RTTManager.h"
#include <ogre/Ogre.h>
#include "common.h"
using namespace Ogre;
namespace demo
{

RTTManager::RTTManager(Ogre::SceneManager* mgr)
:mSceneManager(mgr)
{
 _init(); 
}

RTTManager::~RTTManager()
{
 _destroy();
}

void RTTManager::_init()
{
 mLightPosCamera=mSceneManager->createCamera("RTTCamera"); 
 mLightPosCamera->setPosition(Vector3(0, 130, 400)+Vector3::UNIT_X*50);
 mLightPosCamera->lookAt(LOOKAT);

 mRenderTexture = Ogre::TextureManager::getSingleton().createManual("RttTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
  1024, 1024, 0, Ogre::PF_FLOAT32_R, Ogre::TU_RENDERTARGET);
 mRenderTarget=mRenderTexture->getBuffer()->getRenderTarget();
 mRenderTarget->addViewport(mLightPosCamera);
 mRenderTarget->getViewport(0)->setBackgroundColour(ColourValue::Black);
 mRenderTarget->getViewport(0)->setClearEveryFrame(true);
 mRenderTarget->addListener(this);
}

void RTTManager::_destroy()
{
 mRenderTarget->removeAllListeners();
 Ogre::TextureManager::getSingleton().remove("RttTex");
 mSceneManager->destroyCamera(mLightPosCamera);
}

void RTTManager::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
 

 for(size_t i=0;i<mShadowCasters.size();++i)
 {
  mShadowCasters[i]->setVisible(true);
  mShadowCasters[i]->setMaterialName("ShadowCaster_test");  
 } 

 for(size_t i=0;i<mShadowReceivers.size();++i)
  mShadowReceivers[i]->setVisible(false);
}

void RTTManager::update()
{
 mRenderTarget->update();
}


void RTTManager::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
 Matrix4 viewProj=getLightViewProjMatrix();
 Vector4 row0(viewProj[0][0], viewProj[0][1], viewProj[0][2], viewProj[0][3]);
 Vector4 row1(viewProj[1][0], viewProj[1][1], viewProj[1][2], viewProj[1][3]);
 Vector4 row2(viewProj[2][0], viewProj[2][1], viewProj[2][2], viewProj[2][3]);
 Vector4 row3(viewProj[3][0], viewProj[3][1], viewProj[3][2], viewProj[3][3]);
 for(size_t i=0;i<mShadowCasters.size();++i)
 {
  mShadowCasters[i]->setVisible(true);
  for(size_t j=0;j<mShadowCasters[i]->getNumSubEntities();++j)
  {
   SubEntity* subEnt=mShadowCasters[i]->getSubEntity(j);
   subEnt->setMaterialName(mShadowCasterOldMaterials[i][j]);
  }
 }
 for(size_t i=0;i<mShadowReceivers.size();++i)
 {
  mShadowReceivers[i]->setMaterialName("ShadowReceiver_test");
  mShadowReceivers[i]->setVisible(true);
  for(size_t j=0;j<mShadowReceivers[i]->getNumSubEntities();++j)
  {
   SubEntity* subEnt=mShadowReceivers[i]->getSubEntity(j);
   subEnt->setCustomParameter(0, row0);
   subEnt->setCustomParameter(1, row1);
   subEnt->setCustomParameter(2, row2);
   subEnt->setCustomParameter(3, row3);
  }
 }
}

Ogre::Matrix4 RTTManager::getLightViewProjMatrix() const

 Matrix4 proj = mLightPosCamera->getProjectionMatrix();
 Matrix4 view = mLightPosCamera->getViewMatrix();
 return proj * view;
}

void RTTManager::addShadowCaster(Ogre::Entity* caster)
{
 mShadowCasters.push_back(caster);
 mShadowCasterOldMaterials.push_back(std::vector<String>());
 for(size_t i=0;i<caster->getNumSubEntities();++i)
 {
  SubEntity* subEnt=caster->getSubEntity(i);
  mShadowCasterOldMaterials.back().push_back(subEnt->getMaterialName());
 }
}

void RTTManager::addShadowReceiver(Ogre::Entity* receiver)
{
 mShadowReceivers.push_back(receiver); 
}

}