Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pch/src/orxonox/objects/worldentities/MobileEntity.cc @ 3149

Last change on this file since 3149 was 3149, checked in by rgrieder, 15 years ago

Extracted OrxAssert from Exception.h to OrxAssert.h since it doesn't really have anything to do with exceptions.

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