Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/src/OgreOdeGeometry.cpp @ 62

Last change on this file since 62 was 21, checked in by nicolasc, 16 years ago

added ogreode and Colladaplugin

File size: 43.3 KB
Line 
1
2#include "OgreOdePrecompiledHeaders.h"
3
4#include "OgreOdeGeometry.h"
5#include "OgreOdeWorld.h"
6#include "OgreOdeSpace.h"
7#include "OgreOdeBody.h"
8#include "OgreOdeCollision.h"
9#include "OgreOdeDebugObject.h"
10#include "OgreOdeDebugContact.h"
11
12using namespace OgreOde;
13using namespace Ogre;
14
15//------------------------------------------------------------------------------------------------
16int Geometry::_geometry_count = 0;
17
18//------------------------------------------------------------------------------------------------
19Geometry::Geometry(World *world, Space* space):
20    UserDefinedObject(),
21        _contact_high_water_mark (0),
22    _last_contact_num(0),
23        _max_contacts (32),
24    _debug_contacts (0),
25        _contacts (0),
26        _encapsulator (0),
27        _debug_obj (0),
28        _debug_node (0),
29        _user_data (0),
30        _user_object (0),
31        _geom (0),
32    _world(world)
33{
34       
35}
36//------------------------------------------------------------------------------------------------
37Geometry::~Geometry()
38{
39    destroyDebugObject();
40
41    delete[] _contacts;
42    if (_debug_contacts)
43    {         
44        for (unsigned int i = 0; i < _max_contacts; i++)
45            delete _debug_contacts[i];
46        delete [] _debug_contacts;
47    }
48    if (_geom)
49    {
50        _world->getGeometryList().unregisterItem((unsigned long)_geom);
51        dGeomDestroy(_geom); 
52    }
53}
54//------------------------------------------------------------------------------------------------
55dGeomID Geometry::getGeometryID() const
56{
57        return _geom;
58}
59
60//------------------------------------------------------------------------------------------------
61void Geometry::setEncapsulator(Geometry* encapsulator)
62{
63        _encapsulator = encapsulator;
64
65        if (_world->getShowDebugGeometries())
66        {
67                reparentDebugObject(encapsulator->_debug_node);
68        }
69}
70
71//------------------------------------------------------------------------------------------------
72void Geometry::reparentDebugObject(Ogre::Node* node)
73{
74        if ((node)&&(_debug_node)&&(_debug_node->getParent() != node))
75        {
76                Ogre::SceneNode* parent = static_cast<Ogre::SceneNode*>(_debug_node->getParent());
77                parent->removeChild(_debug_node->getName());
78                node->addChild(_debug_node);
79
80                _debug_node->setPosition(getPosition());
81                _debug_node->setOrientation(getOrientation());
82        }
83}
84
85//------------------------------------------------------------------------------------------------
86void Geometry::createDebugObject()
87{
88        if (!_debug_node)
89        {
90                Ogre::SceneNode* parent = _world->_manager->getRootSceneNode();
91                _debug_node = static_cast<Ogre::Node*>(parent->createChildSceneNode(Ogre::String("OgreOde::Geometry_") + Ogre::StringConverter::toString(_geometry_count) + Ogre::String("_Debug"))); 
92
93        if (_debug_obj)
94        {
95            static_cast<Ogre::SceneNode*>(_debug_node)->attachObject(_debug_obj);
96        }
97
98        if (getBody())
99        {
100            static_cast<Ogre::SceneNode*>(_debug_node->getParent())->removeChild(_debug_node->getName());
101            getBody()->addDebugNode(_debug_node);
102            if (_debug_obj) 
103                _debug_obj->setMode(DebugObject::Mode_Enabled);
104        }
105                else if (_encapsulator)
106                {
107                        reparentDebugObject(_encapsulator->_debug_node);
108                }
109                else
110                {
111                        if (_debug_obj) 
112                _debug_obj->setMode(DebugObject::Mode_Static);
113                       
114                        _debug_node->setPosition(getPosition());
115                        _debug_node->setOrientation(getOrientation());
116                }
117                _geometry_count++;
118        }
119}
120
121//------------------------------------------------------------------------------------------------
122void Geometry::destroyDebugObject()
123{
124        if (_debug_node)
125    {
126
127        Ogre::SceneNode* sn = static_cast<Ogre::SceneNode*>(_debug_node);
128        sn->removeAndDestroyAllChildren ();
129        sn = static_cast<Ogre::SceneNode*>(_debug_node->getParent());
130        sn->removeAndDestroyChild(_debug_node->getName());
131                _debug_node = 0;
132        }
133
134        if (_debug_obj)
135        {
136                delete _debug_obj;
137                _debug_obj = 0;
138        }
139}
140
141//------------------------------------------------------------------------------------------------
142void Geometry::registerGeometry()
143{
144        dGeomSetData(_geom, (void*)this);
145    _world->getGeometryList().registerItem(this);
146
147    if (_world->getShowDebugGeometries()) 
148        createDebugObject();
149
150    setMaxContacts (_max_contacts);
151}
152//------------------------------------------------------------------------------------------------
153dSpaceID Geometry::getSpaceID(Space* space) const
154{
155        if (!space) return 0;
156        return space->getSpaceID();
157}
158
159//------------------------------------------------------------------------------------------------
160void Geometry::setBody(Body* body)
161{
162        destroyDebugObject();
163    if (body)
164    {
165        body->addGeometry (this);
166        dGeomSetBody(_geom, body->getBodyID()); 
167    }
168    else
169    {
170        dGeomSetBody(_geom, 0); 
171    }
172        if (_world->getShowDebugGeometries()) 
173        createDebugObject();
174}
175
176//------------------------------------------------------------------------------------------------
177Body* Geometry::getBody()
178{
179        const dBodyID body = dGeomGetBody(_geom);
180        if (!body) return 0;
181        else return (Body*)dBodyGetData(body); 
182}
183
184//------------------------------------------------------------------------------------------------
185void Geometry::notify(Body* body)
186{
187        if (getBody() == body)
188        {
189                destroyDebugObject();
190        }
191}
192
193//------------------------------------------------------------------------------------------------
194void Geometry::setDebug(const bool debug)
195{
196    destroyDebugObject();
197    if (debug) 
198        createDebugObject();   
199}
200//------------------------------------------------------------------------------------------------
201void Geometry::setDebugContact(const bool debug)
202{   
203    if (_debug_contacts)
204    {
205        for (unsigned int i = 0; i < _max_contacts; i++)
206            delete _debug_contacts[i];
207        delete [] _debug_contacts;
208        _debug_contacts = 0;
209    }
210    if (debug) 
211    {
212        _debug_contacts = new DebugContact*[_max_contacts];
213        for (unsigned int i = 0; i < _max_contacts; i++)
214            _debug_contacts[i] = new DebugContact(Ogre::StringConverter::toString(_geom) + 
215                                                    "_Contact_" + 
216                                                    Ogre::StringConverter::toString(i),
217                                                    _world);
218    }
219}
220//------------------------------------------------------------------------------------------------
221void Geometry::setPosition(const Ogre::Vector3& position)
222{
223    dGeomSetPosition(_geom,(dReal)position.x,(dReal)position.y,(dReal)position.z);
224
225    if ((_debug_node)&& ((!getBody()) || (_encapsulator)))
226        _debug_node->setPosition(position);
227}
228
229//------------------------------------------------------------------------------------------------
230void Geometry::setOrientation(const Ogre::Quaternion& orientation)
231{
232        dQuaternion q;
233        q[0] = (dReal)orientation.w;
234        q[1] = (dReal)orientation.x;
235        q[2] = (dReal)orientation.y;
236        q[3] = (dReal)orientation.z;
237        dGeomSetQuaternion(_geom,q); 
238
239        if ((_debug_node)&& ((!getBody()) || (_encapsulator))) _debug_node->setOrientation(orientation);
240}
241
242//------------------------------------------------------------------------------------------------
243const Ogre::Vector3& Geometry::getPosition()
244{
245        const dReal* position = dGeomGetPosition(_geom);
246        _position.x = (Ogre::Real)position[0];
247        _position.y = (Ogre::Real)position[1];
248        _position.z = (Ogre::Real)position[2];
249        return _position;
250}
251
252//------------------------------------------------------------------------------------------------
253const Ogre::Quaternion& Geometry::getOrientation()
254{
255        dQuaternion orientation;
256        dGeomGetQuaternion(_geom,orientation); 
257        _orientation.w = (Real)orientation[0];
258        _orientation.x = (Real)orientation[1];
259        _orientation.y = (Real)orientation[2];
260        _orientation.z = (Real)orientation[3];
261        return _orientation;
262}
263
264//------------------------------------------------------------------------------------------------
265const AxisAlignedBox& Geometry::getAxisAlignedBox()
266{
267        dReal aabb[6];
268        dGeomGetAABB(_geom,aabb);
269        _bounding_box.setExtents((Real)aabb[0],(Real)aabb[2],(Real)aabb[4],(Real)aabb[1],(Real)aabb[3],(Real)aabb[5]);
270        return _bounding_box;
271}
272
273//------------------------------------------------------------------------------------------------
274Space* Geometry::getSpace()
275{
276        return (Space*)_world->getSpaceList().findItem((long unsigned int)dGeomGetSpace(_geom));
277}
278
279
280//------------------------------------------------------------------------------------------------
281void Geometry::enable()
282{
283        dGeomEnable(_geom);
284}
285
286//------------------------------------------------------------------------------------------------
287void Geometry::disable()
288{
289        dGeomDisable(_geom); 
290}
291
292//------------------------------------------------------------------------------------------------
293bool Geometry::isEnabled()
294{
295        return dGeomIsEnabled(_geom); 
296}
297
298//------------------------------------------------------------------------------------------------
299Geometry::Class Geometry::getClass() const
300{
301        return (Geometry::Class)dGeomGetClass(_geom);
302}
303
304//------------------------------------------------------------------------------------------------
305void Geometry::setCategoryBitfield(unsigned long bits)
306{
307        dGeomSetCategoryBits(_geom,bits); 
308}
309
310//------------------------------------------------------------------------------------------------
311void Geometry::setCollisionBitfield(unsigned long bits)
312{
313        dGeomSetCollideBits(_geom,bits); 
314}
315
316//------------------------------------------------------------------------------------------------
317unsigned long Geometry::getCategoryBitfield()
318{
319        return dGeomGetCategoryBits(_geom); 
320}
321
322//------------------------------------------------------------------------------------------------
323unsigned long Geometry::getCollisionBitfield()
324{
325        return dGeomGetCollideBits(_geom); 
326}
327
328//------------------------------------------------------------------------------------------------
329int Geometry::collide(Geometry* geometry,CollisionListener* listener)
330{
331        const unsigned int num_contacts = (unsigned int) dCollide(_geom,
332                                                                                geometry->getGeometryID(),
333                                                                                _max_contacts,
334                                                                                &(_contacts[0].geom),
335                                                                                sizeof(dContact));
336        if (num_contacts)
337        {
338                _contact_high_water_mark = std::max(_contact_high_water_mark,num_contacts);
339
340                Contact contact;
341               
342                const dWorldID wid = _world->getWorldID();
343                const dJointGroupID cid = _world->getContactGroupID();
344                const dBodyID b1 = dGeomGetBody(_geom);
345                const dBodyID b2 = dGeomGetBody(geometry->getGeometryID());
346
347                if (listener)
348                {
349                        for(unsigned int i = 0;i < num_contacts;i++)
350                        {
351                                contact.setContact (&_contacts[i]);
352
353                                if (listener->collision(&contact))
354                                {
355                                        dJointAttach(dJointCreateContact(wid,cid,&_contacts[i]),b1,b2);
356                } 
357                        }
358                }
359                else
360                {
361                        for(unsigned int i = 0;i < num_contacts;i++)
362                        {
363                                contact.setContact (&_contacts[i]);
364   
365                                dJointAttach(dJointCreateContact(wid,cid,&_contacts[i]), b1, b2);
366                        }
367                } 
368    }
369    _last_contact_num = num_contacts;
370        return num_contacts;
371}
372//------------------------------------------------------------------------------------------------
373void Geometry::updateDebugContact()
374{
375    assert (_world->getShowDebugContact ());
376    assert (_debug_contacts);
377    {
378        unsigned int k = 0;
379        while (k < _max_contacts)
380        {
381            _debug_contacts[k++]->setEnabled(false);
382        }
383
384        if (_last_contact_num)
385        {
386            Contact contact;
387            for(unsigned int i = 0;i < _last_contact_num;i++)
388            {
389                k = 0;
390                while (k < _max_contacts)
391                {
392                    if (_debug_contacts[k]->isEnabled() == false)
393                        break;
394                    k++;
395                }
396                assert (k < _max_contacts);
397
398                _debug_contacts[k]->setEnabled(true);
399                contact.setContact (&_contacts[i]);
400                _debug_contacts[k]->update (&contact);
401            }
402        }
403    }
404    _last_contact_num = 0;
405 }
406//------------------------------------------------------------------------------------------------
407unsigned int Geometry::getMaxContacts() const
408{
409        return _max_contacts;
410}
411
412//------------------------------------------------------------------------------------------------
413void Geometry::setMaxContacts(unsigned int max_contacts)
414{
415        delete[] _contacts;
416        _contacts = new dContact[max_contacts];
417
418    if (_world->getShowDebugContact ())
419    {
420        if (_debug_contacts)
421        {         
422            for (unsigned int i = 0; i < _max_contacts; i++)
423                delete _debug_contacts[i];
424            delete [] _debug_contacts;
425        }
426        _debug_contacts = new DebugContact*[max_contacts];
427        for (unsigned int i = 0; i < max_contacts; i++)
428            _debug_contacts[i] = new DebugContact(Ogre::StringConverter::toString(_geom) +  + "_Contact_" + Ogre::StringConverter::toString(i),
429            _world);
430    }
431    _max_contacts = max_contacts;
432}
433
434//------------------------------------------------------------------------------------------------
435unsigned int Geometry::getContactHighWaterMark() const
436{
437        return _contact_high_water_mark;
438}
439
440//------------------------------------------------------------------------------------------------
441unsigned long Geometry::getID() const
442{
443        return (unsigned long)_geom;
444}
445//------------------------------------------------------------------------------------------------
446void Geometry::clearOffset()
447{
448        dGeomClearOffset(_geom);
449}
450//------------------------------------------------------------------------------------------------
451int Geometry::isOffset()
452{
453        return dGeomIsOffset(_geom);
454}
455//------------------------------------------------------------------------------------------------
456void Geometry::setOffsetPosition (const Ogre::Vector3 &pos)
457{
458        dGeomSetOffsetPosition (_geom, pos.x, pos.y, pos.z);
459}
460//------------------------------------------------------------------------------------------------
461void Geometry::setOffsetQuaternion(const Ogre::Quaternion &quat) 
462{
463        dQuaternion q;
464        q[0] = quat.x; 
465        q[1] = quat.y; 
466        q[2] = quat.z; 
467        q[3] = quat.w;
468        dGeomSetOffsetQuaternion (_geom, q);
469}
470//------------------------------------------------------------------------------------------------
471void Geometry::setOffsetWorldPosition(const Ogre::Vector3 &pos) 
472{
473        dGeomSetOffsetWorldPosition(_geom, pos.x, pos.y, pos.z);
474}
475//------------------------------------------------------------------------------------------------
476void Geometry::setOffsetWorldQuaternion(const Ogre::Quaternion &quat) 
477{
478        dQuaternion q;
479        q[0] = quat.x; 
480        q[1] = quat.y; 
481        q[2] = quat.z; 
482        q[3] = quat.w;
483        dGeomSetOffsetWorldQuaternion (_geom, q);
484}
485//------------------------------------------------------------------------------------------------
486Vector3 Geometry::getOffsetPosition() 
487{
488        const dReal *p =  dGeomGetOffsetPosition (_geom);
489        return Ogre::Vector3(p[0], p[1], p[2]);
490}
491//------------------------------------------------------------------------------------------------
492Quaternion Geometry::getOffsetQuaternion() 
493{
494        dQuaternion q;
495        dGeomGetOffsetQuaternion (_geom, q);
496        return Ogre::Quaternion(q[0], q[1], q[2], q[3]);
497}
498//------------------------------------------------------------------------------------------------
499SphereGeometry::SphereGeometry(Real radius, World *world, Space* space):Geometry(world, space)
500{
501        _geom = dCreateSphere(getSpaceID(space),(dReal)radius); 
502        registerGeometry();
503}
504
505//------------------------------------------------------------------------------------------------
506void SphereGeometry::setRadius(Real radius)
507{
508        dGeomSphereSetRadius(_geom,(dReal)radius);
509}
510
511//------------------------------------------------------------------------------------------------
512Real SphereGeometry::getRadius()
513{
514        return (Real)dGeomSphereGetRadius(_geom); 
515}
516
517//------------------------------------------------------------------------------------------------
518Real SphereGeometry::getPointDepth(const Ogre::Vector3& point)
519{
520        return (Real)dGeomSpherePointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
521}
522
523//------------------------------------------------------------------------------------------------
524void SphereGeometry::createDebugObject()
525{
526        _debug_obj = new SphereDebugObject(getRadius());
527        Geometry::createDebugObject();
528}
529
530//------------------------------------------------------------------------------------------------
531SphereGeometry::~SphereGeometry()
532{
533}
534
535//------------------------------------------------------------------------------------------------
536BoxGeometry::BoxGeometry(const Ogre::Vector3& size, World *world, Space* space):Geometry(world, space)
537{
538        _geom = dCreateBox(getSpaceID(space),(dReal)size.x,(dReal)size.y,(dReal)size.z); 
539        registerGeometry();
540}
541
542//------------------------------------------------------------------------------------------------
543void BoxGeometry::setSize(const Ogre::Vector3& size)
544{
545        dGeomBoxSetLengths(_geom,(dReal)size.x,(dReal)size.y,(dReal)size.z); 
546}
547
548//------------------------------------------------------------------------------------------------
549const Ogre::Vector3& BoxGeometry::getSize()
550{
551        dVector3 result;
552        dGeomBoxGetLengths(_geom,result); 
553        _size.x = (Real)result[0];
554        _size.y = (Real)result[1];
555        _size.z = (Real)result[2];
556        return _size;
557}
558
559//------------------------------------------------------------------------------------------------
560Real BoxGeometry::getPointDepth(const Ogre::Vector3& point)
561{
562        return (Real)dGeomBoxPointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
563}
564
565//------------------------------------------------------------------------------------------------
566void BoxGeometry::createDebugObject()
567{
568        _debug_obj = new BoxDebugObject(getSize());
569        Geometry::createDebugObject(); 
570}
571
572//------------------------------------------------------------------------------------------------
573BoxGeometry::~BoxGeometry()
574{
575}
576
577//------------------------------------------------------------------------------------------------
578InfinitePlaneGeometry::InfinitePlaneGeometry(const Plane& plane,World *world, Space* space):Geometry(world, space)
579{
580        _geom = dCreatePlane(getSpaceID(space),(dReal)plane.normal.x,(dReal)plane.normal.y,(dReal)plane.normal.z,(dReal)-plane.d); 
581        registerGeometry();
582}
583
584//------------------------------------------------------------------------------------------------
585void InfinitePlaneGeometry::setDefinition(const Plane& plane)
586{
587        dGeomPlaneSetParams(_geom,(dReal)plane.normal.x,(dReal)plane.normal.y,(dReal)plane.normal.z,(dReal)-plane.d); 
588}
589
590//------------------------------------------------------------------------------------------------
591const Plane& InfinitePlaneGeometry::getDefinition()
592{
593        dVector4 result;
594        dGeomPlaneGetParams(_geom,result); 
595        _plane.normal.x = result[0];
596        _plane.normal.y = result[1];
597        _plane.normal.z = result[2];
598        _plane.d = -result[3];
599        return _plane;
600}
601
602//------------------------------------------------------------------------------------------------
603Real InfinitePlaneGeometry::getPointDepth(const Ogre::Vector3& point)
604{
605        return (Real)dGeomPlanePointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
606}
607
608//------------------------------------------------------------------------------------------------
609void InfinitePlaneGeometry::setPosition(const Ogre::Vector3& position)
610{
611}
612
613//------------------------------------------------------------------------------------------------
614void InfinitePlaneGeometry::setOrientation(const Ogre::Quaternion& orientation)
615{
616}
617
618//------------------------------------------------------------------------------------------------
619const Ogre::Vector3& InfinitePlaneGeometry::getPosition()
620{
621        return Ogre::Vector3::ZERO;
622}
623
624//------------------------------------------------------------------------------------------------
625const Ogre::Quaternion& InfinitePlaneGeometry::getOrientation()
626{
627        return Ogre::Quaternion::ZERO;
628}
629
630//------------------------------------------------------------------------------------------------
631const AxisAlignedBox& InfinitePlaneGeometry::getAxisAlignedBox()
632{
633        return _bounding_box;
634}
635
636//------------------------------------------------------------------------------------------------
637InfinitePlaneGeometry::~InfinitePlaneGeometry()
638{
639}
640
641//------------------------------------------------------------------------------------------------
642CapsuleGeometry::CapsuleGeometry(Real radius,Real length,World *world, Space* space):Geometry(world, space)
643{
644        _geom = dCreateCapsule(getSpaceID(space),(dReal)radius,(dReal)length);
645        registerGeometry();
646}
647
648//------------------------------------------------------------------------------------------------
649void CapsuleGeometry::setDefinition(Real radius,Real length)
650{
651        dGeomCapsuleSetParams(_geom,(dReal)radius,(dReal)length);
652}
653
654//------------------------------------------------------------------------------------------------
655Real CapsuleGeometry::getRadius()
656{
657        dReal radius,length;
658        dGeomCapsuleGetParams(_geom,&radius,&length); 
659        return radius;
660}
661
662//------------------------------------------------------------------------------------------------
663Real CapsuleGeometry::getLength()
664{
665        dReal radius,length;
666        dGeomCapsuleGetParams(_geom,&radius,&length); 
667        return length;
668}
669
670//------------------------------------------------------------------------------------------------
671Real CapsuleGeometry::getPointDepth(const Ogre::Vector3& point)
672{
673        return (Real)dGeomCapsulePointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
674}
675
676//------------------------------------------------------------------------------------------------
677void CapsuleGeometry::createDebugObject()
678{
679        _debug_obj = new CapsuleDebugObject(getRadius(),getLength());
680        Geometry::createDebugObject();
681}
682
683//------------------------------------------------------------------------------------------------
684CapsuleGeometry::~CapsuleGeometry()
685{
686}
687
688//------------------------------------------------------------------------------------------------
689CylinderGeometry::CylinderGeometry(Real radius,Real length,World *world, Space* space):Geometry(world, space)
690{
691        _geom = dCreateCCylinder(getSpaceID(space),(dReal)radius,(dReal)length);
692        registerGeometry();
693}
694
695//------------------------------------------------------------------------------------------------
696void CylinderGeometry::setDefinition(Real radius,Real length)
697{
698        dGeomCCylinderSetParams(_geom,(dReal)radius,(dReal)length);
699}
700
701//------------------------------------------------------------------------------------------------
702Real CylinderGeometry::getRadius()
703{
704        dReal radius,length;
705        dGeomCCylinderGetParams(_geom,&radius,&length); 
706        return radius;
707}
708
709//------------------------------------------------------------------------------------------------
710Real CylinderGeometry::getLength()
711{
712        dReal radius,length;
713        dGeomCCylinderGetParams(_geom,&radius,&length); 
714        return length;
715}
716
717//------------------------------------------------------------------------------------------------
718Real CylinderGeometry::getPointDepth(const Ogre::Vector3& point)
719{
720        return (Real)dGeomCCylinderPointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
721}
722
723//------------------------------------------------------------------------------------------------
724void CylinderGeometry::createDebugObject()
725{
726        _debug_obj = new CylinderDebugObject(getRadius(),getLength());
727        Geometry::createDebugObject();
728}
729
730//------------------------------------------------------------------------------------------------
731CylinderGeometry::~CylinderGeometry()
732{
733}
734//------------------------------------------------------------------------------------------------
735RayGeometry::RayGeometry(Real length,World *world, Space* space) : Geometry(world, space)
736{
737        _geom = dCreateRay(getSpaceID(space),(dReal)length);
738        registerGeometry();
739}
740
741//------------------------------------------------------------------------------------------------
742void RayGeometry::createDebugObject()
743{
744        _debug_obj = new RayDebugObject(getStart(),getDirection(),getLength());
745        Geometry::createDebugObject();
746        if (_debug_node)
747        {
748                _debug_node->setPosition(Vector3::ZERO);
749                _debug_node->setOrientation(Quaternion::IDENTITY);
750        }
751}
752
753//------------------------------------------------------------------------------------------------
754void RayGeometry::setLength(Real length)
755{
756        dGeomRaySetLength(_geom,(dReal)length); 
757}
758
759//------------------------------------------------------------------------------------------------
760Real RayGeometry::getLength()
761{
762        return (Real)dGeomRayGetLength(_geom); 
763}
764
765//------------------------------------------------------------------------------------------------
766void RayGeometry::setDefinition(const Ogre::Vector3& start,const Ogre::Vector3& direction)
767{
768        dGeomRaySet(_geom,
769                                        (dReal)start.x,(dReal)start.y,(dReal)start.z,
770                                        (dReal)direction.x,(dReal)direction.y,(dReal)direction.z);
771
772        if ((_debug_node)&& ((!getBody()) || (_encapsulator))) 
773                (static_cast<RayDebugObject *>(_debug_obj))->setDefinition(start, direction, (Real)dGeomRayGetLength(_geom));
774
775}
776
777//------------------------------------------------------------------------------------------------
778const Ogre::Vector3& RayGeometry::getStart()
779{
780        dVector3 start,direction;
781        dGeomRayGet(_geom,start,direction); 
782        _start.x = (Real)start[0];
783        _start.y = (Real)start[1];
784        _start.z = (Real)start[2];
785        return _start;
786}
787
788//------------------------------------------------------------------------------------------------
789const Ogre::Vector3& RayGeometry::getDirection()
790{
791        dVector3 start,direction;
792        dGeomRayGet(_geom,start,direction); 
793        _direction.x = (Real)direction[0];
794        _direction.y = (Real)direction[1];
795        _direction.z = (Real)direction[2];
796        return _direction;
797}
798
799//------------------------------------------------------------------------------------------------
800RayGeometry::~RayGeometry()
801{
802}
803
804//------------------------------------------------------------------------------------------------
805TransformGeometry::TransformGeometry(World *world, Space* space) : Geometry(world, space)
806{
807        _geom = dCreateGeomTransform(getSpaceID(space)); 
808        dGeomTransformSetCleanup(_geom,0);
809        dGeomTransformSetInfo(_geom,1);
810        registerGeometry();
811}
812
813//------------------------------------------------------------------------------------------------
814void TransformGeometry::setEncapsulatedGeometry(Geometry* geometry)
815{
816        dGeomTransformSetGeom(_geom,geometry->getGeometryID()); 
817        destroyDebugObject();
818        if (_world->getShowDebugGeometries()) 
819                createDebugObject();   
820
821        geometry->setEncapsulator(this);
822}
823
824//------------------------------------------------------------------------------------------------
825void TransformGeometry::createDebugObject()
826{
827        Geometry::createDebugObject();
828        if (getEncapsulatedGeometry())
829        {
830                getEncapsulatedGeometry()->destroyDebugObject();
831                getEncapsulatedGeometry()->createDebugObject();
832        }
833}
834
835//------------------------------------------------------------------------------------------------
836void TransformGeometry::destroyDebugObject()
837{
838        if (getEncapsulatedGeometry()) getEncapsulatedGeometry()->destroyDebugObject();
839        Geometry::destroyDebugObject();
840}
841
842//------------------------------------------------------------------------------------------------
843Geometry* TransformGeometry::getEncapsulatedGeometry() const
844{
845        dGeomID id = dGeomTransformGetGeom(_geom);
846        if (id == 0) return 0;
847        else return (Geometry*)dGeomGetData(id); 
848}
849
850//------------------------------------------------------------------------------------------------
851TransformGeometry::~TransformGeometry()
852{
853}
854
855
856//------------------------------------------------------------------------------------------------
857TriangleMeshGeometry::TriangleMeshGeometry(const Ogre::Vector3* vertices,
858                                           unsigned int vertex_count,
859                                           const unsigned int* indices,
860                                           unsigned int index_count,
861                                           World *world, Space* space) : 
862    Geometry(world, space),
863    _vertex_count (vertex_count),
864    _index_count (index_count)
865{
866        _vertex_count = vertex_count;
867        _index_count = index_count;
868        _vertices = new dVector3[vertex_count];
869        _indices = new unsigned int[index_count];
870
871        for(unsigned int i = 0;i < vertex_count;i++)
872        {
873                _vertices[i][0] = (dReal)vertices[i].x;
874                _vertices[i][1] = (dReal)vertices[i].y;
875                _vertices[i][2] = (dReal)vertices[i].z;
876        }
877
878        memcpy(_indices,indices,sizeof(unsigned int) * index_count);
879
880        _data = dGeomTriMeshDataCreate(); 
881        dGeomTriMeshDataBuildSimple(_data,(const dReal*)_vertices, (int)vertex_count, (int*)_indices, (int)index_count); 
882        _geom = dCreateTriMesh(getSpaceID(space),_data,0,0,0);
883        registerGeometry();
884
885        _collision_listener = 0;
886}
887
888//------------------------------------------------------------------------------------------------
889Vector3 TriangleMeshGeometry::getPoint(unsigned int index,const Ogre::Vector3& uv)
890{
891        dVector3 out;
892        dGeomTriMeshGetPoint(_geom, (int) index, (dReal)uv.x, (dReal)uv.y, out); 
893        return Ogre::Vector3((Real)out[0],(Real)out[1],(Real)out[2]);
894}
895
896//------------------------------------------------------------------------------------------------
897TriangleMeshTriangle TriangleMeshGeometry::getTriangle(int index)
898{
899        dVector3 v0,v1,v2;
900        dGeomTriMeshGetTriangle(_geom,(int)index, &v0, &v1, &v2); 
901       
902        TriangleMeshTriangle tri;
903
904        tri.v0.x = v0[0]; tri.v0.y = v0[1]; tri.v0.z = v0[2];
905        tri.v1.x = v1[0]; tri.v1.y = v1[1]; tri.v1.z = v1[2];
906        tri.v2.x = v2[0]; tri.v2.y = v2[1]; tri.v2.z = v2[2];
907       
908        return tri;
909}
910
911//------------------------------------------------------------------------------------------------
912void TriangleMeshGeometry::clearTemporalCoherenceCache()
913{
914        dGeomTriMeshClearTCCache(_geom); 
915}
916
917//------------------------------------------------------------------------------------------------
918void TriangleMeshGeometry::enableTemporalCoherence(Geometry::Class geometry_class, bool enable)
919{
920        assert((geometry_class == Geometry::Class_Sphere)||(geometry_class == Geometry::Class_Box));
921        dGeomTriMeshEnableTC(_geom,(int)geometry_class,(enable)?1:0); 
922}
923
924//------------------------------------------------------------------------------------------------
925bool TriangleMeshGeometry::isTemporalCoherenceEnabled(Geometry::Class geometry_class)
926{
927        return ((dGeomTriMeshIsTCEnabled(_geom,(int)geometry_class))?true:false);
928}
929
930//------------------------------------------------------------------------------------------------
931int TriangleMeshGeometry::_collisionCallback(dGeomID mesh,dGeomID object,int triangle)
932{
933        TriangleMeshGeometry* trimesh = (TriangleMeshGeometry*)dGeomGetData(mesh);
934        if (trimesh->_collision_listener)
935        {
936                Geometry* geometry = (object)?((Geometry*)dGeomGetData(object)):0;
937                return ((trimesh->_collision_listener->collide(trimesh,geometry,triangle))?1:0);
938        }
939        return 1;
940}
941
942//------------------------------------------------------------------------------------------------
943void TriangleMeshGeometry::setCollisionListener(TriangleMeshCollisionListener* collision_listener)
944{
945        _collision_listener = collision_listener;
946        dGeomTriMeshSetCallback(_geom,(_collision_listener)?TriangleMeshGeometry::_collisionCallback:0); 
947}
948
949//------------------------------------------------------------------------------------------------
950void TriangleMeshGeometry::_intersectionCallback(dGeomID mesh,dGeomID object,const int* triangles,int triangle_count)
951{
952        TriangleMeshGeometry* trimesh = (TriangleMeshGeometry*)dGeomGetData(mesh);
953        if (trimesh->_intersection_listener)
954        {
955                Geometry* geometry = (object)?((Geometry*)dGeomGetData(object)):0;
956                trimesh->_intersection_listener->intersect(trimesh,geometry,triangles,triangle_count);
957        }
958}
959
960//------------------------------------------------------------------------------------------------
961void TriangleMeshGeometry::setIntersectionListener(TriangleMeshIntersectionListener* intersection_listener)
962{
963        _intersection_listener = intersection_listener;
964        dGeomTriMeshSetArrayCallback(_geom,(_intersection_listener)?TriangleMeshGeometry::_intersectionCallback:0); 
965}
966
967//------------------------------------------------------------------------------------------------
968int TriangleMeshGeometry::_rayCallback(dGeomID mesh,dGeomID ray,int triangle,dReal u,dReal v)
969{
970        TriangleMeshGeometry* trimesh = (TriangleMeshGeometry*)dGeomGetData(mesh);
971        if (trimesh->_ray_listener)
972        {
973                RayGeometry* ray_geometry = (ray)?((RayGeometry*)dGeomGetData(ray)):0;
974                return ((trimesh->_ray_listener->collide(trimesh,ray_geometry,triangle,Vector3((Real)u,(Real)v,0.0)))?1:0);
975        }
976        return 1;
977}
978
979//------------------------------------------------------------------------------------------------
980void TriangleMeshGeometry::setRayListener(TriangleMeshRayListener* ray_listener)
981{
982        _ray_listener = ray_listener;
983        dGeomTriMeshSetRayCallback(_geom,(_ray_listener)?TriangleMeshGeometry::_rayCallback:0); 
984}
985
986//------------------------------------------------------------------------------------------------
987void TriangleMeshGeometry::createDebugObject()
988{
989        _debug_obj = new TriangleMeshDebugObject((_index_count / 3) * 6);
990        TriangleMeshDebugObject* obj = static_cast<TriangleMeshDebugObject*>(_debug_obj);
991
992        obj->beginDefinition();
993        for(unsigned int i = 0,j = 0;i < _index_count;i+=3,j+=6)
994        {
995                obj->setVertex(j,Vector3((Real)_vertices[_indices[i]][0],(Real)_vertices[_indices[i]][1],(Real)_vertices[_indices[i]][2]));
996                obj->setVertex(j+1,Vector3((Real)_vertices[_indices[i+1]][0],(Real)_vertices[_indices[i+1]][1],(Real)_vertices[_indices[i+1]][2]));
997
998                obj->setVertex(j+2,Vector3((Real)_vertices[_indices[i+1]][0],(Real)_vertices[_indices[i+1]][1],(Real)_vertices[_indices[i+1]][2]));
999                obj->setVertex(j+3,Vector3((Real)_vertices[_indices[i+2]][0],(Real)_vertices[_indices[i+2]][1],(Real)_vertices[_indices[i+2]][2]));
1000
1001                obj->setVertex(j+4,Vector3((Real)_vertices[_indices[i+2]][0],(Real)_vertices[_indices[i+2]][1],(Real)_vertices[_indices[i+2]][2]));
1002                obj->setVertex(j+5,Vector3((Real)_vertices[_indices[i]][0],(Real)_vertices[_indices[i]][1],(Real)_vertices[_indices[i]][2]));
1003        }
1004        obj->endDefinition();
1005
1006        Geometry::createDebugObject();
1007}
1008
1009//------------------------------------------------------------------------------------------------
1010TriangleMeshGeometry::~TriangleMeshGeometry()
1011{
1012        dGeomTriMeshDataDestroy(_data); 
1013        delete[] _vertices;
1014        delete[] _indices;
1015}
1016
1017
1018//------------------------------------------------------------------------------------------------
1019ConvexGeometry::ConvexGeometry(const Ogre::Vector3* vertices,
1020                                                           unsigned int vertex_count,
1021                                                           const unsigned int* indices,
1022                                                           unsigned int index_count,
1023                               World *world, Space* space) : 
1024    Geometry(world, space),
1025    _vertex_count (vertex_count),
1026    _index_count (index_count)
1027{
1028        _vertices = new dReal[vertex_count*3];
1029        _indices = new unsigned int[index_count];
1030
1031        for(unsigned int i = 0;i < vertex_count;i++)
1032        {
1033                _vertices[i*3 + 0] = (dReal)vertices[i].x;
1034                _vertices[i*3 + 1] = (dReal)vertices[i].y;
1035                _vertices[i*3 + 2] = (dReal)vertices[i].z;
1036        }
1037
1038        memcpy(_indices,indices,sizeof(unsigned int) * index_count);
1039
1040
1041        _geom = dCreateConvex (getSpaceID(space),
1042                0,//dReal *_planes,
1043                0,//unsigned int _planecount,
1044                _vertices,
1045                vertex_count,
1046                0);//unsigned int *_polygons)
1047
1048        //      dGeomSetConvex (dGeomID g,
1049        //              dReal *_planes,
1050        //              unsigned int _count,
1051        //              dReal *_points,
1052        //              unsigned int _pointcount,unsigned int *_polygons);
1053
1054        registerGeometry();
1055}
1056//------------------------------------------------------------------------------------------------
1057void ConvexGeometry::createDebugObject()
1058{
1059        _debug_obj = new TriangleMeshDebugObject((_index_count / 3) * 6);
1060        TriangleMeshDebugObject* obj = static_cast<TriangleMeshDebugObject*>(_debug_obj);
1061
1062        obj->beginDefinition();
1063        for(unsigned int i = 0,j = 0;i < _index_count;i+=3,j+=6)
1064        {
1065                obj->setVertex(j,Vector3((Real)_vertices[_indices[i]*3 + 0],(Real)_vertices[_indices[i]*3 + 1],(Real)_vertices[_indices[i]*3 + 2]));
1066                obj->setVertex(j+1,Vector3((Real)_vertices[_indices[i+1]*3 + 0],(Real)_vertices[_indices[i+1]*3 + 1],(Real)_vertices[_indices[i+1]*3 + 2]));
1067
1068                obj->setVertex(j+2,Vector3((Real)_vertices[_indices[i+1]*3 + 0],(Real)_vertices[_indices[i+1]*3 + 1],(Real)_vertices[_indices[i+1]*3 + 2]));
1069                obj->setVertex(j+3,Vector3((Real)_vertices[_indices[i+2]*3 + 0],(Real)_vertices[_indices[i+2]*3 + 1],(Real)_vertices[_indices[i+2]*3 + 2]));
1070
1071                obj->setVertex(j+4,Vector3((Real)_vertices[_indices[i+2]*3 + 0],(Real)_vertices[_indices[i+2]*3 + 1],(Real)_vertices[_indices[i+2]*3 + 2]));
1072                obj->setVertex(j+5,Vector3((Real)_vertices[_indices[i]*3 + 0],(Real)_vertices[_indices[i]*3 + 1],(Real)_vertices[_indices[i]*3 + 2]));
1073        }
1074        obj->endDefinition();
1075
1076        Geometry::createDebugObject();
1077}
1078//------------------------------------------------------------------------------------------------
1079ConvexGeometry::~ConvexGeometry()
1080{
1081        delete[] _vertices;
1082        delete[] _indices;
1083}
1084
1085//------------------------------------------------------------------------------------------------
1086TerrainGeometry::TerrainGeometry(World *world, Space* space,
1087                                                                const Ogre::Vector3 &scale,
1088                                int nodes_per_sideX,
1089                                int nodes_per_sideY,
1090                                Ogre::Real worldSizeX,
1091                                Ogre::Real worldSizeZ,
1092                                                                bool centered,
1093                                Ogre::Real thickness) :
1094                        Geometry(world, space),
1095                        _sample_width(scale.x),
1096                        _sample_height(scale.z),
1097                        _max_height (scale.y),
1098                        _halfWorldSizeX(worldSizeX * 0.5),
1099                        _halfWorldSizeZ(worldSizeZ * 0.5),
1100                        _centered(centered)
1101{
1102        dHeightfieldDataID heightid = dGeomHeightfieldDataCreate();
1103        dGeomHeightfieldDataBuildCallback(      heightid, //getSpaceID(space),
1104                                                                                this, // pUserData ?
1105                                                                                TerrainGeometry::_heightCallback, 
1106                                                                                (dReal) (worldSizeX), //X
1107                                                                                (dReal) (worldSizeZ), //Z
1108                                                                                nodes_per_sideX, // w // Vertex count along edge >= 2
1109                                                                                nodes_per_sideY, // h // Vertex count along edge >= 2
1110                                                                                REAL( 1.0 ),     //scale
1111                                                                                REAL( 0.0 ),    // vOffset
1112                                                                                thickness,      // vThickness
1113                                                                                 0); // nWrapMode
1114
1115
1116        // Give some very bounds which, while conservative,
1117        // makes AABB computation more accurate than +/-INF.
1118        dGeomHeightfieldDataSetBounds( heightid, REAL( 0.0 ),  _max_height );
1119        _geom = dCreateHeightfield( getSpaceID(space), heightid, 1 );
1120
1121        _listener = 0;
1122        _ray = Ogre::Ray (Ogre::Vector3::ZERO, Ogre::Vector3::NEGATIVE_UNIT_Y);
1123        _ray_query = _world->getSceneManager()->createRayQuery(_ray);
1124
1125        _ray_query->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
1126        _ray_query->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION); 
1127
1128        registerGeometry();
1129
1130        if (_centered)
1131        {
1132                // PLSM2 is centered by default.       
1133        //setPosition (Ogre::Vector3::ZERO);
1134        ;
1135        }
1136        else
1137        {
1138        // TSM is not centered by default.     
1139                setPosition (Ogre::Vector3(_halfWorldSizeX, 
1140                                    0, 
1141                                    _halfWorldSizeZ));
1142        }
1143        setOrientation(Ogre::Quaternion::ZERO);
1144}
1145
1146//------------------------------------------------------------------------------------------------
1147dReal TerrainGeometry::_heightCallback(void* data,int x,int z)
1148{
1149        TerrainGeometry * const terrain = (TerrainGeometry*)data;   
1150        if (terrain->_listener)
1151        {
1152                return static_cast <dReal> (terrain->_listener->heightAt(Vector3((Ogre::Real)x,
1153                                                                terrain->_max_height,
1154                                                                (Ogre::Real)z)));
1155        }
1156    else
1157    {
1158        return static_cast <dReal> (terrain->getHeightAt(Vector3((Ogre::Real)x, 
1159                                                        terrain->_max_height, 
1160                                                        (Ogre::Real)z)));
1161    }
1162}
1163
1164//------------------------------------------------------------------------------------------------
1165Ogre::Real TerrainGeometry::getPointDepth(const Ogre::Vector3& point)
1166{
1167        //return (Real)dGeomTerrainCallbackPointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
1168        //return (Real) dGeomHeightfieldPointDepth (_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
1169        //dGetDepthFn(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
1170        return (Real) 0.0;
1171}
1172
1173//------------------------------------------------------------------------------------------------
1174void TerrainGeometry::setHeightListener(TerrainGeometryHeightListener* listener)
1175{
1176        _listener = listener;
1177}
1178//------------------------------------------------------------------------------------------------
1179bool TerrainGeometry::queryResult(Ogre::MovableObject *obj, Ogre::Real distance)
1180{
1181        return false;
1182}
1183
1184//------------------------------------------------------------------------------------------------
1185bool TerrainGeometry::queryResult(Ogre::SceneQuery::WorldFragment *fragment,Ogre::Real distance)
1186{
1187        _distance_to_terrain = distance;
1188        return false;
1189}
1190//------------------------------------------------------------------------------------------------
1191const Ogre::Vector3& TerrainGeometry::getPosition()
1192{
1193        return Ogre::Vector3::ZERO;
1194}
1195
1196//------------------------------------------------------------------------------------------------
1197const Ogre::Quaternion& TerrainGeometry::getOrientation()
1198{
1199        return Ogre::Quaternion::ZERO;
1200}
1201
1202//------------------------------------------------------------------------------------------------
1203TerrainGeometry::~TerrainGeometry()
1204{
1205        _world->getSceneManager()->destroyQuery(_ray_query);
1206}
1207
1208//------------------------------------------------------------------------------------------------
1209std::list<Ogre::Plane>* PlaneBoundedRegionGeometry::_planeCallback(void* data,int x,int z)
1210{
1211    PlaneBoundedRegionGeometry* terrain = (PlaneBoundedRegionGeometry*)data;
1212
1213    if (terrain->_listener)
1214    {
1215        return terrain->_listener->planesAt(Vector3((Ogre::Real)x,
1216            terrain->_max_height,
1217            (Ogre::Real)z));
1218    }
1219    else
1220    {
1221        return  terrain->planesAt(Vector3((Ogre::Real)x, 
1222                terrain->_max_height, 
1223                (Ogre::Real)z));
1224    }
1225    return 0;
1226}
1227//------------------------------------------------------------------------------------------------
1228PlaneBoundedRegionGeometry::PlaneBoundedRegionGeometry (World *world, Space* space,
1229                                                        const Ogre::AxisAlignedBox &Size) : 
1230    Geometry(world,space)
1231{
1232
1233    _ray = Ogre::Ray (Ogre::Vector3::ZERO, Ogre::Vector3::NEGATIVE_UNIT_Y);
1234    _ray_query = _world->getSceneManager()->createRayQuery(_ray);
1235
1236    _ray_query->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
1237    _ray_query->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION); 
1238
1239}
1240
1241//------------------------------------------------------------------------------------------------
1242Ogre::Real PlaneBoundedRegionGeometry::getPointDepth(const Ogre::Vector3& point)
1243{
1244    //dGetDepthFn(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
1245    return (Real) 0.0;
1246}
1247
1248//------------------------------------------------------------------------------------------------
1249void PlaneBoundedRegionGeometry::setPlaneListener(PlaneBoundedRegionGeometryPlaneListener* listener)
1250{
1251    _listener = listener;
1252}
1253//------------------------------------------------------------------------------------------------
1254bool PlaneBoundedRegionGeometry::queryResult(Ogre::MovableObject *obj, Ogre::Real distance)
1255{
1256    return false;
1257}
1258
1259//------------------------------------------------------------------------------------------------
1260bool PlaneBoundedRegionGeometry::queryResult(Ogre::SceneQuery::WorldFragment *fragment,Ogre::Real distance)
1261{
1262    _distance_to_terrain = distance;
1263    return false;
1264}
1265//------------------------------------------------------------------------------------------------
1266const Ogre::Vector3& PlaneBoundedRegionGeometry::getPosition()
1267{
1268    return Ogre::Vector3::ZERO;
1269}
1270
1271//------------------------------------------------------------------------------------------------
1272const Ogre::Quaternion& PlaneBoundedRegionGeometry::getOrientation()
1273{
1274    return Ogre::Quaternion::ZERO;
1275}
1276
1277//------------------------------------------------------------------------------------------------
1278PlaneBoundedRegionGeometry::~PlaneBoundedRegionGeometry()
1279{
1280    _world->getSceneManager()->destroyQuery(_ray_query);
1281}
1282
1283
Note: See TracBrowser for help on using the repository browser.