Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added customized visualization for cylinders and cones to BulletDebugDrawer.
improved DebugDrawer by making circle, cylinder, and sphere rotatable. added rendering function for cones.

File size: 20.0 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::Matrix4& transform, 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(transform * Ogre::Vector3(radius * Ogre::Math::Cos(angle), 0, 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::Matrix4& transform, float radius, int segmentsCount, const Ogre::ColourValue& colour, bool up, 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(transform * Ogre::Vector3(radius * Ogre::Math::Cos(angle), 0, radius * Ogre::Math::Sin(angle)),
112                    Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
113            angle += increment;
114        }
115
116        addTriangleVertex(transform.getTrans(), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
117
118        for (int i = 0; i < segmentsCount; i++)
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        }
125    }
126
127    void DebugDrawer::buildCylinder(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, float alpha)
128    {
129        int index = linesIndex;
130
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);
136
137        for (int i = 0; i < segmentsCount; i++)
138            addLineIndices(index + i, segmentsCount + index + i);
139    }
140
141    void DebugDrawer::buildFilledCylinder(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour,
142            float alpha)
143    {
144        int index = trianglesIndex;
145
146        Ogre::Matrix4 transform(rotation);
147        transform.setTrans(centre + rotation * Ogre::Vector3(0, height / 2, 0));
148        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
149        this->buildFilledCircle(transform, radius, segmentsCount, colour, true, alpha);
150
151        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
152        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
153        this->buildFilledCircle(transform, radius, segmentsCount, colour, false, alpha);
154
155        for (int i = 0; i < segmentsCount; i++)
156        {
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);
159        }
160    }
161
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;
165
166        Ogre::Matrix4 transform(rotation);
167        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
168        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
169
170        addLineVertex(centre + rotation * Ogre::Vector3(0, height / 2, 0), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
171
172        for (int i = 0; i < segmentsCount; i++)
173            addLineIndices(index + i, index + segmentsCount);
174    }
175
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;
180
181        Ogre::Matrix4 transform(rotation);
182        transform.setTrans(centre + rotation * Ogre::Vector3(0, -height / 2, 0));
183        this->buildCircle(transform, radius, segmentsCount, colour, alpha);
184        this->buildFilledCircle(transform, radius, segmentsCount, colour, false, alpha);
185
186        addTriangleVertex(centre + rotation * Ogre::Vector3(0, height / 2, 0), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
187
188        for (int i = 0; i < segmentsCount; i++)
189            addTriangleIndices(index + i, index + segmentsCount + 1, i + 1 < segmentsCount ? index + i + 1 : index);
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
300    void DebugDrawer::drawCircle(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, const Ogre::ColourValue& colour, bool isFilled)
301    {
302        int segmentsCount = std::min(100.0, radius / 2.5);
303
304        Ogre::Matrix4 transform(rotation);
305        transform.setTrans(centre);
306
307        buildCircle(transform, radius, segmentsCount, colour);
308        if (isFilled)
309            buildFilledCircle(transform, radius, segmentsCount, colour, fillAlpha);
310    }
311
312    void DebugDrawer::drawCylinder(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, float height, const Ogre::ColourValue& colour, bool isFilled)
313    {
314        int segmentsCount = std::min(100.0, radius / 2.5);
315
316        if (isFilled)
317            buildFilledCylinder(centre, rotation, radius, segmentsCount, height, colour, fillAlpha);
318        else
319            buildCylinder(centre, rotation, radius, segmentsCount, height, colour);
320    }
321
322    void DebugDrawer::drawCone(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, float height, const Ogre::ColourValue& colour, bool isFilled)
323    {
324        int segmentsCount = std::min(100.0, radius / 2.5);
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
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
346    void DebugDrawer::drawSphere(const Ogre::Vector3& centre, const Ogre::Quaternion& rotation, float radius, const Ogre::ColourValue& colour, bool isFilled)
347    {
348        const IcoSphere& sphere = this->getIcoSphere(radius);
349
350        if (isFilled)
351        {
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;
357            trianglesIndex += sphere.addToVertices(&triangleVertices, centre, Ogre::ColourValue(colour.r, colour.g, colour.b, fillAlpha), radius);
358            sphere.addToTriangleIndices(baseIndex, &triangleIndices);
359        }
360        else
361        {
362            int baseIndex = linesIndex;
363            linesIndex += sphere.addToVertices(&lineVertices, centre, colour, radius);
364            sphere.addToLineIndices(baseIndex, &lineIndices);
365        }
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.