[138] | 1 | #include "OgreGTGeometry.h"
|
---|
| 2 | #include <Ogre.h>
|
---|
| 3 |
|
---|
| 4 | OgreGTGeometry *Ogre::Singleton<OgreGTGeometry>::ms_Singleton = 0;
|
---|
| 5 |
|
---|
| 6 | Geometry::Mesh *OgreGTGeometry::transform( const Ogre::Mesh *ogreMesh )
|
---|
| 7 | {
|
---|
| 8 | bool copiedShared = false;
|
---|
| 9 | size_t numSubMeshes = 0;
|
---|
| 10 | size_t subMeshIndex = 0;
|
---|
| 11 | Geometry::Mesh *mesh = new Geometry::Mesh();
|
---|
| 12 |
|
---|
| 13 | mesh->mSubMeshCount = ogreMesh->getNumSubMeshes();
|
---|
| 14 |
|
---|
| 15 | //--- Calc num of triangle-list subMeshes
|
---|
| 16 | for(unsigned short i = 0; i < ogreMesh->getNumSubMeshes(); ++i)
|
---|
| 17 | {
|
---|
| 18 | Ogre::SubMesh *subMeshSrc = ogreMesh->getSubMesh(i);
|
---|
| 19 | if (subMeshSrc->operationType == Ogre::RenderOperation::OT_TRIANGLE_LIST)
|
---|
| 20 | {
|
---|
| 21 | ++numSubMeshes;
|
---|
| 22 | }
|
---|
| 23 | else
|
---|
| 24 | {
|
---|
| 25 | Ogre::LogManager::getSingleton().logMessage(
|
---|
| 26 | Ogre::String("SubMesh number ")+
|
---|
| 27 | Ogre::StringConverter::toString((unsigned int)i)+
|
---|
| 28 | Ogre::String(" ")+ogreMesh->getName()+
|
---|
| 29 | Ogre::String(" hasn't a valid Render Operation"));
|
---|
| 30 | }
|
---|
| 31 | }
|
---|
| 32 |
|
---|
| 33 | //--- allocate memory
|
---|
| 34 | mesh->mSubMesh = new Geometry::SubMesh[numSubMeshes];
|
---|
| 35 |
|
---|
| 36 | //--- foreach Ogre-SubMesh create our Geometry-SubMesh
|
---|
| 37 | for(unsigned short smi = 0; smi < ogreMesh->getNumSubMeshes(); ++smi)
|
---|
| 38 | {
|
---|
| 39 | Ogre::SubMesh *subMeshSrc = ogreMesh->getSubMesh(smi);
|
---|
| 40 |
|
---|
| 41 | // Only Triangle list subMeshes
|
---|
| 42 | if (subMeshSrc->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST)
|
---|
| 43 | {
|
---|
| 44 | continue;
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | Ogre::VertexData *vertexSrc = (subMeshSrc->useSharedVertices)? ogreMesh->sharedVertexData : subMeshSrc->vertexData;
|
---|
| 48 | Ogre::IndexData *indexSrc = subMeshSrc->indexData;
|
---|
| 49 |
|
---|
| 50 | Geometry::SubMesh *subMeshDst = &(mesh->mSubMesh[subMeshIndex]);
|
---|
| 51 | Geometry::VertexBuffer *vertexDst = 0;
|
---|
| 52 | Geometry::Index *indexDst = 0;
|
---|
| 53 |
|
---|
| 54 |
|
---|
| 55 | //--- Vertex info ---
|
---|
| 56 | if (subMeshSrc->useSharedVertices)
|
---|
| 57 | {
|
---|
| 58 | if (!copiedShared)
|
---|
| 59 | {
|
---|
| 60 | mesh->mVertexBuffer = new Geometry::VertexBuffer;
|
---|
| 61 | vertexDst = mesh->mVertexBuffer;
|
---|
| 62 | vertexDst->mVertexCount = vertexSrc->vertexCount;
|
---|
| 63 | copiedShared = true;
|
---|
| 64 | }
|
---|
| 65 | else
|
---|
| 66 | {
|
---|
| 67 | vertexDst = 0;
|
---|
| 68 | }
|
---|
| 69 | subMeshDst->mSharedVertexBuffer = true;
|
---|
| 70 | subMeshDst->mVertexBuffer = mesh->mVertexBuffer;
|
---|
| 71 | }
|
---|
| 72 | else
|
---|
| 73 | {
|
---|
| 74 | subMeshDst->mSharedVertexBuffer = false;
|
---|
| 75 | subMeshDst->mVertexBuffer = new Geometry::VertexBuffer;
|
---|
| 76 | vertexDst = subMeshDst->mVertexBuffer;
|
---|
| 77 | vertexDst->mVertexCount = vertexSrc->vertexCount;
|
---|
| 78 | }
|
---|
| 79 |
|
---|
| 80 | if (vertexDst)
|
---|
| 81 | {
|
---|
| 82 | unsigned int vertexInfo = Geometry::VERTEX_EMPTY;
|
---|
| 83 | if (loadVertexInfo(vertexSrc, vertexDst,
|
---|
| 84 | Ogre::VES_POSITION, Geometry::VERTEX_POSITION))
|
---|
| 85 | {
|
---|
| 86 | vertexInfo |= Geometry::VERTEX_POSITION;
|
---|
| 87 | }
|
---|
| 88 | if (loadVertexInfo(vertexSrc, vertexDst,
|
---|
| 89 | Ogre::VES_NORMAL, Geometry::VERTEX_NORMAL))
|
---|
| 90 | {
|
---|
| 91 | vertexInfo |= Geometry::VERTEX_NORMAL;
|
---|
| 92 | }
|
---|
| 93 | if(loadVertexInfo(vertexSrc, vertexDst,
|
---|
| 94 | Ogre::VES_TEXTURE_COORDINATES, Geometry::VERTEX_TEXCOORDS))
|
---|
| 95 | {
|
---|
| 96 | vertexInfo |= Geometry::VERTEX_TEXCOORDS;
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | vertexDst->mVertexInfo = vertexInfo;
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | if (subMeshDst->mSharedVertexBuffer)
|
---|
| 103 | {
|
---|
| 104 | subMeshDst->mVertexBuffer = mesh->mVertexBuffer;
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | //--- Index info ---
|
---|
| 108 | indexDst = new Geometry::Index[indexSrc->indexCount];
|
---|
| 109 | subMeshDst->mIndex = indexDst;
|
---|
| 110 | subMeshDst->mIndexCount = indexSrc->indexCount;
|
---|
| 111 | Ogre::HardwareIndexBufferSharedPtr ibuf = indexSrc->indexBuffer;
|
---|
| 112 | unsigned short *index16 = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
|
---|
| 113 | if (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT)
|
---|
| 114 | {
|
---|
| 115 | unsigned int *index32 = (unsigned int*) index16;
|
---|
| 116 | memcpy(indexDst, index32 + indexSrc->indexStart, indexSrc->indexCount*sizeof(unsigned int));
|
---|
| 117 | }
|
---|
| 118 | else
|
---|
| 119 | {
|
---|
| 120 | for(size_t i = 0; i < indexSrc->indexCount; ++i, ++index16)
|
---|
| 121 | {
|
---|
| 122 | indexDst[i] = (unsigned int) *index16;
|
---|
| 123 | }
|
---|
| 124 | }
|
---|
| 125 | ibuf->unlock();
|
---|
| 126 |
|
---|
| 127 | subMeshIndex++;
|
---|
| 128 | }
|
---|
| 129 |
|
---|
| 130 |
|
---|
| 131 | return mesh;
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 |
|
---|
| 135 | bool OgreGTGeometry::loadVertexInfo(const Ogre::VertexData* ogreV, Geometry::VertexBuffer *geoV,
|
---|
| 136 | Ogre::VertexElementSemantic ogreType,unsigned int geoType)
|
---|
| 137 | {
|
---|
| 138 | const Ogre::VertexElement* posElem = ogreV->vertexDeclaration->
|
---|
| 139 | findElementBySemantic(ogreType);
|
---|
| 140 |
|
---|
| 141 | if (posElem)
|
---|
| 142 | {
|
---|
| 143 | Ogre::HardwareVertexBufferSharedPtr vbuf = ogreV->vertexBufferBinding->
|
---|
| 144 | getBuffer(posElem->getSource());
|
---|
| 145 | unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
|
---|
| 146 | void* pSrc = 0;
|
---|
| 147 | void* pDst = 0;
|
---|
| 148 | size_t elementSize = 0;
|
---|
| 149 |
|
---|
| 150 | switch(geoType)
|
---|
| 151 | {
|
---|
| 152 | case (Geometry::VERTEX_POSITION):
|
---|
| 153 | geoV->mPosition = new Geometry::Vector3[geoV->mVertexCount];
|
---|
| 154 | pDst = geoV->mPosition;
|
---|
| 155 | elementSize = sizeof(Geometry::Vector3);
|
---|
| 156 | break;
|
---|
| 157 | case (Geometry::VERTEX_NORMAL):
|
---|
| 158 | geoV->mNormal = new Geometry::Vector3[geoV->mVertexCount];
|
---|
| 159 | pDst = geoV->mNormal;
|
---|
| 160 | elementSize = sizeof(Geometry::Vector3);
|
---|
| 161 | break;
|
---|
| 162 | case (Geometry::VERTEX_TEXCOORDS):
|
---|
| 163 | geoV->mTexCoords = new Geometry::Vector2[geoV->mVertexCount];
|
---|
| 164 | pDst = geoV->mTexCoords;
|
---|
| 165 | elementSize = sizeof(Geometry::Vector2);
|
---|
| 166 | break;
|
---|
| 167 | }
|
---|
| 168 |
|
---|
| 169 | for(size_t i = 0; i < ogreV->vertexCount;
|
---|
| 170 | ++i, vertex += vbuf->getVertexSize(), pDst = (char*)pDst + elementSize )
|
---|
| 171 | {
|
---|
| 172 | posElem->baseVertexPointerToElement(vertex, &pSrc);
|
---|
| 173 | memcpy(pDst,pSrc,elementSize);
|
---|
| 174 | }
|
---|
| 175 | vbuf->unlock();
|
---|
| 176 | return true;
|
---|
| 177 | }
|
---|
| 178 | else
|
---|
| 179 | {
|
---|
| 180 | return false;
|
---|
| 181 | }
|
---|
| 182 | }
|
---|
| 183 |
|
---|
| 184 | Ogre::MeshPtr OgreGTGeometry::transform( const Geometry::Mesh *geoMesh,
|
---|
| 185 | const Ogre::String name, const Ogre::String groupName)
|
---|
| 186 | {
|
---|
| 187 | Geometry::Real max_squaredLength = 0;
|
---|
| 188 | Ogre::AxisAlignedBox aab;
|
---|
| 189 |
|
---|
| 190 | bool sharedVertexCopied = false;
|
---|
| 191 | Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(name, groupName, 0);
|
---|
| 192 |
|
---|
| 193 | for(size_t i = 0; i < geoMesh->mSubMeshCount; ++i)
|
---|
| 194 | {
|
---|
| 195 | Geometry::SubMesh *subMeshSrc = &(geoMesh->mSubMesh[i]);
|
---|
| 196 | Ogre::SubMesh *subMeshDst = mesh->createSubMesh();
|
---|
| 197 |
|
---|
| 198 | //--- Vertex Info ----
|
---|
| 199 | if ((subMeshSrc->mSharedVertexBuffer && !sharedVertexCopied) ||
|
---|
| 200 | !subMeshSrc->mSharedVertexBuffer)
|
---|
| 201 | {
|
---|
| 202 | Geometry::VertexBuffer *vertexDataSrc = (subMeshSrc->mSharedVertexBuffer)?
|
---|
| 203 | geoMesh->mVertexBuffer : subMeshSrc->mVertexBuffer;
|
---|
| 204 | unsigned int vertexInfo = vertexDataSrc->mVertexInfo;
|
---|
| 205 | size_t numVerts = vertexDataSrc->mVertexCount;
|
---|
| 206 |
|
---|
| 207 | Ogre::VertexData *vertexData = new Ogre::VertexData();
|
---|
| 208 | Ogre::VertexDeclaration *vertexDec = new Ogre::VertexDeclaration();
|
---|
| 209 | size_t offset = 0;
|
---|
| 210 |
|
---|
| 211 |
|
---|
| 212 | vertexData->vertexCount = numVerts;
|
---|
| 213 | vertexData->vertexDeclaration = vertexDec;
|
---|
| 214 |
|
---|
| 215 | if (vertexInfo & Geometry::VERTEX_POSITION)
|
---|
| 216 | {
|
---|
| 217 | offset += vertexDec->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION).getSize();
|
---|
| 218 | }
|
---|
| 219 | if (vertexInfo & Geometry::VERTEX_NORMAL)
|
---|
| 220 | {
|
---|
| 221 | offset += vertexDec->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL).getSize();
|
---|
| 222 | }
|
---|
| 223 | if (vertexInfo & Geometry::VERTEX_TEXCOORDS)
|
---|
| 224 | {
|
---|
| 225 | offset += vertexDec->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES).getSize();
|
---|
| 226 | }
|
---|
| 227 |
|
---|
| 228 | Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().
|
---|
| 229 | createVertexBuffer(vertexDec->getVertexSize(0), numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
|
---|
| 230 |
|
---|
| 231 | unsigned char* data = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
|
---|
| 232 |
|
---|
| 233 |
|
---|
| 234 | // Fill data
|
---|
| 235 | for(size_t j = 0; j < numVerts; ++j)
|
---|
| 236 | {
|
---|
| 237 | if (vertexInfo & Geometry::VERTEX_POSITION)
|
---|
| 238 | {
|
---|
| 239 | Geometry::Vector3 &v = vertexDataSrc->mPosition[j];
|
---|
| 240 | Ogre::Vector3 ogre_v(v.val);
|
---|
| 241 |
|
---|
| 242 | *((Geometry::Vector3*)data) = v;
|
---|
| 243 | data+=sizeof(Geometry::Vector3);
|
---|
| 244 | if (v.squaredLength() > max_squaredLength) max_squaredLength = v.squaredLength();
|
---|
| 245 | aab.merge(ogre_v);
|
---|
| 246 | }
|
---|
| 247 | if (vertexInfo & Geometry::VERTEX_NORMAL)
|
---|
| 248 | {
|
---|
| 249 | *((Geometry::Vector3*)data) = vertexDataSrc->mNormal[j];
|
---|
| 250 | data+=sizeof(Geometry::Vector3);
|
---|
| 251 | }
|
---|
| 252 | if (vertexInfo & Geometry::VERTEX_TEXCOORDS)
|
---|
| 253 | {
|
---|
| 254 | *((Geometry::Vector2*)data) = vertexDataSrc->mTexCoords[j];
|
---|
| 255 | data+=sizeof(Geometry::Vector2);
|
---|
| 256 | }
|
---|
| 257 | }
|
---|
| 258 |
|
---|
| 259 | vbuf->unlock();
|
---|
| 260 | vertexData->vertexBufferBinding->setBinding(0, vbuf);
|
---|
| 261 |
|
---|
| 262 |
|
---|
| 263 | if (subMeshSrc->mSharedVertexBuffer)
|
---|
| 264 | {
|
---|
| 265 | mesh->sharedVertexData = vertexData;
|
---|
| 266 | sharedVertexCopied = true;
|
---|
| 267 | subMeshDst->useSharedVertices = true;
|
---|
| 268 | }
|
---|
| 269 | else
|
---|
| 270 | {
|
---|
| 271 | subMeshDst->vertexData = vertexData;
|
---|
| 272 | subMeshDst->useSharedVertices = false;
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 | //--- Index info ---
|
---|
| 278 | Ogre::HardwareIndexBufferSharedPtr ibuf= Ogre::HardwareBufferManager::getSingleton().
|
---|
| 279 | createIndexBuffer(Ogre::HardwareIndexBuffer::IT_32BIT, subMeshSrc->mIndexCount,
|
---|
| 280 | Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
|
---|
| 281 |
|
---|
| 282 | ibuf->writeData(0, ibuf->getSizeInBytes(), subMeshSrc->mIndex, true);
|
---|
| 283 |
|
---|
| 284 | subMeshDst->indexData->indexBuffer = ibuf;
|
---|
| 285 | subMeshDst->indexData->indexCount = subMeshSrc->mIndexCount;
|
---|
| 286 | subMeshDst->indexData->indexStart = 0;
|
---|
| 287 |
|
---|
| 288 |
|
---|
| 289 | //--- Misc ----
|
---|
| 290 | subMeshDst->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
|
---|
| 291 | }
|
---|
| 292 |
|
---|
| 293 | mesh->_setBounds(aab);
|
---|
| 294 | mesh->_setBoundingSphereRadius(sqrt(max_squaredLength));
|
---|
| 295 | mesh->load();
|
---|
| 296 | return mesh;
|
---|
| 297 | } |
---|