Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreMeshManager.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright © 2000-2002 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #include "OgreStableHeaders.h"
    00026
    00027 #include "OgreMeshManager.h"
    00028
    00029 #include "OgreMesh.h"
    00030 #include "OgreSubMesh.h"
    00031 #include "OgreMatrix4.h"
    00032 #include "OgreMatrix3.h"
    00033 #include "OgreVector3.h"
    00034 #include "OgrePlane.h"
    00035 #include "OgreHardwareBufferManager.h"
    00036 #include "OgrePatchSurface.h"
    00037 #include "OgreException.h"
    00038
    00039 namespace Ogre
    00040 {
    00041     #define PI 3.1415926535897932384626433832795
    00042
    00043     //-----------------------------------------------------------------------
    00044     template<> MeshManager* Singleton<MeshManager>::ms_Singleton = 0;
    00045     MeshManager* MeshManager::getSingletonPtr(void)
    00046     {
    00047         return ms_Singleton;
    00048     }
    00049     MeshManager& MeshManager::getSingleton(void)
    00050     {
    00051         assert( ms_Singleton );  return ( *ms_Singleton );
    00052     }
    00053     //-----------------------------------------------------------------------
    00054     MeshManager::MeshManager():
    00055     mBoundsPaddingFactor(0.01)
    00056     {
    00057         mPrepAllMeshesForShadowVolumes = false;
    00058
    00059
    00060     }
    00061     //-----------------------------------------------------------------------
    00062     void MeshManager::_initialise(void)
    00063     {
    00064         // Create prefab objects
    00065         createPrefabPlane();
    00066
    00067
    00068     }
    00069     //-----------------------------------------------------------------------
    00070     Resource* MeshManager::create( const String& name)
    00071     {
    00072         return new Mesh(name);
    00073     }
    00074     //-----------------------------------------------------------------------
    00075     Mesh* MeshManager::load( const String& filename,
    00076         HardwareBuffer::Usage vertexBufferUsage,
    00077         HardwareBuffer::Usage indexBufferUsage,
    00078         bool vertexBufferShadowed, bool indexBufferShadowed,
    00079         int priority)
    00080     {
    00081         Mesh* pMesh = (Mesh*)(getByName(filename));
    00082         if (!pMesh)
    00083         {
    00084             pMesh = (Mesh*)create(filename);
    00085             pMesh->setVertexBufferPolicy(vertexBufferUsage, vertexBufferShadowed);
    00086             pMesh->setIndexBufferPolicy(indexBufferUsage, indexBufferShadowed);
    00087             ResourceManager::load(pMesh, priority);
    00088             //pMesh->_registerMaterials();
    00089         }
    00090         return pMesh;
    00091
    00092     }
    00093     //-----------------------------------------------------------------------
    00094     Mesh* MeshManager::createManual( const String& name)
    00095     {
    00096         Mesh* pMesh = (Mesh*)(getByName(name));
    00097         if (!pMesh)
    00098         {
    00099             pMesh = (Mesh*)create(name);
    00100             pMesh->setManuallyDefined(true);
    00101             this->add(pMesh);
    00102         }
    00103
    00104         return pMesh;
    00105     }
    00106     //-----------------------------------------------------------------------
    00107     Mesh* MeshManager::createPlane( const String& name, const Plane& plane, Real width, Real height, int xsegments, int ysegments,
    00108         bool normals, int numTexCoordSets, Real xTile, Real yTile, const Vector3& upVector,
    00109         HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage,
    00110         bool vertexShadowBuffer, bool indexShadowBuffer)
    00111     {
    00112         int i;
    00113         Mesh* pMesh = createManual(name);
    00114         SubMesh *pSub = pMesh->createSubMesh();
    00115
    00116         // Set up vertex data
    00117         // Use a single shared buffer
    00118         pMesh->sharedVertexData = new VertexData();
    00119         VertexData* vertexData = pMesh->sharedVertexData;
    00120         // Set up Vertex Declaration
    00121         VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
    00122         size_t currOffset = 0;
    00123         // We always need positions
    00124         vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
    00125         currOffset += VertexElement::getTypeSize(VET_FLOAT3);
    00126         // Optional normals
    00127         if(normals)
    00128         {
    00129             vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
    00130             currOffset += VertexElement::getTypeSize(VET_FLOAT3);
    00131         }
    00132
    00133         for (i = 0; i < numTexCoordSets; ++i)
    00134         {
    00135             // Assumes 2D texture coords
    00136             vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
    00137             currOffset += VertexElement::getTypeSize(VET_FLOAT2);
    00138         }
    00139
    00140         vertexData->vertexCount = (xsegments + 1) * (ysegments + 1);
    00141
    00142         // Allocate vertex buffer
    00143         HardwareVertexBufferSharedPtr vbuf =
    00144             HardwareBufferManager::getSingleton().
    00145             createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
    00146             vertexBufferUsage, vertexShadowBuffer);
    00147
    00148         // Set up the binding (one source only)
    00149         VertexBufferBinding* binding = vertexData->vertexBufferBinding;
    00150         binding->setBinding(0, vbuf);
    00151
    00152         // Work out the transform required
    00153         // Default orientation of plane is normal along +z, distance 0
    00154         Matrix4 xlate, xform, rot;
    00155         Matrix3 rot3;
    00156         xlate = rot = Matrix4::IDENTITY;
    00157         // Determine axes
    00158         Vector3 zAxis, yAxis, xAxis;
    00159         zAxis = plane.normal;
    00160         zAxis.normalise();
    00161         yAxis = upVector;
    00162         yAxis.normalise();
    00163         xAxis = yAxis.crossProduct(zAxis);
    00164         if (xAxis.length() == 0)
    00165         {
    00166             //upVector must be wrong
    00167             Except(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
    00168                 "MeshManager::createPlane");
    00169         }
    00170
    00171         rot3.FromAxes(xAxis, yAxis, zAxis);
    00172         rot = rot3;
    00173
    00174         // Set up standard xform from origin
    00175         xlate.setTrans(plane.normal * -plane.d);
    00176
    00177         // concatenate
    00178         xform = xlate * rot;
    00179
    00180         // Generate vertex data
    00181         // Lock the whole buffer
    00182         Real* pReal = static_cast<Real*>(
    00183             vbuf->lock(HardwareBuffer::HBL_DISCARD) );
    00184         Real xSpace = width / xsegments;
    00185         Real ySpace = height / ysegments;
    00186         Real halfWidth = width / 2;
    00187         Real halfHeight = height / 2;
    00188         Real xTex = (1.0f * xTile) / xsegments;
    00189         Real yTex = (1.0f * yTile) / ysegments;
    00190         Vector3 vec;
    00191         Vector3 min, max;
    00192         Real maxSquaredLength;
    00193         bool firstTime = true;
    00194
    00195         for (int y = 0; y < ysegments + 1; ++y)
    00196         {
    00197             for (int x = 0; x < xsegments + 1; ++x)
    00198             {
    00199                 // Work out centered on origin
    00200                 vec.x = (x * xSpace) - halfWidth;
    00201                 vec.y = (y * ySpace) - halfHeight;
    00202                 vec.z = 0.0f;
    00203                 // Transform by orientation and distance
    00204                 vec = xform * vec;
    00205                 // Assign to geometry
    00206                 *pReal++ = vec.x;
    00207                 *pReal++ = vec.y;
    00208                 *pReal++ = vec.z;
    00209
    00210                 // Build bounds as we go
    00211                 if (firstTime)
    00212                 {
    00213                     min = vec;
    00214                     max = vec;
    00215                     maxSquaredLength = vec.squaredLength();
    00216                     firstTime = false;
    00217                 }
    00218                 else
    00219                 {
    00220                     min.makeFloor(vec);
    00221                     max.makeCeil(vec);
    00222                     maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
    00223                 }
    00224
    00225                 if (normals)
    00226                 {
    00227                     // Default normal is along unit Z
    00228                     vec = Vector3::UNIT_Z;
    00229                     // Rotate
    00230                     vec = rot * vec;
    00231
    00232                     *pReal++ = vec.x;
    00233                     *pReal++ = vec.y;
    00234                     *pReal++ = vec.z;
    00235                 }
    00236
    00237                 for (i = 0; i < numTexCoordSets; ++i)
    00238                 {
    00239                     *pReal++ = x * xTex;
    00240                     *pReal++ = 1 - (y * yTex);
    00241                 }
    00242
    00243
    00244             } // x
    00245         } // y
    00246
    00247         // Unlock
    00248         vbuf->unlock();
    00249         // Generate face list
    00250         pSub->useSharedVertices = true;
    00251         tesselate2DMesh(pSub, xsegments + 1, ysegments + 1, false, indexBufferUsage, indexShadowBuffer);
    00252
    00253         //pMesh->_updateBounds();
    00254         pMesh->_setBounds(AxisAlignedBox(min, max), true);
    00255         pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
    00256         // load
    00257         pMesh->load();
    00258         pMesh->touch();
    00259         return pMesh;
    00260     }
    00261
    00262     //-----------------------------------------------------------------------
    00263     Mesh* MeshManager::createCurvedPlane( const String& name, const Plane& plane, Real width, Real height, Real bow, int xsegments, int ysegments,
    00264         bool normals, int numTexCoordSets, Real xTile, Real yTile, const Vector3& upVector,
    00265             HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage,
    00266             bool vertexShadowBuffer, bool indexShadowBuffer)
    00267     {
    00268         int i;
    00269         Mesh* pMesh = createManual(name);
    00270         SubMesh *pSub = pMesh->createSubMesh();
    00271
    00272         // Set options
    00273         pMesh->sharedVertexData = new VertexData();
    00274         pMesh->sharedVertexData->vertexStart = 0;
    00275         VertexBufferBinding* bind = pMesh->sharedVertexData->vertexBufferBinding;
    00276         VertexDeclaration* decl = pMesh->sharedVertexData->vertexDeclaration;
    00277
    00278         pMesh->sharedVertexData->vertexCount = (xsegments + 1) * (ysegments + 1);
    00279
    00280         size_t offset = 0;
    00281         decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    00282         offset += VertexElement::getTypeSize(VET_FLOAT3);
    00283         if (normals)
    00284         {
    00285             decl->addElement(0, 0, VET_FLOAT3, VES_NORMAL);
    00286             offset += VertexElement::getTypeSize(VET_FLOAT3);
    00287         }
    00288
    00289         for (i = 0; i < numTexCoordSets; ++i)
    00290         {
    00291             decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
    00292             offset += VertexElement::getTypeSize(VET_FLOAT2);
    00293         }
    00294
    00295
    00296         // Allocate memory
    00297         HardwareVertexBufferSharedPtr vbuf =
    00298             HardwareBufferManager::getSingleton().createVertexBuffer(
    00299                 offset,
    00300                 pMesh->sharedVertexData->vertexCount,
    00301                 vertexBufferUsage,
    00302                 vertexShadowBuffer);
    00303         bind->setBinding(0, vbuf);
    00304
    00305         // Work out the transform required
    00306         // Default orientation of plane is normal along +z, distance 0
    00307         Matrix4 xlate, xform, rot;
    00308         Matrix3 rot3;
    00309         xlate = rot = Matrix4::IDENTITY;
    00310         // Determine axes
    00311         Vector3 zAxis, yAxis, xAxis;
    00312         zAxis = plane.normal;
    00313         zAxis.normalise();
    00314         yAxis = upVector;
    00315         yAxis.normalise();
    00316         xAxis = yAxis.crossProduct(zAxis);
    00317         if (xAxis.length() == 0)
    00318         {
    00319             //upVector must be wrong
    00320             Except(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
    00321                 "MeshManager::createPlane");
    00322         }
    00323
    00324         rot3.FromAxes(xAxis, yAxis, zAxis);
    00325         rot = rot3;
    00326
    00327         // Set up standard xform from origin
    00328         xlate.setTrans(plane.normal * -plane.d);
    00329
    00330         // concatenate
    00331         xform = xlate * rot;
    00332
    00333         // Generate vertex data
    00334         Real* pReal = static_cast<Real*>(
    00335             vbuf->lock(HardwareBuffer::HBL_DISCARD));
    00336         Real xSpace = width / xsegments;
    00337         Real ySpace = height / ysegments;
    00338         Real halfWidth = width / 2;
    00339         Real halfHeight = height / 2;
    00340         Real xTex = (1.0f * xTile) / xsegments;
    00341         Real yTex = (1.0f * yTile) / ysegments;
    00342         Vector3 vec;
    00343
    00344         Vector3 min, max;
    00345         Real maxSqLen;
    00346         bool first = true;
    00347
    00348         Real diff_x, diff_y, dist;
    00349
    00350         for (int y = 0; y < ysegments + 1; ++y)
    00351         {
    00352             for (int x = 0; x < xsegments + 1; ++x)
    00353             {
    00354                 // Work out centered on origin
    00355                 vec.x = (x * xSpace) - halfWidth;
    00356                 vec.y = (y * ySpace) - halfHeight;
    00357
    00358                 // Here's where curved plane is different from standard plane.  Amazing, I know.
    00359                 diff_x = (x - ((xsegments) / 2)) / static_cast<Real>((xsegments));
    00360                 diff_y = (y - ((ysegments) / 2)) / static_cast<Real>((ysegments));
    00361                 dist = sqrt(diff_x*diff_x + diff_y * diff_y );
    00362                 vec.z = (-sin((1-dist) * (PI/2)) * bow) + bow;
    00363
    00364                 // Transform by orientation and distance
    00365                 vec = xform * vec;
    00366                 // Assign to geometry
    00367                 *pReal++ = vec.x;
    00368                 *pReal++ = vec.y;
    00369                 *pReal++ = vec.z;
    00370
    00371                 // Record bounds
    00372                 if (first)
    00373                 {
    00374                     min = max = vec;
    00375                     maxSqLen = vec.squaredLength();
    00376                     first = false;
    00377                 }
    00378                 else
    00379                 {
    00380                     min.makeFloor(vec);
    00381                     max.makeCeil(vec);
    00382                     maxSqLen = std::max(maxSqLen, vec.squaredLength());
    00383                 }
    00384
    00385                 if (normals)
    00386                 {
    00387                     // This part is kinda 'wrong' for curved planes... but curved planes are
    00388                     //   very valuable outside sky planes, which don't typically need normals
    00389                     //   so I'm not going to mess with it for now.
    00390
    00391                     // Default normal is along unit Z
    00392                     vec = Vector3::UNIT_Z;
    00393                     // Rotate
    00394                     vec = rot * vec;
    00395
    00396                     *pReal++ = vec.x;
    00397                     *pReal++ = vec.y;
    00398                     *pReal++ = vec.z;
    00399                 }
    00400
    00401                 for (i = 0; i < numTexCoordSets; ++i)
    00402                 {
    00403                     *pReal++ = x * xTex;
    00404                     *pReal++ = 1 - (y * yTex);
    00405                 }
    00406
    00407             } // x
    00408         } // y
    00409         vbuf->unlock();
    00410
    00411         // Generate face list
    00412         tesselate2DMesh(pSub, xsegments + 1, ysegments + 1,
    00413             false, indexBufferUsage, indexShadowBuffer);
    00414
    00415         pMesh->_setBounds(AxisAlignedBox(min, max), true);
    00416         pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSqLen));
    00417
    00418         pMesh->load();
    00419         pMesh->touch();
    00420         return pMesh;
    00421     }
    00422     //-----------------------------------------------------------------------
    00423     Mesh* MeshManager::createCurvedIllusionPlane(
    00424         const String& name, const Plane& plane,
    00425         Real width, Real height, Real curvature,
    00426         int xsegments, int ysegments,
    00427         bool normals, int numTexCoordSets,
    00428         Real uTile, Real vTile, const Vector3& upVector,
    00429         const Quaternion& orientation,
    00430         HardwareBuffer::Usage vertexBufferUsage,
    00431         HardwareBuffer::Usage indexBufferUsage,
    00432         bool vertexShadowBuffer, bool indexShadowBuffer,
    00433         int ySegmentsToKeep)
    00434     {
    00435         int i;
    00436         Mesh* pMesh = createManual(name);
    00437         SubMesh *pSub = pMesh->createSubMesh();
    00438
    00439         if (ySegmentsToKeep == -1) ySegmentsToKeep = ysegments;
    00440
    00441         // Set up vertex data
    00442         // Use a single shared buffer
    00443         pMesh->sharedVertexData = new VertexData();
    00444         VertexData* vertexData = pMesh->sharedVertexData;
    00445         // Set up Vertex Declaration
    00446         VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
    00447         size_t currOffset = 0;
    00448         // We always need positions
    00449         vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
    00450         currOffset += VertexElement::getTypeSize(VET_FLOAT3);
    00451         // Optional normals
    00452         if(normals)
    00453         {
    00454             vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
    00455             currOffset += VertexElement::getTypeSize(VET_FLOAT3);
    00456         }
    00457
    00458         for (i = 0; i < numTexCoordSets; ++i)
    00459         {
    00460             // Assumes 2D texture coords
    00461             vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
    00462             currOffset += VertexElement::getTypeSize(VET_FLOAT2);
    00463         }
    00464
    00465         vertexData->vertexCount = (xsegments + 1) * (ySegmentsToKeep + 1);
    00466
    00467         // Allocate vertex buffer
    00468         HardwareVertexBufferSharedPtr vbuf =
    00469             HardwareBufferManager::getSingleton().
    00470             createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
    00471             vertexBufferUsage, vertexShadowBuffer);
    00472
    00473         // Set up the binding (one source only)
    00474         VertexBufferBinding* binding = vertexData->vertexBufferBinding;
    00475         binding->setBinding(0, vbuf);
    00476
    00477         // Work out the transform required
    00478         // Default orientation of plane is normal along +z, distance 0
    00479         Matrix4 xlate, xform, rot;
    00480         Matrix3 rot3;
    00481         xlate = rot = Matrix4::IDENTITY;
    00482         // Determine axes
    00483         Vector3 zAxis, yAxis, xAxis;
    00484         zAxis = plane.normal;
    00485         zAxis.normalise();
    00486         yAxis = upVector;
    00487         yAxis.normalise();
    00488         xAxis = yAxis.crossProduct(zAxis);
    00489         if (xAxis.length() == 0)
    00490         {
    00491             //upVector must be wrong
    00492             Except(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
    00493                 "MeshManager::createPlane");
    00494         }
    00495
    00496         rot3.FromAxes(xAxis, yAxis, zAxis);
    00497         rot = rot3;
    00498
    00499         // Set up standard xform from origin
    00500         xlate.setTrans(plane.normal * -plane.d);
    00501
    00502         // concatenate
    00503         xform = xlate * rot;
    00504
    00505         // Generate vertex data
    00506         // Imagine a large sphere with the camera located near the top
    00507         // The lower the curvature, the larger the sphere
    00508         // Use the angle from viewer to the points on the plane
    00509         // Credit to Aftershock for the general approach
    00510         Real camPos;      // Camera position relative to sphere center
    00511
    00512         // Derive sphere radius
    00513         Vector3 vertPos;  // position relative to camera
    00514         Real sphDist;      // Distance from camera to sphere along box vertex vector
    00515         // Vector3 camToSph; // camera position to sphere
    00516         Real sphereRadius;// Sphere radius
    00517         // Actual values irrelevant, it's the relation between sphere radius and camera position that's important
    00518         const Real SPHERE_RAD = 100.0;
    00519         const Real CAM_DIST = 5.0;
    00520
    00521         sphereRadius = SPHERE_RAD - curvature;
    00522         camPos = sphereRadius - CAM_DIST;
    00523
    00524         // Lock the whole buffer
    00525         Real* pReal = static_cast<Real*>(
    00526             vbuf->lock(HardwareBuffer::HBL_DISCARD) );
    00527         Real xSpace = width / xsegments;
    00528         Real ySpace = height / ysegments;
    00529         Real halfWidth = width / 2;
    00530         Real halfHeight = height / 2;
    00531         Vector3 vec, norm;
    00532         Vector3 min, max;
    00533         Real maxSquaredLength;
    00534         bool firstTime = true;
    00535
    00536         for (int y = ysegments - ySegmentsToKeep; y < ysegments + 1; ++y)
    00537         {
    00538             for (int x = 0; x < xsegments + 1; ++x)
    00539             {
    00540                 // Work out centered on origin
    00541                 vec.x = (x * xSpace) - halfWidth;
    00542                 vec.y = (y * ySpace) - halfHeight;
    00543                 vec.z = 0.0f;
    00544                 // Transform by orientation and distance
    00545                 vec = xform * vec;
    00546                 // Assign to geometry
    00547                 *pReal++ = vec.x;
    00548                 *pReal++ = vec.y;
    00549                 *pReal++ = vec.z;
    00550
    00551                 // Build bounds as we go
    00552                 if (firstTime)
    00553                 {
    00554                     min = vec;
    00555                     max = vec;
    00556                     maxSquaredLength = vec.squaredLength();
    00557                     firstTime = false;
    00558                 }
    00559                 else
    00560                 {
    00561                     min.makeFloor(vec);
    00562                     max.makeCeil(vec);
    00563                     maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
    00564                 }
    00565
    00566                 if (normals)
    00567                 {
    00568                     // Default normal is along unit Z
    00569                     norm = Vector3::UNIT_Z;
    00570                     // Rotate
    00571                     norm = orientation * norm;
    00572
    00573                     *pReal++ = norm.x;
    00574                     *pReal++ = norm.y;
    00575                     *pReal++ = norm.z;
    00576                 }
    00577
    00578                 // Generate texture coords
    00579                 // Normalise position
    00580                 // modify by orientation to return +y up
    00581                 vec = orientation.Inverse() * vec;
    00582                 vec.normalise();
    00583                 // Find distance to sphere
    00584                 sphDist = Math::Sqrt(camPos*camPos * (vec.y*vec.y-1.0) + sphereRadius*sphereRadius) - camPos*vec.y;
    00585
    00586                 vec.x *= sphDist;
    00587                 vec.z *= sphDist;
    00588
    00589                 // Use x and y on sphere as texture coordinates, tiled
    00590                 Real s = vec.x * (0.01 * uTile);
    00591                 Real t = 1 - (vec.z * (0.01 * vTile));
    00592                 for (i = 0; i < numTexCoordSets; ++i)
    00593                 {
    00594                     *pReal++ = s;
    00595                     *pReal++ = t;
    00596                 }
    00597
    00598
    00599             } // x
    00600         } // y
    00601
    00602         // Unlock
    00603         vbuf->unlock();
    00604         // Generate face list
    00605         pSub->useSharedVertices = true;
    00606         tesselate2DMesh(pSub, xsegments + 1, ySegmentsToKeep + 1, false,
    00607             indexBufferUsage, indexShadowBuffer);
    00608
    00609         //pMesh->_updateBounds();
    00610         pMesh->_setBounds(AxisAlignedBox(min, max), true);
    00611         pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
    00612         pMesh->load();
    00613         pMesh->touch();
    00614
    00615         return pMesh;
    00616     }
    00617
    00618     //-----------------------------------------------------------------------
    00619     void MeshManager::tesselate2DMesh(SubMesh* sm, int meshWidth, int meshHeight,
    00620         bool doubleSided, HardwareBuffer::Usage indexBufferUsage, bool indexShadowBuffer)
    00621     {
    00622         // The mesh is built, just make a list of indexes to spit out the triangles
    00623         int vInc, uInc, v, u, iterations;
    00624         int vCount, uCount;
    00625
    00626         if (doubleSided)
    00627         {
    00628             iterations = 2;
    00629             vInc = 1;
    00630             v = 0; // Start with front
    00631         }
    00632         else
    00633         {
    00634             iterations = 1;
    00635             vInc = 1;
    00636             v = 0;
    00637         }
    00638
    00639         // Allocate memory for faces
    00640         // Num faces, width*height*2 (2 tris per square), index count is * 3 on top
    00641         sm->indexData->indexCount = (meshWidth-1) * (meshHeight-1) * 2 * iterations * 3;
    00642         sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().
    00643             createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
    00644             sm->indexData->indexCount, indexBufferUsage, indexShadowBuffer);
    00645
    00646         int v1, v2, v3;
    00647         //bool firstTri = true;
    00648         HardwareIndexBufferSharedPtr ibuf = sm->indexData->indexBuffer;
    00649         // Lock the whole buffer
    00650         unsigned short* pIndexes = static_cast<unsigned short*>(
    00651             ibuf->lock(HardwareBuffer::HBL_DISCARD) );
    00652
    00653         while (iterations--)
    00654         {
    00655             // Make tris in a zigzag pattern (compatible with strips)
    00656             u = 0;
    00657             uInc = 1; // Start with moving +u
    00658
    00659             vCount = meshHeight - 1;
    00660             while (vCount--)
    00661             {
    00662                 uCount = meshWidth - 1;
    00663                 while (uCount--)
    00664                 {
    00665                     // First Tri in cell
    00666                     // -----------------
    00667                     v1 = ((v + vInc) * meshWidth) + u;
    00668                     v2 = (v * meshWidth) + u;
    00669                     v3 = ((v + vInc) * meshWidth) + (u + uInc);
    00670                     // Output indexes
    00671                     *pIndexes++ = v1;
    00672                     *pIndexes++ = v2;
    00673                     *pIndexes++ = v3;
    00674                     // Second Tri in cell
    00675                     // ------------------
    00676                     v1 = ((v + vInc) * meshWidth) + (u + uInc);
    00677                     v2 = (v * meshWidth) + u;
    00678                     v3 = (v * meshWidth) + (u + uInc);
    00679                     // Output indexes
    00680                     *pIndexes++ = v1;
    00681                     *pIndexes++ = v2;
    00682                     *pIndexes++ = v3;
    00683
    00684                     // Next column
    00685                     u += uInc;
    00686                 }
    00687                 // Next row
    00688                 v += vInc;
    00689                 u = 0;
    00690
    00691
    00692             }
    00693
    00694             // Reverse vInc for double sided
    00695             v = meshHeight - 1;
    00696             vInc = -vInc;
    00697
    00698         }
    00699         // Unlock
    00700         ibuf->unlock();
    00701
    00702     }
    00703
    00704     //-----------------------------------------------------------------------
    00705     void MeshManager::createPrefabPlane(void)
    00706     {
    00707         Mesh* msh = (Mesh*)create("Prefab_Plane");
    00708         SubMesh* sub = msh->createSubMesh();
    00709         Real vertices[32] = {
    00710             -100, -100, 0,  // pos
    00711             0,0,1,          // normal
    00712             0,1,            // texcoord
    00713             100, -100, 0,
    00714             0,0,1,
    00715             1,1,
    00716             100,  100, 0,
    00717             0,0,1,
    00718             1,0,
    00719             -100,  100, 0 ,
    00720             0,0,1,
    00721             0,0
    00722         };
    00723         msh->sharedVertexData = new VertexData();
    00724         msh->sharedVertexData->vertexCount = 4;
    00725         VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    00726         VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
    00727
    00728         size_t offset = 0;
    00729         decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    00730         offset += VertexElement::getTypeSize(VET_FLOAT3);
    00731         decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    00732         offset += VertexElement::getTypeSize(VET_FLOAT3);
    00733         decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    00734         offset += VertexElement::getTypeSize(VET_FLOAT2);
    00735
    00736         HardwareVertexBufferSharedPtr vbuf =
    00737             HardwareBufferManager::getSingleton().createVertexBuffer(
    00738                 offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    00739         bind->setBinding(0, vbuf);
    00740
    00741         vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
    00742
    00743         sub->useSharedVertices = true;
    00744         HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
    00745             createIndexBuffer(
    00746                 HardwareIndexBuffer::IT_16BIT,
    00747                 6,
    00748                 HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    00749
    00750         unsigned short faces[6] = {0,1,2,
    00751                                    0,2,3 };
    00752         sub->indexData->indexBuffer = ibuf;
    00753         sub->indexData->indexCount = 6;
    00754         sub->indexData->indexStart =0;
    00755         ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
    00756
    00757         msh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true);
    00758         msh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100));
    00759
    00760         mResources[msh->getName()] = msh;
    00761     }
    00762     //-----------------------------------------------------------------------
    00763     PatchMesh* MeshManager::createBezierPatch(const String& name,
    00764             void* controlPointBuffer, VertexDeclaration *declaration,
    00765             size_t width, size_t height,
    00766             size_t uMaxSubdivisionLevel, size_t vMaxSubdivisionLevel,
    00767             PatchSurface::VisibleSide visibleSide,
    00768             HardwareBuffer::Usage vbUsage, HardwareBuffer::Usage ibUsage,
    00769             bool vbUseShadow, bool ibUseShadow)
    00770     {
    00771
    00772         PatchMesh* pMesh = (PatchMesh*)(getByName(name));
    00773         if (pMesh)
    00774         {
    00775             Except(Exception::ERR_DUPLICATE_ITEM, "A mesh called " + name +
    00776                 " already exists!", "MeshManager::createBezierPatch");
    00777         }
    00778         pMesh = new PatchMesh(name, controlPointBuffer, declaration, width, height,
    00779             uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide, vbUsage, ibUsage,
    00780             vbUseShadow, ibUseShadow);
    00781         pMesh->setManuallyDefined(true);
    00782         ResourceManager::load(pMesh,0);
    00783
    00784         return pMesh;
    00785     }
    00786     //-----------------------------------------------------------------------
    00787     void MeshManager::setPrepareAllMeshesForShadowVolumes(bool enable)
    00788     {
    00789         mPrepAllMeshesForShadowVolumes = enable;
    00790     }
    00791     //-----------------------------------------------------------------------
    00792     bool MeshManager::getPrepareAllMeshesForShadowVolumes(void)
    00793     {
    00794         return mPrepAllMeshesForShadowVolumes;
    00795     }
    00796     //-----------------------------------------------------------------------
    00797     Real MeshManager::getBoundsPaddingFactor(void)
    00798     {
    00799         return mBoundsPaddingFactor;
    00800     }
    00801     //-----------------------------------------------------------------------
    00802     void MeshManager::setBoundsPaddingFactor(Real paddingFactor)
    00803     {
    00804         mBoundsPaddingFactor = paddingFactor;
    00805     }
    00806     //-----------------------------------------------------------------------
    00807
    00808
    00809 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:35 2004