[1] | 1 | /// From the WIKI -- tesselate a sphere |
---|
| 2 | void createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16) |
---|
| 3 | { |
---|
| 4 | MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); |
---|
| 5 | SubMesh *pSphereVertex = pSphere->createSubMesh(); |
---|
| 6 | |
---|
| 7 | pSphere->sharedVertexData = new VertexData(); |
---|
| 8 | VertexData* vertexData = pSphere->sharedVertexData; |
---|
| 9 | |
---|
| 10 | // define the vertex format |
---|
| 11 | VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; |
---|
| 12 | size_t currOffset = 0; |
---|
| 13 | // positions |
---|
| 14 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); |
---|
| 15 | currOffset += VertexElement::getTypeSize(VET_FLOAT3); |
---|
| 16 | // normals |
---|
| 17 | vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); |
---|
| 18 | currOffset += VertexElement::getTypeSize(VET_FLOAT3); |
---|
| 19 | // two dimensional texture coordinates |
---|
| 20 | vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); |
---|
| 21 | currOffset += VertexElement::getTypeSize(VET_FLOAT2); |
---|
| 22 | |
---|
| 23 | // allocate the vertex buffer |
---|
| 24 | vertexData->vertexCount = (nRings + 1) * (nSegments+1); |
---|
| 25 | HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); |
---|
| 26 | VertexBufferBinding* binding = vertexData->vertexBufferBinding; |
---|
| 27 | binding->setBinding(0, vBuf); |
---|
| 28 | float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD)); |
---|
| 29 | |
---|
| 30 | // allocate index buffer |
---|
| 31 | pSphereVertex->indexData->indexCount = 6 * nRings * (nSegments + 1); |
---|
| 32 | pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); |
---|
| 33 | HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer; |
---|
| 34 | unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD)); |
---|
| 35 | |
---|
| 36 | float fDeltaRingAngle = (Math::PI / nRings); |
---|
| 37 | float fDeltaSegAngle = (2 * Math::PI / nSegments); |
---|
| 38 | unsigned short wVerticeIndex = 0 ; |
---|
| 39 | |
---|
| 40 | // Generate the group of rings for the sphere |
---|
| 41 | for( int ring = 0; ring <= nRings; ring++ ) { |
---|
| 42 | float r0 = r * sinf (ring * fDeltaRingAngle); |
---|
| 43 | float y0 = r * cosf (ring * fDeltaRingAngle); |
---|
| 44 | |
---|
| 45 | // Generate the group of segments for the current ring |
---|
| 46 | for(int seg = 0; seg <= nSegments; seg++) { |
---|
| 47 | float x0 = r0 * sinf(seg * fDeltaSegAngle); |
---|
| 48 | float z0 = r0 * cosf(seg * fDeltaSegAngle); |
---|
| 49 | |
---|
| 50 | // Add one vertex to the strip which makes up the sphere |
---|
| 51 | *pVertex++ = x0; |
---|
| 52 | *pVertex++ = y0; |
---|
| 53 | *pVertex++ = z0; |
---|
| 54 | |
---|
| 55 | Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); |
---|
| 56 | *pVertex++ = vNormal.x; |
---|
| 57 | *pVertex++ = vNormal.y; |
---|
| 58 | *pVertex++ = vNormal.z; |
---|
| 59 | |
---|
| 60 | *pVertex++ = (float) seg / (float) nSegments; |
---|
| 61 | *pVertex++ = (float) ring / (float) nRings; |
---|
| 62 | |
---|
| 63 | if (ring != nRings) { |
---|
| 64 | // each vertex (except the last) has six indicies pointing to it |
---|
| 65 | *pIndices++ = wVerticeIndex + nSegments + 1; |
---|
| 66 | *pIndices++ = wVerticeIndex; |
---|
| 67 | *pIndices++ = wVerticeIndex + nSegments; |
---|
| 68 | *pIndices++ = wVerticeIndex + nSegments + 1; |
---|
| 69 | *pIndices++ = wVerticeIndex + 1; |
---|
| 70 | *pIndices++ = wVerticeIndex; |
---|
| 71 | wVerticeIndex ++; |
---|
| 72 | } |
---|
| 73 | }; // end for seg |
---|
| 74 | } // end for ring |
---|
| 75 | |
---|
| 76 | // Unlock |
---|
| 77 | vBuf->unlock(); |
---|
| 78 | iBuf->unlock(); |
---|
| 79 | // Generate face list |
---|
| 80 | pSphereVertex->useSharedVertices = true; |
---|
| 81 | |
---|
| 82 | // the original code was missing this line: |
---|
| 83 | pSphere->_setBounds( AxisAlignedBox( Vector3(-r, -r, -r), Vector3(r, r, r) ), false ); |
---|
| 84 | pSphere->_setBoundingSphereRadius(r); |
---|
| 85 | // this line makes clear the mesh is loaded (avoids memory leakes) |
---|
| 86 | pSphere->load(); |
---|
| 87 | } |
---|