// ################################################
// 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);
}
}