00001 #include "lugre_prefix.h"
00002 #include "lugre_beam.h"
00003 #include <Ogre.h>
00004 #include <math.h>
00005
00006 namespace Lugre {
00007
00008 cBeamFilter cBeamFilter::IDENTITY;
00009
00010
00011
00012 cBeamFilter::cBeamFilter() {}
00013 cBeamFilter::~cBeamFilter() {}
00014 cBeamPoint& cBeamFilter::CurPoint (cBeamPoint& p,const int iLine,const int iPoint) { return p; }
00015 cBeamPoint& cBeamFilter::NextPoint (cBeamPoint& p,const int iLine,const int iPoint) { return p; }
00016 cBeamPoint& cBeamFilter::PrevPoint (cBeamPoint& p,const int iLine,const int iPoint) { return p; }
00017
00018
00019
00020 cSimpleBeam::cSimpleBeam(const bool mbUseVertexColour) : mbUseVertexColour(mbUseVertexColour), pFilter(0) {}
00021 cSimpleBeam::~cSimpleBeam() {
00022 if (pFilter) { delete pFilter; pFilter = 0; }
00023 }
00024
00025 void cSimpleBeam::_notifyCurrentCamera (Ogre::Camera* cam) {
00026 if (cam && getParentSceneNode())
00027 Draw(*this,*cam,*getParentSceneNode(),mbUseVertexColour,pFilter?*pFilter:cBeamFilter::IDENTITY);
00028 else Draw(*this,Ogre::Vector3::ZERO,mbUseVertexColour,pFilter?*pFilter:cBeamFilter::IDENTITY);
00029 }
00030
00031 void cSimpleBeam::UpdateBounds () { UpdateBeamBounds(*this); }
00032
00033 const Ogre::AxisAlignedBox& cSimpleBeam::getBoundingBox(void) const {
00034 assert(!mbBoundsDirty && "call update bounds after changing geometry");
00035
00036 return cRobSimpleRenderable::getBoundingBox();
00037 }
00038
00039 Ogre::Real cSimpleBeam::getBoundingRadius (void) const {
00040 assert(!mbBoundsDirty && "call update bounds after changing geometry");
00041
00042
00043 return cRobSimpleRenderable::getBoundingRadius();
00044 }
00045
00046 Ogre::Real cSimpleBeam::getSquaredViewDepth (const Ogre::Camera* cam) const {
00047 assert(!mbBoundsDirty && "call update bounds after changing geometry");
00048
00049
00050 return cRobSimpleRenderable::getSquaredViewDepth(cam);
00051 }
00052
00053
00054
00055 cBeam::cBeam () : mbBoundsDirty(true) {}
00056 cBeam::~cBeam () {}
00057
00058 void cBeam::Draw (cRobRenderOp& pRobRenderOp,Ogre::Camera& pCam,Ogre::SceneNode& pBeamSceneNode,const bool bUseVertexColour,cBeamFilter &filter) {
00059 Draw(pRobRenderOp,CalcEyePos(pCam,pBeamSceneNode),bUseVertexColour,filter);
00060 }
00061
00062 void cBeam::UpdateBeamBounds (cRobRenderOp& pRobRenderOp) {
00063 int i,j;
00064 float fMaxDist = 0;
00065 mbBoundsDirty = false;
00066 for (i=0;i<mlBeamLines.size();++i) {
00067 std::deque<cBeamPoint>& myBeamLine = *mlBeamLines[i];
00068 int iLinePointCount = myBeamLine.size();
00069 if (iLinePointCount < 2) continue;
00070 for (j=0;j<iLinePointCount;++j) {
00071 fMaxDist = mymax(fMaxDist,myBeamLine[j].pos.squaredLength());
00072 }
00073 }
00074 pRobRenderOp.mfBoundingRadius = sqrt(fMaxDist);
00075 pRobRenderOp.mpBox->setExtents(Ogre::Vector3(-fMaxDist,-fMaxDist,-fMaxDist),Ogre::Vector3(fMaxDist,fMaxDist,fMaxDist));
00076 }
00077
00079 void cBeam::Draw (cRobRenderOp& pRobRenderOp,Ogre::Vector3 vEyePos,const bool bUseVertexColour,cBeamFilter &filter) {
00080 int iTotalVertexCount = 0;
00081 int iTotalIndexCount = 0;
00082 int i,j;
00083 Ogre::Vector3 vTangent;
00084
00085 for (i=0;i<mlBeamLines.size();++i) {
00086 int iLinePointCount = mlBeamLines[i]->size();
00087 if (iLinePointCount < 2) continue;
00088 iTotalVertexCount += iLinePointCount*2;
00089 iTotalIndexCount += 6 * (iLinePointCount-1);
00090 }
00091
00092 pRobRenderOp.Begin(iTotalVertexCount,iTotalIndexCount,true);
00093 iTotalVertexCount = 0;
00094 for (i=0;i<mlBeamLines.size();++i) {
00095 std::deque<cBeamPoint>& myBeamLine = *mlBeamLines[i];
00096 int iLinePointCount = myBeamLine.size();
00097 if (iLinePointCount < 2) continue;
00098
00099
00100 for (j=0;j<iLinePointCount-1;++j) {
00101 pRobRenderOp.Index(iTotalVertexCount + j*2 + 0);
00102 pRobRenderOp.Index(iTotalVertexCount + j*2 + 1);
00103 pRobRenderOp.Index(iTotalVertexCount + j*2 + 2);
00104 pRobRenderOp.Index(iTotalVertexCount + j*2 + 2);
00105 pRobRenderOp.Index(iTotalVertexCount + j*2 + 1);
00106 pRobRenderOp.Index(iTotalVertexCount + j*2 + 3);
00107 }
00108 iTotalVertexCount += iLinePointCount*2;
00109
00110
00111 for (j=0;j<iLinePointCount;++j) {
00112 cBeamPoint& pCurPoint = filter.CurPoint(myBeamLine[j+0],i,j);
00113 if (j==0) vTangent = filter.NextPoint(myBeamLine[j+1],i,j+1).pos - pCurPoint.pos;
00114 else if (j == iLinePointCount - 1) vTangent = pCurPoint.pos - filter.PrevPoint(myBeamLine[j-1],i,j-1).pos;
00115 else vTangent = filter.NextPoint(myBeamLine[j+1],i,j+1).pos - filter.PrevPoint(myBeamLine[j-1],i,j-1).pos;
00116
00117 Ogre::Vector3 vPerpendicular = vTangent.crossProduct(vEyePos - pCurPoint.pos);
00118 vPerpendicular.normalise();
00119
00120 if (bUseVertexColour) {
00121 pRobRenderOp.Vertex(pCurPoint.pos + pCurPoint.h1*vPerpendicular,pCurPoint.u1,pCurPoint.v1,pCurPoint.col1);
00122 pRobRenderOp.Vertex(pCurPoint.pos + pCurPoint.h2*vPerpendicular,pCurPoint.u2,pCurPoint.v2,pCurPoint.col2);
00123 } else {
00124 pRobRenderOp.Vertex(pCurPoint.pos + pCurPoint.h1*vPerpendicular,pCurPoint.u1,pCurPoint.v1);
00125 pRobRenderOp.Vertex(pCurPoint.pos + pCurPoint.h2*vPerpendicular,pCurPoint.u2,pCurPoint.v2);
00126 }
00127 }
00128 }
00129 pRobRenderOp.End();
00130 mbBoundsDirty = false;
00131 }
00132
00133
00134 Ogre::Vector3 cBeam::CalcEyePos (Ogre::Camera& pCam,Ogre::SceneNode& pBeamSceneNode) {
00135 return pBeamSceneNode._getDerivedOrientation().Inverse() *
00136 (pCam.getDerivedPosition() - pBeamSceneNode._getDerivedPosition()) / pBeamSceneNode._getDerivedScale();
00137 }
00138
00139 };