Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/prefab/src/OgreOdeRagdoll.cpp @ 21

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

added ogreode and Colladaplugin

File size: 24.1 KB
Line 
1
2#include "OgreOdeWorld.h"
3#include "OgreOdeBody.h"
4#include "OgreOdeJoint.h"
5#include "OgreOdeGeometry.h"
6#include "OgreOdeSpace.h"
7#include "OgreOdeEntityInformer.h"
8#include "OgreOdeMass.h"
9#include "OgreOdeUtility.h"
10
11#include "OgreOde_Prefab.h"
12#include "OgreOdeRagdoll.h"
13
14using namespace Ogre;
15using namespace OgreOde;
16using namespace OgreOde_Prefab;
17
18
19//------------------------------------------------------------------------------------------------
20Ragdoll::PhysicalBone::PhysicalBone()
21{
22        _body = 0;
23        _geometry = 0;
24        _original_position = Ogre::Vector3::ZERO;
25        _original_orientation = Ogre::Quaternion::IDENTITY;
26        _bone = 0;
27        _parent_bone = 0;
28        _joint = 0;
29        _motor = 0;
30}
31//------------------------------------------------------------------------------------------------
32Ragdoll::PhysicalBone::~PhysicalBone()
33{
34        delete _joint;
35        delete _geometry;
36        delete _body;
37        delete _motor;
38
39        for (RagdollPhysicalBoneList::iterator i = _child_bones.begin();
40        i != _child_bones.end(); ++i) 
41        delete (*i);
42}
43//------------------------------------------------------------------------------------------------
44Ragdoll::BoneSettings::BoneSettings()
45{
46        _geometry_class         = Geometry::Class_Capsule;
47        _joint_type                     = Joint::Type_BallJoint;
48        _primary_axis           = Ogre::Vector3::UNIT_X;
49        _secondary_axis         = Ogre::Vector3::UNIT_Y;
50        _collapse                       = Ragdoll::BoneSettings::Collapse_None;
51        _mass                           = 1.0;
52        _radius                         = 1.0;
53        _primary_histop         = OgreOde::Utility::Infinity;
54        _primary_lostop         = -OgreOde::Utility::Infinity;
55        _secondary_histop       = OgreOde::Utility::Infinity;
56        _secondary_lostop       = -OgreOde::Utility::Infinity;
57        _linear_damping     = 0.0;
58        _angular_damping    = 0.0;
59}
60//------------------------------------------------------------------------------------------------
61Ragdoll::BoneSettings::~BoneSettings()
62{
63}
64//------------------------------------------------------------------------------------------------
65Ragdoll::Ragdoll(const String& name, MeshPtr& ptr):
66    Entity(name, ptr),
67    Object(OgreOde_Prefab::ObjectType_Ragdoll, 0)
68{ 
69        setDefaultBoneSettings(Ragdoll::BoneSettings());
70        _ei = 0;
71        _joint_group = 0;
72        _is_static = true;
73        _space = 0;
74        _is_physical = false;
75
76        _node_trans = Matrix4::IDENTITY;
77        _node_trans_inv = _node_trans.inverse();
78        _node_orient = Ogre::Quaternion::IDENTITY;
79        _node_posn = Ogre::Vector3::ZERO;
80    _is_hardwareAnimationRemovedByMe = false;
81
82    //mDisplaySkeleton = true;
83}
84
85//------------------------------------------------------------------------------------------------
86void Ragdoll::sleep(Ragdoll::PhysicalBone* bone)
87{
88        bone->_body->sleep();
89        for (RagdollPhysicalBoneList::iterator i = bone->_child_bones.begin();
90                i != bone->_child_bones.end();++i)
91        {
92                sleep(*i);
93        }
94}
95//------------------------------------------------------------------------------------------------
96void Ragdoll::sleep()
97{
98        if (!_is_static)
99        {
100                for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();
101                        i != _root_bones.end();++i)
102                {
103                        sleep(*i);
104                }
105        }
106}
107//------------------------------------------------------------------------------------------------
108bool Ragdoll::isAwake(Ragdoll::PhysicalBone* bone)
109{
110        if (bone->_body->isAwake())
111                return true;
112        for (RagdollPhysicalBoneList::iterator i = bone->_child_bones.begin();
113                i != bone->_child_bones.end();++i)
114        {
115                if (isAwake(*i) == true)
116                        return true;
117        }
118        return false;
119}
120//------------------------------------------------------------------------------------------------
121bool Ragdoll::isAwake()
122{
123        if (!_is_static)
124        {
125                for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();
126                        i != _root_bones.end();++i)
127                {
128                        if (isAwake(*i) == true)
129                                return true;
130                }
131        }
132        return false;
133}
134//------------------------------------------------------------------------------------------------
135void Ragdoll::wake(Ragdoll::PhysicalBone* bone)
136{
137        bone->_body->wake();
138        for (RagdollPhysicalBoneList::iterator i = bone->_child_bones.begin();
139                i != bone->_child_bones.end();++i)
140        {
141                wake(*i);
142        }
143}
144//------------------------------------------------------------------------------------------------
145void Ragdoll::wake()
146{
147        if (!_is_static)
148        {
149                for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();
150                        i != _root_bones.end();++i)
151                {
152                        wake(*i);
153                }
154        }
155}
156//------------------------------------------------------------------------------------------------
157void Ragdoll::setDefaultBoneSettings(const Ragdoll::BoneSettings &settings)
158{
159        _default_bone_settings = settings;
160}
161//------------------------------------------------------------------------------------------------
162void Ragdoll::setBoneSettings(const String& bone_name,const Ragdoll::BoneSettings &settings)
163{
164        _bone_settings.insert(std::pair<String,Ragdoll::BoneSettings>(bone_name,settings));
165}
166//------------------------------------------------------------------------------------------------
167void Ragdoll::setSelfCollisions(bool collide)
168{
169        _space->setInternalCollisions(collide);
170}
171//------------------------------------------------------------------------------------------------
172void Ragdoll::takePhysicalControl(World *world, Space* space,bool static_geometry)
173{
174    _world = world;
175    // disable Hardware Animation
176    assert (hasSkeleton()) ;
177    if (isHardwareAnimationEnabled())
178    {   
179        const unsigned int numSubEntities  = getNumSubEntities ();
180        for (unsigned int k = 0; k < numSubEntities; k++)
181        {
182            SubEntity *subEntity = getSubEntity (k);
183
184            MaterialPtr mHWAnimated = MaterialManager::getSingleton().getByName(subEntity->getMaterialName ());
185            // check if we didn't modify that once before
186            MaterialPtr mSWAnimated = MaterialManager::getSingleton().getByName(subEntity->getMaterialName ()  + "ClonedSW");
187            if (mSWAnimated.isNull ())
188            {
189                mSWAnimated = mHWAnimated->clone (subEntity->getMaterialName () + "ClonedSW");
190                mSWAnimated->load ();
191
192                bool notEmptiedOfHWTechnique = true;
193                bool removedAtLeastOne = false;
194                Technique *t;
195                while (notEmptiedOfHWTechnique)
196                {             
197                    unsigned short i = 0  ;     
198                    const unsigned short numTechniques = mSWAnimated->getNumSupportedTechniques ();
199                    while (i < numTechniques)
200                    {
201                        t = mSWAnimated->getSupportedTechnique (i);
202                        if (t->getPass(0) &&
203                            t->getPass(0)->hasVertexProgram() &&
204                            t->getPass(0)->getVertexProgram()->isSkeletalAnimationIncluded()
205                            //t->getPass(0)->getVertexProgram()->isPoseAnimationIncluded() ??
206                            )
207                        {
208                            mSWAnimated->removeTechnique (i);
209                            removedAtLeastOne = true;
210                            break;
211                        }
212                        i++;
213                    }
214                    if (i == numTechniques)
215                    {
216                        notEmptiedOfHWTechnique = false;
217                        mSWAnimated->reload ();
218                    }
219                    // re-loop to ensure there is no HW animation left...                   
220                }
221            }
222            subEntity->setMaterialName (mSWAnimated->getName());               
223        }
224        _is_hardwareAnimationRemovedByMe = true;
225    }
226
227        // Cache node transformations
228        _node_posn = mParentNode->_getDerivedPosition();
229        _node_orient = mParentNode->_getDerivedOrientation();
230        _node_trans = mParentNode->_getFullTransform();
231        _node_trans_inv = _node_trans.inverse();
232
233        _space = new SimpleSpace(world, space);
234        _space->setInternalCollisions(false);
235        _space->setAutoCleanup(false);
236
237        _is_physical = true;
238        _is_static = static_geometry;
239
240        _joint_group = new JointGroup(_world);
241
242        _ei = new EntityInformer(this, _node_trans);
243
244
245    addSoftwareAnimationRequest(false);
246
247    Skeleton::BoneIterator rbi = mSkeletonInstance->getRootBoneIterator();
248
249        while(rbi.hasMoreElements())
250        {
251                createBoneBody(rbi.getNext(), 0, static_geometry);
252        }
253
254}
255//------------------------------------------------------------------------------------------------
256void Ragdoll::createBoneBody(Bone *bone,Ragdoll::PhysicalBone *parent,bool static_geometry)
257{
258        // We're controlling the bone now
259        bone->setManuallyControlled (true);
260    //bone->setInheritOrientation (false);
261
262        // Make up a name
263        String body_name = mName + bone->getName();
264
265        // Cache bone transformations
266        Matrix4 bone_trans = bone->_getFullTransform();
267        Vector3 bone_posn = bone->_getDerivedPosition();
268        Quaternion bone_orient = bone->_getDerivedOrientation();
269
270        // Find the settings for this bone, or use defaults
271        std::map<String,Ragdoll::BoneSettings>::iterator i = _bone_settings.find(bone->getName());
272        Ragdoll::BoneSettings settings = (i != _bone_settings.end())? i->second : _default_bone_settings;       
273        Ragdoll::PhysicalBone *physical_bone = 0;
274
275        // Create an oriented capsule
276        if (settings._geometry_class == Geometry::Class_Capsule)
277        {
278                // Create the geometry
279                CapsuleGeometry *geom = _ei->createOrientedCapsule(bone->getHandle(), _world, _space);
280                if (geom)
281                {
282                        // Create a bone
283                        physical_bone = new Ragdoll::PhysicalBone();
284                        physical_bone->_body = (static_geometry)?0:(new Body(_world, body_name));
285                        physical_bone->_geometry = geom;
286
287                        // Don't collapse, set capsule inertia tensor
288                        if (settings._collapse == Ragdoll::BoneSettings::Collapse_None)
289                        {
290                                if (physical_bone->_body) 
291                    physical_bone->_body->setMass(
292                            CapsuleMass(settings._mass,
293                                        geom->getRadius(),
294                                        Ogre::Vector3::UNIT_Z,
295                                        geom->getLength()));
296                        }
297                        else
298                        {
299                                // Get the details of the capsule we created and work out where it is in relation to the bone (joint)
300                                const Ogre::Real radius = geom->getRadius();
301                                const Ogre::Real length = geom->getLength();
302                                const Ogre::Quaternion orient = geom->getOrientation(); 
303                               
304                                const Ogre::Vector3 jpos = _node_trans * bone_posn;
305                                const Ogre::Vector3 posn = geom->getPosition();
306                                const Ogre::Vector3 offs = jpos - posn;
307
308                                // Don't need the capsule geometry anymore, create a new sphere one
309                                delete geom;
310                SphereGeometry *newGeom = new SphereGeometry(radius, _world, _space);
311                                physical_bone->_geometry = newGeom;
312                                if (physical_bone->_body) 
313                    physical_bone->_body->setMass(SphereMass(settings._mass,radius));
314
315                                // Move the geometry up away from the joint, or down to the joint
316                                if (settings._collapse == Ragdoll::BoneSettings::Collapse_Up)
317                                {
318                                        newGeom->setPosition(posn - offs);
319                                        newGeom->setOrientation(orient);
320                                }
321                                else
322                                {
323                                        newGeom->setPosition(posn + offs);
324                                        newGeom->setOrientation(orient);
325                                }
326                        }
327                }
328        }
329        // Create an oriented box
330        else if (settings._geometry_class == Geometry::Class_Box)
331        {
332                BoxGeometry *geom = _ei->createOrientedBox(bone->getHandle(), _world, _space);
333                if (geom)
334                {
335                        physical_bone = new Ragdoll::PhysicalBone();
336                        physical_bone->_body = (static_geometry)?0:(new Body(_world, body_name));
337                        physical_bone->_geometry = geom;
338
339                        if (physical_bone->_body) 
340                physical_bone->_body->setMass(
341                        BoxMass(settings._mass, geom->getSize()));
342                }
343        }
344        // Don't create any geometry
345        else if (settings._geometry_class == Geometry::Class_NoGeometry)
346        {
347                physical_bone = new Ragdoll::PhysicalBone();
348                physical_bone->_body = (static_geometry)?0:(new Body(_world, body_name));
349
350                if (physical_bone->_body)
351                {
352                        physical_bone->_body->setMass(SphereMass(settings._mass,settings._radius));
353                        physical_bone->_body->setPosition(_node_trans * bone_posn);
354                }
355        }
356       
357        if (physical_bone)
358    {
359        // set what does control the bone
360        physical_bone->_parent_bone = parent;
361        physical_bone->_bone = bone;
362
363                // Sync the body and geometry
364                if ((physical_bone->_body) && (physical_bone->_geometry))
365                {
366                        physical_bone->_body->setPosition(physical_bone->_geometry->getPosition());
367                        physical_bone->_body->setOrientation(physical_bone->_geometry->getOrientation());
368                }
369
370                if (physical_bone->_geometry)
371                {
372                        physical_bone->_geometry->setBody(physical_bone->_body);
373                        physical_bone->_geometry->setUserObject(this);
374                }
375
376                if (physical_bone->_body)
377                {
378                        physical_bone->_original_orientation = bone_orient.UnitInverse() * (_node_orient.UnitInverse() * physical_bone->_body->getOrientation());
379                        physical_bone->_original_position = physical_bone->_body->getPointBodyPosition(_node_trans * bone_posn);
380
381                        physical_bone->_body->setDamping(settings._linear_damping,settings._angular_damping);
382                }
383
384        // update and record in parent
385                if ((physical_bone->_parent_bone) 
386            && (physical_bone->_parent_bone->_body) 
387            && (physical_bone->_body))
388                {
389                        if (settings._joint_type == Joint::Type_BallJoint)
390                        {
391                                physical_bone->_joint = new BallJoint(_world, _joint_group);
392                                physical_bone->_joint->attach(physical_bone->_parent_bone->_body,physical_bone->_body);
393                                physical_bone->_joint->setAnchor(_node_trans * bone_posn);
394
395                                physical_bone->_motor = new AngularMotorJoint(_world, _joint_group);
396                                physical_bone->_motor->attach(physical_bone->_parent_bone->_body,physical_bone->_body);
397                                physical_bone->_motor->setMode(AngularMotorJoint::Mode_UserAngularMotor);
398                                physical_bone->_motor->setAnchor(_node_trans * bone_posn);
399                                physical_bone->_motor->setAxisCount(2);
400                               
401                                physical_bone->_motor->setAxis(1,AngularMotorJoint::RelativeOrientation_FirstBody,(_node_orient * physical_bone->_parent_bone->_bone->_getDerivedOrientation()) * settings._primary_axis);
402                                physical_bone->_motor->setAngle(1,0);
403                                physical_bone->_motor->setParameter(Joint::Parameter_LowStop,settings._primary_lostop,1);
404                                physical_bone->_motor->setParameter(Joint::Parameter_HighStop,settings._primary_histop,1);
405
406                                physical_bone->_motor->setAxis(2,AngularMotorJoint::RelativeOrientation_FirstBody,(_node_orient * physical_bone->_parent_bone->_bone->_getDerivedOrientation()) * settings._secondary_axis);
407                                physical_bone->_motor->setAngle(2,0);
408                                physical_bone->_motor->setParameter(Joint::Parameter_LowStop,settings._secondary_lostop,2);
409                                physical_bone->_motor->setParameter(Joint::Parameter_HighStop,settings._secondary_histop,2);
410                        }
411                        else if (settings._joint_type == Joint::Type_HingeJoint)
412                        {
413                                physical_bone->_joint = new HingeJoint(_world, _joint_group);
414                                physical_bone->_joint->attach(physical_bone->_parent_bone->_body,physical_bone->_body);
415                                physical_bone->_joint->setAnchor(_node_trans * bone_posn);
416                                physical_bone->_joint->setAxis((_node_orient * physical_bone->_parent_bone->_bone->_getDerivedOrientation()) * settings._primary_axis);
417
418                                physical_bone->_joint->setParameter(Joint::Parameter_LowStop,settings._primary_lostop);
419                                physical_bone->_joint->setParameter(Joint::Parameter_HighStop,settings._primary_histop);
420                        }
421                        else if (settings._joint_type == Joint::Type_UniversalJoint)
422                        {
423                                physical_bone->_joint = new UniversalJoint(_world, _joint_group);
424                                physical_bone->_joint->attach(physical_bone->_parent_bone->_body,physical_bone->_body);
425                                physical_bone->_joint->setAnchor(_node_trans * bone_posn);
426                                physical_bone->_joint->setAxis((_node_orient * physical_bone->_parent_bone->_bone->_getDerivedOrientation()) * settings._primary_axis);
427                                physical_bone->_joint->setAdditionalAxis((_node_orient * physical_bone->_parent_bone->_bone->_getDerivedOrientation()) * settings._secondary_axis);
428
429                                physical_bone->_joint->setParameter(Joint::Parameter_LowStop,settings._primary_lostop);
430                                physical_bone->_joint->setParameter(Joint::Parameter_HighStop,settings._primary_histop);
431
432                                physical_bone->_joint->setParameter(Joint::Parameter_LowStop,settings._secondary_lostop,2);
433                                physical_bone->_joint->setParameter(Joint::Parameter_HighStop,settings._secondary_histop,2);
434                        }
435                        else if (settings._joint_type == Joint::Type_FixedJoint)
436                        {
437                                physical_bone->_joint = new FixedJoint(_world, _joint_group);
438                                physical_bone->_joint->attach(physical_bone->_parent_bone->_body,physical_bone->_body);
439                                physical_bone->_joint->setAnchor(_node_trans * bone_posn);
440                        }
441
442                        physical_bone->_parent_bone->_child_bones.push_back(physical_bone);
443                }
444                else 
445        {
446            _root_bones.push_back(physical_bone);
447        }
448        }
449
450        Node::ChildNodeIterator cni = bone->getChildIterator();
451        while(cni.hasMoreElements())
452        {
453                createBoneBody((Bone*)cni.getNext(),(physical_bone)?physical_bone:parent,static_geometry);
454        }
455}
456//------------------------------------------------------------------------------------------------
457void Ragdoll::turnToStone(Ragdoll::PhysicalBone* bone)
458{
459        if(bone->_geometry != 0) 
460                bone->_geometry->setBody(0);
461
462        delete bone->_motor;
463        delete bone->_joint;
464        delete bone->_body;
465
466        bone->_motor = 0;
467        bone->_joint = 0;
468        bone->_body = 0;
469
470        for (RagdollPhysicalBoneList::iterator i = bone->_child_bones.begin();i != bone->_child_bones.end();++i)
471        {
472                turnToStone(*i);
473        }
474}
475//------------------------------------------------------------------------------------------------
476void Ragdoll::turnToStone()
477{
478        if (!_is_static)
479        {
480                for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();
481            i != _root_bones.end();++i)
482                {
483                        turnToStone(*i);
484                }
485
486                delete _joint_group;
487                _joint_group = 0;
488
489                _is_static = true;
490        }
491}
492//------------------------------------------------------------------------------------------------
493void Ragdoll::releasePhysicalControl(Ragdoll::PhysicalBone* bone)
494{
495        bone->_bone->setManuallyControlled(false);
496
497        delete bone->_geometry;
498        bone->_geometry = 0;
499
500        for (RagdollPhysicalBoneList::iterator i = bone->_child_bones.begin();i != bone->_child_bones.end();++i)
501        {
502                releasePhysicalControl(*i);
503        }
504}
505//------------------------------------------------------------------------------------------------
506void Ragdoll::releasePhysicalControl()
507{
508        turnToStone();
509   
510        if (_is_physical)
511    {
512       // re-enable hardware Animation if previously disabled
513        if (_is_hardwareAnimationRemovedByMe) 
514        {
515            const unsigned int numSubEntities  = getNumSubEntities ();
516            for (unsigned int k = 0; k < numSubEntities; k++)
517            {
518                SubEntity *subEntity = getSubEntity (k);
519                const String hwMatName (subEntity->getMaterialName ());
520                MaterialPtr mSWAnimated = MaterialManager::getSingleton().getByName(hwMatName);
521                assert (std::string::npos != hwMatName.find("ClonedSW"));
522                const String swMatName(hwMatName, 0, hwMatName.find("ClonedSW"));
523                MaterialPtr mHWAnimated = MaterialManager::getSingleton().getByName(swMatName);
524                assert (!mHWAnimated.isNull ());
525               
526                subEntity->setMaterialName (mHWAnimated->getName());               
527            }
528            _is_hardwareAnimationRemovedByMe = false;
529        }
530
531                for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();i != _root_bones.end();++i)
532                {
533                        releasePhysicalControl(*i);
534                        delete (*i);
535                }
536                _root_bones.clear();
537
538                delete _space;
539                _space = 0;
540
541        _is_physical = false;
542
543        removeSoftwareAnimationRequest(false);
544        }
545}
546//------------------------------------------------------------------------------------------------
547void Ragdoll::updatePhysicalBone(Ragdoll::PhysicalBone *physical_bone,const Matrix4 &this_trans,const Matrix4 &base_trans)
548{
549
550    // USE OF BASE_TRANS ???
551        Quaternion body_orient = physical_bone->_body->getOrientation() * physical_bone->_original_orientation.UnitInverse();
552        Quaternion bone_orient = Ogre::Quaternion::IDENTITY;
553
554        Vector3 body_posn = physical_bone->_body->getPointWorldPosition(physical_bone->_original_position);
555        Vector3 bone_posn = Ogre::Vector3::ZERO;
556
557        Matrix3 bone_rot;
558        body_orient.ToRotationMatrix(bone_rot);
559
560        Matrix4 bone_trans = Matrix4::IDENTITY;
561        bone_trans = bone_rot;
562        bone_trans.setTrans(body_posn);
563
564        bone_trans = this_trans.inverse() * bone_trans;
565
566        bone_posn = Ogre::Vector3(bone_trans[0][3], bone_trans[1][3], bone_trans[2][3]);
567        bone_trans.extract3x3Matrix(bone_rot);
568        bone_orient.FromRotationMatrix(bone_rot);
569
570        physical_bone->_bone->setOrientation(bone_orient);
571        physical_bone->_bone->setPosition(bone_posn);
572
573    //physical_bone->_bone->needUpdate (true);
574
575        for (RagdollPhysicalBoneList::iterator i = physical_bone->_child_bones.begin();
576        i != physical_bone->_child_bones.end();++i)
577        {
578                updatePhysicalBone(*i,
579            base_trans * (*i)->_bone->getParent()->_getFullTransform(),
580            base_trans);
581        }
582}
583//------------------------------------------------------------------------------------------------
584void Ragdoll::update()
585{
586        if ((_is_physical) && (!_is_static))
587        {               
588                for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();
589            i != _root_bones.end();++i)
590                {
591                        updatePhysicalBone(*i, _node_trans, _node_trans);
592                }
593                mParentNode->needUpdate();       
594        }
595}
596//------------------------------------------------------------------------------------------------
597const AxisAlignedBox& Ragdoll::getBoundingBox(void) const
598{
599        if (_space)
600        {
601                // Get from space and convert to local
602                mFullBoundingBox = _space->getAxisAlignedBox();
603                mFullBoundingBox.transform(_node_trans_inv);
604        }
605        else
606        {
607                // Get from Mesh
608                mFullBoundingBox = mMesh->getBounds();
609                mFullBoundingBox.merge(getChildObjectsBoundingBox());
610        }
611        return mFullBoundingBox;
612}
613//------------------------------------------------------------------------------------------------
614bool Ragdoll::collision(Contact* contact)
615{
616        Body *body = contact->getFirstGeometry()->getBody();
617        if (!body) 
618        body = contact->getSecondGeometry()->getBody();
619        _hit_list.push_back(std::pair<Body*,Vector3>(body,contact->getPosition()));
620        return false;
621}
622//------------------------------------------------------------------------------------------------
623void Ragdoll::pick(Ragdoll::PhysicalBone *bone,RayGeometry *ray)
624{
625        if (bone->_geometry) 
626        ray->collide(bone->_geometry,this);
627       
628        for (RagdollPhysicalBoneList::iterator i = bone->_child_bones.begin();
629        i != bone->_child_bones.end();++i)
630        {
631                pick(*i,ray);
632        }
633}
634//------------------------------------------------------------------------------------------------
635bool Ragdoll::pick(RayGeometry *ray,Body* &body,Vector3 &position)
636{
637        _hit_list.clear();
638        for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();
639        i != _root_bones.end();++i)
640        {
641                pick(*i, ray);
642        }
643
644        const bool rc = (_hit_list.empty())? false : true;
645
646        if (rc)
647        {
648            const Ogre::Real dist = ray->getLength();
649            for (std::vector<std::pair<Body*,Vector3> >::iterator i = _hit_list.begin();
650            i != _hit_list.end();++i)
651            {
652                    const Ogre::Real this_dist = (i->second - ray->getPosition()).length();
653                    if (this_dist < dist)
654                    {
655                            body = i->first;
656                            position = i->second;
657                    }
658            }
659        }
660
661        return rc;
662}
663//------------------------------------------------------------------------------------------------
664Ragdoll::~Ragdoll()
665{
666    releasePhysicalControl ();
667        for (RagdollPhysicalBoneList::iterator i = _root_bones.begin();i != _root_bones.end();++i) 
668        delete (*i);
669        delete _space;
670        delete _ei;
671        delete _joint_group;
672}
673
674//-----------------------------------------------------------------------
675//-----------------------------------------------------------------------
676String RagdollFactory::FACTORY_TYPE_NAME = "ODERagdoll";
677//-----------------------------------------------------------------------
678const String& RagdollFactory::getType(void) const
679{
680        return FACTORY_TYPE_NAME;
681}
682//-----------------------------------------------------------------------
683MovableObject* RagdollFactory::createInstanceImpl( const String& name,
684                                                                                                  const NameValuePairList* params)
685{
686        // must have mesh parameter
687        MeshPtr pMesh;
688        if (params != 0)
689        {
690                NameValuePairList::const_iterator ni = params->find("mesh");
691                if (ni != params->end())
692                {
693                        // Get mesh (load if required)
694                        pMesh = MeshManager::getSingleton().load(
695                                ni->second,
696                                // note that you can change the group by pre-loading the mesh
697                                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
698                }
699        }
700        if (pMesh.isNull())
701        {
702                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
703                        "'mesh' parameter required when constructing an Ragdoll.",
704                        "RagdollFactory::createInstance");
705        }
706        return new Ragdoll(name, pMesh);
707
708}
709//-----------------------------------------------------------------------
710void RagdollFactory::destroyInstance( MovableObject* obj)
711{
712        delete obj;
713} 
Note: See TracBrowser for help on using the repository browser.