00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "SO3BaseMeshsTools.h"
00029
00030 namespace SO3
00031 {
00032
00033 SBaseMeshsTools::SBaseMeshsTools()
00034 {
00035
00036 }
00037
00038 void SBaseMeshsTools::CreateSphere(const Ogre::String& strName, float radius, int nRings, int nSegments, bool bNormals, bool bTexCoords, Ogre::String groupName)
00039 {
00040 Ogre::MeshPtr pSphere = Ogre::MeshManager::getSingleton().createManual(strName, groupName);
00041 Ogre::SubMesh* pSphereVertex = pSphere->createSubMesh();
00042 pSphere->sharedVertexData = new Ogre::VertexData();
00043 CreateSphere(pSphere->sharedVertexData, pSphereVertex->indexData, radius, nRings, nSegments, bNormals, bTexCoords);
00044
00045
00046 pSphereVertex->useSharedVertices = true;
00047 pSphere->_setBounds(Ogre::AxisAlignedBox(Ogre::Vector3(-radius, -radius, -radius), Ogre::Vector3(radius, radius, radius)), false);
00048 pSphere->_setBoundingSphereRadius(radius);
00049
00050
00051 pSphere->load();
00052 }
00053
00054 void SBaseMeshsTools::CreateSphere(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData, float radius, int nRings, int nSegments, bool bNormals, bool bTexCoords)
00055 {
00056 assert(vertexData && indexData);
00057
00058
00059 Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
00060 size_t currOffset = 0;
00061
00062
00063 vertexDecl->addElement(0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00064 currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
00065
00066
00067 if (bNormals)
00068 {
00069 vertexDecl->addElement(0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
00070 currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
00071 }
00072
00073
00074 if (bTexCoords)
00075 {
00076 vertexDecl->addElement(0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
00077 currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
00078 }
00079
00080
00081 vertexData->vertexCount = (nRings+1) * (nSegments+1);
00082 Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
00083 Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
00084 binding->setBinding(0, vBuf);
00085 float* pVertex = static_cast<float*>(vBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
00086
00087
00088 indexData->indexCount = 6 * nRings * (nSegments+1);
00089 indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
00090 Ogre::HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
00091 unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
00092
00093 float fDeltaRingAngle = (Ogre::Math::PI / nRings);
00094 float fDeltaSegAngle = (2 * Ogre::Math::PI / nSegments);
00095 unsigned short wVerticeIndex = 0 ;
00096
00097
00098 for(int ring = 0; ring <= nRings; ring++)
00099 {
00100 float r0 = radius * sinf (ring * fDeltaRingAngle);
00101 float y0 = radius * cosf (ring * fDeltaRingAngle);
00102
00103
00104 for(int seg = 0; seg <= nSegments; seg++)
00105 {
00106 float x0 = r0 * sinf(seg * fDeltaSegAngle);
00107 float z0 = r0 * cosf(seg * fDeltaSegAngle);
00108
00109
00110 *pVertex++ = x0;
00111 *pVertex++ = y0;
00112 *pVertex++ = z0;
00113
00114 if (bNormals)
00115 {
00116 Ogre::Vector3 vNormal = Ogre::Vector3(x0, y0, z0).normalisedCopy();
00117 *pVertex++ = vNormal.x;
00118 *pVertex++ = vNormal.y;
00119 *pVertex++ = vNormal.z;
00120 }
00121
00122 if (bTexCoords)
00123 {
00124 *pVertex++ = (float) seg / (float) nSegments;
00125 *pVertex++ = (float) ring / (float) nRings;
00126 }
00127
00128 if (ring != nRings)
00129 {
00130
00131 *pIndices++ = wVerticeIndex + nSegments + 1;
00132 *pIndices++ = wVerticeIndex;
00133 *pIndices++ = wVerticeIndex + nSegments;
00134 *pIndices++ = wVerticeIndex + nSegments + 1;
00135 *pIndices++ = wVerticeIndex + 1;
00136 *pIndices++ = wVerticeIndex;
00137 wVerticeIndex ++;
00138 }
00139 }
00140 }
00141
00142
00143 vBuf->unlock();
00144 iBuf->unlock();
00145 }
00146
00147 void SBaseMeshsTools::CreateCone(const Ogre::String& strName , float radius , float height, int nVerticesInBase, Ogre::String groupName)
00148 {
00149 Ogre::MeshPtr pCone = Ogre::MeshManager::getSingleton().createManual(strName, groupName);
00150 Ogre::SubMesh *pConeVertex = pCone->createSubMesh();
00151 pCone->sharedVertexData = new Ogre::VertexData();
00152
00153 CreateCone(pCone->sharedVertexData, pConeVertex->indexData, radius, height, nVerticesInBase);
00154
00155
00156 pConeVertex->useSharedVertices = true;
00157 pCone->_setBounds(Ogre::AxisAlignedBox(Ogre::Vector3(-radius, 0, -radius), Ogre::Vector3(radius, height, radius)), false);
00158 pCone->_setBoundingSphereRadius(Ogre::Math::Sqrt(height*height + radius*radius));
00159
00160
00161 pCone->load();
00162 }
00163
00164 void SBaseMeshsTools::CreateCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData, float radius , float height, int nVerticesInBase)
00165 {
00166 assert(vertexData && indexData);
00167
00168
00169 Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
00170
00171
00172 vertexDecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00173
00174
00175 vertexData->vertexCount = nVerticesInBase + 1;
00176 Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
00177 Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
00178 binding->setBinding(0, vBuf);
00179 float* pVertex = static_cast<float*>(vBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
00180
00181
00182 indexData->indexCount = (3 * nVerticesInBase) + (3 * (nVerticesInBase - 2));
00183 indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
00184 Ogre::HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
00185 unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
00186
00187
00188 for (int i=0; i<3; i++)
00189 *pVertex++ = 0.0f;
00190
00191
00192 float fDeltaBaseAngle = (2 * Ogre::Math::PI) / nVerticesInBase;
00193 for (int i=0; i<nVerticesInBase; i++)
00194 {
00195 float angle = i * fDeltaBaseAngle;
00196 *pVertex++ = radius * cosf(angle);
00197 *pVertex++ = height;
00198 *pVertex++ = radius * sinf(angle);
00199 }
00200
00201
00202
00203 for (int i=0; i<nVerticesInBase; i++)
00204 {
00205 *pIndices++ = 0;
00206 *pIndices++ = (i%nVerticesInBase) + 1;
00207 *pIndices++ = ((i+1)%nVerticesInBase) + 1;
00208 }
00209
00210
00211 for (int i=0; i<nVerticesInBase-2; i++)
00212 {
00213 *pIndices++ = 1;
00214 *pIndices++ = i + 3;
00215 *pIndices++ = i + 2;
00216 }
00217
00218
00219 vBuf->unlock();
00220 iBuf->unlock();
00221 }
00222
00223 void SBaseMeshsTools::CreateOctahedron(const Ogre::String& strName, float baseLength, float bottomDistance, float upDistance, Ogre::String groupName)
00224 {
00225 assert(baseLength > 0);
00226 assert(bottomDistance > 0);
00227 assert(upDistance > 0);
00228
00229 Ogre::MeshPtr pOctahedron = Ogre::MeshManager::getSingleton().createManual(strName, groupName);
00230 Ogre::SubMesh *pOctahedronVertex = pOctahedron->createSubMesh();
00231 pOctahedron->sharedVertexData = new Ogre::VertexData();
00232
00233 CreateOctahedron(pOctahedron->sharedVertexData, pOctahedronVertex->indexData, baseLength, bottomDistance, upDistance);
00234
00235
00236 pOctahedronVertex->useSharedVertices = true;
00237 float totalLength = bottomDistance + upDistance;
00238 pOctahedron->_setBounds(Ogre::AxisAlignedBox(Ogre::Vector3(-baseLength/2, 0, -baseLength/2), Ogre::Vector3(baseLength/2, upDistance, baseLength/2)), false);
00239
00240 pOctahedron->_setBoundingSphereRadius(Ogre::Math::Sqrt(totalLength*totalLength + (baseLength/2)*(baseLength/2)));
00241
00242
00243 pOctahedron->load();
00244 }
00245
00246 void SBaseMeshsTools::CreateOctahedron(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData, float baseLength, float bottomDistance, float upDistance)
00247 {
00248 assert(vertexData && indexData);
00249
00250
00251 Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
00252 vertexDecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00253
00254
00255 vertexData->vertexCount = 6;
00256 Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), 6, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
00257 Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
00258 binding->setBinding(0, vBuf);
00259 float* pVertex = static_cast<float*>(vBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
00260
00261
00262 indexData->indexCount = 3 * 6;
00263 indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, 24, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
00264 Ogre::HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
00265 unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
00266
00267
00268 for (int i=0; i<3; i++)
00269 *pVertex++ = 0.0f;
00270
00271
00272 float baseOffset = baseLength / 2.0f;
00273 *pVertex++ = baseOffset; *pVertex++ = bottomDistance; *pVertex++ = baseOffset;
00274 *pVertex++ = baseOffset; *pVertex++ = bottomDistance; *pVertex++ = -baseOffset;
00275 *pVertex++ = -baseOffset; *pVertex++ = bottomDistance; *pVertex++ = -baseOffset;
00276 *pVertex++ = -baseOffset; *pVertex++ = bottomDistance; *pVertex++ = baseOffset;
00277
00278
00279 *pVertex++ = 0;
00280 *pVertex++ = upDistance;
00281 *pVertex++ = 0;
00282
00283
00284
00285 for (int i=0; i<4; i++)
00286 {
00287 *pIndices++ = 0;
00288 *pIndices++ = (i%4) + 1;
00289 *pIndices++ = ((i+1)%4) + 1;
00290 }
00291
00292
00293 for (int i=0; i<4; i++)
00294 {
00295 *pIndices++ = 5;
00296 *pIndices++ = (i%4) + 1;
00297 *pIndices++ = ((i+1)%4) + 1;
00298 }
00299
00300
00301 vBuf->unlock();
00302 iBuf->unlock();
00303 }
00304
00305 void SBaseMeshsTools::CreateQuad(Ogre::VertexData*& vertexData)
00306 {
00307 assert(vertexData);
00308
00309 vertexData->vertexCount = 4;
00310 vertexData->vertexStart = 0;
00311
00312 Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
00313 Ogre::VertexBufferBinding* bind = vertexData->vertexBufferBinding;
00314
00315 vertexDecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00316 Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
00317
00318
00319 bind->setBinding(0, vbuf);
00320
00321
00322 float data[]=
00323 {
00324 -1,1,-1,
00325 -1,-1,-1,
00326 1,1,-1,
00327 1,-1,-1
00328 };
00329 vbuf->writeData(0, sizeof(data), data, true);
00330 }
00331
00332 }