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