Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/libraries/tools/IcoSphere.cc @ 10916

Last change on this file since 10916 was 10916, checked in by landauf, 10 years ago

use actual types instead of 'auto'. only exception is for complicated template types, e.g. when iterating over a map

  • Property svn:eol-style set to native
File size: 6.4 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.push_back(TriangleIndices(f.v1, a, c));
129                faces2.push_back(TriangleIndices(f.v2, b, a));
130                faces2.push_back(TriangleIndices(f.v3, c, b));
131                faces2.push_back(TriangleIndices(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.push_back(LineIndices(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.push_back(Ogre::Vector3(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.push_back(TriangleIndices(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->push_back(VertexPair(transform * vertex, colour));
220
221        return vertices.size();
222    }
223}
Note: See TracBrowser for help on using the repository browser.