lugre_transform_mesh.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include <Ogre.h>
00003 using namespace Ogre;
00004 using namespace Lugre;
00005 
00006 void    TransformSubMeshTexCoords   (Ogre::SubMesh& pSubMesh,const float u0,const float v0,const float u1,const float v1) {
00007     if (pSubMesh.useSharedVertices) { printf("ERROR: TransformSubMeshTexCoords : shared vertex data not supported\n"); return; }
00008     float ud = u1 - u0;
00009     float vd = v1 - v0;
00010     
00011     //----------------------------------------------------------------
00012     // GET VERTEXDATA
00013     //----------------------------------------------------------------
00014     const VertexData * vertex_data = pSubMesh.vertexData;
00015     const VertexElement* texCoordElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
00016     
00017     HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(texCoordElem->getSource());
00018 
00019     unsigned char* vertex =
00020         static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_NORMAL)); // allows read and write,.. see also HBL_READ_ONLY
00021 
00022     // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
00023     //  as second argument. So make it float, to avoid trouble when Ogre::Real is
00024     //  comiled/typedefed as double:
00025     float* pReal;
00026 
00027     for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) {
00028         texCoordElem->baseVertexPointerToElement(vertex, &pReal);
00029         float u = pReal[0];
00030         float v = pReal[1];
00031         pReal[0] = u0 + ud*mymax(0.0,mymin(1.0,u));
00032         pReal[1] = v0 + vd*mymax(0.0,mymin(1.0,v));
00033     }
00034 
00035     vbuf->unlock();
00036 }
00037         
00039 void    TransformMesh   (Ogre::Mesh* pMesh,const Ogre::Vector3& vMove,const Ogre::Vector3& vScale,const Ogre::Quaternion& qRot) {
00040     
00041     bool added_shared = false;
00042     
00043     // Run through the submeshes again, adding the data into the arrays
00044     for ( size_t i = 0; i < pMesh->getNumSubMeshes(); ++i) {
00045         SubMesh* submesh = pMesh->getSubMesh(i);
00046         bool useSharedVertices = submesh->useSharedVertices;
00047 
00048         //----------------------------------------------------------------
00049         // GET VERTEXDATA
00050         //----------------------------------------------------------------
00051         const VertexData * vertex_data;
00052         vertex_data = useSharedVertices ? pMesh->sharedVertexData : submesh->vertexData;
00053 
00054         if((!useSharedVertices)||(useSharedVertices && !added_shared))
00055         {
00056             if(useSharedVertices)
00057             {
00058                 added_shared = true;
00059             }
00060 
00061             const VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
00062             const VertexElement* normalElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL);
00063             
00064             HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
00065 
00066             unsigned char* vertex =
00067                 static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_NORMAL)); // allows read and write,.. see also HBL_READ_ONLY
00068 
00069             // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
00070             //  as second argument. So make it float, to avoid trouble when Ogre::Real is
00071             //  comiled/typedefed as double:
00072             float* pReal;
00073 
00074             for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
00075             {
00076                 posElem->baseVertexPointerToElement(vertex, &pReal);
00077                 
00078                 // read vertex p
00079                 Vector3 p(pReal[0],pReal[1],pReal[2]);
00080                 
00081                 // transform p
00082                 p += vMove;
00083                 p *= vScale;
00084                 p = qRot * p;
00085                 
00086                 // write back
00087                 pReal[0] = p.x;
00088                 pReal[1] = p.y;
00089                 pReal[2] = p.z;
00090                 
00091                 // rotate and scale normal
00092                 if (normalElem) {
00093                     normalElem->baseVertexPointerToElement(vertex, &pReal);
00094                     
00095                     // read vertex p
00096                     Vector3 n(pReal[0],pReal[1],pReal[2]);
00097                     
00098                     // transform p
00099                     n *= vScale;
00100                     n = qRot * n;
00101                     n.normalise(); // re-normalise
00102                     
00103                     // write back
00104                     pReal[0] = n.x;
00105                     pReal[1] = n.y;
00106                     pReal[2] = n.z;
00107                 }
00108             }
00109 
00110             vbuf->unlock();
00111         }
00112     }
00113 }
00114 
00116 void    MeshReadOutExactBounds  (Ogre::Mesh* pMesh,Ogre::Vector3& vMin,Ogre::Vector3& vMax) {
00117     
00118     bool added_shared = false;
00119     bool bInitMinMax = true;
00120     
00121     // Run through the submeshes again, adding the data into the arrays
00122     for ( size_t i = 0; i < pMesh->getNumSubMeshes(); ++i) {
00123         SubMesh* submesh = pMesh->getSubMesh(i);
00124         bool useSharedVertices = submesh->useSharedVertices;
00125 
00126         //----------------------------------------------------------------
00127         // GET VERTEXDATA
00128         //----------------------------------------------------------------
00129         const VertexData * vertex_data;
00130         vertex_data = useSharedVertices ? pMesh->sharedVertexData : submesh->vertexData;
00131 
00132         if((!useSharedVertices)||(useSharedVertices && !added_shared))
00133         {
00134             if(useSharedVertices)
00135             {
00136                 added_shared = true;
00137             }
00138 
00139             const VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
00140             
00141             HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
00142 
00143             unsigned char* vertex =
00144                 static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_READ_ONLY));
00145 
00146             // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
00147             //  as second argument. So make it float, to avoid trouble when Ogre::Real is
00148             //  comiled/typedefed as double:
00149             float* pReal;
00150 
00151             for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
00152             {
00153                 posElem->baseVertexPointerToElement(vertex, &pReal);
00154                 
00155                 // extend min,max
00156                 if (bInitMinMax) {
00157                     bInitMinMax = false;
00158                     vMin.x = vMax.x = pReal[0];
00159                     vMin.y = vMax.y = pReal[1];
00160                     vMin.z = vMax.z = pReal[2];
00161                 } else {
00162                     if (vMin.x > pReal[0]) vMin.x = pReal[0];
00163                     if (vMin.y > pReal[1]) vMin.y = pReal[1];
00164                     if (vMin.z > pReal[2]) vMin.z = pReal[2];
00165                     if (vMax.x < pReal[0]) vMax.x = pReal[0];
00166                     if (vMax.y < pReal[1]) vMax.y = pReal[1];
00167                     if (vMax.z < pReal[2]) vMax.z = pReal[2];
00168                 }
00169             }
00170 
00171             vbuf->unlock();
00172         }
00173     }
00174 }

Generated on Wed May 23 06:00:15 2012 for cpp by  doxygen 1.5.6