Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/orxonox/objects/worldentities/ControllableEntity.cc @ 2300

Last change on this file since 2300 was 2300, checked in by rgrieder, 15 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: 12.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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "ControllableEntity.h"
31
32#include "core/CoreIncludes.h"
33#include "core/Core.h"
34#include "core/XMLPort.h"
35#include "core/Template.h"
36
37#include "objects/infos/PlayerInfo.h"
38#include "objects/worldentities/Camera.h"
39#include "objects/worldentities/CameraPosition.h"
40#include "overlays/OverlayGroup.h"
41
42namespace orxonox
43{
44    CreateFactory(ControllableEntity);
45
46    ControllableEntity::ControllableEntity(BaseObject* creator) : MovableEntity(creator)
47    {
48        RegisterObject(ControllableEntity);
49
50        this->bControlled_ = false;
51        this->server_overwrite_ = 0;
52        this->client_overwrite_ = 0;
53        this->player_ = 0;
54        this->playerID_ = network::OBJECTID_UNKNOWN;
55        this->hud_ = 0;
56        this->camera_ = 0;
57        this->bDestroyWhenPlayerLeft_ = false;
58
59        this->acceleration_ = Vector3::ZERO;
60
61        this->server_position_ = Vector3::ZERO;
62        this->client_position_ = Vector3::ZERO;
63        this->server_velocity_ = Vector3::ZERO;
64        this->client_velocity_ = Vector3::ZERO;
65        this->server_orientation_ = Quaternion::IDENTITY;
66        this->client_orientation_ = Quaternion::IDENTITY;
67
68        this->registerVariables();
69    }
70
71    ControllableEntity::~ControllableEntity()
72    {
73        if (this->isInitialized())
74        {
75            if (this->bControlled_)
76                this->stopLocalControl();
77
78            if (this->hud_)
79                delete this->hud_;
80
81            if (this->camera_)
82                delete this->camera_;
83
84            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
85                this->getPlayer()->stopControl(this, false);
86        }
87    }
88
89    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
90    {
91        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
92
93        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
94        XMLPortParam(ControllableEntity, "camerapositiontemplate", setCameraPositionTemplate, getCameraPositionTemkplate, xmlelement, mode);
95
96        XMLPortObject(ControllableEntity, CameraPosition, "camerapositions", addCameraPosition, getCameraPosition, xmlelement, mode);
97    }
98
99    void ControllableEntity::addCameraPosition(CameraPosition* position)
100    {
101        this->attach(position);
102        this->cameraPositions_.push_back(position);
103    }
104
105    CameraPosition* ControllableEntity::getCameraPosition(unsigned int index) const
106    {
107        unsigned int i = 0;
108        for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
109        {
110            if (i == index)
111                return (*it);
112            ++i;
113        }
114        return 0;
115    }
116
117    void ControllableEntity::switchCamera()
118    {
119        if (this->camera_)
120        {
121            if (this->camera_->getParent() == this && this->cameraPositions_.size() > 0)
122            {
123                this->cameraPositions_.front()->attachCamera(this->camera_);
124            }
125            else if (this->cameraPositions_.size() > 0)
126            {
127                for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
128                {
129                    if ((*it) == this->camera_->getParent())
130                    {
131                        ++it;
132                        if (it != this->cameraPositions_.end())
133                            (*it)->attachCamera(this->camera_);
134                        else
135                            (*this->cameraPositions_.begin())->attachCamera(this->camera_);
136                        break;
137                    }
138                }
139            }
140            else
141            {
142                this->attach(this->camera_);
143            }
144        }
145    }
146
147    void ControllableEntity::setPlayer(PlayerInfo* player)
148    {
149        if (!player)
150        {
151            this->removePlayer();
152            return;
153        }
154
155        this->player_ = player;
156        this->playerID_ = player->getObjectID();
157        this->bControlled_ = (player->isLocalPlayer() && player->isHumanPlayer());
158        if (this->bControlled_)
159        {
160            this->startLocalControl();
161
162            if (!Core::isMaster())
163            {
164                this->client_overwrite_ = this->server_overwrite_;
165COUT(0) << "CE: bidirectional synchronization" << std::endl;
166                this->setObjectMode(network::direction::bidirectional);
167            }
168        }
169    }
170
171    void ControllableEntity::removePlayer()
172    {
173        if (this->bControlled_)
174            this->stopLocalControl();
175
176        this->player_ = 0;
177        this->playerID_ = network::OBJECTID_UNKNOWN;
178        this->bControlled_ = false;
179        this->setObjectMode(network::direction::toclient);
180
181        if (this->bDestroyWhenPlayerLeft_)
182            delete this;
183    }
184
185    void ControllableEntity::networkcallback_changedplayerID()
186    {
187        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
188        if (this->playerID_ != network::OBJECTID_UNKNOWN)
189        {
190            this->player_ = dynamic_cast<PlayerInfo*>(network::Synchronisable::getSynchronisable(this->playerID_));
191            if (this->player_ && (this->player_->getControllableEntity() != this))
192                this->player_->startControl(this);
193        }
194    }
195
196    void ControllableEntity::startLocalControl()
197    {
198//        std::cout << this->getObjectID() << " ###### start local control" << std::endl;
199        this->camera_ = new Camera(this);
200        this->camera_->requestFocus();
201        if (this->cameraPositionTemplate_ != "")
202            this->addTemplate(this->cameraPositionTemplate_);
203        if (this->cameraPositions_.size() > 0)
204            this->cameraPositions_.front()->attachCamera(this->camera_);
205        else
206            this->attach(this->camera_);
207
208        if (this->hudtemplate_ != "")
209        {
210            this->hud_ = new OverlayGroup(this);
211            this->hud_->addTemplate(this->hudtemplate_);
212        }
213    }
214
215    void ControllableEntity::stopLocalControl()
216    {
217//        std::cout << "###### stop local control" << std::endl;
218        this->camera_->detachFromParent();
219        delete this->camera_;
220        this->camera_ = 0;
221
222        delete this->hud_;
223        this->hud_ = 0;
224    }
225
226    void ControllableEntity::tick(float dt)
227    {
228        if (this->isActive())
229        {
230            if (!this->isDynamic())
231            {
232                this->velocity_ += (dt * this->acceleration_);
233                this->node_->translate(dt * this->velocity_, Ogre::Node::TS_LOCAL);
234            }
235
236            if (Core::isMaster())
237            {
238                this->server_velocity_ = this->velocity_;
239                this->server_position_ = this->node_->getPosition();
240            }
241            else if (this->bControlled_)
242            {
243//                COUT(2) << "setting client position" << endl;
244                this->client_velocity_ = this->velocity_;
245                this->client_position_ = this->node_->getPosition();
246            }
247        }
248    }
249
250    void ControllableEntity::registerVariables()
251    {
252        REGISTERSTRING(this->cameraPositionTemplate_, network::direction::toclient);
253
254        REGISTERDATA(this->server_position_,    network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
255        REGISTERDATA(this->server_velocity_,    network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));
256        REGISTERDATA(this->server_orientation_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
257
258        REGISTERDATA(this->server_overwrite_,   network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
259        REGISTERDATA(this->client_overwrite_,   network::direction::toserver);
260
261        REGISTERDATA(this->client_position_,    network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
262        REGISTERDATA(this->client_velocity_,    network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));
263        REGISTERDATA(this->client_orientation_, network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
264
265
266        REGISTERDATA(this->playerID_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
267    }
268
269    void ControllableEntity::processServerPosition()
270    {
271        if (!this->bControlled_)
272            this->node_->setPosition(this->server_position_);
273    }
274
275    void ControllableEntity::processServerVelocity()
276    {
277        if (!this->bControlled_)
278            this->velocity_ = this->server_velocity_;
279    }
280
281    void ControllableEntity::processServerOrientation()
282    {
283        if (!this->bControlled_)
284            this->node_->setOrientation(this->server_orientation_);
285    }
286
287    void ControllableEntity::processOverwrite()
288    {
289        if (this->bControlled_)
290        {
291            this->setPosition(this->server_position_);
292            this->setVelocity(this->server_velocity_);
293            this->setOrientation(this->server_orientation_);
294
295            this->client_overwrite_ = this->server_overwrite_;
296        }
297    }
298
299    void ControllableEntity::processClientPosition()
300    {
301        if (this->server_overwrite_ == this->client_overwrite_)
302        {
303//            COUT(2) << "callback: setting client position" << endl;
304            this->node_->setPosition(this->client_position_);
305            this->server_position_ = this->client_position_;
306        }
307//        else
308//          COUT(2) << "callback: not setting client position" << endl;
309    }
310
311    void ControllableEntity::processClientVelocity()
312    {
313        if (this->server_overwrite_ == this->client_overwrite_)
314        {
315            this->velocity_ = this->client_velocity_;
316            this->server_velocity_ = this->client_velocity_;
317        }
318    }
319
320    void ControllableEntity::processClientOrientation()
321    {
322        if (this->server_overwrite_ == this->client_overwrite_)
323        {
324            this->node_->setOrientation(this->client_orientation_);
325            this->server_orientation_ = this->client_orientation_;
326        }
327    }
328
329    void ControllableEntity::positionChanged()
330    {
331        if (Core::isMaster())
332        {
333            this->server_position_ = this->getPosition();
334            ++this->server_overwrite_;
335        }
336        else if (this->bControlled_)
337        {
338            this->client_position_ = this->getPosition();
339        }
340    }
341
342    void ControllableEntity::orientationChanged()
343    {
344        if (Core::isMaster())
345        {
346            this->server_orientation_ = this->getOrientation();
347            ++this->server_overwrite_;
348        }
349        else if (this->bControlled_)
350        {
351            this->client_orientation_ = this->getOrientation();
352        }
353    }
354
355    void ControllableEntity::velocityChanged()
356    {
357        if (Core::isMaster())
358        {
359            this->server_velocity_ = this->getVelocity();
360            ++this->server_overwrite_;
361        }
362        else if (this->bControlled_)
363        {
364            this->client_velocity_ = this->getVelocity();
365        }
366    }
367}
Note: See TracBrowser for help on using the repository browser.