Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/orxonox/objects/worldentities/MovableEntity.cc @ 2301

Last change on this file since 2301 was 2300, checked in by rgrieder, 16 years ago

Still getting physics and its implications straight:

  • Removed PositionableEntity —> StaticEntity is now the way to go. They cannot be translated in any way during physics simulation. The trick will be to remove them and add them again to Bullet. This however is not yet implemented.
  • Forgot a few consts in WorldEntity
  • Fixed a bug with infinite masses
  • WE throws exception if you try to apply physics when the SceneNode is not in the root space of the Scene.
  • Moved velocity_ to MovableEntity
  • Outside world reference of WE/ME are now always the non-physical values. getPosition() will always return node_→getPosition() and when setting it, both RigidBody and SceneNode are translated. This accounts for velocity, orientation and position.
  • Property svn:eol-style set to native
File size: 13.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 *   Co-authors:
25 *      Martin Stypinski
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "MovableEntity.h"
31
32#include "util/Exception.h"
33#include "core/CoreIncludes.h"
34#include "core/XMLPort.h"
35
36#include "objects/Scene.h"
37
38namespace orxonox
39{
40    MovableEntity::MovableEntity(BaseObject* creator) : WorldEntity(creator)
41    {
42        RegisterObject(MovableEntity);
43
44        this->velocity_ = Vector3::ZERO;
45
46        this->registerVariables();
47    }
48
49    MovableEntity::~MovableEntity()
50    {
51    }
52
53    void MovableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
54    {
55        SUPER(MovableEntity, XMLPort, xmlelement, mode);
56
57        XMLPortParamTemplate(MovableEntity, "velocity", setVelocity, getVelocity, xmlelement, mode, const Vector3&);
58    }
59
60    void MovableEntity::registerVariables()
61    {
62    }
63
64    //void MovableEntity::setPosition(const Vector3& position)
65    //{
66    //    //if (isDynamic() && bAddedToPhysicalWorld_)
67    //    //{
68    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
69    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
70    //    //}
71    //    this->node_->setPosition(position);
72    //    positionChanged();
73    //}
74
75    //void MovableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
76    //{
77    //    //if (isDynamic() && bAddedToPhysicalWorld_)
78    //    //{
79    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
80    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
81    //    //}
82    //    this->node_->translate(distance, relativeTo);
83    //    positionChanged();
84    //}
85
86    //void MovableEntity::setOrientation(const Quaternion& orientation)
87    //{
88    //    //if (isDynamic() && bAddedToPhysicalWorld_)
89    //    //{
90    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
91    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
92    //    //}
93    //    this->node_->setOrientation(orientation);
94    //    orientationChanged();
95    //}
96
97    //void MovableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
98    //{
99    //    //if (isDynamic() && bAddedToPhysicalWorld_)
100    //    //{
101    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
102    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
103    //    //}
104    //    this->node_->rotate(rotation, relativeTo);
105    //    orientationChanged();
106    //}
107
108    //void MovableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
109    //{
110    //    //if (isDynamic() && bAddedToPhysicalWorld_)
111    //    //{
112    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
113    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
114    //    //}
115    //    this->node_->yaw(angle, relativeTo);
116    //    orientationChanged();
117    //}
118
119    //void MovableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
120    //{
121    //    //if (isDynamic() && bAddedToPhysicalWorld_)
122    //    //{
123    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
124    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
125    //    //}
126    //    this->node_->pitch(angle, relativeTo);
127    //    orientationChanged();
128    //}
129
130    //void MovableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
131    //{
132    //    //if (isDynamic() && bAddedToPhysicalWorld_)
133    //    //{
134    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
135    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
136    //    //}
137    //    this->node_->roll(angle, relativeTo);
138    //    orientationChanged();
139    //}
140
141    //void MovableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
142    //{
143    //    //if (isDynamic() && bAddedToPhysicalWorld_)
144    //    //{
145    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
146    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
147    //    //}
148    //    this->node_->lookAt(target, relativeTo, localDirectionVector);
149    //    orientationChanged();
150    //}
151
152    //void MovableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
153    //{
154    //    //if (isDynamic() && bAddedToPhysicalWorld_)
155    //    //{
156    //    //    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
157    //    //    this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
158    //    //}
159    //    this->node_->setDirection(direction, relativeTo, localDirectionVector);
160    //    orientationChanged();
161    //}
162
163    void MovableEntity::setPosition(const Vector3& position)
164    {
165        if (this->isDynamic())
166        {
167            btTransform transf = this->physicalBody_->getWorldTransform();
168            transf.setOrigin(btVector3(position.x, position.y, position.z));
169            this->physicalBody_->setWorldTransform(transf);
170        }
171
172        this->node_->setPosition(position);
173        positionChanged();
174    }
175
176    void MovableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
177    {
178        if (this->isDynamic())
179        {
180            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot translate physical object relative \
181                                                          to any other space than TS_LOCAL.");
182            this->physicalBody_->translate(btVector3(distance.x, distance.y, distance.z));
183        }
184
185        this->node_->translate(distance, relativeTo);
186        positionChanged();
187    }
188
189    void MovableEntity::setOrientation(const Quaternion& orientation)
190    {
191        if (this->isDynamic())
192        {
193            btTransform transf = this->physicalBody_->getWorldTransform();
194            transf.setRotation(btQuaternion(orientation.w, orientation.x, orientation.y, orientation.z));
195            this->physicalBody_->setWorldTransform(transf);
196        }
197
198        this->node_->setOrientation(orientation);
199        orientationChanged();
200    }
201
202    void MovableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
203    {
204        if (this->isDynamic())
205        {
206            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot rotate physical object relative \
207                                                          to any other space than TS_LOCAL.");
208            btTransform transf = this->physicalBody_->getWorldTransform();
209            this->physicalBody_->setWorldTransform(transf * btTransform(btQuaternion(rotation.w, rotation.x, rotation.y, rotation.z)));
210        }
211
212        this->node_->rotate(rotation, relativeTo);
213        orientationChanged();
214    }
215
216    void MovableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
217    {
218        if (this->isDynamic())
219        {
220            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot yaw physical object relative \
221                                                          to any other space than TS_LOCAL.");
222            btTransform transf = this->physicalBody_->getWorldTransform();
223            btTransform rotation(btQuaternion(angle.valueRadians(), 0.0f, 0.0f));
224            this->physicalBody_->setWorldTransform(transf * rotation);
225        }
226
227        this->node_->yaw(angle, relativeTo);
228        orientationChanged();
229    }
230
231    void MovableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
232    {
233        if (this->isDynamic())
234        {
235            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot pitch physical object relative \
236                                                          to any other space than TS_LOCAL.");
237            btTransform transf = this->physicalBody_->getWorldTransform();
238            btTransform rotation(btQuaternion(0.0f, angle.valueRadians(), 0.0f));
239            this->physicalBody_->setWorldTransform(transf * rotation);
240        }
241
242        this->node_->pitch(angle, relativeTo);
243        orientationChanged();
244    }
245
246    void MovableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
247    {
248        if (this->isDynamic())
249        {
250            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot roll physical object relative \
251                                                          to any other space than TS_LOCAL.");
252            btTransform transf = this->physicalBody_->getWorldTransform();
253            btTransform rotation(btQuaternion(angle.valueRadians(), 0.0f, 0.0f));
254            this->physicalBody_->setWorldTransform(transf * rotation);
255        }
256
257        this->node_->roll(angle, relativeTo);
258        orientationChanged();
259    }
260
261    void MovableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
262    {
263        if (this->isDynamic())
264        {
265            ThrowException(NotImplemented, "ControllableEntity::lookAt() is not yet supported for physical objects.");
266            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot align physical object relative \
267                                                          to any other space than TS_LOCAL.");
268            //btTransform transf = this->physicalBody_->getWorldTransform();
269            //this->physicalBody_->setWorldTransform(transf);
270        }
271
272        this->node_->lookAt(target, relativeTo, localDirectionVector);
273        orientationChanged();
274    }
275
276    void MovableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
277    {
278        if (this->isDynamic())
279        {
280            ThrowException(NotImplemented, "ControllableEntity::setDirection() is not yet supported for physical objects.");
281            OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot align physical object relative \
282                                                          to any other space than TS_LOCAL.");
283            //btTransform transf = this->physicalBody_->getWorldTransform();
284            //this->physicalBody_->setWorldTransform(transf);
285        }
286
287        this->node_->setDirection(direction, relativeTo, localDirectionVector);
288        orientationChanged();
289    }
290
291    void MovableEntity::setVelocity(const Vector3& velocity)
292    {
293        if (this->isDynamic())
294        {
295            this->physicalBody_->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z));
296        }
297
298        this->velocity_ = velocity;
299        velocityChanged();
300    }
301
302    bool MovableEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
303    {
304        if (type == WorldEntity::Static)
305        {
306            ThrowException(PhysicsViolation, "Cannot tell a MovableEntity to have static collision type");
307            return false;
308        }
309        else
310            return true;
311    }
312
313    void MovableEntity::setWorldTransform(const btTransform& worldTrans)
314    {
315        // We use a dynamic body. So we translate our node accordingly.
316        this->node_->setPosition(Vector3(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z()));
317        this->node_->setOrientation(Quaternion(worldTrans.getRotation().w(), worldTrans.getRotation().x(), worldTrans.getRotation().y(), worldTrans.getRotation().z()));
318        const btVector3& velocity = this->physicalBody_->getLinearVelocity();
319        this->velocity_ = Vector3(velocity.x(), velocity.y(), velocity.z());
320        velocityChanged();
321        positionChanged();
322        orientationChanged();
323    }
324
325    void MovableEntity::getWorldTransform(btTransform& worldTrans) const
326    {
327        // We use a kinematic body
328        worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
329        worldTrans.setRotation(btQuaternion(node_->getOrientation().w, node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z));
330        if (this->isDynamic())
331        {
332            // This function gets called only once for dynamic objects to set the initial conditions
333            // We have to set the velocity too.
334            this->physicalBody_->setLinearVelocity(btVector3(velocity_.x, velocity_.y, velocity_.z));
335        }
336    }
337}
Note: See TracBrowser for help on using the repository browser.