Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/orxonox/objects/worldentities/ControllableEntity.cc @ 2254

Last change on this file since 2254 was 2254, checked in by landauf, 15 years ago

Update your media repository and delete keybindings.ini if you want to use boost (space).

  • Added new class "Engine" to control the speed of a SpaceShip (Engine is an Item, MultiStateEngine is a specialized version of Engine)
  • Added FadingBillboard, a billboard with the ability to fade in and out smoothly when activated/deactivated.
  • Several changes in Backlight, it's now a child of FadingBillboard
  • Some changes concerning local control in ControllableEntity
  • Fixed a bug in WorldEntity caused by different destruction order of attached objects on server and client
  • Added a "MainState" to BaseObject. An object has several states (activity, visibility, …) and one of it can be defined as "MainState" in the XML file. Other objects can change this state without knowing which state it really is (used by MultiStateEngine).
  • Property svn:eol-style set to native
File size: 16.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) : WorldEntity(creator)
47    {
48        RegisterObject(ControllableEntity);
49
50        this->bHasLocalController_ = false;
51        this->bHasHumanController_ = false;
52
53        this->server_overwrite_ = 0;
54        this->client_overwrite_ = 0;
55        this->player_ = 0;
56        this->playerID_ = OBJECTID_UNKNOWN;
57        this->hud_ = 0;
58        this->camera_ = 0;
59        this->bDestroyWhenPlayerLeft_ = false;
60
61        this->velocity_ = Vector3::ZERO;
62        this->acceleration_ = Vector3::ZERO;
63
64        this->server_position_ = Vector3::ZERO;
65        this->client_position_ = Vector3::ZERO;
66        this->server_velocity_ = Vector3::ZERO;
67        this->client_velocity_ = Vector3::ZERO;
68        this->server_orientation_ = Quaternion::IDENTITY;
69        this->client_orientation_ = Quaternion::IDENTITY;
70
71        this->registerVariables();
72    }
73
74    ControllableEntity::~ControllableEntity()
75    {
76        if (this->isInitialized())
77        {
78            if (this->bHasLocalController_)
79                this->stopLocalHumanControl();
80
81            if (this->hud_)
82                delete this->hud_;
83
84            if (this->camera_)
85                delete this->camera_;
86
87            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
88                this->getPlayer()->stopControl(this, false);
89        }
90    }
91
92    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
93    {
94        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
95
96        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
97        XMLPortParam(ControllableEntity, "camerapositiontemplate", setCameraPositionTemplate, getCameraPositionTemkplate, xmlelement, mode);
98
99        XMLPortObject(ControllableEntity, CameraPosition, "camerapositions", addCameraPosition, getCameraPosition, xmlelement, mode);
100    }
101
102    void ControllableEntity::addCameraPosition(CameraPosition* position)
103    {
104        this->attach(position);
105        this->cameraPositions_.push_back(position);
106    }
107
108    CameraPosition* ControllableEntity::getCameraPosition(unsigned int index) const
109    {
110        unsigned int i = 0;
111        for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
112        {
113            if (i == index)
114                return (*it);
115            ++i;
116        }
117        return 0;
118    }
119
120    void ControllableEntity::switchCamera()
121    {
122        if (this->camera_)
123        {
124            if (this->camera_->getParent() == this && this->cameraPositions_.size() > 0)
125            {
126                this->cameraPositions_.front()->attachCamera(this->camera_);
127            }
128            else if (this->cameraPositions_.size() > 0)
129            {
130                for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
131                {
132                    if ((*it) == this->camera_->getParent())
133                    {
134                        ++it;
135                        if (it != this->cameraPositions_.end())
136                            (*it)->attachCamera(this->camera_);
137                        else
138                            (*this->cameraPositions_.begin())->attachCamera(this->camera_);
139                        break;
140                    }
141                }
142            }
143            else
144            {
145                this->attach(this->camera_);
146            }
147        }
148    }
149
150    void ControllableEntity::setPlayer(PlayerInfo* player)
151    {
152        if (!player)
153        {
154            this->removePlayer();
155            return;
156        }
157
158        this->player_ = player;
159        this->playerID_ = player->getObjectID();
160        this->bHasLocalController_ = player->isLocalPlayer();
161        this->bHasHumanController_ = player->isHumanPlayer();
162
163        if (this->bHasLocalController_ && this->bHasHumanController_)
164        {
165            this->startLocalHumanControl();
166
167            if (!Core::isMaster())
168            {
169                this->client_overwrite_ = this->server_overwrite_;
170COUT(0) << "CE: bidirectional synchronization" << std::endl;
171                this->setObjectMode(direction::bidirectional);
172            }
173        }
174    }
175
176    void ControllableEntity::removePlayer()
177    {
178        if (this->bHasLocalController_ && this->bHasHumanController_)
179            this->stopLocalHumanControl();
180
181        this->player_ = 0;
182        this->playerID_ = OBJECTID_UNKNOWN;
183        this->bHasLocalController_ = false;
184        this->bHasHumanController_ = false;
185        this->setObjectMode(direction::toclient);
186
187        if (this->bDestroyWhenPlayerLeft_)
188            delete this;
189    }
190
191    void ControllableEntity::networkcallback_changedplayerID()
192    {
193        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
194        if (this->playerID_ != OBJECTID_UNKNOWN)
195        {
196            this->player_ = dynamic_cast<PlayerInfo*>(Synchronisable::getSynchronisable(this->playerID_));
197            if (this->player_ && (this->player_->getControllableEntity() != this))
198                this->player_->startControl(this);
199        }
200    }
201
202    void ControllableEntity::startLocalHumanControl()
203    {
204//        std::cout << this->getObjectID() << " ###### start local control" << std::endl;
205        this->camera_ = new Camera(this);
206        this->camera_->requestFocus();
207        if (this->cameraPositionTemplate_ != "")
208            this->addTemplate(this->cameraPositionTemplate_);
209        if (this->cameraPositions_.size() > 0)
210            this->cameraPositions_.front()->attachCamera(this->camera_);
211        else
212            this->attach(this->camera_);
213
214        if (this->hudtemplate_ != "")
215        {
216            this->hud_ = new OverlayGroup(this);
217            this->hud_->addTemplate(this->hudtemplate_);
218        }
219    }
220
221    void ControllableEntity::stopLocalHumanControl()
222    {
223//        std::cout << "###### stop local control" << std::endl;
224        this->camera_->detachFromParent();
225        delete this->camera_;
226        this->camera_ = 0;
227
228        delete this->hud_;
229        this->hud_ = 0;
230    }
231
232    void ControllableEntity::tick(float dt)
233    {
234        if (this->isActive())
235        {
236            this->velocity_ += (dt * this->acceleration_);
237            this->node_->translate(dt * this->velocity_, Ogre::Node::TS_LOCAL);
238
239            if (Core::isMaster())
240            {
241                this->server_velocity_ = this->velocity_;
242                this->server_position_ = this->node_->getPosition();
243            }
244            else if (this->bHasLocalController_)
245            {
246//                COUT(2) << "setting client position" << endl;
247                this->client_velocity_ = this->velocity_;
248                this->client_position_ = this->node_->getPosition();
249            }
250        }
251    }
252
253    void ControllableEntity::registerVariables()
254    {
255        REGISTERSTRING(this->cameraPositionTemplate_, direction::toclient);
256
257        REGISTERDATA(this->client_overwrite_,   direction::toserver);
258
259        REGISTERDATA(this->server_position_,    direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
260        REGISTERDATA(this->server_velocity_,    direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));
261        REGISTERDATA(this->server_orientation_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
262        REGISTERDATA(this->server_overwrite_,   direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
263
264        REGISTERDATA(this->client_position_,    direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
265        REGISTERDATA(this->client_velocity_,    direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));
266        REGISTERDATA(this->client_orientation_, direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
267
268
269        REGISTERDATA(this->playerID_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
270    }
271
272    void ControllableEntity::processServerPosition()
273    {
274        if (!this->bHasLocalController_)
275            this->node_->setPosition(this->server_position_);
276    }
277
278    void ControllableEntity::processServerVelocity()
279    {
280        if (!this->bHasLocalController_)
281            this->velocity_ = this->server_velocity_;
282    }
283
284    void ControllableEntity::processServerOrientation()
285    {
286        if (!this->bHasLocalController_)
287            this->node_->setOrientation(this->server_orientation_);
288    }
289
290    void ControllableEntity::processOverwrite()
291    {
292        if (this->bHasLocalController_)
293        {
294            this->setPosition(this->server_position_);
295            this->setVelocity(this->server_velocity_);
296            this->setOrientation(this->server_orientation_);
297
298            this->client_overwrite_ = this->server_overwrite_;
299        }
300    }
301
302    void ControllableEntity::processClientPosition()
303    {
304        if (this->server_overwrite_ == this->client_overwrite_)
305        {
306//            COUT(2) << "callback: setting client position" << endl;
307            this->node_->setPosition(this->client_position_);
308            this->server_position_ = this->client_position_;
309        }
310//        else
311//          COUT(2) << "callback: not setting client position" << endl;
312    }
313
314    void ControllableEntity::processClientVelocity()
315    {
316        if (this->server_overwrite_ == this->client_overwrite_)
317        {
318            this->velocity_ = this->client_velocity_;
319            this->server_velocity_ = this->client_velocity_;
320        }
321    }
322
323    void ControllableEntity::processClientOrientation()
324    {
325        if (this->server_overwrite_ == this->client_overwrite_)
326        {
327            this->node_->setOrientation(this->client_orientation_);
328            this->server_orientation_ = this->client_orientation_;
329        }
330    }
331
332
333    void ControllableEntity::setPosition(const Vector3& position)
334    {
335        if (Core::isMaster())
336        {
337            this->node_->setPosition(position);
338            this->server_position_ = position;
339            ++this->server_overwrite_;
340        }
341        else if (this->bHasLocalController_)
342        {
343            this->node_->setPosition(position);
344            this->client_position_ = position;
345        }
346    }
347
348    void ControllableEntity::setVelocity(const Vector3& velocity)
349    {
350        if (Core::isMaster())
351        {
352            this->velocity_ = velocity;
353            this->server_velocity_ = velocity;
354            ++this->server_overwrite_;
355        }
356        else if (this->bHasLocalController_)
357        {
358            this->velocity_ = velocity;
359            this->client_velocity_ = velocity;
360        }
361    }
362
363    void ControllableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
364    {
365        if (Core::isMaster())
366        {
367            this->node_->translate(distance, relativeTo);
368            this->server_position_ = this->node_->getPosition();
369            ++this->server_overwrite_;
370        }
371        else if (this->bHasLocalController_)
372        {
373            this->node_->translate(distance, relativeTo);
374            this->client_position_ = this->node_->getPosition();
375        }
376    }
377
378    void ControllableEntity::setOrientation(const Quaternion& orientation)
379    {
380        if (Core::isMaster())
381        {
382            this->node_->setOrientation(orientation);
383            this->server_orientation_ = orientation;
384            ++this->server_overwrite_;
385        }
386        else if (this->bHasLocalController_)
387        {
388            this->node_->setOrientation(orientation);
389            this->client_orientation_ = orientation;
390        }
391    }
392
393    void ControllableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
394    {
395        if (Core::isMaster())
396        {
397            this->node_->rotate(rotation, relativeTo);
398            this->server_orientation_ = this->node_->getOrientation();
399            ++this->server_overwrite_;
400        }
401        else if (this->bHasLocalController_)
402        {
403            this->node_->rotate(rotation, relativeTo);
404            this->client_orientation_ = this->node_->getOrientation();
405        }
406    }
407
408    void ControllableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
409    {
410        if (Core::isMaster())
411        {
412            this->node_->yaw(angle, relativeTo);
413            this->server_orientation_ = this->node_->getOrientation();
414            ++this->server_overwrite_;
415        }
416        else if (this->bHasLocalController_)
417        {
418            this->node_->yaw(angle, relativeTo);
419            this->client_orientation_ = this->node_->getOrientation();
420        }
421    }
422
423    void ControllableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
424    {
425        if (Core::isMaster())
426        {
427            this->node_->pitch(angle, relativeTo);
428            this->server_orientation_ = this->node_->getOrientation();
429            ++this->server_overwrite_;
430        }
431        else if (this->bHasLocalController_)
432        {
433            this->node_->pitch(angle, relativeTo);
434            this->client_orientation_ = this->node_->getOrientation();
435        }
436    }
437
438    void ControllableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
439    {
440        if (Core::isMaster())
441        {
442            this->node_->roll(angle, relativeTo);
443            this->server_orientation_ = this->node_->getOrientation();
444            ++this->server_overwrite_;
445        }
446        else if (this->bHasLocalController_)
447        {
448            this->node_->roll(angle, relativeTo);
449            this->client_orientation_ = this->node_->getOrientation();
450        }
451    }
452
453    void ControllableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
454    {
455        if (Core::isMaster())
456        {
457            this->node_->lookAt(target, relativeTo, localDirectionVector);
458            this->server_orientation_ = this->node_->getOrientation();
459            ++this->server_overwrite_;
460        }
461        else if (this->bHasLocalController_)
462        {
463            this->node_->lookAt(target, relativeTo, localDirectionVector);
464            this->client_orientation_ = this->node_->getOrientation();
465        }
466    }
467
468    void ControllableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
469    {
470        if (Core::isMaster())
471        {
472            this->node_->setDirection(direction, relativeTo, localDirectionVector);
473            this->server_orientation_ = this->node_->getOrientation();
474            ++this->server_overwrite_;
475        }
476        else if (this->bHasLocalController_)
477        {
478            this->node_->setDirection(direction, relativeTo, localDirectionVector);
479            this->client_orientation_ = this->node_->getOrientation();
480        }
481    }
482}
Note: See TracBrowser for help on using the repository browser.