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 | }
|
---|