[657] | 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::DEFAULT_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 | vec = xform * vec;
|
---|
| 662 | // Assign to geometry
|
---|
| 663 | *pFloat++ = vec.x;
|
---|
| 664 | *pFloat++ = vec.y;
|
---|
| 665 | *pFloat++ = vec.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 |
|
---|
| 692 | *pFloat++ = vec.x;
|
---|
| 693 | *pFloat++ = vec.y;
|
---|
| 694 | *pFloat++ = vec.z;
|
---|
| 695 | }
|
---|
| 696 |
|
---|
| 697 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
| 698 | {
|
---|
| 699 | *pFloat++ = x * xTex;
|
---|
| 700 | *pFloat++ = 1 - (y * yTex);
|
---|
| 701 | }
|
---|
| 702 |
|
---|
| 703 | } // x
|
---|
| 704 | } // y
|
---|
| 705 | vbuf->unlock();
|
---|
| 706 |
|
---|
| 707 | // Generate face list
|
---|
| 708 | tesselate2DMesh(pSub, params.xsegments + 1, params.ysegments + 1,
|
---|
| 709 | false, params.indexBufferUsage, params.indexShadowBuffer);
|
---|
| 710 |
|
---|
| 711 | pMesh->_setBounds(AxisAlignedBox(min, max), true);
|
---|
| 712 | pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSqLen));
|
---|
| 713 |
|
---|
| 714 | }
|
---|
| 715 | //-----------------------------------------------------------------------
|
---|
| 716 | void MeshManager::loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params)
|
---|
| 717 | {
|
---|
| 718 | int i;
|
---|
| 719 | SubMesh *pSub = pMesh->createSubMesh();
|
---|
| 720 |
|
---|
| 721 | if (params.ySegmentsToKeep == -1) params.ySegmentsToKeep = params.ysegments;
|
---|
| 722 |
|
---|
| 723 | // Set up vertex data
|
---|
| 724 | // Use a single shared buffer
|
---|
| 725 | pMesh->sharedVertexData = new VertexData();
|
---|
| 726 | VertexData* vertexData = pMesh->sharedVertexData;
|
---|
| 727 | // Set up Vertex Declaration
|
---|
| 728 | VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
|
---|
| 729 | size_t currOffset = 0;
|
---|
| 730 | // We always need positions
|
---|
| 731 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
|
---|
| 732 | currOffset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
| 733 | // Optional normals
|
---|
| 734 | if(params.normals)
|
---|
| 735 | {
|
---|
| 736 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
|
---|
| 737 | currOffset += VertexElement::getTypeSize(VET_FLOAT3);
|
---|
| 738 | }
|
---|
| 739 |
|
---|
| 740 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
| 741 | {
|
---|
| 742 | // Assumes 2D texture coords
|
---|
| 743 | vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
|
---|
| 744 | currOffset += VertexElement::getTypeSize(VET_FLOAT2);
|
---|
| 745 | }
|
---|
| 746 |
|
---|
| 747 | vertexData->vertexCount = (params.xsegments + 1) * (params.ySegmentsToKeep + 1);
|
---|
| 748 |
|
---|
| 749 | // Allocate vertex buffer
|
---|
| 750 | HardwareVertexBufferSharedPtr vbuf =
|
---|
| 751 | HardwareBufferManager::getSingleton().
|
---|
| 752 | createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
|
---|
| 753 | params.vertexBufferUsage, params.vertexShadowBuffer);
|
---|
| 754 |
|
---|
| 755 | // Set up the binding (one source only)
|
---|
| 756 | VertexBufferBinding* binding = vertexData->vertexBufferBinding;
|
---|
| 757 | binding->setBinding(0, vbuf);
|
---|
| 758 |
|
---|
| 759 | // Work out the transform required
|
---|
| 760 | // Default orientation of plane is normal along +z, distance 0
|
---|
| 761 | Matrix4 xlate, xform, rot;
|
---|
| 762 | Matrix3 rot3;
|
---|
| 763 | xlate = rot = Matrix4::IDENTITY;
|
---|
| 764 | // Determine axes
|
---|
| 765 | Vector3 zAxis, yAxis, xAxis;
|
---|
| 766 | zAxis = params.plane.normal;
|
---|
| 767 | zAxis.normalise();
|
---|
| 768 | yAxis = params.upVector;
|
---|
| 769 | yAxis.normalise();
|
---|
| 770 | xAxis = yAxis.crossProduct(zAxis);
|
---|
| 771 | if (xAxis.length() == 0)
|
---|
| 772 | {
|
---|
| 773 | //upVector must be wrong
|
---|
| 774 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
|
---|
| 775 | "MeshManager::createPlane");
|
---|
| 776 | }
|
---|
| 777 |
|
---|
| 778 | rot3.FromAxes(xAxis, yAxis, zAxis);
|
---|
| 779 | rot = rot3;
|
---|
| 780 |
|
---|
| 781 | // Set up standard xform from origin
|
---|
| 782 | xlate.setTrans(params.plane.normal * -params.plane.d);
|
---|
| 783 |
|
---|
| 784 | // concatenate
|
---|
| 785 | xform = xlate * rot;
|
---|
| 786 |
|
---|
| 787 | // Generate vertex data
|
---|
| 788 | // Imagine a large sphere with the camera located near the top
|
---|
| 789 | // The lower the curvature, the larger the sphere
|
---|
| 790 | // Use the angle from viewer to the points on the plane
|
---|
| 791 | // Credit to Aftershock for the general approach
|
---|
| 792 | Real camPos; // Camera position relative to sphere center
|
---|
| 793 |
|
---|
| 794 | // Derive sphere radius
|
---|
| 795 | Vector3 vertPos; // position relative to camera
|
---|
| 796 | Real sphDist; // Distance from camera to sphere along box vertex vector
|
---|
| 797 | // Vector3 camToSph; // camera position to sphere
|
---|
| 798 | Real sphereRadius;// Sphere radius
|
---|
| 799 | // Actual values irrelevant, it's the relation between sphere radius and camera position that's important
|
---|
| 800 | const Real SPHERE_RAD = 100.0;
|
---|
| 801 | const Real CAM_DIST = 5.0;
|
---|
| 802 |
|
---|
| 803 | sphereRadius = SPHERE_RAD - params.curvature;
|
---|
| 804 | camPos = sphereRadius - CAM_DIST;
|
---|
| 805 |
|
---|
| 806 | // Lock the whole buffer
|
---|
| 807 | float* pFloat = static_cast<float*>(
|
---|
| 808 | vbuf->lock(HardwareBuffer::HBL_DISCARD) );
|
---|
| 809 | Real xSpace = params.width / params.xsegments;
|
---|
| 810 | Real ySpace = params.height / params.ysegments;
|
---|
| 811 | Real halfWidth = params.width / 2;
|
---|
| 812 | Real halfHeight = params.height / 2;
|
---|
| 813 | Vector3 vec, norm;
|
---|
| 814 | Vector3 min, max;
|
---|
| 815 | Real maxSquaredLength;
|
---|
| 816 | bool firstTime = true;
|
---|
| 817 |
|
---|
| 818 | for (int y = params.ysegments - params.ySegmentsToKeep; y < params.ysegments + 1; ++y)
|
---|
| 819 | {
|
---|
| 820 | for (int x = 0; x < params.xsegments + 1; ++x)
|
---|
| 821 | {
|
---|
| 822 | // Work out centered on origin
|
---|
| 823 | vec.x = (x * xSpace) - halfWidth;
|
---|
| 824 | vec.y = (y * ySpace) - halfHeight;
|
---|
| 825 | vec.z = 0.0f;
|
---|
| 826 | // Transform by orientation and distance
|
---|
| 827 | vec = xform * vec;
|
---|
| 828 | // Assign to geometry
|
---|
| 829 | *pFloat++ = vec.x;
|
---|
| 830 | *pFloat++ = vec.y;
|
---|
| 831 | *pFloat++ = vec.z;
|
---|
| 832 |
|
---|
| 833 | // Build bounds as we go
|
---|
| 834 | if (firstTime)
|
---|
| 835 | {
|
---|
| 836 | min = vec;
|
---|
| 837 | max = vec;
|
---|
| 838 | maxSquaredLength = vec.squaredLength();
|
---|
| 839 | firstTime = false;
|
---|
| 840 | }
|
---|
| 841 | else
|
---|
| 842 | {
|
---|
| 843 | min.makeFloor(vec);
|
---|
| 844 | max.makeCeil(vec);
|
---|
| 845 | maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
|
---|
| 846 | }
|
---|
| 847 |
|
---|
| 848 | if (params.normals)
|
---|
| 849 | {
|
---|
| 850 | // Default normal is along unit Z
|
---|
| 851 | norm = Vector3::UNIT_Z;
|
---|
| 852 | // Rotate
|
---|
| 853 | norm = params.orientation * norm;
|
---|
| 854 |
|
---|
| 855 | *pFloat++ = norm.x;
|
---|
| 856 | *pFloat++ = norm.y;
|
---|
| 857 | *pFloat++ = norm.z;
|
---|
| 858 | }
|
---|
| 859 |
|
---|
| 860 | // Generate texture coords
|
---|
| 861 | // Normalise position
|
---|
| 862 | // modify by orientation to return +y up
|
---|
| 863 | vec = params.orientation.Inverse() * vec;
|
---|
| 864 | vec.normalise();
|
---|
| 865 | // Find distance to sphere
|
---|
| 866 | sphDist = Math::Sqrt(camPos*camPos * (vec.y*vec.y-1.0) + sphereRadius*sphereRadius) - camPos*vec.y;
|
---|
| 867 |
|
---|
| 868 | vec.x *= sphDist;
|
---|
| 869 | vec.z *= sphDist;
|
---|
| 870 |
|
---|
| 871 | // Use x and y on sphere as texture coordinates, tiled
|
---|
| 872 | Real s = vec.x * (0.01 * params.xTile);
|
---|
| 873 | Real t = 1 - (vec.z * (0.01 * params.yTile));
|
---|
| 874 | for (i = 0; i < params.numTexCoordSets; ++i)
|
---|
| 875 | {
|
---|
| 876 | *pFloat++ = s;
|
---|
| 877 | *pFloat++ = t;
|
---|
| 878 | }
|
---|
| 879 |
|
---|
| 880 |
|
---|
| 881 | } // x
|
---|
| 882 | } // y
|
---|
| 883 |
|
---|
| 884 | // Unlock
|
---|
| 885 | vbuf->unlock();
|
---|
| 886 | // Generate face list
|
---|
| 887 | pSub->useSharedVertices = true;
|
---|
| 888 | tesselate2DMesh(pSub, params.xsegments + 1, params.ySegmentsToKeep + 1, false,
|
---|
| 889 | params.indexBufferUsage, params.indexShadowBuffer);
|
---|
| 890 |
|
---|
| 891 | pMesh->_setBounds(AxisAlignedBox(min, max), true);
|
---|
| 892 | pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
|
---|
| 893 | }
|
---|
| 894 | //-----------------------------------------------------------------------
|
---|
| 895 | PatchMeshPtr MeshManager::createBezierPatch(const String& name, const String& groupName,
|
---|
| 896 | void* controlPointBuffer, VertexDeclaration *declaration,
|
---|
| 897 | size_t width, size_t height,
|
---|
| 898 | size_t uMaxSubdivisionLevel, size_t vMaxSubdivisionLevel,
|
---|
| 899 | PatchSurface::VisibleSide visibleSide,
|
---|
| 900 | HardwareBuffer::Usage vbUsage, HardwareBuffer::Usage ibUsage,
|
---|
| 901 | bool vbUseShadow, bool ibUseShadow)
|
---|
| 902 | {
|
---|
| 903 | if (width < 3 || height < 3)
|
---|
| 904 | {
|
---|
| 905 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
|
---|
| 906 | "Bezier patch require at least 3x3 control points",
|
---|
| 907 | "MeshManager::createBezierPatch");
|
---|
| 908 | }
|
---|
| 909 |
|
---|
| 910 | MeshPtr pMesh = getByName(name);
|
---|
| 911 | if (!pMesh.isNull())
|
---|
| 912 | {
|
---|
| 913 | OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "A mesh called " + name +
|
---|
| 914 | " already exists!", "MeshManager::createBezierPatch");
|
---|
| 915 | }
|
---|
| 916 | PatchMesh* pm = new PatchMesh(this, name, getNextHandle(), groupName);
|
---|
| 917 | pm->define(controlPointBuffer, declaration, width, height,
|
---|
| 918 | uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide, vbUsage, ibUsage,
|
---|
| 919 | vbUseShadow, ibUseShadow);
|
---|
| 920 | pm->load();
|
---|
| 921 | ResourcePtr res(pm);
|
---|
| 922 | addImpl(res);
|
---|
| 923 |
|
---|
| 924 | return res;
|
---|
| 925 | }
|
---|
| 926 | //-----------------------------------------------------------------------
|
---|
| 927 | void MeshManager::setPrepareAllMeshesForShadowVolumes(bool enable)
|
---|
| 928 | {
|
---|
| 929 | mPrepAllMeshesForShadowVolumes = enable;
|
---|
| 930 | }
|
---|
| 931 | //-----------------------------------------------------------------------
|
---|
| 932 | bool MeshManager::getPrepareAllMeshesForShadowVolumes(void)
|
---|
| 933 | {
|
---|
| 934 | return mPrepAllMeshesForShadowVolumes;
|
---|
| 935 | }
|
---|
| 936 | //-----------------------------------------------------------------------
|
---|
| 937 | Real MeshManager::getBoundsPaddingFactor(void)
|
---|
| 938 | {
|
---|
| 939 | return mBoundsPaddingFactor;
|
---|
| 940 | }
|
---|
| 941 | //-----------------------------------------------------------------------
|
---|
| 942 | void MeshManager::setBoundsPaddingFactor(Real paddingFactor)
|
---|
| 943 | {
|
---|
| 944 | mBoundsPaddingFactor = paddingFactor;
|
---|
| 945 | }
|
---|
| 946 | //-----------------------------------------------------------------------
|
---|
| 947 | Resource* MeshManager::createImpl(const String& name, ResourceHandle handle,
|
---|
| 948 | const String& group, bool isManual, ManualResourceLoader* loader,
|
---|
| 949 | const NameValuePairList* createParams)
|
---|
| 950 | {
|
---|
| 951 | // no use for createParams here
|
---|
| 952 | return new Mesh(this, name, handle, group, isManual, loader);
|
---|
| 953 | }
|
---|
| 954 | //-----------------------------------------------------------------------
|
---|
| 955 |
|
---|
| 956 | }
|
---|