Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/worldentities/MobileEntity.cc @ 8727

Last change on this file since 8727 was 8727, checked in by dafrick, 13 years ago

Cleaning up in SpaceShip and Engine. Fixed several bugs.
Kicked localLinearAcceleration, primaryThrust and auxiliaryThrust out of the SpaceShip, since it wasn't used anymore.
Moved the trail lights back a bit.
Added some documentation to SpaceShip and Engine.
SpeedPickup is working again, will need some further tuning.

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