Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutorial6/src/libraries/tools/DebugDrawer.cc @ 11815

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