Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_merge/src/orxonox/objects/worldentities/WorldEntity.cc @ 2446

Last change on this file since 2446 was 2446, checked in by rgrieder, 15 years ago
  • orxonox::Scene should work properly with XMLPort and network synchronisation, no matter what input. No guarantee of course ;)
  • If you disable physics completely and then reactivate it, all rigid bodies that were removed will be added again.
  • new XML attributes: gravity, negativeWorldRange and positiveWorldRange
  • Property svn:eol-style set to native
File size: 24.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *      Reto Grieder (physics)
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30#include "OrxonoxStableHeaders.h"
31#include "WorldEntity.h"
32
33#include <cassert>
34#include <OgreSceneNode.h>
35#include <OgreSceneManager.h>
36#include "BulletDynamics/Dynamics/btRigidBody.h"
37
38#include "util/Exception.h"
39#include "util/Convert.h"
40#include "core/CoreIncludes.h"
41#include "core/XMLPort.h"
42
43#include "objects/Scene.h"
44#include "objects/collisionshapes/CompoundCollisionShape.h"
45
46namespace orxonox
47{
48    const Vector3 WorldEntity::FRONT = Vector3::NEGATIVE_UNIT_Z;
49    const Vector3 WorldEntity::BACK  = Vector3::UNIT_Z;
50    const Vector3 WorldEntity::LEFT  = Vector3::NEGATIVE_UNIT_X;
51    const Vector3 WorldEntity::RIGHT = Vector3::UNIT_X;
52    const Vector3 WorldEntity::DOWN  = Vector3::NEGATIVE_UNIT_Y;
53    const Vector3 WorldEntity::UP    = Vector3::UNIT_Y;
54
55    WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
56    {
57        RegisterObject(WorldEntity);
58
59        if (!this->getScene() || !this->getScene()->getRootSceneNode())
60            ThrowException(AbortLoading, "Can't create WorldEntity, no scene or no root-scenenode given.");
61
62        this->node_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
63
64        this->parent_ = 0;
65        this->parentID_ = OBJECTID_UNKNOWN;
66
67        this->node_->setPosition(Vector3::ZERO);
68        this->node_->setOrientation(Quaternion::IDENTITY);
69
70        // Default behaviour does not include physics
71        this->physicalBody_ = 0;
72        this->bPhysicsActive_ = false;
73        this->collisionShape_ = new CompoundCollisionShape(this);
74        this->collisionType_ = None;
75        this->collisionTypeSynchronised_ = None;
76        this->mass_           = 0;
77        this->childrenMass_   = 0;
78        // Use bullet default values
79        this->restitution_    = 0;
80        this->angularFactor_  = 1;
81        this->linearDamping_  = 0;
82        this->angularDamping_ = 0;
83        this->friction_       = 0.5;
84
85        this->registerVariables();
86    }
87
88    WorldEntity::~WorldEntity()
89    {
90        if (this->isInitialized())
91        {
92            this->node_->detachAllObjects();
93            if (this->getScene()->getSceneManager())
94                this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
95
96            // TODO: Detach from parent and detach all children.
97
98            if (this->physicalBody_)
99            {
100                this->deactivatePhysics();
101                delete this->physicalBody_;
102            }
103            delete this->collisionShape_;
104        }
105    }
106
107    void WorldEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
108    {
109        SUPER(WorldEntity, XMLPort, xmlelement, mode);
110
111        XMLPortParamTemplate(WorldEntity, "position",    setPosition,    getPosition,    xmlelement, mode, const Vector3&);
112        XMLPortParamTemplate(WorldEntity, "orientation", setOrientation, getOrientation, xmlelement, mode, const Quaternion&);
113        XMLPortParamTemplate(WorldEntity, "scale3D",     setScale3D,     getScale3D,     xmlelement, mode, const Vector3&);
114        XMLPortParam        (WorldEntity, "scale",       setScale,       getScale,       xmlelement, mode);
115        XMLPortParamLoadOnly(WorldEntity, "lookat",      lookAt_xmlport,       xmlelement, mode);
116        XMLPortParamLoadOnly(WorldEntity, "direction",   setDirection_xmlport, xmlelement, mode);
117        XMLPortParamLoadOnly(WorldEntity, "yaw",         yaw_xmlport,          xmlelement, mode);
118        XMLPortParamLoadOnly(WorldEntity, "pitch",       pitch_xmlport,        xmlelement, mode);
119        XMLPortParamLoadOnly(WorldEntity, "roll",        roll_xmlport,         xmlelement, mode);
120
121        // Physics
122        XMLPortParam(WorldEntity, "collisionType",  setCollisionTypeStr, getCollisionTypeStr, xmlelement, mode);
123        XMLPortParam(WorldEntity, "mass",           setMass,             getMass,             xmlelement, mode);
124        XMLPortParam(WorldEntity, "restitution",    setRestitution,      getRestitution,      xmlelement, mode);
125        XMLPortParam(WorldEntity, "angularFactor",  setAngularFactor,    getAngularFactor,    xmlelement, mode);
126        XMLPortParam(WorldEntity, "linearDamping",  setLinearDamping,    getLinearDamping,    xmlelement, mode);
127        XMLPortParam(WorldEntity, "angularDamping", setAngularDamping,   getAngularDamping,   xmlelement, mode);
128        XMLPortParam(WorldEntity, "friction",       setFriction,         getFriction,         xmlelement, mode);
129
130        // Other attached WorldEntities
131        XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);
132        // Attached collision shapes
133        XMLPortObject(WorldEntity, CollisionShape, "collisionShapes", attachCollisionShape, getAttachedCollisionShape, xmlelement, mode);
134    }
135
136    void WorldEntity::registerVariables()
137    {
138        registerVariable(this->bActive_,        variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity));
139        registerVariable(this->bVisible_,       variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility));
140
141        registerVariable(this->getScale3D(),    variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::scaleChanged));
142
143        registerVariable((int&)this->collisionTypeSynchronised_,
144                                                variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionTypeChanged));
145        registerVariable(this->mass_,           variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::massChanged));
146        registerVariable(this->restitution_,    variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::restitutionChanged));
147        registerVariable(this->angularFactor_,  variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::angularFactorChanged));
148        registerVariable(this->linearDamping_,  variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::linearDampingChanged));
149        registerVariable(this->angularDamping_, variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::angularDampingChanged));
150        registerVariable(this->friction_,       variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::frictionChanged));
151        registerVariable(this->bPhysicsActiveSynchronised_,
152                                                variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::physicsActivityChanged));
153
154        registerVariable(this->parentID_,       variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::parentChanged));
155    }
156
157    void WorldEntity::parentChanged()
158    {
159        if (this->parentID_ != OBJECTID_UNKNOWN)
160        {
161            WorldEntity* parent = dynamic_cast<WorldEntity*>(Synchronisable::getSynchronisable(this->parentID_));
162            if (parent)
163                this->attachToParent(parent);
164        }
165    }
166
167    void WorldEntity::collisionTypeChanged()
168    {
169        if (this->collisionTypeSynchronised_ != Dynamic &&
170            this->collisionTypeSynchronised_ != Kinematic &&
171            this->collisionTypeSynchronised_ != Static &&
172            this->collisionTypeSynchronised_ != None)
173        {
174            CCOUT(1) << "Error when collsion Type was received over network. Unknown enum value:" << this->collisionTypeSynchronised_ << std::endl;
175        }
176        else if (this->collisionTypeSynchronised_ != collisionType_)
177        {
178            if (this->parent_)
179                CCOUT(2) << "Warning: Network connection tried to set the collision type of an attached WE. Ignoring." << std::endl;
180            else
181                this->setCollisionType(this->collisionTypeSynchronised_);
182        }
183    }
184
185    void WorldEntity::physicsActivityChanged()
186    {
187        if (this->bPhysicsActiveSynchronised_)
188            this->activatePhysics();
189        else
190            this->deactivatePhysics();
191    }
192
193    void WorldEntity::attach(WorldEntity* object)
194    {
195        // check first whether attaching is even allowed
196        if (object->hasPhysics())
197        {
198            if (!this->hasPhysics())
199            {
200                COUT(2) << "Warning: Cannot attach a physical object to a non physical one." << std::endl;
201                return;
202            }
203            else if (object->isDynamic())
204            {
205                COUT(2) << "Warning: Cannot attach a dynamic object to a WorldEntity." << std::endl;
206                return;
207            }
208            else if (object->isKinematic() && this->isDynamic())
209            {
210                COUT(2) << "Warning: Cannot attach a kinematic object to a dynamic one." << std::endl;
211                return;
212            }
213            else if (object->isKinematic())
214            {
215                COUT(2) << "Warning: Cannot attach a kinematic object to a static or kinematic one: Not yet implemented." << std::endl;
216                return;
217            }
218            else
219            {
220                object->deactivatePhysics();
221            }
222        }
223
224        if (object->getParent())
225            object->detachFromParent();
226        else
227        {
228            Ogre::Node* parent = object->node_->getParent();
229            if (parent)
230                parent->removeChild(object->node_);
231        }
232
233        this->node_->addChild(object->node_);
234        this->children_.insert(object);
235        object->parent_ = this;
236        object->parentID_ = this->getObjectID();
237
238        // collision shapes
239        this->attachCollisionShape(object->getCollisionShape());
240        // mass
241        this->childrenMass_ += object->getMass();
242        recalculateMassProps();
243    }
244
245    void WorldEntity::detach(WorldEntity* object)
246    {
247        // collision shapes
248        this->detachCollisionShape(object->getCollisionShape());
249        // mass
250        if (object->getMass() > 0.0f)
251        {
252            this->childrenMass_ -= object->getMass();
253            recalculateMassProps();
254        }
255
256        this->node_->removeChild(object->node_);
257        this->children_.erase(object);
258        object->parent_ = 0;
259        object->parentID_ = OBJECTID_UNKNOWN;
260//        this->getScene()->getRootSceneNode()->addChild(object->node_);
261
262        // Note: It is possible that the object has physics but was disabled when attaching
263        object->activatePhysics();
264    }
265
266    WorldEntity* WorldEntity::getAttachedObject(unsigned int index) const
267    {
268        unsigned int i = 0;
269        for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
270        {
271            if (i == index)
272                return (*it);
273            ++i;
274        }
275        return 0;
276    }
277
278    void WorldEntity::attachOgreObject(Ogre::MovableObject* object)
279    {
280        this->node_->attachObject(object);
281    }
282
283    void WorldEntity::detachOgreObject(Ogre::MovableObject* object)
284    {
285        this->node_->detachObject(object);
286    }
287
288    Ogre::MovableObject* WorldEntity::detachOgreObject(const Ogre::String& name)
289    {
290        return this->node_->detachObject(name);
291    }
292
293    void WorldEntity::attachCollisionShape(CollisionShape* shape)
294    {
295        this->collisionShape_->addChildShape(shape);
296        // Note: this->collisionShape_ already notifies us of any changes.
297    }
298
299    void WorldEntity::detachCollisionShape(CollisionShape* shape)
300    {
301        this->collisionShape_->removeChildShape(shape);
302        // Note: this->collisionShape_ already notifies us of any changes.
303    }
304
305    CollisionShape* WorldEntity::getAttachedCollisionShape(unsigned int index) const
306    {
307        return this->collisionShape_->getChildShape(index);
308    }
309
310    void WorldEntity::activatePhysics()
311    {
312        if (this->isActive() && this->hasPhysics() && !this->isPhysicsActive() && !this->parent_)
313        {
314            this->getScene()->addPhysicalObject(this);
315            this->bPhysicsActive_ = true;
316        }
317    }
318
319    void WorldEntity::deactivatePhysics()
320    {
321        if (this->isPhysicsActive())
322        {
323            this->getScene()->removePhysicalObject(this);
324            this->bPhysicsActive_ = false;
325        }
326    }
327
328    bool WorldEntity::addedToPhysicalWorld() const
329    {
330        return this->physicalBody_ && this->physicalBody_->isInWorld();
331    }
332
333#ifndef _NDEBUG
334    const Vector3& WorldEntity::getPosition() const
335    {
336        return this->node_->getPosition();
337    }
338
339    const Quaternion& WorldEntity::getOrientation() const
340    {
341        return this->node_->getOrientation();
342    }
343
344    const Vector3& WorldEntity::getScale3D() const
345    {
346        return this->node_->getScale();
347    }
348#endif
349
350    const Vector3& WorldEntity::getWorldPosition() const
351    {
352        return this->node_->_getDerivedPosition();
353    }
354
355    const Quaternion& WorldEntity::getWorldOrientation() const
356    {
357        return this->node_->_getDerivedOrientation();
358    }
359
360    void WorldEntity::translate(const Vector3& distance, TransformSpace::Space relativeTo)
361    {
362        switch (relativeTo)
363        {
364        case TransformSpace::Local:
365            // position is relative to parent so transform downwards
366            this->setPosition(this->getPosition() + this->getOrientation() * distance);
367            break;
368        case TransformSpace::Parent:
369            this->setPosition(this->getPosition() + distance);
370            break;
371        case TransformSpace::World:
372            // position is relative to parent so transform upwards
373            if (this->node_->getParent())
374                setPosition(getPosition() + (node_->getParent()->_getDerivedOrientation().Inverse() * distance)
375                    / node_->getParent()->_getDerivedScale());
376            else
377                this->setPosition(this->getPosition() + distance);
378            break;
379        }
380    }
381
382    void WorldEntity::rotate(const Quaternion& rotation, TransformSpace::Space relativeTo)
383    {
384        switch(relativeTo)
385        {
386        case TransformSpace::Local:
387            this->setOrientation(this->getOrientation() * rotation);
388            break;
389        case TransformSpace::Parent:
390            // Rotations are normally relative to local axes, transform up
391            this->setOrientation(rotation * this->getOrientation());
392            break;
393        case TransformSpace::World:
394            // Rotations are normally relative to local axes, transform up
395            this->setOrientation(this->getOrientation() * this->getWorldOrientation().Inverse()
396                * rotation * this->getWorldOrientation());
397            break;
398        }
399    }
400
401    void WorldEntity::lookAt(const Vector3& target, TransformSpace::Space relativeTo, const Vector3& localDirectionVector)
402    {
403        Vector3 origin;
404        switch (relativeTo)
405        {
406        case TransformSpace::Local:
407            origin = Vector3::ZERO;
408            break;
409        case TransformSpace::Parent:
410            origin = this->getPosition();
411            break;
412        case TransformSpace::World:
413            origin = this->getWorldPosition();
414            break;
415        }
416        this->setDirection(target - origin, relativeTo, localDirectionVector);
417    }
418
419    void WorldEntity::setDirection(const Vector3& direction, TransformSpace::Space relativeTo, const Vector3& localDirectionVector)
420    {
421        Quaternion savedOrientation(this->getOrientation());
422        Ogre::Node::TransformSpace ogreRelativeTo;
423        switch (relativeTo)
424        {
425        case TransformSpace::Local:
426            ogreRelativeTo = Ogre::Node::TS_LOCAL; break;
427        case TransformSpace::Parent:
428            ogreRelativeTo = Ogre::Node::TS_PARENT; break;
429        case TransformSpace::World:
430            ogreRelativeTo = Ogre::Node::TS_WORLD; break;
431        }
432        this->node_->setDirection(direction, ogreRelativeTo, localDirectionVector);
433        Quaternion newOrientation(this->node_->getOrientation());
434        this->node_->setOrientation(savedOrientation);
435        this->setOrientation(newOrientation);
436    }
437
438    void WorldEntity::setScale3D(const Vector3& scale)
439    {
440        if (this->hasPhysics())
441        {
442            CCOUT(2) << "Warning: Cannot set the scale of a physical object: Not yet implemented." << std::endl;
443            return;
444        }
445
446        this->node_->setScale(scale);
447    }
448
449    void WorldEntity::setCollisionType(CollisionType type)
450    {
451        // If we are already attached to a parent, this would be a bad idea..
452        if (this->parent_)
453        {
454            CCOUT(2) << "Warning: Cannot set the collision type of a WorldEntity with a parent." << std::endl;
455            return;
456        }
457        else if (this->addedToPhysicalWorld())
458        {
459            CCOUT(2) << "Warning: Cannot set the collision type at run time." << std::endl;
460            return;
461        }
462
463        // Check for type legality. Could be StaticEntity or MobileEntity
464        if (!this->isCollisionTypeLegal(type))
465            return; // exception gets issued anyway
466        if (type != None && !this->getScene()->hasPhysics())
467        {
468            CCOUT(2) << "Warning: Cannot have physical bodies in a non physical scene." << std::endl;
469            return;
470        }
471
472        // Check whether we have to create or destroy.
473        if (type != None && this->collisionType_ == None)
474        {
475            // Check whether there was some scaling applied.
476            if (!this->node_->getScale().positionEquals(Vector3(1, 1, 1), 0.001))
477            {
478                CCOUT(2) << "Warning: Cannot create a physical body if there is scaling applied to the node: Not yet implemented." << std::endl;
479                return;
480            }
481
482            // Create new rigid body
483            btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, this->collisionShape_->getCollisionShape());
484            this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
485            this->physicalBody_->setUserPointer(this);
486            this->physicalBody_->setActivationState(DISABLE_DEACTIVATION);
487        }
488        else if (type == None && this->collisionType_ != None)
489        {
490            // Destroy rigid body
491            assert(this->physicalBody_);
492            deactivatePhysics();
493            delete this->physicalBody_;
494            this->physicalBody_ = 0;
495            this->collisionType_ = None;
496            this->collisionTypeSynchronised_ = None;
497            return;
498        }
499
500        // Change type
501        switch (type)
502        {
503        case Dynamic:
504            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !(btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT));
505            break;
506        case Kinematic:
507            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT);
508            break;
509        case Static:
510            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT);
511            break;
512        case None:
513            return; // this->collisionType_ was None too
514        }
515
516        // Only sets this->collisionShape_
517        // However the assertion is to ensure that the internal bullet setting is right
518        updateCollisionType();
519        assert(this->collisionType_ == type);
520
521        // update mass and inertia tensor
522        recalculateMassProps();
523        resetPhysicsProps();
524        activatePhysics();
525    }
526
527    void WorldEntity::setCollisionTypeStr(const std::string& typeStr)
528    {
529        std::string typeStrLower = getLowercase(typeStr);
530        CollisionType type;
531        if (typeStrLower == "dynamic")
532            type = Dynamic;
533        else if (typeStrLower == "static")
534            type = Static;
535        else if (typeStrLower == "kinematic")
536            type = Kinematic;
537        else if (typeStrLower == "none")
538            type = None;
539        else
540            ThrowException(ParseError, std::string("Attempting to set an unknown collision type: '") + typeStr + "'.");
541        this->setCollisionType(type);
542    }
543
544    std::string WorldEntity::getCollisionTypeStr() const
545    {
546        switch (this->getCollisionType())
547        {
548            case Dynamic:
549                return "dynamic";
550            case Kinematic:
551                return "kinematic";
552            case Static:
553                return "static";
554            case None:
555                return "none";
556            default:
557                assert(false);
558                return "";
559        }
560    }
561
562    void WorldEntity::updateCollisionType()
563    {
564        if (!this->physicalBody_)
565            this->collisionType_ = None;
566        else if (this->physicalBody_->isKinematicObject())
567            this->collisionType_ = Kinematic;
568        else if (this->physicalBody_->isStaticObject())
569            this->collisionType_ = Static;
570        else
571            this->collisionType_ = Dynamic;
572        this->collisionTypeSynchronised_ = this->collisionType_;
573    }
574
575    void WorldEntity::notifyChildMassChanged() // Called by a child WE
576    {
577        // Note: CollisionShape changes of a child get handled over the internal CompoundCollisionShape already
578        // Recalculate mass
579        this->childrenMass_ = 0.0f;
580        for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
581            this->childrenMass_ += (*it)->getMass();
582        recalculateMassProps();
583        // Notify parent WE
584        if (this->parent_)
585            parent_->notifyChildMassChanged();
586    }
587
588    void WorldEntity::notifyCollisionShapeChanged() // called by this->collisionShape_
589    {
590        if (hasPhysics())
591        {
592            // Bullet doesn't like sudden changes of the collision shape, so we remove and add it again
593            if (this->addedToPhysicalWorld())
594            {
595                this->deactivatePhysics();
596                this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
597                this->activatePhysics();
598            }
599            else
600                this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
601        }
602        recalculateMassProps();
603    }
604
605    void WorldEntity::recalculateMassProps()
606    {
607        if (this->hasPhysics())
608        {
609            if (this->isStatic())
610            {
611                // Just set everything to zero
612                this->physicalBody_->setMassProps(0.0f, btVector3(0, 0, 0));
613            }
614            else if ((this->mass_ + this->childrenMass_) == 0.0f)
615            {
616                // Use default values to avoid very large or very small values
617                CCOUT(4) << "Warning: Setting the internal physical mass to 1.0 because mass_ is 0.0." << std::endl;
618                this->physicalBody_->setMassProps(1.0f, this->collisionShape_->getLocalInertia(1.0f));
619            }
620            else
621            {
622                float mass = this->mass_ + this->childrenMass_;
623                this->physicalBody_->setMassProps(mass, this->collisionShape_->getLocalInertia(mass));
624            }
625        }
626    }
627
628    void WorldEntity::resetPhysicsProps()
629    {
630        if (this->hasPhysics())
631        {
632            this->physicalBody_->setRestitution(this->restitution_);
633            this->physicalBody_->setAngularFactor(this->angularFactor_);
634            this->physicalBody_->setDamping(this->linearDamping_, this->angularDamping_);
635            this->physicalBody_->setFriction(this->friction_);
636        }
637    }
638}
Note: See TracBrowser for help on using the repository browser.