Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 19.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#define DEFAULT_ICOSPHERE_RECURSION_LEVEL 1
19
20namespace orxonox
21{
22    DebugDrawer::DebugDrawer(Ogre::SceneManager *_sceneManager, float _fillAlpha) :
23            sceneManager(_sceneManager), fillAlpha(_fillAlpha), manualObject(nullptr), 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 (const VertexPair& pair : lineVertices)
395            {
396                manualObject->position(pair.first);
397                manualObject->colour(pair.second);
398            }
399            for (int lineIndex : lineIndices)
400                manualObject->index(lineIndex);
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 (const VertexPair& pair : triangleVertices)
412            {
413                manualObject->position(pair.first);
414                manualObject->colour(pair.second.r, pair.second.g, pair.second.b, fillAlpha);
415            }
416            for (int triangleIndex : triangleIndices)
417                manualObject->index(triangleIndex);
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.emplace_back(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.emplace_back(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.