Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10190 was 10190, checked in by landauf, 9 years ago

added utility to visualize collision shapes

File size: 6.8 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 (std::list<TriangleIndices>::iterator j = faces.begin(); j != faces.end(); j++)
119            {
120                TriangleIndices f = *j;
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.push_back(TriangleIndices(f.v1, a, c));
130                faces2.push_back(TriangleIndices(f.v2, b, a));
131                faces2.push_back(TriangleIndices(f.v3, c, b));
132                faces2.push_back(TriangleIndices(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.push_back(LineIndices(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.push_back(Ogre::Vector3(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 smallerIndex = isFirstSmaller ? index0 : index1;
174        __int64 largerIndex = isFirstSmaller ? index1 : index0;
175        __int64 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.push_back(TriangleIndices(index0, index1, index2));
192    }
193
194    void IcoSphere::addToLineIndices(int baseIndex, std::list<int>* target) const
195    {
196        for (std::list<LineIndices>::const_iterator i = lineIndices.begin(); i != lineIndices.end(); i++)
197        {
198            target->push_back(baseIndex + (*i).v1);
199            target->push_back(baseIndex + (*i).v2);
200        }
201    }
202
203    void IcoSphere::addToTriangleIndices(int baseIndex, std::list<int>* target) const
204    {
205        for (std::list<TriangleIndices>::const_iterator i = faces.begin(); i != faces.end(); i++)
206        {
207            target->push_back(baseIndex + (*i).v1);
208            target->push_back(baseIndex + (*i).v2);
209            target->push_back(baseIndex + (*i).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 (int i = 0; i < (int) vertices.size(); i++)
220            target->push_back(VertexPair(transform * vertices[i], colour));
221
222        return vertices.size();
223    }
224}
Note: See TracBrowser for help on using the repository browser.