Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/tools/DebugDrawer.cc @ 10194

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

bugfix

File size: 20.0 KB
RevLine 
[10190]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) :
[10194]25            sceneManager(_sceneManager), fillAlpha(_fillAlpha), manualObject(0), isEnabled(true), linesIndex(0), trianglesIndex(0)
[10190]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
[10191]86    void DebugDrawer::buildCircle(const Ogre::Matrix4& transform, float radius, int segmentsCount, const Ogre::ColourValue& colour, float alpha)
[10190]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        {
[10191]94            addLineVertex(transform * Ogre::Vector3(radius * Ogre::Math::Cos(angle), 0, radius * Ogre::Math::Sin(angle)),
[10190]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
[10191]103    void DebugDrawer::buildFilledCircle(const Ogre::Matrix4& transform, float radius, int segmentsCount, const Ogre::ColourValue& colour, bool up, float alpha)
[10190]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        {
[10191]111            addTriangleVertex(transform * Ogre::Vector3(radius * Ogre::Math::Cos(angle), 0, radius * Ogre::Math::Sin(angle)),
[10190]112                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
113            angle += increment;
114        }
115
[10191]116        addTriangleVertex(transform.getTrans(), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
[10190]117
118        for (int i = 0; i < segmentsCount; i++)
[10191]119        {
120            if (up)
121                addTriangleIndices(i + 1 < segmentsCount ? index + i + 1 : index, index + i, index + segmentsCount);
122            else
123                addTriangleIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index, index + segmentsCount);
124        }
[10190]125    }
126
[10191]127    void DebugDrawer::buildCylinder(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, float alpha)
[10190]128    {
129        int index = linesIndex;
130
[10191]131        Ogre::Matrix4 transform(rotation);
132        transform.setTrans(centre + rotation * Ogre::Vector3(0, height / 2, 0));
133        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
134        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
135        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
[10190]136
137        for (int i = 0; i < segmentsCount; i++)
138            addLineIndices(index + i, segmentsCount + index + i);
139    }
140
[10191]141    void DebugDrawer::buildFilledCylinder(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour,
[10190]142            float alpha)
143    {
144        int index = trianglesIndex;
145
[10191]146        Ogre::Matrix4 transform(rotation);
147        transform.setTrans(centre + rotation * Ogre::Vector3(0, height / 2, 0));
[10193]148        this->buildCircle(transform, radius, segmentsCount, colour);
[10191]149        this->buildFilledCircle(transform, radius, segmentsCount, colour, true, alpha);
150
151        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
[10193]152        this->buildCircle(transform, radius, segmentsCount, colour);
[10191]153        this->buildFilledCircle(transform, radius, segmentsCount, colour, false, alpha);
154
[10190]155        for (int i = 0; i < segmentsCount; i++)
156        {
[10191]157            addQuadIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index,
158                    i + 1 < segmentsCount ? (segmentsCount + 1) + index + i + 1 : (segmentsCount + 1) + index, (segmentsCount + 1) + index + i);
[10190]159        }
[10191]160    }
[10190]161
[10191]162    void DebugDrawer::buildCone(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, float alpha)
163    {
164        int index = linesIndex;
[10190]165
[10191]166        Ogre::Matrix4 transform(rotation);
167        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
168        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
[10190]169
[10191]170        addLineVertex(centre + rotation * Ogre::Vector3(0, height / 2, 0), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
171
[10190]172        for (int i = 0; i < segmentsCount; i++)
[10191]173            addLineIndices(index + i, index + segmentsCount);
174    }
[10190]175
[10191]176    void DebugDrawer::buildFilledCone(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour,
177            float alpha)
178    {
179        int index = trianglesIndex;
[10190]180
[10191]181        Ogre::Matrix4 transform(rotation);
182        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
[10193]183        this->buildCircle(transform, radius, segmentsCount, colour);
[10191]184        this->buildFilledCircle(transform, radius, segmentsCount, colour, false, alpha);
[10190]185
[10191]186        addTriangleVertex(centre + rotation * Ogre::Vector3(0, height / 2, 0), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
[10190]187
[10191]188        for (int i = 0; i < segmentsCount; i++)
189            addTriangleIndices(index + i, index + segmentsCount + 1, i + 1 < segmentsCount ? index + i + 1 : index);
[10190]190    }
191
192    void DebugDrawer::buildCuboid(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
193    {
194        int index = addLineVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
195        for (int i = 1; i < 8; ++i)
196            addLineVertex(vertices[i], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
197
198        for (int i = 0; i < 4; ++i)
199            addLineIndices(index + i, index + ((i + 1) % 4));
200        for (int i = 4; i < 8; ++i)
201            addLineIndices(index + i, i == 7 ? index + 4 : index + i + 1);
202        addLineIndices(index + 1, index + 5);
203        addLineIndices(index + 2, index + 4);
204        addLineIndices(index, index + 6);
205        addLineIndices(index + 3, index + 7);
206    }
207
208    void DebugDrawer::buildFilledCuboid(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
209    {
210        int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
211        for (int i = 1; i < 8; ++i)
212            addTriangleVertex(vertices[i], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
213
214        addQuadIndices(index, index + 1, index + 2, index + 3);
215        addQuadIndices(index + 4, index + 5, index + 6, index + 7);
216
217        addQuadIndices(index + 1, index + 5, index + 4, index + 2);
218        addQuadIndices(index, index + 3, index + 7, index + 6);
219
220        addQuadIndices(index + 1, index, index + 6, index + 5);
221        addQuadIndices(index + 4, index + 7, index + 3, index + 2);
222    }
223
224    void DebugDrawer::buildFilledQuad(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
225    {
226        int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
227        addTriangleVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
228        addTriangleVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
229        addTriangleVertex(vertices[3], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
230
231        addQuadIndices(index, index + 1, index + 2, index + 3);
232    }
233
234    void DebugDrawer::buildFilledTriangle(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, float alpha)
235    {
236        int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
237        addTriangleVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
238        addTriangleVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
239
240        addTriangleIndices(index, index + 1, index + 2);
241    }
242
243    void DebugDrawer::buildTetrahedron(const Ogre::Vector3& centre, float scale, const Ogre::ColourValue& colour, float alpha)
244    {
245        int index = linesIndex;
246
247        // Distance from the centre
248        float bottomDistance = scale * 0.2f;
249        float topDistance = scale * 0.62f;
250        float frontDistance = scale * 0.289f;
251        float backDistance = scale * 0.577f;
252        float leftRightDistance = scale * 0.5f;
253
254        addLineVertex(Ogre::Vector3(centre.x, centre.y + topDistance, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
255        addLineVertex(Ogre::Vector3(centre.x, centre.y - bottomDistance, centre.z + frontDistance), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
256        addLineVertex(Ogre::Vector3(centre.x + leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
257                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
258        addLineVertex(Ogre::Vector3(centre.x - leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
259                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
260
261        addLineIndices(index, index + 1);
262        addLineIndices(index, index + 2);
263        addLineIndices(index, index + 3);
264
265        addLineIndices(index + 1, index + 2);
266        addLineIndices(index + 2, index + 3);
267        addLineIndices(index + 3, index + 1);
268    }
269
270    void DebugDrawer::buildFilledTetrahedron(const Ogre::Vector3& centre, float scale, const Ogre::ColourValue& colour, float alpha)
271    {
272        int index = trianglesIndex;
273
274        // Distance from the centre
275        float bottomDistance = scale * 0.2f;
276        float topDistance = scale * 0.62f;
277        float frontDistance = scale * 0.289f;
278        float backDistance = scale * 0.577f;
279        float leftRightDistance = scale * 0.5f;
280
281        addTriangleVertex(Ogre::Vector3(centre.x, centre.y + topDistance, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
282        addTriangleVertex(Ogre::Vector3(centre.x, centre.y - bottomDistance, centre.z + frontDistance), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
283        addTriangleVertex(Ogre::Vector3(centre.x + leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
284                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
285        addTriangleVertex(Ogre::Vector3(centre.x - leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
286                Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
287
288        addTriangleIndices(index, index + 1, index + 2);
289        addTriangleIndices(index, index + 2, index + 3);
290        addTriangleIndices(index, index + 3, index + 1);
291
292        addTriangleIndices(index + 1, index + 3, index + 2);
293    }
294
295    void DebugDrawer::drawLine(const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::ColourValue& colour)
296    {
297        buildLine(start, end, colour);
298    }
299
[10191]300    void DebugDrawer::drawCircle(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, const Ogre::ColourValue& colour, bool isFilled)
[10190]301    {
[10193]302        int segmentsCount = std::min<int>(100, (int) (radius / 2.5));
[10191]303
304        Ogre::Matrix4 transform(rotation);
305        transform.setTrans(centre);
306
307        buildCircle(transform, radius, segmentsCount, colour);
[10190]308        if (isFilled)
[10191]309            buildFilledCircle(transform, radius, segmentsCount, colour, fillAlpha);
[10190]310    }
311
[10191]312    void DebugDrawer::drawCylinder(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, float height, const Ogre::ColourValue& colour, bool isFilled)
[10190]313    {
[10193]314        int segmentsCount = std::min<int>(100, (int) (radius / 2.5));
[10191]315
[10190]316        if (isFilled)
[10191]317            buildFilledCylinder(centre, rotation, radius, segmentsCount, height, colour, fillAlpha);
318        else
319            buildCylinder(centre, rotation, radius, segmentsCount, height, colour);
[10190]320    }
321
[10191]322    void DebugDrawer::drawCone(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, float height, const Ogre::ColourValue& colour, bool isFilled)
323    {
[10193]324        int segmentsCount = std::min<int>(100, (int) (radius / 2.5));
[10191]325
326        if (isFilled)
327            buildFilledCone(centre, rotation, radius, segmentsCount, height, colour, fillAlpha);
328        else
329            buildCone(centre, rotation, radius, segmentsCount, height, colour);
330    }
331
[10190]332    void DebugDrawer::drawQuad(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, bool isFilled)
333    {
334        buildQuad(vertices, colour);
335        if (isFilled)
336            buildFilledQuad(vertices, colour, fillAlpha);
337    }
338
339    void DebugDrawer::drawCuboid(const Ogre::Vector3* vertices, const Ogre::ColourValue& colour, bool isFilled)
340    {
341        buildCuboid(vertices, colour);
342        if (isFilled)
343            buildFilledCuboid(vertices, colour, fillAlpha);
344    }
345
[10191]346    void DebugDrawer::drawSphere(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, const Ogre::ColourValue& colour, bool isFilled)
[10190]347    {
348        const IcoSphere& sphere = this->getIcoSphere(radius);
349
350        if (isFilled)
351        {
[10191]352            this->drawCircle(centre, rotation * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3(1, 0, 0)), radius, colour, false);
353            this->drawCircle(centre, rotation * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3(0, 1, 0)), radius, colour, false);
354            this->drawCircle(centre, rotation * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3(0, 0, 1)), radius, colour, false);
355
356            int baseIndex = trianglesIndex;
[10190]357            trianglesIndex += sphere.addToVertices(&triangleVertices, centre, Ogre::ColourValue(colour.r, colour.g, colour.b, fillAlpha), radius);
358            sphere.addToTriangleIndices(baseIndex, &triangleIndices);
359        }
[10191]360        else
361        {
362            int baseIndex = linesIndex;
363            linesIndex += sphere.addToVertices(&lineVertices, centre, colour, radius);
364            sphere.addToLineIndices(baseIndex, &lineIndices);
365        }
[10190]366    }
367
368    const IcoSphere& DebugDrawer::getIcoSphere(float radius) const
369    {
370        if (radius < 50)
371            return this->icoSphere0;
372        else if (radius < 500)
373            return this->icoSphere1;
374        else if (radius < 5000)
375            return this->icoSphere2;
376        else if (radius < 50000)
377            return this->icoSphere3;
378        else
379            return this->icoSphere4;
380    }
381
382    void DebugDrawer::drawTetrahedron(const Ogre::Vector3& centre, float scale, const Ogre::ColourValue& colour, bool isFilled)
383    {
384        buildTetrahedron(centre, scale, colour);
385        if (isFilled)
386            buildFilledTetrahedron(centre, scale, colour, fillAlpha);
387    }
388
389    void DebugDrawer::build()
390    {
391        manualObject->beginUpdate(0);
392        if (lineVertices.size() > 0 && isEnabled)
393        {
394            manualObject->estimateVertexCount(lineVertices.size());
395            manualObject->estimateIndexCount(lineIndices.size());
396            for (std::list<VertexPair>::iterator i = lineVertices.begin(); i != lineVertices.end(); i++)
397            {
398                manualObject->position(i->first);
399                manualObject->colour(i->second);
400            }
401            for (std::list<int>::iterator i = lineIndices.begin(); i != lineIndices.end(); i++)
402                manualObject->index(*i);
403        }
404        manualObject->end();
405
406        manualObject->beginUpdate(1);
407        if (triangleVertices.size() > 0 && isEnabled)
408        {
409            manualObject->estimateVertexCount(triangleVertices.size());
410            manualObject->estimateIndexCount(triangleIndices.size());
411            for (std::list<VertexPair>::iterator i = triangleVertices.begin(); i != triangleVertices.end(); i++)
412            {
413                manualObject->position(i->first);
414                manualObject->colour(i->second.r, i->second.g, i->second.b, fillAlpha);
415            }
416            for (std::list<int>::iterator i = triangleIndices.begin(); i != triangleIndices.end(); i++)
417                manualObject->index(*i);
418        }
419        manualObject->end();
420    }
421
422    void DebugDrawer::clear()
423    {
424        lineVertices.clear();
425        triangleVertices.clear();
426        lineIndices.clear();
427        triangleIndices.clear();
428        linesIndex = trianglesIndex = 0;
429    }
430
431    int DebugDrawer::addLineVertex(const Ogre::Vector3& vertex, const Ogre::ColourValue& colour)
432    {
433        lineVertices.push_back(VertexPair(vertex, colour));
434        return linesIndex++;
435    }
436
437    void DebugDrawer::addLineIndices(int index1, int index2)
438    {
439        lineIndices.push_back(index1);
440        lineIndices.push_back(index2);
441    }
442
443    int DebugDrawer::addTriangleVertex(const Ogre::Vector3& vertex, const Ogre::ColourValue& colour)
444    {
445        triangleVertices.push_back(VertexPair(vertex, colour));
446        return trianglesIndex++;
447    }
448
449    void DebugDrawer::addTriangleIndices(int index1, int index2, int index3)
450    {
451        triangleIndices.push_back(index1);
452        triangleIndices.push_back(index2);
453        triangleIndices.push_back(index3);
454    }
455
456    void DebugDrawer::addQuadIndices(int index1, int index2, int index3, int index4)
457    {
458        triangleIndices.push_back(index1);
459        triangleIndices.push_back(index2);
460        triangleIndices.push_back(index3);
461
462        triangleIndices.push_back(index1);
463        triangleIndices.push_back(index3);
464        triangleIndices.push_back(index4);
465    }
466}
Note: See TracBrowser for help on using the repository browser.