Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutorial6/src/libraries/tools/IcoSphere.cc @ 12389

Last change on this file since 12389 was 11099, checked in by muemart, 9 years ago

Fix loads of doxygen warnings and other documentation issues

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1/**
2 * @file IcoSphere.cc
3 * Copy-pasted from
4 *  - https://bitbucket.org/hasyimi/ogre-debug-drawing-utility/src
5 *  - http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Debug+Drawing+Utility+Class
6 *
7 * This source code is released into the Public Domain.
8 *
9 * Modified by Fabian 'x3n' Landau
10 */
11
12#include "IcoSphere.h"
13
14#include <OgreSceneManager.h>
15#include <OgreRenderQueue.h>
16#include <OgreManualObject.h>
17#include <OgreAxisAlignedBox.h>
18
19namespace orxonox
20{
21    IcoSphere::IcoSphere() :
22            index(0)
23    {
24    }
25
26    IcoSphere::~IcoSphere()
27    {
28    }
29
30    void IcoSphere::create(int recursionLevel)
31    {
32        vertices.clear();
33        lineIndices.clear();
34        triangleIndices.clear();
35        faces.clear();
36        middlePointIndexCache.clear();
37        index = 0;
38
39        float t = (1.0f + Ogre::Math::Sqrt(5.0f)) / 2.0f;
40
41        addVertex(Ogre::Vector3(-1.0f, t, 0.0f));
42        addVertex(Ogre::Vector3(1.0f, t, 0.0f));
43        addVertex(Ogre::Vector3(-1.0f, -t, 0.0f));
44        addVertex(Ogre::Vector3(1.0f, -t, 0.0f));
45
46        addVertex(Ogre::Vector3(0.0f, -1.0f, t));
47        addVertex(Ogre::Vector3(0.0f, 1.0f, t));
48        addVertex(Ogre::Vector3(0.0f, -1.0f, -t));
49        addVertex(Ogre::Vector3(0.0f, 1.0f, -t));
50
51        addVertex(Ogre::Vector3(t, 0.0f, -1.0f));
52        addVertex(Ogre::Vector3(t, 0.0f, 1.0f));
53        addVertex(Ogre::Vector3(-t, 0.0f, -1.0f));
54        addVertex(Ogre::Vector3(-t, 0.0f, 1.0f));
55
56        addFace(0, 11, 5);
57        addFace(0, 5, 1);
58        addFace(0, 1, 7);
59        addFace(0, 7, 10);
60        addFace(0, 10, 11);
61
62        addFace(1, 5, 9);
63        addFace(5, 11, 4);
64        addFace(11, 10, 2);
65        addFace(10, 7, 6);
66        addFace(7, 1, 8);
67
68        addFace(3, 9, 4);
69        addFace(3, 4, 2);
70        addFace(3, 2, 6);
71        addFace(3, 6, 8);
72        addFace(3, 8, 9);
73
74        addFace(4, 9, 5);
75        addFace(2, 4, 11);
76        addFace(6, 2, 10);
77        addFace(8, 6, 7);
78        addFace(9, 8, 1);
79
80        addLineIndices(1, 0);
81        addLineIndices(1, 5);
82        addLineIndices(1, 7);
83        addLineIndices(1, 8);
84        addLineIndices(1, 9);
85
86        addLineIndices(2, 3);
87        addLineIndices(2, 4);
88        addLineIndices(2, 6);
89        addLineIndices(2, 10);
90        addLineIndices(2, 11);
91
92        addLineIndices(0, 5);
93        addLineIndices(5, 9);
94        addLineIndices(9, 8);
95        addLineIndices(8, 7);
96        addLineIndices(7, 0);
97
98        addLineIndices(10, 11);
99        addLineIndices(11, 4);
100        addLineIndices(4, 3);
101        addLineIndices(3, 6);
102        addLineIndices(6, 10);
103
104        addLineIndices(0, 11);
105        addLineIndices(11, 5);
106        addLineIndices(5, 4);
107        addLineIndices(4, 9);
108        addLineIndices(9, 3);
109        addLineIndices(3, 8);
110        addLineIndices(8, 6);
111        addLineIndices(6, 7);
112        addLineIndices(7, 10);
113        addLineIndices(10, 0);
114
115        for (int i = 0; i < recursionLevel; i++)
116        {
117            std::list<TriangleIndices> faces2;
118
119            for (const TriangleIndices& f : faces)
120            {
121                int a = getMiddlePoint(f.v1, f.v2);
122                int b = getMiddlePoint(f.v2, f.v3);
123                int c = getMiddlePoint(f.v3, f.v1);
124
125                removeLineIndices(f.v1, f.v2);
126                removeLineIndices(f.v2, f.v3);
127                removeLineIndices(f.v3, f.v1);
128
129                faces2.emplace_back(f.v1, a, c);
130                faces2.emplace_back(f.v2, b, a);
131                faces2.emplace_back(f.v3, c, b);
132                faces2.emplace_back(a, b, c);
133
134                addTriangleLines(f.v1, a, c);
135                addTriangleLines(f.v2, b, a);
136                addTriangleLines(f.v3, c, b);
137            }
138
139            faces = faces2;
140        }
141    }
142
143    void IcoSphere::addLineIndices(int index0, int index1)
144    {
145        lineIndices.emplace_back(index0, index1);
146    }
147
148    void IcoSphere::removeLineIndices(int index0, int index1)
149    {
150        std::list<LineIndices>::iterator result = std::find(lineIndices.begin(), lineIndices.end(), LineIndices(index0, index1));
151
152        if (result != lineIndices.end())
153            lineIndices.erase(result);
154    }
155
156    void IcoSphere::addTriangleLines(int index0, int index1, int index2)
157    {
158        addLineIndices(index0, index1);
159        addLineIndices(index1, index2);
160        addLineIndices(index2, index0);
161    }
162
163    int IcoSphere::addVertex(const Ogre::Vector3& vertex)
164    {
165        Ogre::Real length = vertex.length();
166        vertices.emplace_back(vertex.x / length, vertex.y / length, vertex.z / length);
167        return index++;
168    }
169
170    int IcoSphere::getMiddlePoint(int index0, int index1)
171    {
172        bool isFirstSmaller = index0 < index1;
173        int64_t smallerIndex = isFirstSmaller ? index0 : index1;
174        int64_t largerIndex = isFirstSmaller ? index1 : index0;
175        int64_t key = (smallerIndex << 32) | largerIndex;
176
177        if (middlePointIndexCache.find(key) != middlePointIndexCache.end())
178            return middlePointIndexCache[key];
179
180        Ogre::Vector3 point1 = vertices[index0];
181        Ogre::Vector3 point2 = vertices[index1];
182        Ogre::Vector3 middle = point1.midPoint(point2);
183
184        int index = addVertex(middle);
185        middlePointIndexCache[key] = index;
186        return index;
187    }
188
189    void IcoSphere::addFace(int index0, int index1, int index2)
190    {
191        faces.emplace_back(index0, index1, index2);
192    }
193
194    void IcoSphere::addToLineIndices(int baseIndex, std::list<int>* target) const
195    {
196        for (const LineIndices& line : lineIndices)
197        {
198            target->push_back(baseIndex + line.v1);
199            target->push_back(baseIndex + line.v2);
200        }
201    }
202
203    void IcoSphere::addToTriangleIndices(int baseIndex, std::list<int>* target) const
204    {
205        for (const TriangleIndices& triangle : faces)
206        {
207            target->push_back(baseIndex + triangle.v1);
208            target->push_back(baseIndex + triangle.v2);
209            target->push_back(baseIndex + triangle.v3);
210        }
211    }
212
213    int IcoSphere::addToVertices(std::list<VertexPair>* target, const Ogre::Vector3& position, const Ogre::ColourValue& colour, float scale) const
214    {
215        Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY;
216        transform.setTrans(position);
217        transform.setScale(Ogre::Vector3(scale, scale, scale));
218
219        for (const Ogre::Vector3& vertex : vertices)
220            target->emplace_back(transform * vertex, colour);
221
222        return vertices.size();
223    }
224}
Note: See TracBrowser for help on using the repository browser.