Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_merge/src/orxonox/objects/worldentities/MobileEntity.cc @ 2518

Last change on this file since 2518 was 2454, checked in by rgrieder, 16 years ago

Replaced bad collision type exceptions with asserts. The developer will know about the obvious error immediately and the end end user only sees a warning.

  • Property svn:eol-style set to native
File size: 7.8 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 *      Reto Grieder
24 *   Co-authors:
25 *      Martin Stypinski
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "MobileEntity.h"
31
32#include <OgreSceneNode.h>
33#include "BulletDynamics/Dynamics/btRigidBody.h"
34
35#include "util/Debug.h"
36#include "util/MathConvert.h"
37#include "util/Exception.h"
38#include "core/CoreIncludes.h"
39#include "core/XMLPort.h"
40
41#include "objects/Scene.h"
42
43namespace orxonox
44{
45    MobileEntity::MobileEntity(BaseObject* creator) : WorldEntity(creator)
46    {
47        RegisterObject(MobileEntity);
48
49        this->linearAcceleration_  = Vector3::ZERO;
50        this->linearVelocity_      = Vector3::ZERO;
51        this->angularAcceleration_ = Vector3::ZERO;
52        this->angularVelocity_     = Vector3::ZERO;
53    }
54
55    MobileEntity::~MobileEntity()
56    {
57    }
58
59    void MobileEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
60    {
61        SUPER(MobileEntity, XMLPort, xmlelement, mode);
62
63        XMLPortParamTemplate(MobileEntity, "velocity",     setVelocity,     getVelocity,     xmlelement, mode, const Vector3&);
64        XMLPortParamTemplate(MobileEntity, "rotationaxis", setRotationAxis, getRotationAxis, xmlelement, mode, const Vector3&);
65        XMLPortParam(MobileEntity, "rotationrate", setRotationRate, getRotationRate, xmlelement, mode);
66    }
67
68    void MobileEntity::tick(float dt)
69    {
70        if (this->isActive())
71        {
72            // Check whether Bullet doesn't do the physics for us
73            if (!this->isDynamic())
74            {
75                // Linear part
76                this->linearVelocity_.x += this->linearAcceleration_.x * dt;
77                this->linearVelocity_.y += this->linearAcceleration_.y * dt;
78                this->linearVelocity_.z += this->linearAcceleration_.z * dt;
79                this->node_->translate(this->linearVelocity_ * dt);
80
81                // Angular part
82                // Note: angularVelocity_ is a Quaternion with w = 0 while angularAcceleration_ is a Vector3
83                this->angularVelocity_.x += angularAcceleration_.x * dt;
84                this->angularVelocity_.y += angularAcceleration_.y * dt;
85                this->angularVelocity_.z += angularAcceleration_.z * dt;
86                // Calculate new orientation with quaternion derivative. This is about 30% faster than with angle/axis method.
87                float mult = dt * 0.5;
88                // TODO: this could be optimized by writing it out. The calls currently create 4 new Quaternions!
89                Quaternion newOrientation(0.0f, this->angularVelocity_.x * mult, this->angularVelocity_.y * mult, this->angularVelocity_.z * mult);
90                newOrientation = this->node_->getOrientation() + newOrientation * this->node_->getOrientation();
91                newOrientation.normalise();
92                this->node_->setOrientation(newOrientation);
93            }
94        }
95    }
96
97    void MobileEntity::setPosition(const Vector3& position)
98    {
99        if (this->isDynamic())
100        {
101            btTransform transf = this->physicalBody_->getWorldTransform();
102            transf.setOrigin(btVector3(position.x, position.y, position.z));
103            this->physicalBody_->setWorldTransform(transf);
104        }
105
106        this->node_->setPosition(position);
107    }
108
109    void MobileEntity::setOrientation(const Quaternion& orientation)
110    {
111        if (this->isDynamic())
112        {
113            btTransform transf = this->physicalBody_->getWorldTransform();
114            transf.setRotation(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w));
115            this->physicalBody_->setWorldTransform(transf);
116        }
117
118        this->node_->setOrientation(orientation);
119    }
120
121    void MobileEntity::setVelocity(const Vector3& velocity)
122    {
123        if (this->isDynamic())
124            this->physicalBody_->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z));
125
126        this->linearVelocity_ = velocity;
127    }
128
129    void MobileEntity::setAngularVelocity(const Vector3& velocity)
130    {
131        if (this->isDynamic())
132            this->physicalBody_->setAngularVelocity(btVector3(velocity.x, velocity.y, velocity.z));
133
134        this->angularVelocity_ = velocity;
135    }
136
137    void MobileEntity::setAcceleration(const Vector3& acceleration)
138    {
139        if (this->isDynamic())
140            this->physicalBody_->applyCentralForce(btVector3(acceleration.x * this->getMass(), acceleration.y * this->getMass(), acceleration.z * this->getMass()));
141
142        this->linearAcceleration_ = acceleration;
143    }
144
145    void MobileEntity::setAngularAcceleration(const Vector3& acceleration)
146    {
147        if (this->isDynamic())
148        {
149            btVector3 inertia(btVector3(1, 1, 1) / this->physicalBody_->getInvInertiaDiagLocal());
150            this->physicalBody_->applyTorque(btVector3(acceleration.x, acceleration.y, acceleration.z) * inertia);
151        }
152
153        this->angularAcceleration_ = acceleration;
154    }
155
156    bool MobileEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
157    {
158        if (type == WorldEntity::Static)
159        {
160            CCOUT(1) << "Error: Cannot tell a MobileEntity to have static collision type! Ignoring." << std::endl;
161            assert(false); // Only in debug mode
162            return false;
163        }
164        else
165            return true;
166    }
167
168    void MobileEntity::setWorldTransform(const btTransform& worldTrans)
169    {
170        // We use a dynamic body. So we translate our node accordingly.
171        this->node_->setPosition(Vector3(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z()));
172        this->node_->setOrientation(Quaternion(worldTrans.getRotation().w(), worldTrans.getRotation().x(), worldTrans.getRotation().y(), worldTrans.getRotation().z()));
173        this->linearVelocity_.x = this->physicalBody_->getLinearVelocity().x();
174        this->linearVelocity_.y = this->physicalBody_->getLinearVelocity().y();
175        this->linearVelocity_.z = this->physicalBody_->getLinearVelocity().z();
176        this->angularVelocity_.x = this->physicalBody_->getAngularVelocity().x();
177        this->angularVelocity_.y = this->physicalBody_->getAngularVelocity().y();
178        this->angularVelocity_.z = this->physicalBody_->getAngularVelocity().z();
179    }
180
181    void MobileEntity::getWorldTransform(btTransform& worldTrans) const
182    {
183        // We use a kinematic body
184        worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
185        worldTrans.setRotation(btQuaternion(node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z, node_->getOrientation().w));
186        if (this->isDynamic())
187        {
188            // This function gets called only once for dynamic objects to set the initial conditions
189            // We have to set the velocities too.
190            this->physicalBody_->setLinearVelocity(btVector3(linearVelocity_.x, linearVelocity_.y, linearVelocity_.z));
191            this->physicalBody_->setAngularVelocity(btVector3(angularVelocity_.x, angularVelocity_.y, angularVelocity_.z));
192        }
193    }
194}
Note: See TracBrowser for help on using the repository browser.