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 | } |
---|