[692] | 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 | Real* pVertex = static_cast<Real*>(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 | }
|
---|