Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

removed unnecessary material from BulletDebugDrawer.
fixed crash with ogre 1.7 if the number of vertices dropped to 0 in DebugDrawer.

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