Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/tools/DebugDrawer.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: 18.6 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 "DebugDrawer.h"
12
13#include <OgreSceneManager.h>
14#include <OgreRenderQueue.h>
15#include <OgreManualObject.h>
16#include <OgreAxisAlignedBox.h>
17
18#include "util/Output.h"
19
20#define DEFAULT_ICOSPHERE_RECURSION_LEVEL 1
21
22namespace orxonox
23{
24    DebugDrawer::DebugDrawer(Ogre::SceneManager *_sceneManager, float _fillAlpha) :
25            sceneManager(_sceneManager), fillAlpha(_fillAlpha), manualObject(0), linesIndex(0), trianglesIndex(0)
26    {
27        initialise();
28    }
29
30    DebugDrawer::~DebugDrawer()
31    {
32        shutdown();
33    }
34
35    void DebugDrawer::initialise()
36    {
37        manualObject = sceneManager->createManualObject("debug_object");
38        sceneManager->getRootSceneNode()->createChildSceneNode("debug_object")->attachObject(manualObject);
39        manualObject->setDynamic(true);
40
41        icoSphere0.create(0);
42        icoSphere1.create(1);
43        icoSphere2.create(2);
44        icoSphere3.create(3);
45        icoSphere4.create(4);
46
47        manualObject->begin("debug_draw", Ogre::RenderOperation::OT_LINE_LIST);
48        manualObject->position(Ogre::Vector3::ZERO);
49        manualObject->colour(Ogre::ColourValue::ZERO);
50        manualObject->index(0);
51        manualObject->end();
52        manualObject->begin("debug_draw", Ogre::RenderOperation::OT_TRIANGLE_LIST);
53        manualObject->position(Ogre::Vector3::ZERO);
54        manualObject->colour(Ogre::ColourValue::ZERO);
55        manualObject->index(0);
56        manualObject->end();
57
58        linesIndex = trianglesIndex = 0;
59    }
60
61    void DebugDrawer::shutdown()
62    {
63        sceneManager->destroySceneNode("debug_object");
64        sceneManager->destroyManualObject(manualObject);
65    }
66
67    void DebugDrawer::buildLine(const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::ColourValue& colour, float alpha)
68    {
69        int i = addLineVertex(start, Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
70        addLineVertex(end, Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
71
72        addLineIndices(i, i + 1);
73    }
74
75    void DebugDrawer::buildQuad(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
76    {
77        int index = addLineVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
78        addLineVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
79        addLineVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
80        addLineVertex(vertices[3], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
81
82        for (int i = 0; i < 4; ++i)
83            addLineIndices(index + i, index + ((i + 1) % 4));
84    }
85
86    void DebugDrawer::buildCircle(const Ogre::Vector3& centre, float radius, int segmentsCount, const Ogre::ColourValue& colour, float alpha)
87    {
88        int index = linesIndex;
89        float increment = 2 * Ogre::Math::PI / segmentsCount;
90        float angle = 0.0f;
91
92        for (int i = 0; i < segmentsCount; i++)
93        {
94            addLineVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y, centre.z + radius * Ogre::Math::Sin(angle)),
95                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
96            angle += increment;
97        }
98
99        for (int i = 0; i < segmentsCount; i++)
100            addLineIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index);
101    }
102
103    void DebugDrawer::buildFilledCircle(const Ogre::Vector3& centre, float radius, int segmentsCount, const Ogre::ColourValue& colour, float alpha)
104    {
105        int index = trianglesIndex;
106        float increment = 2 * Ogre::Math::PI / segmentsCount;
107        float angle = 0.0f;
108
109        for (int i = 0; i < segmentsCount; i++)
110        {
111            addTriangleVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y, centre.z + radius * Ogre::Math::Sin(angle)),
112                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
113            angle += increment;
114        }
115
116        addTriangleVertex(centre, Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
117
118        for (int i = 0; i < segmentsCount; i++)
119            addTriangleIndices(i + 1 < segmentsCount ? index + i + 1 : index, index + i, index + segmentsCount);
120    }
121
122    void DebugDrawer::buildCylinder(const Ogre::Vector3& centre, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, float alpha)
123    {
124        int index = linesIndex;
125        float increment = 2 * Ogre::Math::PI / segmentsCount;
126        float angle = 0.0f;
127
128        // Top circle
129        for (int i = 0; i < segmentsCount; i++)
130        {
131            addLineVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y + height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
132                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
133            angle += increment;
134        }
135
136        angle = 0.0f;
137
138        // Bottom circle
139        for (int i = 0; i < segmentsCount; i++)
140        {
141            addLineVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y - height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
142                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
143            angle += increment;
144        }
145
146        for (int i = 0; i < segmentsCount; i++)
147        {
148            addLineIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index);
149            addLineIndices(segmentsCount + index + i, i + 1 < segmentsCount ? segmentsCount + index + i + 1 : segmentsCount + index);
150            addLineIndices(index + i, segmentsCount + index + i);
151        }
152    }
153
154    void DebugDrawer::buildFilledCylinder(const Ogre::Vector3& centre, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour,
155            float alpha)
156    {
157        int index = trianglesIndex;
158        float increment = 2 * Ogre::Math::PI / segmentsCount;
159        float angle = 0.0f;
160
161        // Top circle
162        for (int i = 0; i < segmentsCount; i++)
163        {
164            addTriangleVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y + height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
165                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
166            angle += increment;
167        }
168
169        addTriangleVertex(Ogre::Vector3(centre.x, centre.y + height / 2, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
170
171        angle = 0.0f;
172
173        // Bottom circle
174        for (int i = 0; i < segmentsCount; i++)
175        {
176            addTriangleVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y - height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
177                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
178            angle += increment;
179        }
180
181        addTriangleVertex(Ogre::Vector3(centre.x, centre.y - height / 2, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
182
183        for (int i = 0; i < segmentsCount; i++)
184        {
185            addTriangleIndices(i + 1 < segmentsCount ? index + i + 1 : index, index + i, index + segmentsCount);
186
187            addTriangleIndices(i + 1 < segmentsCount ? (segmentsCount + 1) + index + i + 1 : (segmentsCount + 1) + index,
188                    (segmentsCount + 1) + index + segmentsCount, (segmentsCount + 1) + index + i);
189
190            addQuadIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index,
191                    i + 1 < segmentsCount ? (segmentsCount + 1) + index + i + 1 : (segmentsCount + 1) + index, (segmentsCount + 1) + index + i);
192        }
193    }
194
195    void DebugDrawer::buildCuboid(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
196    {
197        int index = addLineVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
198        for (int i = 1; i < 8; ++i)
199            addLineVertex(vertices[i], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
200
201        for (int i = 0; i < 4; ++i)
202            addLineIndices(index + i, index + ((i + 1) % 4));
203        for (int i = 4; i < 8; ++i)
204            addLineIndices(index + i, i == 7 ? index + 4 : index + i + 1);
205        addLineIndices(index + 1, index + 5);
206        addLineIndices(index + 2, index + 4);
207        addLineIndices(index, index + 6);
208        addLineIndices(index + 3, index + 7);
209    }
210
211    void DebugDrawer::buildFilledCuboid(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
212    {
213        int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
214        for (int i = 1; i < 8; ++i)
215            addTriangleVertex(vertices[i], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
216
217        addQuadIndices(index, index + 1, index + 2, index + 3);
218        addQuadIndices(index + 4, index + 5, index + 6, index + 7);
219
220        addQuadIndices(index + 1, index + 5, index + 4, index + 2);
221        addQuadIndices(index, index + 3, index + 7, index + 6);
222
223        addQuadIndices(index + 1, index, index + 6, index + 5);
224        addQuadIndices(index + 4, index + 7, index + 3, index + 2);
225    }
226
227    void DebugDrawer::buildFilledQuad(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
228    {
229        int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
230        addTriangleVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
231        addTriangleVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
232        addTriangleVertex(vertices[3], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
233
234        addQuadIndices(index, index + 1, index + 2, index + 3);
235    }
236
237    void DebugDrawer::buildFilledTriangle(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
238    {
239        int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
240        addTriangleVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
241        addTriangleVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
242
243        addTriangleIndices(index, index + 1, index + 2);
244    }
245
246    void DebugDrawer::buildTetrahedron(const Ogre::Vector3& centre, float scale, const Ogre::ColourValue& colour, float alpha)
247    {
248        int index = linesIndex;
249
250        // Distance from the centre
251        float bottomDistance = scale * 0.2f;
252        float topDistance = scale * 0.62f;
253        float frontDistance = scale * 0.289f;
254        float backDistance = scale * 0.577f;
255        float leftRightDistance = scale * 0.5f;
256
257        addLineVertex(Ogre::Vector3(centre.x, centre.y + topDistance, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
258        addLineVertex(Ogre::Vector3(centre.x, centre.y - bottomDistance, centre.z + frontDistance), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
259        addLineVertex(Ogre::Vector3(centre.x + leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
260                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
261        addLineVertex(Ogre::Vector3(centre.x - leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
262                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
263
264        addLineIndices(index, index + 1);
265        addLineIndices(index, index + 2);
266        addLineIndices(index, index + 3);
267
268        addLineIndices(index + 1, index + 2);
269        addLineIndices(index + 2, index + 3);
270        addLineIndices(index + 3, index + 1);
271    }
272
273    void DebugDrawer::buildFilledTetrahedron(const Ogre::Vector3& centre, float scale, const Ogre::ColourValue& colour, float alpha)
274    {
275        int index = trianglesIndex;
276
277        // Distance from the centre
278        float bottomDistance = scale * 0.2f;
279        float topDistance = scale * 0.62f;
280        float frontDistance = scale * 0.289f;
281        float backDistance = scale * 0.577f;
282        float leftRightDistance = scale * 0.5f;
283
284        addTriangleVertex(Ogre::Vector3(centre.x, centre.y + topDistance, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
285        addTriangleVertex(Ogre::Vector3(centre.x, centre.y - bottomDistance, centre.z + frontDistance), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
286        addTriangleVertex(Ogre::Vector3(centre.x + leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
287                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
288        addTriangleVertex(Ogre::Vector3(centre.x - leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
289                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
290
291        addTriangleIndices(index, index + 1, index + 2);
292        addTriangleIndices(index, index + 2, index + 3);
293        addTriangleIndices(index, index + 3, index + 1);
294
295        addTriangleIndices(index + 1, index + 3, index + 2);
296    }
297
298    void DebugDrawer::drawLine(const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::ColourValue& colour)
299    {
300        buildLine(start, end, colour);
301    }
302
303    void DebugDrawer::drawCircle(const Ogre::Vector3& centre, float radius, int segmentsCount, const Ogre::ColourValue& colour, bool isFilled)
304    {
305        buildCircle(centre, radius, segmentsCount, colour);
306        if (isFilled)
307            buildFilledCircle(centre, radius, segmentsCount, colour, fillAlpha);
308    }
309
310    void DebugDrawer::drawCylinder(const Ogre::Vector3& centre, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, bool isFilled)
311    {
312        buildCylinder(centre, radius, segmentsCount, height, colour);
313        if (isFilled)
314            buildFilledCylinder(centre, radius, segmentsCount, height, colour, fillAlpha);
315    }
316
317    void DebugDrawer::drawQuad(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, bool isFilled)
318    {
319        buildQuad(vertices, colour);
320        if (isFilled)
321            buildFilledQuad(vertices, colour, fillAlpha);
322    }
323
324    void DebugDrawer::drawCuboid(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, bool isFilled)
325    {
326        buildCuboid(vertices, colour);
327        if (isFilled)
328            buildFilledCuboid(vertices, colour, fillAlpha);
329    }
330
331    void DebugDrawer::drawSphere(const Ogre::Vector3& centre, float radius, const Ogre::ColourValue& colour, bool isFilled)
332    {
333        const IcoSphere& sphere = this->getIcoSphere(radius);
334
335        int baseIndex = linesIndex;
336        linesIndex += sphere.addToVertices(&lineVertices, centre, colour, radius);
337        sphere.addToLineIndices(baseIndex, &lineIndices);
338
339        if (isFilled)
340        {
341            baseIndex = trianglesIndex;
342            trianglesIndex += sphere.addToVertices(&triangleVertices, centre, Ogre::ColourValue(colour.r, colour.g, colour.b, fillAlpha), radius);
343            sphere.addToTriangleIndices(baseIndex, &triangleIndices);
344        }
345    }
346
347    const IcoSphere& DebugDrawer::getIcoSphere(float radius) const
348    {
349        if (radius < 50)
350            return this->icoSphere0;
351        else if (radius < 500)
352            return this->icoSphere1;
353        else if (radius < 5000)
354            return this->icoSphere2;
355        else if (radius < 50000)
356            return this->icoSphere3;
357        else
358            return this->icoSphere4;
359    }
360
361    void DebugDrawer::drawTetrahedron(const Ogre::Vector3& centre, float scale, const Ogre::ColourValue& colour, bool isFilled)
362    {
363        buildTetrahedron(centre, scale, colour);
364        if (isFilled)
365            buildFilledTetrahedron(centre, scale, colour, fillAlpha);
366    }
367
368    void DebugDrawer::build()
369    {
370        manualObject->beginUpdate(0);
371        if (lineVertices.size() > 0 && isEnabled)
372        {
373            manualObject->estimateVertexCount(lineVertices.size());
374            manualObject->estimateIndexCount(lineIndices.size());
375            for (std::list<VertexPair>::iterator i = lineVertices.begin(); i != lineVertices.end(); i++)
376            {
377                manualObject->position(i->first);
378                manualObject->colour(i->second);
379            }
380            for (std::list<int>::iterator i = lineIndices.begin(); i != lineIndices.end(); i++)
381                manualObject->index(*i);
382        }
383        manualObject->end();
384
385        manualObject->beginUpdate(1);
386        if (triangleVertices.size() > 0 && isEnabled)
387        {
388            manualObject->estimateVertexCount(triangleVertices.size());
389            manualObject->estimateIndexCount(triangleIndices.size());
390            for (std::list<VertexPair>::iterator i = triangleVertices.begin(); i != triangleVertices.end(); i++)
391            {
392                manualObject->position(i->first);
393                manualObject->colour(i->second.r, i->second.g, i->second.b, fillAlpha);
394            }
395            for (std::list<int>::iterator i = triangleIndices.begin(); i != triangleIndices.end(); i++)
396                manualObject->index(*i);
397        }
398        manualObject->end();
399    }
400
401    void DebugDrawer::clear()
402    {
403        lineVertices.clear();
404        triangleVertices.clear();
405        lineIndices.clear();
406        triangleIndices.clear();
407        linesIndex = trianglesIndex = 0;
408    }
409
410    int DebugDrawer::addLineVertex(const Ogre::Vector3& vertex, const Ogre::ColourValue& colour)
411    {
412        lineVertices.push_back(VertexPair(vertex, colour));
413        return linesIndex++;
414    }
415
416    void DebugDrawer::addLineIndices(int index1, int index2)
417    {
418        lineIndices.push_back(index1);
419        lineIndices.push_back(index2);
420    }
421
422    int DebugDrawer::addTriangleVertex(const Ogre::Vector3& vertex, const Ogre::ColourValue& colour)
423    {
424        triangleVertices.push_back(VertexPair(vertex, colour));
425        return trianglesIndex++;
426    }
427
428    void DebugDrawer::addTriangleIndices(int index1, int index2, int index3)
429    {
430        triangleIndices.push_back(index1);
431        triangleIndices.push_back(index2);
432        triangleIndices.push_back(index3);
433    }
434
435    void DebugDrawer::addQuadIndices(int index1, int index2, int index3, int index4)
436    {
437        triangleIndices.push_back(index1);
438        triangleIndices.push_back(index2);
439        triangleIndices.push_back(index3);
440
441        triangleIndices.push_back(index1);
442        triangleIndices.push_back(index3);
443        triangleIndices.push_back(index4);
444    }
445}
Note: See TracBrowser for help on using the repository browser.