Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/tools/IcoSphere.cc @ 11071

Last change on this file since 11071 was 11071, checked in by landauf, 8 years ago

merged branch cpp11_v3 back to trunk

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