1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #include "OgreStableHeaders.h"
|
---|
26 |
|
---|
27 | #include "OgreMeshManager.h"
|
---|
28 |
|
---|
29 | #include "OgreMesh.h"
|
---|
30 | #include "OgreSubMesh.h"
|
---|
31 | #include "OgreMatrix4.h"
|
---|
32 | #include "OgreMatrix3.h"
|
---|
33 | #include "OgreVector3.h"
|
---|
34 | #include "OgrePlane.h"
|
---|
35 | #include "OgreHardwareBufferManager.h"
|
---|
36 | #include "OgrePatchSurface.h"
|
---|
37 | #include "OgreException.h"
|
---|
38 |
|
---|
39 | namespace Ogre
|
---|
40 | {
|
---|
41 | #define PI 3.1415926535897932384626433832795
|
---|
42 |
|
---|
43 | //-----------------------------------------------------------------------
|
---|
44 | template<> MeshManager* Singleton<MeshManager>::ms_Singleton = 0;
|
---|
45 | MeshManager* MeshManager::getSingletonPtr(void)
|
---|
46 | {
|
---|
47 | return ms_Singleton;
|
---|
48 | }
|
---|
49 | MeshManager& MeshManager::getSingleton(void)
|
---|
50 | {
|
---|
51 | assert( ms_Singleton ); return ( *ms_Singleton );
|
---|
52 | }
|
---|
53 | //-----------------------------------------------------------------------
|
---|
54 | MeshManager::MeshManager():
|
---|
55 | mBoundsPaddingFactor(0.01)
|
---|
56 | {
|
---|
57 | mPrepAllMeshesForShadowVolumes = false;
|
---|
58 |
|
---|
59 | mLoadOrder = 350.0f;
|
---|
60 | mResourceType = "Mesh";
|
---|
61 |
|
---|
62 | ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);
|
---|
63 |
|
---|
64 | }
|
---|
65 | //-----------------------------------------------------------------------
|
---|
66 | MeshManager::~MeshManager()
|
---|
67 | {
|
---|
68 | ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
|
---|
69 | }
|
---|
70 | //-----------------------------------------------------------------------
|
---|
71 | void MeshManager::_initialise(void)
|
---|
72 | {
|
---|
73 | // Create prefab objects
|
---|
74 | createPrefabPlane();
|
---|
75 |
|
---|
76 |
|
---|
77 | }
|
---|
78 | //-----------------------------------------------------------------------
|
---|
79 | MeshPtr MeshManager::load( const String& filename, const String& groupName,
|
---|
80 | HardwareBuffer::Usage vertexBufferUsage,
|
---|
81 | HardwareBuffer::Usage indexBufferUsage,
|
---|
82 | bool vertexBufferShadowed, bool indexBufferShadowed)
|
---|
83 | {
|
---|
84 | MeshPtr pMesh = getByName(filename);
|
---|
85 | if (pMesh.isNull())
|
---|
86 | {
|
---|
87 | pMesh = this->create(filename, groupName);
|
---|
88 | pMesh->setVertexBufferPolicy(vertexBufferUsage, vertexBufferShadowed);
|
---|
89 | pMesh->setIndexBufferPolicy(indexBufferUsage, indexBufferShadowed);
|
---|
90 | }
|
---|
91 | pMesh->load();
|
---|
92 | return pMesh;
|
---|
93 |
|
---|
94 | }
|
---|
95 | //-----------------------------------------------------------------------
|
---|
96 | MeshPtr MeshManager::createManual( const String& name, const String& groupName,
|
---|
97 | ManualResourceLoader* loader)
|
---|
98 | {
|
---|
99 | MeshPtr pMesh = getByName(name);
|
---|
100 | if (pMesh.isNull())
|
---|
101 | {
|
---|
102 | pMesh = create(name, groupName, true, loader);
|
---|
103 | }
|
---|
104 |
|
---|
105 | return pMesh;
|
---|
106 | }
|
---|
107 | //-----------------------------------------------------------------------
|
---|
108 | MeshPtr MeshManager::createPlane( const String& name, const String& groupName,
|
---|
109 | const Plane& plane, Real width, Real height, int xsegments, int ysegments,
|
---|
110 | bool normals, int numTexCoordSets, Real xTile, Real yTile, const Vector3& upVector,
|
---|
111 | HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage,
|
---|
112 | bool vertexShadowBuffer, bool indexShadowBuffer)
|
---|
113 | {
|
---|
114 | // Create manual mesh which calls back self to load
|
---|
115 | MeshPtr pMesh = createManual(name, groupName, this);
|
---|
116 | // Planes can never be manifold
|
---|
117 | pMesh->setAutoBuildEdgeLists(false);
|
---|
118 | // store parameters
|
---|
119 | MeshBuildParams params;
|
---|
120 | params.type = MBT_PLANE;
|
---|
121 | params.plane = plane;
|
---|
122 | params.width = width;
|
---|
123 | params.height = height;
|
---|
124 | params.xsegments = xsegments;
|
---|
125 | params.ysegments = ysegments;
|
---|
126 | params.normals = normals;
|
---|
127 | params.numTexCoordSets = numTexCoordSets;
|
---|
128 | params.xTile = xTile;
|
---|
129 | params.yTile = yTile;
|
---|
130 | params.upVector = upVector;
|
---|
131 | params.vertexBufferUsage = vertexBufferUsage;
|
---|
132 | params.indexBufferUsage = indexBufferUsage;
|
---|
133 | params.vertexShadowBuffer = vertexShadowBuffer;
|
---|
134 | params.indexShadowBuffer = indexShadowBuffer;
|
---|
135 | mMeshBuildParams[pMesh.getPointer()] = params;
|
---|
136 |
|
---|
137 | // to preserve previous behaviour, load immediately
|
---|
138 | pMesh->load();
|
---|
139 |
|
---|
140 | return pMesh;
|
---|
141 | }
|
---|
142 |
|
---|
143 | //-----------------------------------------------------------------------
|
---|
144 | MeshPtr MeshManager::createCurvedPlane( const String& name, const String& groupName,
|
---|
145 | const Plane& plane, Real width, Real height, Real bow, int xsegments, int ysegments,
|
---|
146 | bool normals, int numTexCoordSets, Real xTile, Real yTile, const Vector3& upVector,
|
---|
147 | HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage,
|
---|
148 | bool vertexShadowBuffer, bool indexShadowBuffer)
|
---|
149 | {
|
---|
150 | // Create manual mesh which calls back self to load
|
---|
151 | MeshPtr pMesh = createManual(name, groupName, this);
|
---|
152 | // Planes can never be manifold
|
---|
153 | pMesh->setAutoBuildEdgeLists(false);
|
---|
154 | // store parameters
|
---|
155 | MeshBuildParams params;
|
---|
156 | params.type = MBT_CURVED_PLANE;
|
---|
157 | params.plane = plane;
|
---|
158 | params.width = width;
|
---|
159 | params.height = height;
|
---|
160 | params.curvature = bow;
|
---|
161 | params.xsegments = xsegments;
|
---|
162 | params.ysegments = ysegments;
|
---|
163 | params.normals = normals;
|
---|
164 | params.numTexCoordSets = numTexCoordSets;
|
---|
165 | params.xTile = xTile;
|
---|
166 | params.yTile = yTile;
|
---|
167 | params.upVector = upVector;
|
---|
168 | params.vertexBufferUsage = vertexBufferUsage;
|
---|
169 | params.indexBufferUsage = indexBufferUsage;
|
---|
170 | params.vertexShadowBuffer = vertexShadowBuffer;
|
---|
171 | params.indexShadowBuffer = indexShadowBuffer;
|
---|
172 | mMeshBuildParams[pMesh.getPointer()] = params;
|
---|
173 |
|
---|
174 | // to preserve previous behaviour, load immediately
|
---|
175 | pMesh->load();
|
---|
176 |
|
---|
177 | return pMesh;
|
---|
178 |
|
---|
179 | }
|
---|
180 | //-----------------------------------------------------------------------
|
---|
181 | MeshPtr MeshManager::createCurvedIllusionPlane(
|
---|
182 | const String& name, const String& groupName, const Plane& plane,
|
---|
183 | Real width, Real height, Real curvature,
|
---|
184 | int xsegments, int ysegments,
|
---|
185 | bool normals, int numTexCoordSets,
|
---|
186 | Real uTile, Real vTile, const Vector3& upVector,
|
---|
187 | const Quaternion& orientation,
|
---|
188 | HardwareBuffer::Usage vertexBufferUsage,
|
---|
189 | HardwareBuffer::Usage indexBufferUsage,
|
---|
190 | bool vertexShadowBuffer, bool indexShadowBuffer,
|
---|
191 | int ySegmentsToKeep)
|
---|
192 | {
|
---|
193 | // Create manual mesh which calls back self to load
|
---|
194 | MeshPtr pMesh = createManual(name, groupName, this);
|
---|
195 | // Planes can never be manifold
|
---|
196 | pMesh->setAutoBuildEdgeLists(false);
|
---|
197 | // store parameters
|
---|
198 | MeshBuildParams params;
|
---|
199 | params.type = MBT_CURVED_ILLUSION_PLANE;
|
---|
200 | params.plane = plane;
|
---|
201 | params.width = width;
|
---|
202 | params.height = height;
|
---|
203 | params.curvature = curvature;
|
---|
204 | params.xsegments = xsegments;
|
---|
205 | params.ysegments = ysegments;
|
---|
206 | params.normals = normals;
|
---|
207 | params.numTexCoordSets = numTexCoordSets;
|
---|
208 | params.xTile = uTile;
|
---|
209 | params.yTile = vTile;
|
---|
210 | params.upVector = upVector;
|
---|
211 | params.orientation = orientation;
|
---|
212 | params.vertexBufferUsage = vertexBufferUsage;
|
---|
213 | params.indexBufferUsage = indexBufferUsage;
|
---|
214 | params.vertexShadowBuffer = vertexShadowBuffer;
|
---|
215 | params.indexShadowBuffer = indexShadowBuffer;
|
---|
216 | params.ySegmentsToKeep = ySegmentsToKeep;
|
---|
217 | mMeshBuildParams[pMesh.getPointer()] = params;
|
---|
218 |
|
---|
219 | // to preserve previous behaviour, load immediately
|
---|
220 | pMesh->load();
|
---|
221 |
|
---|
222 | return pMesh;
|
---|
223 | }
|
---|
224 |
|
---|
225 | //-----------------------------------------------------------------------
|
---|
226 | void MeshManager::tesselate2DMesh(SubMesh* sm, int meshWidth, int meshHeight,
|
---|
227 | bool doubleSided, HardwareBuffer::Usage indexBufferUsage, bool indexShadowBuffer)
|
---|
228 | {
|
---|
229 | // The mesh is built, just make a list of indexes to spit out the triangles
|
---|
230 | int vInc, uInc, v, u, iterations;
|
---|
231 | int vCount, uCount;
|
---|
232 |
|
---|
233 | if (doubleSided)
|
---|
234 | {
|
---|
235 | iterations = 2;
|
---|
236 | vInc = 1;
|
---|
237 | v = 0; // Start with front
|
---|
238 | }
|
---|
239 | else
|
---|
240 | {
|
---|
241 | iterations = 1;
|
---|
242 | vInc = 1;
|
---|
243 | v = 0;
|
---|
244 | }
|
---|
245 |
|
---|
246 | // Allocate memory for faces
|
---|
247 | // Num faces, width*height*2 (2 tris per square), index count is * 3 on top
|
---|
248 | sm->indexData->indexCount = (meshWidth-1) * (meshHeight-1) * 2 * iterations * 3;
|
---|
249 | sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().
|
---|
250 | createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
|
---|
251 | sm->indexData->indexCount, indexBufferUsage, indexShadowBuffer);
|
---|
252 |
|
---|
253 | int v1, v2, v3;
|
---|
254 | //bool firstTri = true;
|
---|
255 | HardwareIndexBufferSharedPtr ibuf = sm->indexData->indexBuffer;
|
---|
256 | // Lock the whole buffer
|
---|
257 | unsigned short* pIndexes = static_cast<unsigned short*>(
|
---|
258 | ibuf->lock(HardwareBuffer::HBL_DISCARD) );
|
---|
259 |
|
---|
260 | while (iterations--)
|
---|
261 | {
|
---|
262 | // Make tris in a zigzag pattern (compatible with strips)
|
---|
263 | u = 0;
|
---|
264 | uInc = 1; // Start with moving +u
|
---|
265 |
|
---|
266 | vCount = meshHeight - 1;
|
---|
267 | while (vCount--)
|
---|
268 | {
|
---|
269 | uCount = meshWidth - 1;
|
---|
270 | while (uCount--)
|
---|
271 | {
|
---|
272 | // First Tri in cell
|
---|
273 | // -----------------
|
---|
274 | v1 = ((v + vInc) * meshWidth) + u;
|
---|
275 | v2 = (v * meshWidth) + u;
|
---|
276 | v3 = ((v + vInc) * meshWidth) + (u + uInc);
|
---|
277 | // Output indexes
|
---|
278 | *pIndexes++ = v1;
|
---|
279 | *pIndexes++ = v2;
|
---|
280 | *pIndexes++ = v3;
|
---|
281 | // Second Tri in cell
|
---|
282 | // ------------------
|
---|
283 | v1 = ((v + vInc) * meshWidth) + (u + uInc);
|
---|
284 | v2 = (v * meshWidth) + u;
|
---|
285 | v3 = (v * meshWidth) + (u + uInc);
|
---|
286 | // Output indexes
|
---|
287 | *pIndexes++ = v1;
|
---|
288 | *pIndexes++ = v2;
|
---|
289 | *pIndexes++ = v3;
|
---|
290 |
|
---|
291 | // Next column
|
---|
292 | u += uInc;
|
---|
293 | }
|
---|
294 | // Next row
|
---|
295 | v += vInc;
|
---|
296 | u = 0;
|
---|
297 |
|
---|
298 |
|
---|
299 | }
|
---|
300 |
|
---|
301 | // Reverse vInc for double sided
|
---|
302 | v = meshHeight - 1;
|
---|
303 | vInc = -vInc;
|
---|
304 |
|
---|
305 | }
|
---|
306 | // Unlock
|
---|
307 | ibuf->unlock();
|
---|
308 |
|
---|
309 | }
|
---|
310 |
|
---|
311 | //-----------------------------------------------------------------------
|
---|
312 | void MeshManager::createPrefabPlane(void)
|
---|
313 | {
|
---|
314 | MeshPtr msh = create(
|
---|
315 | "Prefab_Plane",
|
---|
316 | ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME,
|
---|
317 | true, // manually loaded
|
---|
318 | this);
|
---|
319 | // Planes can never be manifold
|
---|
320 | msh->setAutoBuildEdgeLists(false);
|
---|
321 | // to preserve previous behaviour, load immediately
|
---|
322 | msh->load();
|
---|
323 | }
|
---|
324 | //-----------------------------------------------------------------------
|
---|
325 | void MeshManager::loadResource(Resource* res)
|
---|
326 | {
|
---|
327 | Mesh* msh = static_cast<Mesh*>(res);
|
---|
328 | // Manual resource load
|
---|
329 | if (res->getName() == "Prefab_Plane")
|
---|
330 | {
|
---|
331 | SubMesh* sub = msh->createSubMesh();
|
---|
332 | float vertices[32] = {
|
---|
333 | -100, -100, 0, // pos
|
---|
334 | 0,0,1, // normal
|
---|
335 | 0,1, // texcoord
|
---|
336 | 100, -100, 0,
|
---|
337 | 0,0,1,
|
---|
338 | 1,1,
|
---|
339 | 100, 100, 0,
|
---|
340 | 0,0,1,
|
---|
341 | 1,0,
|
---|
342 | -100, 100, 0 ,
|
---|
343 | 0,0,1,
|
---|
344 | 0,0
|
---|
345 | };
|
---|
346 | msh->sharedVertexData = new VertexData();
|
---|
347 | msh->sharedVertexData->vertexCount = 4;
|
---|
348 | VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
|
---|
349 | VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
|
---|
350 |
|
---|
351 | size_t offset = 0;
|
---|
352 | decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
|
---|
353 | offset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
354 | decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
|
---|
355 | offset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
356 | decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
|
---|
357 | offset += VertexElement::getTypeSize(VET_FLOAT2);
|
---|
358 |
|
---|
359 | HardwareVertexBufferSharedPtr vbuf =
|
---|
360 | HardwareBufferManager::getSingleton().createVertexBuffer(
|
---|
361 | offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
---|
362 | bind->setBinding(0, vbuf);
|
---|
363 |
|
---|
364 | vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
|
---|
365 |
|
---|
366 | sub->useSharedVertices = true;
|
---|
367 | HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
|
---|
368 | createIndexBuffer(
|
---|
369 | HardwareIndexBuffer::IT_16BIT,
|
---|
370 | 6,
|
---|
371 | HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
---|
372 |
|
---|
373 | unsigned short faces[6] = {0,1,2,
|
---|
374 | 0,2,3 };
|
---|
375 | sub->indexData->indexBuffer = ibuf;
|
---|
376 | sub->indexData->indexCount = 6;
|
---|
377 | sub->indexData->indexStart =0;
|
---|
378 | ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
|
---|
379 |
|
---|
380 | msh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true);
|
---|
381 | msh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100));
|
---|
382 | }
|
---|
383 | else
|
---|
384 | {
|
---|
385 | // Find build parameters
|
---|
386 | MeshBuildParamsMap::iterator ibld = mMeshBuildParams.find(res);
|
---|
387 | if (ibld == mMeshBuildParams.end())
|
---|
388 | {
|
---|
389 | OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
|
---|
390 | "Cannot find build parameters for " + res->getName(),
|
---|
391 | "MeshManager::loadResource");
|
---|
392 | }
|
---|
393 | MeshBuildParams& params = ibld->second;
|
---|
394 |
|
---|
395 | switch(params.type)
|
---|
396 | {
|
---|
397 | case MBT_PLANE:
|
---|
398 | loadManualPlane(msh, params);
|
---|
399 | break;
|
---|
400 | case MBT_CURVED_ILLUSION_PLANE:
|
---|
401 | loadManualCurvedIllusionPlane(msh, params);
|
---|
402 | break;
|
---|
403 | case MBT_CURVED_PLANE:
|
---|
404 | loadManualCurvedPlane(msh, params);
|
---|
405 | break;
|
---|
406 | default:
|
---|
407 | OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
|
---|
408 | "Unknown build parameters for " + res->getName(),
|
---|
409 | "MeshManager::loadResource");
|
---|
410 | }
|
---|
411 | }
|
---|
412 |
|
---|
413 | }
|
---|
414 | //-----------------------------------------------------------------------
|
---|
415 | void MeshManager::loadManualPlane(Mesh* pMesh, MeshBuildParams& params)
|
---|
416 | {
|
---|
417 | int i;
|
---|
418 |
|
---|
419 | SubMesh *pSub = pMesh->createSubMesh();
|
---|
420 |
|
---|
421 | // Set up vertex data
|
---|
422 | // Use a single shared buffer
|
---|
423 | pMesh->sharedVertexData = new VertexData();
|
---|
424 | VertexData* vertexData = pMesh->sharedVertexData;
|
---|
425 | // Set up Vertex Declaration
|
---|
426 | VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
|
---|
427 | size_t currOffset = 0;
|
---|
428 | // We always need positions
|
---|
429 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
|
---|
430 | currOffset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
431 | // Optional normals
|
---|
432 | if(params.normals)
|
---|
433 | {
|
---|
434 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
|
---|
435 | currOffset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
436 | }
|
---|
437 |
|
---|
438 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
439 | {
|
---|
440 | // Assumes 2D texture coords
|
---|
441 | vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
|
---|
442 | currOffset += VertexElement::getTypeSize(VET_FLOAT2);
|
---|
443 | }
|
---|
444 |
|
---|
445 | vertexData->vertexCount = (params.xsegments + 1) * (params.ysegments + 1);
|
---|
446 |
|
---|
447 | // Allocate vertex buffer
|
---|
448 | HardwareVertexBufferSharedPtr vbuf =
|
---|
449 | HardwareBufferManager::getSingleton().
|
---|
450 | createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
|
---|
451 | params.vertexBufferUsage, params.vertexShadowBuffer);
|
---|
452 |
|
---|
453 | // Set up the binding (one source only)
|
---|
454 | VertexBufferBinding* binding = vertexData->vertexBufferBinding;
|
---|
455 | binding->setBinding(0, vbuf);
|
---|
456 |
|
---|
457 | // Work out the transform required
|
---|
458 | // Default orientation of plane is normal along +z, distance 0
|
---|
459 | Matrix4 xlate, xform, rot;
|
---|
460 | Matrix3 rot3;
|
---|
461 | xlate = rot = Matrix4::IDENTITY;
|
---|
462 | // Determine axes
|
---|
463 | Vector3 zAxis, yAxis, xAxis;
|
---|
464 | zAxis = params.plane.normal;
|
---|
465 | zAxis.normalise();
|
---|
466 | yAxis = params.upVector;
|
---|
467 | yAxis.normalise();
|
---|
468 | xAxis = yAxis.crossProduct(zAxis);
|
---|
469 | if (xAxis.length() == 0)
|
---|
470 | {
|
---|
471 | //upVector must be wrong
|
---|
472 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
|
---|
473 | "MeshManager::createPlane");
|
---|
474 | }
|
---|
475 |
|
---|
476 | rot3.FromAxes(xAxis, yAxis, zAxis);
|
---|
477 | rot = rot3;
|
---|
478 |
|
---|
479 | // Set up standard xform from origin
|
---|
480 | xlate.setTrans(params.plane.normal * -params.plane.d);
|
---|
481 |
|
---|
482 | // concatenate
|
---|
483 | xform = xlate * rot;
|
---|
484 |
|
---|
485 | // Generate vertex data
|
---|
486 | // Lock the whole buffer
|
---|
487 | float* pReal = static_cast<float*>(
|
---|
488 | vbuf->lock(HardwareBuffer::HBL_DISCARD) );
|
---|
489 | Real xSpace = params.width / params.xsegments;
|
---|
490 | Real ySpace = params.height / params.ysegments;
|
---|
491 | Real halfWidth = params.width / 2;
|
---|
492 | Real halfHeight = params.height / 2;
|
---|
493 | Real xTex = (1.0f * params.xTile) / params.xsegments;
|
---|
494 | Real yTex = (1.0f * params.yTile) / params.ysegments;
|
---|
495 | Vector3 vec;
|
---|
496 | Vector3 min, max;
|
---|
497 | Real maxSquaredLength;
|
---|
498 | bool firstTime = true;
|
---|
499 |
|
---|
500 | for (int y = 0; y < params.ysegments + 1; ++y)
|
---|
501 | {
|
---|
502 | for (int x = 0; x < params.xsegments + 1; ++x)
|
---|
503 | {
|
---|
504 | // Work out centered on origin
|
---|
505 | vec.x = (x * xSpace) - halfWidth;
|
---|
506 | vec.y = (y * ySpace) - halfHeight;
|
---|
507 | vec.z = 0.0f;
|
---|
508 | // Transform by orientation and distance
|
---|
509 | vec = xform * vec;
|
---|
510 | // Assign to geometry
|
---|
511 | *pReal++ = vec.x;
|
---|
512 | *pReal++ = vec.y;
|
---|
513 | *pReal++ = vec.z;
|
---|
514 |
|
---|
515 | // Build bounds as we go
|
---|
516 | if (firstTime)
|
---|
517 | {
|
---|
518 | min = vec;
|
---|
519 | max = vec;
|
---|
520 | maxSquaredLength = vec.squaredLength();
|
---|
521 | firstTime = false;
|
---|
522 | }
|
---|
523 | else
|
---|
524 | {
|
---|
525 | min.makeFloor(vec);
|
---|
526 | max.makeCeil(vec);
|
---|
527 | maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
|
---|
528 | }
|
---|
529 |
|
---|
530 | if (params.normals)
|
---|
531 | {
|
---|
532 | // Default normal is along unit Z
|
---|
533 | vec = Vector3::UNIT_Z;
|
---|
534 | // Rotate
|
---|
535 | vec = rot * vec;
|
---|
536 |
|
---|
537 | *pReal++ = vec.x;
|
---|
538 | *pReal++ = vec.y;
|
---|
539 | *pReal++ = vec.z;
|
---|
540 | }
|
---|
541 |
|
---|
542 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
543 | {
|
---|
544 | *pReal++ = x * xTex;
|
---|
545 | *pReal++ = 1 - (y * yTex);
|
---|
546 | }
|
---|
547 |
|
---|
548 |
|
---|
549 | } // x
|
---|
550 | } // y
|
---|
551 |
|
---|
552 | // Unlock
|
---|
553 | vbuf->unlock();
|
---|
554 | // Generate face list
|
---|
555 | pSub->useSharedVertices = true;
|
---|
556 | tesselate2DMesh(pSub, params.xsegments + 1, params.ysegments + 1, false,
|
---|
557 | params.indexBufferUsage, params.indexShadowBuffer);
|
---|
558 |
|
---|
559 | pMesh->_setBounds(AxisAlignedBox(min, max), true);
|
---|
560 | pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
|
---|
561 | }
|
---|
562 | //-----------------------------------------------------------------------
|
---|
563 | void MeshManager::loadManualCurvedPlane(Mesh* pMesh, MeshBuildParams& params)
|
---|
564 | {
|
---|
565 | int i;
|
---|
566 | SubMesh *pSub = pMesh->createSubMesh();
|
---|
567 |
|
---|
568 | // Set options
|
---|
569 | pMesh->sharedVertexData = new VertexData();
|
---|
570 | pMesh->sharedVertexData->vertexStart = 0;
|
---|
571 | VertexBufferBinding* bind = pMesh->sharedVertexData->vertexBufferBinding;
|
---|
572 | VertexDeclaration* decl = pMesh->sharedVertexData->vertexDeclaration;
|
---|
573 |
|
---|
574 | pMesh->sharedVertexData->vertexCount = (params.xsegments + 1) * (params.ysegments + 1);
|
---|
575 |
|
---|
576 | size_t offset = 0;
|
---|
577 | decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
|
---|
578 | offset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
579 | if (params.normals)
|
---|
580 | {
|
---|
581 | decl->addElement(0, 0, VET_FLOAT3, VES_NORMAL);
|
---|
582 | offset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
583 | }
|
---|
584 |
|
---|
585 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
586 | {
|
---|
587 | decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
|
---|
588 | offset += VertexElement::getTypeSize(VET_FLOAT2);
|
---|
589 | }
|
---|
590 |
|
---|
591 |
|
---|
592 | // Allocate memory
|
---|
593 | HardwareVertexBufferSharedPtr vbuf =
|
---|
594 | HardwareBufferManager::getSingleton().createVertexBuffer(
|
---|
595 | offset,
|
---|
596 | pMesh->sharedVertexData->vertexCount,
|
---|
597 | params.vertexBufferUsage,
|
---|
598 | params.vertexShadowBuffer);
|
---|
599 | bind->setBinding(0, vbuf);
|
---|
600 |
|
---|
601 | // Work out the transform required
|
---|
602 | // Default orientation of plane is normal along +z, distance 0
|
---|
603 | Matrix4 xlate, xform, rot;
|
---|
604 | Matrix3 rot3;
|
---|
605 | xlate = rot = Matrix4::IDENTITY;
|
---|
606 | // Determine axes
|
---|
607 | Vector3 zAxis, yAxis, xAxis;
|
---|
608 | zAxis = params.plane.normal;
|
---|
609 | zAxis.normalise();
|
---|
610 | yAxis = params.upVector;
|
---|
611 | yAxis.normalise();
|
---|
612 | xAxis = yAxis.crossProduct(zAxis);
|
---|
613 | if (xAxis.length() == 0)
|
---|
614 | {
|
---|
615 | //upVector must be wrong
|
---|
616 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
|
---|
617 | "MeshManager::createPlane");
|
---|
618 | }
|
---|
619 |
|
---|
620 | rot3.FromAxes(xAxis, yAxis, zAxis);
|
---|
621 | rot = rot3;
|
---|
622 |
|
---|
623 | // Set up standard xform from origin
|
---|
624 | xlate.setTrans(params.plane.normal * -params.plane.d);
|
---|
625 |
|
---|
626 | // concatenate
|
---|
627 | xform = xlate * rot;
|
---|
628 |
|
---|
629 | // Generate vertex data
|
---|
630 | float* pFloat = static_cast<float*>(
|
---|
631 | vbuf->lock(HardwareBuffer::HBL_DISCARD));
|
---|
632 | Real xSpace = params.width / params.xsegments;
|
---|
633 | Real ySpace = params.height / params.ysegments;
|
---|
634 | Real halfWidth = params.width / 2;
|
---|
635 | Real halfHeight = params.height / 2;
|
---|
636 | Real xTex = (1.0f * params.xTile) / params.xsegments;
|
---|
637 | Real yTex = (1.0f * params.yTile) / params.ysegments;
|
---|
638 | Vector3 vec;
|
---|
639 |
|
---|
640 | Vector3 min, max;
|
---|
641 | Real maxSqLen;
|
---|
642 | bool first = true;
|
---|
643 |
|
---|
644 | Real diff_x, diff_y, dist;
|
---|
645 |
|
---|
646 | for (int y = 0; y < params.ysegments + 1; ++y)
|
---|
647 | {
|
---|
648 | for (int x = 0; x < params.xsegments + 1; ++x)
|
---|
649 | {
|
---|
650 | // Work out centered on origin
|
---|
651 | vec.x = (x * xSpace) - halfWidth;
|
---|
652 | vec.y = (y * ySpace) - halfHeight;
|
---|
653 |
|
---|
654 | // Here's where curved plane is different from standard plane. Amazing, I know.
|
---|
655 | diff_x = (x - ((params.xsegments) / 2)) / static_cast<Real>((params.xsegments));
|
---|
656 | diff_y = (y - ((params.ysegments) / 2)) / static_cast<Real>((params.ysegments));
|
---|
657 | dist = sqrt(diff_x*diff_x + diff_y * diff_y );
|
---|
658 | vec.z = (-sin((1-dist) * (PI/2)) * params.curvature) + params.curvature;
|
---|
659 |
|
---|
660 | // Transform by orientation and distance
|
---|
661 | Vector3 pos = xform * vec;
|
---|
662 | // Assign to geometry
|
---|
663 | *pFloat++ = pos.x;
|
---|
664 | *pFloat++ = pos.y;
|
---|
665 | *pFloat++ = pos.z;
|
---|
666 |
|
---|
667 | // Record bounds
|
---|
668 | if (first)
|
---|
669 | {
|
---|
670 | min = max = vec;
|
---|
671 | maxSqLen = vec.squaredLength();
|
---|
672 | first = false;
|
---|
673 | }
|
---|
674 | else
|
---|
675 | {
|
---|
676 | min.makeFloor(vec);
|
---|
677 | max.makeCeil(vec);
|
---|
678 | maxSqLen = std::max(maxSqLen, vec.squaredLength());
|
---|
679 | }
|
---|
680 |
|
---|
681 | if (params.normals)
|
---|
682 | {
|
---|
683 | // This part is kinda 'wrong' for curved planes... but curved planes are
|
---|
684 | // very valuable outside sky planes, which don't typically need normals
|
---|
685 | // so I'm not going to mess with it for now.
|
---|
686 |
|
---|
687 | // Default normal is along unit Z
|
---|
688 | //vec = Vector3::UNIT_Z;
|
---|
689 | // Rotate
|
---|
690 | vec = rot * vec;
|
---|
691 | vec.normalise();
|
---|
692 |
|
---|
693 | *pFloat++ = vec.x;
|
---|
694 | *pFloat++ = vec.y;
|
---|
695 | *pFloat++ = vec.z;
|
---|
696 | }
|
---|
697 |
|
---|
698 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
699 | {
|
---|
700 | *pFloat++ = x * xTex;
|
---|
701 | *pFloat++ = 1 - (y * yTex);
|
---|
702 | }
|
---|
703 |
|
---|
704 | } // x
|
---|
705 | } // y
|
---|
706 | vbuf->unlock();
|
---|
707 |
|
---|
708 | // Generate face list
|
---|
709 | tesselate2DMesh(pSub, params.xsegments + 1, params.ysegments + 1,
|
---|
710 | false, params.indexBufferUsage, params.indexShadowBuffer);
|
---|
711 |
|
---|
712 | pMesh->_setBounds(AxisAlignedBox(min, max), true);
|
---|
713 | pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSqLen));
|
---|
714 |
|
---|
715 | }
|
---|
716 | //-----------------------------------------------------------------------
|
---|
717 | void MeshManager::loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params)
|
---|
718 | {
|
---|
719 | int i;
|
---|
720 | SubMesh *pSub = pMesh->createSubMesh();
|
---|
721 |
|
---|
722 | if (params.ySegmentsToKeep == -1) params.ySegmentsToKeep = params.ysegments;
|
---|
723 |
|
---|
724 | // Set up vertex data
|
---|
725 | // Use a single shared buffer
|
---|
726 | pMesh->sharedVertexData = new VertexData();
|
---|
727 | VertexData* vertexData = pMesh->sharedVertexData;
|
---|
728 | // Set up Vertex Declaration
|
---|
729 | VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
|
---|
730 | size_t currOffset = 0;
|
---|
731 | // We always need positions
|
---|
732 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
|
---|
733 | currOffset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
734 | // Optional normals
|
---|
735 | if(params.normals)
|
---|
736 | {
|
---|
737 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
|
---|
738 | currOffset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
739 | }
|
---|
740 |
|
---|
741 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
742 | {
|
---|
743 | // Assumes 2D texture coords
|
---|
744 | vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
|
---|
745 | currOffset += VertexElement::getTypeSize(VET_FLOAT2);
|
---|
746 | }
|
---|
747 |
|
---|
748 | vertexData->vertexCount = (params.xsegments + 1) * (params.ySegmentsToKeep + 1);
|
---|
749 |
|
---|
750 | // Allocate vertex buffer
|
---|
751 | HardwareVertexBufferSharedPtr vbuf =
|
---|
752 | HardwareBufferManager::getSingleton().
|
---|
753 | createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
|
---|
754 | params.vertexBufferUsage, params.vertexShadowBuffer);
|
---|
755 |
|
---|
756 | // Set up the binding (one source only)
|
---|
757 | VertexBufferBinding* binding = vertexData->vertexBufferBinding;
|
---|
758 | binding->setBinding(0, vbuf);
|
---|
759 |
|
---|
760 | // Work out the transform required
|
---|
761 | // Default orientation of plane is normal along +z, distance 0
|
---|
762 | Matrix4 xlate, xform, rot;
|
---|
763 | Matrix3 rot3;
|
---|
764 | xlate = rot = Matrix4::IDENTITY;
|
---|
765 | // Determine axes
|
---|
766 | Vector3 zAxis, yAxis, xAxis;
|
---|
767 | zAxis = params.plane.normal;
|
---|
768 | zAxis.normalise();
|
---|
769 | yAxis = params.upVector;
|
---|
770 | yAxis.normalise();
|
---|
771 | xAxis = yAxis.crossProduct(zAxis);
|
---|
772 | if (xAxis.length() == 0)
|
---|
773 | {
|
---|
774 | //upVector must be wrong
|
---|
775 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
|
---|
776 | "MeshManager::createPlane");
|
---|
777 | }
|
---|
778 |
|
---|
779 | rot3.FromAxes(xAxis, yAxis, zAxis);
|
---|
780 | rot = rot3;
|
---|
781 |
|
---|
782 | // Set up standard xform from origin
|
---|
783 | xlate.setTrans(params.plane.normal * -params.plane.d);
|
---|
784 |
|
---|
785 | // concatenate
|
---|
786 | xform = xlate * rot;
|
---|
787 |
|
---|
788 | // Generate vertex data
|
---|
789 | // Imagine a large sphere with the camera located near the top
|
---|
790 | // The lower the curvature, the larger the sphere
|
---|
791 | // Use the angle from viewer to the points on the plane
|
---|
792 | // Credit to Aftershock for the general approach
|
---|
793 | Real camPos; // Camera position relative to sphere center
|
---|
794 |
|
---|
795 | // Derive sphere radius
|
---|
796 | Vector3 vertPos; // position relative to camera
|
---|
797 | Real sphDist; // Distance from camera to sphere along box vertex vector
|
---|
798 | // Vector3 camToSph; // camera position to sphere
|
---|
799 | Real sphereRadius;// Sphere radius
|
---|
800 | // Actual values irrelevant, it's the relation between sphere radius and camera position that's important
|
---|
801 | const Real SPHERE_RAD = 100.0;
|
---|
802 | const Real CAM_DIST = 5.0;
|
---|
803 |
|
---|
804 | sphereRadius = SPHERE_RAD - params.curvature;
|
---|
805 | camPos = sphereRadius - CAM_DIST;
|
---|
806 |
|
---|
807 | // Lock the whole buffer
|
---|
808 | float* pFloat = static_cast<float*>(
|
---|
809 | vbuf->lock(HardwareBuffer::HBL_DISCARD) );
|
---|
810 | Real xSpace = params.width / params.xsegments;
|
---|
811 | Real ySpace = params.height / params.ysegments;
|
---|
812 | Real halfWidth = params.width / 2;
|
---|
813 | Real halfHeight = params.height / 2;
|
---|
814 | Vector3 vec, norm;
|
---|
815 | Vector3 min, max;
|
---|
816 | Real maxSquaredLength;
|
---|
817 | bool firstTime = true;
|
---|
818 |
|
---|
819 | for (int y = params.ysegments - params.ySegmentsToKeep; y < params.ysegments + 1; ++y)
|
---|
820 | {
|
---|
821 | for (int x = 0; x < params.xsegments + 1; ++x)
|
---|
822 | {
|
---|
823 | // Work out centered on origin
|
---|
824 | vec.x = (x * xSpace) - halfWidth;
|
---|
825 | vec.y = (y * ySpace) - halfHeight;
|
---|
826 | vec.z = 0.0f;
|
---|
827 | // Transform by orientation and distance
|
---|
828 | vec = xform * vec;
|
---|
829 | // Assign to geometry
|
---|
830 | *pFloat++ = vec.x;
|
---|
831 | *pFloat++ = vec.y;
|
---|
832 | *pFloat++ = vec.z;
|
---|
833 |
|
---|
834 | // Build bounds as we go
|
---|
835 | if (firstTime)
|
---|
836 | {
|
---|
837 | min = vec;
|
---|
838 | max = vec;
|
---|
839 | maxSquaredLength = vec.squaredLength();
|
---|
840 | firstTime = false;
|
---|
841 | }
|
---|
842 | else
|
---|
843 | {
|
---|
844 | min.makeFloor(vec);
|
---|
845 | max.makeCeil(vec);
|
---|
846 | maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
|
---|
847 | }
|
---|
848 |
|
---|
849 | if (params.normals)
|
---|
850 | {
|
---|
851 | // Default normal is along unit Z
|
---|
852 | norm = Vector3::UNIT_Z;
|
---|
853 | // Rotate
|
---|
854 | norm = params.orientation * norm;
|
---|
855 |
|
---|
856 | *pFloat++ = norm.x;
|
---|
857 | *pFloat++ = norm.y;
|
---|
858 | *pFloat++ = norm.z;
|
---|
859 | }
|
---|
860 |
|
---|
861 | // Generate texture coords
|
---|
862 | // Normalise position
|
---|
863 | // modify by orientation to return +y up
|
---|
864 | vec = params.orientation.Inverse() * vec;
|
---|
865 | vec.normalise();
|
---|
866 | // Find distance to sphere
|
---|
867 | sphDist = Math::Sqrt(camPos*camPos * (vec.y*vec.y-1.0) + sphereRadius*sphereRadius) - camPos*vec.y;
|
---|
868 |
|
---|
869 | vec.x *= sphDist;
|
---|
870 | vec.z *= sphDist;
|
---|
871 |
|
---|
872 | // Use x and y on sphere as texture coordinates, tiled
|
---|
873 | Real s = vec.x * (0.01 * params.xTile);
|
---|
874 | Real t = 1 - (vec.z * (0.01 * params.yTile));
|
---|
875 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
876 | {
|
---|
877 | *pFloat++ = s;
|
---|
878 | *pFloat++ = t;
|
---|
879 | }
|
---|
880 |
|
---|
881 |
|
---|
882 | } // x
|
---|
883 | } // y
|
---|
884 |
|
---|
885 | // Unlock
|
---|
886 | vbuf->unlock();
|
---|
887 | // Generate face list
|
---|
888 | pSub->useSharedVertices = true;
|
---|
889 | tesselate2DMesh(pSub, params.xsegments + 1, params.ySegmentsToKeep + 1, false,
|
---|
890 | params.indexBufferUsage, params.indexShadowBuffer);
|
---|
891 |
|
---|
892 | pMesh->_setBounds(AxisAlignedBox(min, max), true);
|
---|
893 | pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
|
---|
894 | }
|
---|
895 | //-----------------------------------------------------------------------
|
---|
896 | PatchMeshPtr MeshManager::createBezierPatch(const String& name, const String& groupName,
|
---|
897 | void* controlPointBuffer, VertexDeclaration *declaration,
|
---|
898 | size_t width, size_t height,
|
---|
899 | size_t uMaxSubdivisionLevel, size_t vMaxSubdivisionLevel,
|
---|
900 | PatchSurface::VisibleSide visibleSide,
|
---|
901 | HardwareBuffer::Usage vbUsage, HardwareBuffer::Usage ibUsage,
|
---|
902 | bool vbUseShadow, bool ibUseShadow)
|
---|
903 | {
|
---|
904 | if (width < 3 || height < 3)
|
---|
905 | {
|
---|
906 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
|
---|
907 | "Bezier patch require at least 3x3 control points",
|
---|
908 | "MeshManager::createBezierPatch");
|
---|
909 | }
|
---|
910 |
|
---|
911 | MeshPtr pMesh = getByName(name);
|
---|
912 | if (!pMesh.isNull())
|
---|
913 | {
|
---|
914 | OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "A mesh called " + name +
|
---|
915 | " already exists!", "MeshManager::createBezierPatch");
|
---|
916 | }
|
---|
917 | PatchMesh* pm = new PatchMesh(this, name, getNextHandle(), groupName);
|
---|
918 | pm->define(controlPointBuffer, declaration, width, height,
|
---|
919 | uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide, vbUsage, ibUsage,
|
---|
920 | vbUseShadow, ibUseShadow);
|
---|
921 | pm->load();
|
---|
922 | ResourcePtr res(pm);
|
---|
923 | addImpl(res);
|
---|
924 |
|
---|
925 | return res;
|
---|
926 | }
|
---|
927 | //-----------------------------------------------------------------------
|
---|
928 | void MeshManager::setPrepareAllMeshesForShadowVolumes(bool enable)
|
---|
929 | {
|
---|
930 | mPrepAllMeshesForShadowVolumes = enable;
|
---|
931 | }
|
---|
932 | //-----------------------------------------------------------------------
|
---|
933 | bool MeshManager::getPrepareAllMeshesForShadowVolumes(void)
|
---|
934 | {
|
---|
935 | return mPrepAllMeshesForShadowVolumes;
|
---|
936 | }
|
---|
937 | //-----------------------------------------------------------------------
|
---|
938 | Real MeshManager::getBoundsPaddingFactor(void)
|
---|
939 | {
|
---|
940 | return mBoundsPaddingFactor;
|
---|
941 | }
|
---|
942 | //-----------------------------------------------------------------------
|
---|
943 | void MeshManager::setBoundsPaddingFactor(Real paddingFactor)
|
---|
944 | {
|
---|
945 | mBoundsPaddingFactor = paddingFactor;
|
---|
946 | }
|
---|
947 | //-----------------------------------------------------------------------
|
---|
948 | Resource* MeshManager::createImpl(const String& name, ResourceHandle handle,
|
---|
949 | const String& group, bool isManual, ManualResourceLoader* loader,
|
---|
950 | const NameValuePairList* createParams)
|
---|
951 | {
|
---|
952 | // no use for createParams here
|
---|
953 | return new Mesh(this, name, handle, group, isManual, loader);
|
---|
954 | }
|
---|
955 | //-----------------------------------------------------------------------
|
---|
956 |
|
---|
957 | }
|
---|