Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_new/src/ogreode/OgreOdeDebugContact.cpp @ 2119

Last change on this file since 2119 was 2119, checked in by rgrieder, 15 years ago

Merged physics branch into physics_new branch.

  • Property svn:eol-style set to native
File size: 22.6 KB
Line 
1/**
2* File: OgreOdeDebugContact.cpp
3*
4* description: This create create a billboarding object that display a text.
5*  From MovableText
6* @author  2003 by cTh see gavocanov@rambler.ru
7* @update  2006 by barraq see nospam@barraquand.com
8*/
9
10#include "OgreOdePrecompiledHeaders.h"
11#include "OgreOdeDebugContact.h"
12
13#include <OgreFontManager.h>
14#include <OgreEntity.h>
15#include <OgreSceneNode.h>
16#include <OgreMaterialManager.h>
17#include <OgreCamera.h>
18#include <OgreRoot.h>
19
20#include "OgreOdeCollision.h"
21#include "OgreOdeWorld.h"
22
23using namespace Ogre;
24
25#define POS_TEX_BINDING    0
26#define COLOUR_BINDING     1
27
28namespace OgreOde
29{
30    //------------------------------------------------------------------------------------------------
31    DebugContact::DebugContact(const String &name, World *world) : 
32        _enabled(false),
33        _name(name), 
34        _world(world)
35    {
36        // scene node
37        _node = _world->getSceneManager()->getRootSceneNode ()->createChildSceneNode ();
38
39        // sphere attach to contact point
40        _point = _world->getSceneManager()->createEntity(name + String("_debug_point"), "sphere.mesh");
41        _point_node = _node->createChildSceneNode ();
42        _point_node->attachObject (_point);
43        _point_node->setScale(0.001, 0.001, 0.001);
44
45        // normal direction debug
46         _normal = new DebugNormal();
47         _node->attachObject (_normal);
48
49         // text info on contact
50        _text = new DebugContactText(name + String("_debug_text"), _node->createChildSceneNode ());
51        _text->setPosition (Vector3(0,5,0));
52        _text->setCaption ("-");
53        _text->setVisible (false);
54
55        _node->setVisible (false);
56    }
57     //------------------------------------------------------------------------------------------------
58    DebugContact::~DebugContact()
59    {
60        delete _text;
61
62        _point_node->detachObject (_point->getName ());
63        _node->detachObject (_normal->getName ());
64
65        _world->getSceneManager()->destroyEntity (_point->getName ());
66
67        _node->detachAllObjects ();
68        _node->removeAndDestroyAllChildren ();
69
70        delete _normal;
71    }
72    //------------------------------------------------------------------------------------------------
73    void DebugContact::update(Contact * const contact)
74    {
75        _node->setPosition (contact->getPosition ());
76
77        _point_node->setPosition (contact->getPenetrationDepth () * contact->getNormal());
78
79        //String contactLabel("p: ");
80        //contactLabel = contactLabel + StringConverter::toString(contact->getPosition());
81        //contactLabel = contactLabel + ", n: ";
82        //contactLabel = contactLabel + StringConverter::toString(contact->getNormal());
83        //_text->setCaption (contactLabel);
84        //_text->setVisible (false);
85
86        //_text->setPosition (contact->getPosition () + Vector3(0,5,0));
87       
88        _normal->update (contact);
89    }
90    //------------------------------------------------------------------------------------------------
91    bool DebugContact::isEnabled () const 
92    {
93        return _enabled;
94    }
95    //------------------------------------------------------------------------------------------------
96    void DebugContact::setEnabled (bool enable)
97    {
98        _enabled = enable;
99        _node->setVisible (_enabled);
100    };
101    //------------------------------------------------------------------------------------------------
102    void DebugNormal::update(Contact * const contact)
103    {
104       DebugLines::clear ();
105       // set normal following contact normal
106       //contact->_normal
107       //contact->_position
108       DebugLines::addLine (Vector3::ZERO, 
109                            5*contact->getNormal ());
110        DebugLines::draw ();
111    }
112    //------------------------------------------------------------------------------------------------
113    DebugContactText::DebugContactText(const String &name, 
114                                SceneNode *node,
115                                const String &caption, 
116                                const String &fontName, 
117                                int charHeight, 
118                                const ColourValue &color)
119        : mFontName(fontName)
120        , mType("DebugContact")
121        , mName(name)
122        , mCaption(caption)
123        , mHorizontalAlignment(H_LEFT)
124        , mVerticalAlignment(V_BELOW)
125        , mColor(color)
126        , mCharHeight(charHeight)
127        , mSpaceWidth(0)
128        , mUpdateColors(true)
129        , mOnTop(false)
130        , mTimeUntilNextToggle(0)
131        , mAdditionalHeight(0.0)
132        , mpCam(NULL)
133        , mpWin(NULL)
134        , mpFont(NULL)
135        , mNode(node)
136
137    {
138        if (name.empty())
139            Exception(Exception::ERR_INVALIDPARAMS, "Trying to create DebugContact without name", "DebugContact::DebugContact");
140//
141//         if (caption.empty())
142//            Exception(Exception::ERR_INVALIDPARAMS, "Trying to create DebugContact without caption", "DebugContact::DebugContact");
143
144        mRenderOp.vertexData = NULL;
145        this->setFontName(mFontName);
146        //this->_setupGeometry();
147        mNode->attachObject(this);
148    }
149    //------------------------------------------------------------------------------------------------
150    DebugContactText::~DebugContactText()
151    {
152        mNode->detachObject(this->getName());
153        if (mRenderOp.vertexData)
154            delete mRenderOp.vertexData;
155    }
156    //------------------------------------------------------------------------------------------------
157    void DebugContactText::setPosition(const Vector3 &pos)
158    {
159        mNode->setPosition (pos);
160    }
161    //------------------------------------------------------------------------------------------------
162    void DebugContactText::setFontName(const String &fontName)
163    {
164        if((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material"))) 
165        { 
166            Ogre::MaterialManager::getSingleton().remove(mName + "Material"); 
167        }
168
169        if (mFontName != fontName || mpMaterial.isNull() || !mpFont)
170        {
171            mFontName = fontName;
172            mpFont = (Font *)FontManager::getSingleton().getByName(mFontName).getPointer();
173            if (!mpFont)
174                Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "DebugContact::setFontName");
175
176            mpFont->load();
177            if (!mpMaterial.isNull())
178            {
179                MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
180                mpMaterial.setNull();
181            }
182
183            mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
184            if (!mpMaterial->isLoaded())
185                mpMaterial->load();
186
187            mpMaterial->setDepthCheckEnabled(!mOnTop);
188            mpMaterial->setDepthBias(0,!mOnTop);
189            mpMaterial->setDepthWriteEnabled(mOnTop);
190            mpMaterial->setLightingEnabled(false);
191            mNeedUpdate = true;
192        }
193    }
194    //------------------------------------------------------------------------------------------------
195    void DebugContactText::setCaption(const String &caption)
196    {
197        if (caption != mCaption)
198        {
199            mCaption = caption;
200            mNeedUpdate = true;
201        }
202    }
203    //------------------------------------------------------------------------------------------------
204    void DebugContactText::setColor(const ColourValue &color)
205    {
206        if (color != mColor)
207        {
208            mColor = color;
209            mUpdateColors = true;
210        }
211    }
212    //------------------------------------------------------------------------------------------------
213    void DebugContactText::setCharacterHeight(unsigned int height)
214    {
215        if (height != mCharHeight)
216        {
217            mCharHeight = height;
218            mNeedUpdate = true;
219        }
220    }
221    //------------------------------------------------------------------------------------------------
222    void DebugContactText::setSpaceWidth(unsigned int width)
223    {
224        if (width != mSpaceWidth)
225        {
226            mSpaceWidth = width;
227            mNeedUpdate = true;
228        }
229    }
230    //------------------------------------------------------------------------------------------------
231    void DebugContactText::setTextAlignment(const HorizontalAlignment& horizontalAlignment, const VerticalAlignment& verticalAlignment)
232    {
233        if(mHorizontalAlignment != horizontalAlignment)
234        {
235            mHorizontalAlignment = horizontalAlignment;
236            mNeedUpdate = true;
237        }
238        if(mVerticalAlignment != verticalAlignment)
239        {
240            mVerticalAlignment = verticalAlignment;
241            mNeedUpdate = true;
242        }
243    }
244    //------------------------------------------------------------------------------------------------
245    void DebugContactText::setAdditionalHeight( Real height )
246    {
247        if( mAdditionalHeight != height )
248        {
249            mAdditionalHeight = height;
250            mNeedUpdate = true;
251        }
252    }
253    //------------------------------------------------------------------------------------------------
254    void DebugContactText::showOnTop(bool show)
255    {
256        if( mOnTop != show && !mpMaterial.isNull() )
257        {
258            mOnTop = show;
259            mpMaterial->setDepthBias(0,!mOnTop);
260            mpMaterial->setDepthCheckEnabled(!mOnTop);
261            mpMaterial->setDepthWriteEnabled(mOnTop);
262        }
263    }
264    //------------------------------------------------------------------------------------------------
265    void DebugContactText::_setupGeometry()
266    {
267        assert(mpFont);
268        assert(!mpMaterial.isNull());
269
270        unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6);
271
272        if (mRenderOp.vertexData)
273        {
274            // Removed this test as it causes problems when replacing a caption
275            // of the same size: replacing "Hello" with "hello"
276            // as well as when changing the text alignment
277            //if (mRenderOp.vertexData->vertexCount != vertexCount)
278            {
279                delete mRenderOp.vertexData;
280                mRenderOp.vertexData = NULL;
281                mUpdateColors = true;
282            }
283        }
284
285        if (!mRenderOp.vertexData)
286            mRenderOp.vertexData = new VertexData();
287
288        mRenderOp.indexData = 0;
289        mRenderOp.vertexData->vertexStart = 0;
290        mRenderOp.vertexData->vertexCount = vertexCount;
291        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 
292        mRenderOp.useIndexes = false; 
293
294        VertexDeclaration  *decl = mRenderOp.vertexData->vertexDeclaration;
295        VertexBufferBinding   *bind = mRenderOp.vertexData->vertexBufferBinding;
296        size_t offset = 0;
297
298        // create/bind positions/tex.ccord. buffer
299        if (!decl->findElementBySemantic(VES_POSITION))
300            decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);
301
302        offset += VertexElement::getTypeSize(VET_FLOAT3);
303
304        if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
305            decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
306
307        HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
308            mRenderOp.vertexData->vertexCount,
309            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
310        bind->setBinding(POS_TEX_BINDING, ptbuf);
311
312        // Colours - store these in a separate buffer because they change less often
313        if (!decl->findElementBySemantic(VES_DIFFUSE))
314            decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
315
316        HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
317            mRenderOp.vertexData->vertexCount,
318            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
319        bind->setBinding(COLOUR_BINDING, cbuf);
320
321                // Unused variable
322        //size_t charlen = mCaption.size();
323        Real *pPCBuff = static_cast<Real*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));
324
325        float largestWidth = 0;
326        float left = 0 * 2.0 - 1.0;
327        float top = -((0 * 2.0) - 1.0);
328
329        // Derive space width from a capital A
330        if (mSpaceWidth == 0)
331            mSpaceWidth = (unsigned int)(mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0);
332
333        // for calculation of AABB
334        Ogre::Vector3 min, max, currPos;
335        Ogre::Real maxSquaredRadius;
336        bool first = true;
337
338        // Use iterator
339        String::iterator i, iend;
340        iend = mCaption.end();
341        bool newLine = true;
342        Real len = 0.0f;
343
344        if(mVerticalAlignment == DebugContactText::V_ABOVE)
345        {
346            // Raise the first line of the caption
347            top += mCharHeight;
348            for (i = mCaption.begin(); i != iend; ++i)
349            {
350                if (*i == '\n')
351                    top += mCharHeight * 2.0;
352            }
353        }
354
355        for (i = mCaption.begin(); i != iend; ++i)
356        {
357            if (newLine)
358            {
359                len = 0.0f;
360                for (String::iterator j = i; j != iend && *j != '\n'; j++)
361                {
362                    if (*j == ' ')
363                        len += mSpaceWidth;
364                    else 
365                        len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0;
366                }
367                newLine = false;
368            }
369
370            if (*i == '\n')
371            {
372                left = 0 * 2.0 - 1.0;
373                top -= mCharHeight * 2.0;
374                newLine = true;
375                continue;
376            }
377
378            if (*i == ' ')
379            {
380                // Just leave a gap, no tris
381                left += mSpaceWidth;
382                // Also reduce tri count
383                mRenderOp.vertexData->vertexCount -= 6;
384                continue;
385            }
386
387            Real horiz_height = mpFont->getGlyphAspectRatio(*i);
388            const Font::UVRect &uvRect = mpFont->getGlyphTexCoords(*i);
389            const Real u1 = uvRect.left; 
390            const Real u2 = uvRect.right; 
391            const Real v1 = uvRect.top; 
392            const Real v2 = uvRect.bottom; 
393
394            // each vert is (x, y, z, u, v)
395            //-------------------------------------------------------------------------------------
396            // First tri
397            //
398            // Upper left
399            if(mHorizontalAlignment == DebugContactText::H_LEFT)
400                *pPCBuff++ = left;
401            else
402                *pPCBuff++ = left - (len / 2);
403            *pPCBuff++ = top;
404            *pPCBuff++ = -1.0;
405            *pPCBuff++ = u1;
406            *pPCBuff++ = v1;
407
408            // Deal with bounds
409            if(mHorizontalAlignment == DebugContactText::H_LEFT)
410                currPos = Ogre::Vector3(left, top, -1.0);
411            else
412                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
413            if (first)
414            {
415                min = max = currPos;
416                maxSquaredRadius = currPos.squaredLength();
417                first = false;
418            }
419            else
420            {
421                min.makeFloor(currPos);
422                max.makeCeil(currPos);
423                maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
424            }
425
426            top -= mCharHeight * 2.0;
427
428            // Bottom left
429            if(mHorizontalAlignment == DebugContactText::H_LEFT)
430                *pPCBuff++ = left;
431            else
432                *pPCBuff++ = left - (len / 2);
433            *pPCBuff++ = top;
434            *pPCBuff++ = -1.0;
435            *pPCBuff++ = u1;
436            *pPCBuff++ = v2;
437
438            // Deal with bounds
439            if(mHorizontalAlignment == DebugContactText::H_LEFT)
440                currPos = Ogre::Vector3(left, top, -1.0);
441            else
442                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
443            min.makeFloor(currPos);
444            max.makeCeil(currPos);
445            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
446
447            top += mCharHeight * 2.0;
448            left += horiz_height * mCharHeight * 2.0;
449
450            // Top right
451            if(mHorizontalAlignment == DebugContactText::H_LEFT)
452                *pPCBuff++ = left;
453            else
454                *pPCBuff++ = left - (len / 2);
455            *pPCBuff++ = top;
456            *pPCBuff++ = -1.0;
457            *pPCBuff++ = u2;
458            *pPCBuff++ = v1;
459            //-------------------------------------------------------------------------------------
460
461            // Deal with bounds
462            if(mHorizontalAlignment == DebugContactText::H_LEFT)
463                currPos = Ogre::Vector3(left, top, -1.0);
464            else
465                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
466            min.makeFloor(currPos);
467            max.makeCeil(currPos);
468            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
469
470            //-------------------------------------------------------------------------------------
471            // Second tri
472            //
473            // Top right (again)
474            if(mHorizontalAlignment == DebugContactText::H_LEFT)
475                *pPCBuff++ = left;
476            else
477                *pPCBuff++ = left - (len / 2);
478            *pPCBuff++ = top;
479            *pPCBuff++ = -1.0;
480            *pPCBuff++ = u2;
481            *pPCBuff++ = v1;
482
483            currPos = Ogre::Vector3(left, top, -1.0);
484            min.makeFloor(currPos);
485            max.makeCeil(currPos);
486            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
487
488            top -= mCharHeight * 2.0;
489            left -= horiz_height  * mCharHeight * 2.0;
490
491            // Bottom left (again)
492            if(mHorizontalAlignment == DebugContactText::H_LEFT)
493                *pPCBuff++ = left;
494            else
495                *pPCBuff++ = left - (len / 2);
496            *pPCBuff++ = top;
497            *pPCBuff++ = -1.0;
498            *pPCBuff++ = u1;
499            *pPCBuff++ = v2;
500
501            currPos = Ogre::Vector3(left, top, -1.0);
502            min.makeFloor(currPos);
503            max.makeCeil(currPos);
504            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
505
506            left += horiz_height  * mCharHeight * 2.0;
507
508            // Bottom right
509            if(mHorizontalAlignment == DebugContactText::H_LEFT)
510                *pPCBuff++ = left;
511            else
512                *pPCBuff++ = left - (len / 2);
513            *pPCBuff++ = top;
514            *pPCBuff++ = -1.0;
515            *pPCBuff++ = u2;
516            *pPCBuff++ = v2;
517            //-------------------------------------------------------------------------------------
518
519            currPos = Ogre::Vector3(left, top, -1.0);
520            min.makeFloor(currPos);
521            max.makeCeil(currPos);
522            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
523
524            // Go back up with top
525            top += mCharHeight * 2.0;
526
527            float currentWidth = (left + 1)/2 - 0;
528            if (currentWidth > largestWidth)
529                largestWidth = currentWidth;
530        }
531
532        // Unlock vertex buffer
533        ptbuf->unlock();
534
535        // update AABB/Sphere radius
536        mAABB = Ogre::AxisAlignedBox(min, max);
537        mRadius = Ogre::Math::Sqrt(maxSquaredRadius);
538
539        if (mUpdateColors)
540            this->_updateColors();
541
542        mNeedUpdate = false;
543    }
544    //------------------------------------------------------------------------------------------------
545    void DebugContactText::_updateColors(void)
546    {
547        assert(mpFont);
548        assert(!mpMaterial.isNull());
549
550        // Convert to system-specific
551        RGBA color;
552        Root::getSingleton().convertColourValue(mColor, &color);
553        HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
554        RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
555        for (unsigned int i = 0; i < mRenderOp.vertexData->vertexCount; ++i)
556            *pDest++ = color;
557        vbuf->unlock();
558        mUpdateColors = false;
559    }
560    //------------------------------------------------------------------------------------------------
561#if OGRE_VERSION < ((1 << 16) | (5 << 8))
562    const Quaternion& DebugContactText::getWorldOrientation(void) const
563#else
564    const Quaternion& DebugContactText::_getDerivedOrientation(void) const
565#endif
566    {
567        assert(mpCam);
568        return const_cast<Quaternion&>(mpCam->getDerivedOrientation());
569    }
570    //------------------------------------------------------------------------------------------------
571#if OGRE_VERSION < ((1 << 16) | (5 << 8))
572    const Vector3& DebugContactText::getWorldPosition(void) const
573#else
574    const Vector3& DebugContactText::_getDerivedPosition(void) const
575#endif
576    {
577        assert(mParentNode);
578        return mParentNode->_getDerivedPosition();
579    }
580    //------------------------------------------------------------------------------------------------
581    void DebugContactText::getWorldTransforms(Matrix4 *xform) const 
582    {   
583        if (this->isVisible() && mpCam)
584        {
585            Matrix3 rot3x3, scale3x3 = Matrix3::IDENTITY;
586
587            // store rotation in a matrix
588            mpCam->getDerivedOrientation().ToRotationMatrix(rot3x3);
589
590            // parent node position
591            Vector3 ppos = mParentNode->_getDerivedPosition() + Vector3::UNIT_Y*mAdditionalHeight;
592
593            // apply scale
594            scale3x3[0][0] = mParentNode->_getDerivedScale().x / 2;
595            scale3x3[1][1] = mParentNode->_getDerivedScale().y / 2;
596            scale3x3[2][2] = mParentNode->_getDerivedScale().z / 2;
597
598            // apply all transforms to xform       
599            *xform = (rot3x3 * scale3x3);
600            xform->setTrans(ppos);
601        }
602   }
603    //------------------------------------------------------------------------------------------------
604    void DebugContactText::getRenderOperation(RenderOperation &op)
605    {
606        if (this->isVisible())
607        {
608            if (mNeedUpdate)
609                this->_setupGeometry();
610            if (mUpdateColors)
611                this->_updateColors();
612            op = mRenderOp;
613        }
614    }
615    //------------------------------------------------------------------------------------------------
616    void DebugContactText::_notifyCurrentCamera(Camera *cam)
617    {
618        mpCam = cam;
619    }
620    //------------------------------------------------------------------------------------------------
621    void DebugContactText::_updateRenderQueue(RenderQueue* queue)
622    {
623        if (this->isVisible())
624        {
625            if (mNeedUpdate)
626                this->_setupGeometry();
627            if (mUpdateColors)
628                this->_updateColors();
629
630            queue->addRenderable(this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY);
631            //      queue->addRenderable(this, mRenderQueueID, RENDER_QUEUE_SKIES_LATE);
632        }
633    }
634}
Note: See TracBrowser for help on using the repository browser.