Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2578 was 2478, checked in by landauf, 16 years ago
  • Readded smooth camera movement (configurable through CameraPosition), works also with camera-position-changes
  • Added free mouse look (press left control key)
  • Made strength of boost-blur configurable
  • Property svn:eol-style set to native
File size: 19.2 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 <OgreSceneManager.h>
33
34#include "core/CoreIncludes.h"
35#include "core/ConfigValueIncludes.h"
36#include "core/Core.h"
37#include "core/XMLPort.h"
38#include "core/Template.h"
39
40#include "objects/Scene.h"
41#include "objects/infos/PlayerInfo.h"
42#include "objects/worldentities/Camera.h"
43#include "objects/worldentities/CameraPosition.h"
44#include "objects/gametypes/Gametype.h"
45#include "overlays/OverlayGroup.h"
46
47namespace orxonox
48{
49    CreateFactory(ControllableEntity);
50
51    ControllableEntity::ControllableEntity(BaseObject* creator) : WorldEntity(creator)
52    {
53        RegisterObject(ControllableEntity);
54
55        this->bHasLocalController_ = false;
56        this->bHasHumanController_ = false;
57
58        this->server_overwrite_ = 0;
59        this->client_overwrite_ = 0;
60        this->player_ = 0;
61        this->playerID_ = OBJECTID_UNKNOWN;
62        this->hud_ = 0;
63        this->camera_ = 0;
64        this->bDestroyWhenPlayerLeft_ = false;
65        this->cameraPositionRootNode_ = this->node_->createChildSceneNode();
66        this->bMouseLook_ = false;
67        this->mouseLookSpeed_ = 200;
68
69        this->gtinfo_ = 0;
70        this->gtinfoID_ = OBJECTID_UNKNOWN;
71        this->changedGametype();
72
73        this->velocity_ = Vector3::ZERO;
74        this->acceleration_ = Vector3::ZERO;
75
76        this->server_position_ = Vector3::ZERO;
77        this->client_position_ = Vector3::ZERO;
78        this->server_velocity_ = Vector3::ZERO;
79        this->client_velocity_ = Vector3::ZERO;
80        this->server_orientation_ = Quaternion::IDENTITY;
81        this->client_orientation_ = Quaternion::IDENTITY;
82
83        this->setConfigValues();
84        this->registerVariables();
85    }
86
87    ControllableEntity::~ControllableEntity()
88    {
89        if (this->isInitialized())
90        {
91            this->bDestroyWhenPlayerLeft_ = false;
92
93            if (this->bHasLocalController_ && this->bHasHumanController_)
94                this->stopLocalHumanControl();
95
96            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
97                this->getPlayer()->stopControl(this, false);
98
99            if (this->hud_)
100                delete this->hud_;
101
102            if (this->camera_)
103                delete this->camera_;
104
105            for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
106                delete (*it);
107
108            if (this->getScene()->getSceneManager())
109                this->getScene()->getSceneManager()->destroySceneNode(this->cameraPositionRootNode_->getName());
110        }
111    }
112
113    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
114    {
115        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
116
117        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
118        XMLPortParam(ControllableEntity, "camerapositiontemplate", setCameraPositionTemplate, getCameraPositionTemkplate, xmlelement, mode);
119
120        XMLPortObject(ControllableEntity, CameraPosition, "camerapositions", addCameraPosition, getCameraPosition, xmlelement, mode);
121    }
122
123    void ControllableEntity::setConfigValues()
124    {
125        SetConfigValue(mouseLookSpeed_, 3.0f);
126    }
127
128    void ControllableEntity::changedGametype()
129    {
130        //SUPER(ControllableEntity, changedGametype);
131        WorldEntity::changedGametype();
132
133        this->gtinfo_ = 0;
134        this->gtinfoID_ = OBJECTID_UNKNOWN;
135
136        if (this->getGametype() && this->getGametype()->getGametypeInfo())
137        {
138            this->gtinfo_ = this->getGametype()->getGametypeInfo();
139            this->gtinfoID_ = this->gtinfo_->getObjectID();
140        }
141    }
142
143    void ControllableEntity::addCameraPosition(CameraPosition* position)
144    {
145        if (position->getAllowMouseLook())
146            position->attachToNode(this->cameraPositionRootNode_);
147        else
148            this->attach(position);
149        this->cameraPositions_.push_back(position);
150    }
151
152    CameraPosition* ControllableEntity::getCameraPosition(unsigned int index) const
153    {
154        unsigned int i = 0;
155        for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
156        {
157            if (i == index)
158                return (*it);
159            ++i;
160        }
161        return 0;
162    }
163
164    void ControllableEntity::switchCamera()
165    {
166        if (this->camera_)
167        {
168            if (this->camera_->getParent() == this && this->cameraPositions_.size() > 0)
169            {
170                this->cameraPositions_.front()->attachCamera(this->camera_);
171            }
172            else if (this->cameraPositions_.size() > 0)
173            {
174                for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
175                {
176                    if ((*it) == this->camera_->getParent())
177                    {
178                        ++it;
179                        if (it != this->cameraPositions_.end())
180                            (*it)->attachCamera(this->camera_);
181                        else
182                            (*this->cameraPositions_.begin())->attachCamera(this->camera_);
183                        break;
184                    }
185                }
186            }
187            else
188            {
189                this->camera_->attachToNode(this->cameraPositionRootNode_);
190            }
191        }
192    }
193
194    void ControllableEntity::mouseLook()
195    {
196        this->bMouseLook_ = !this->bMouseLook_;
197
198        if (!this->bMouseLook_)
199            this->cameraPositionRootNode_->setOrientation(Quaternion::IDENTITY);
200    }
201
202    void ControllableEntity::rotateYaw(const Vector2& value)
203    {
204        if (this->bMouseLook_)
205            this->cameraPositionRootNode_->yaw(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
206    }
207
208    void ControllableEntity::rotatePitch(const Vector2& value)
209    {
210        if (this->bMouseLook_)
211            this->cameraPositionRootNode_->pitch(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
212    }
213
214    void ControllableEntity::rotateRoll(const Vector2& value)
215    {
216        if (this->bMouseLook_)
217            this->cameraPositionRootNode_->roll(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
218    }
219
220    void ControllableEntity::setPlayer(PlayerInfo* player)
221    {
222        if (!player)
223        {
224            this->removePlayer();
225            return;
226        }
227
228        this->player_ = player;
229        this->playerID_ = player->getObjectID();
230        this->bHasLocalController_ = player->isLocalPlayer();
231        this->bHasHumanController_ = player->isHumanPlayer();
232
233        if (this->bHasLocalController_ && this->bHasHumanController_)
234        {
235            this->startLocalHumanControl();
236
237            if (!Core::isMaster())
238            {
239                this->client_overwrite_ = this->server_overwrite_;
240                this->setObjectMode(direction::bidirectional);
241            }
242        }
243    }
244
245    void ControllableEntity::removePlayer()
246    {
247        if (this->bHasLocalController_ && this->bHasHumanController_)
248            this->stopLocalHumanControl();
249
250        this->player_ = 0;
251        this->playerID_ = OBJECTID_UNKNOWN;
252        this->bHasLocalController_ = false;
253        this->bHasHumanController_ = false;
254        this->setObjectMode(direction::toclient);
255
256        if (this->bDestroyWhenPlayerLeft_)
257            delete this;
258    }
259
260    void ControllableEntity::networkcallback_changedplayerID()
261    {
262        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
263        if (this->playerID_ != OBJECTID_UNKNOWN)
264        {
265            this->player_ = dynamic_cast<PlayerInfo*>(Synchronisable::getSynchronisable(this->playerID_));
266            if (this->player_ && (this->player_->getControllableEntity() != this))
267                this->player_->startControl(this);
268        }
269    }
270
271    void ControllableEntity::networkcallback_changedgtinfoID()
272    {
273        if (this->gtinfoID_ != OBJECTID_UNKNOWN)
274        {
275            this->gtinfo_ = dynamic_cast<GametypeInfo*>(Synchronisable::getSynchronisable(this->gtinfoID_));
276
277            if (!this->gtinfo_)
278                this->gtinfoID_ = OBJECTID_UNKNOWN;
279        }
280    }
281
282    void ControllableEntity::startLocalHumanControl()
283    {
284        if (!this->camera_)
285        {
286            this->camera_ = new Camera(this);
287            this->camera_->requestFocus();
288            if (this->cameraPositionTemplate_ != "")
289                this->addTemplate(this->cameraPositionTemplate_);
290            if (this->cameraPositions_.size() > 0)
291                this->cameraPositions_.front()->attachCamera(this->camera_);
292            else
293                this->camera_->attachToNode(this->cameraPositionRootNode_);
294        }
295
296        if (!this->hud_)
297        {
298            if (this->hudtemplate_ != "")
299            {
300                this->hud_ = new OverlayGroup(this);
301                this->hud_->addTemplate(this->hudtemplate_);
302                this->hud_->setOwner(this);
303            }
304        }
305    }
306
307    void ControllableEntity::stopLocalHumanControl()
308    {
309        if (this->camera_)
310        {
311            this->camera_->detachFromParent();
312            delete this->camera_;
313            this->camera_ = 0;
314        }
315
316        if (this->hud_)
317        {
318            delete this->hud_;
319            this->hud_ = 0;
320        }
321    }
322
323    void ControllableEntity::tick(float dt)
324    {
325        if (this->isActive())
326        {
327            SUPER(ControllableEntity, tick, dt);
328
329            this->velocity_ += (dt * this->acceleration_);
330            this->node_->translate(dt * this->velocity_, Ogre::Node::TS_LOCAL);
331
332            if (Core::isMaster())
333            {
334                this->server_velocity_ = this->velocity_;
335                this->server_position_ = this->node_->getPosition();
336            }
337            else if (this->bHasLocalController_)
338            {
339                this->client_velocity_ = this->velocity_;
340                this->client_position_ = this->node_->getPosition();
341            }
342        }
343    }
344
345    void ControllableEntity::registerVariables()
346    {
347        REGISTERSTRING(this->cameraPositionTemplate_, direction::toclient);
348        REGISTERSTRING(this->hudtemplate_, direction::toclient);
349
350        REGISTERDATA(this->client_overwrite_,   direction::toserver);
351
352        REGISTERDATA(this->server_position_,    direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
353        REGISTERDATA(this->server_velocity_,    direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));
354        REGISTERDATA(this->server_orientation_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
355        REGISTERDATA(this->server_overwrite_,   direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
356
357        REGISTERDATA(this->client_position_,    direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
358        REGISTERDATA(this->client_velocity_,    direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));
359        REGISTERDATA(this->client_orientation_, direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
360
361
362        REGISTERDATA(this->playerID_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
363        REGISTERDATA(this->gtinfoID_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedgtinfoID));
364    }
365
366    void ControllableEntity::processServerPosition()
367    {
368        if (!this->bHasLocalController_)
369            this->node_->setPosition(this->server_position_);
370    }
371
372    void ControllableEntity::processServerVelocity()
373    {
374        if (!this->bHasLocalController_)
375            this->velocity_ = this->server_velocity_;
376    }
377
378    void ControllableEntity::processServerOrientation()
379    {
380        if (!this->bHasLocalController_)
381            this->node_->setOrientation(this->server_orientation_);
382    }
383
384    void ControllableEntity::processOverwrite()
385    {
386        if (this->bHasLocalController_)
387        {
388            this->setPosition(this->server_position_);
389            this->setVelocity(this->server_velocity_);
390            this->setOrientation(this->server_orientation_);
391
392            this->client_overwrite_ = this->server_overwrite_;
393        }
394    }
395
396    void ControllableEntity::processClientPosition()
397    {
398        if (this->server_overwrite_ == this->client_overwrite_)
399        {
400            this->node_->setPosition(this->client_position_);
401            this->server_position_ = this->client_position_;
402        }
403    }
404
405    void ControllableEntity::processClientVelocity()
406    {
407        if (this->server_overwrite_ == this->client_overwrite_)
408        {
409            this->velocity_ = this->client_velocity_;
410            this->server_velocity_ = this->client_velocity_;
411        }
412    }
413
414    void ControllableEntity::processClientOrientation()
415    {
416        if (this->server_overwrite_ == this->client_overwrite_)
417        {
418            this->node_->setOrientation(this->client_orientation_);
419            this->server_orientation_ = this->client_orientation_;
420        }
421    }
422
423
424    void ControllableEntity::setPosition(const Vector3& position)
425    {
426        if (Core::isMaster())
427        {
428            this->node_->setPosition(position);
429            this->server_position_ = position;
430            ++this->server_overwrite_;
431        }
432        else if (this->bHasLocalController_)
433        {
434            this->node_->setPosition(position);
435            this->client_position_ = position;
436        }
437    }
438
439    void ControllableEntity::setVelocity(const Vector3& velocity)
440    {
441        if (Core::isMaster())
442        {
443            this->velocity_ = velocity;
444            this->server_velocity_ = velocity;
445            ++this->server_overwrite_;
446        }
447        else if (this->bHasLocalController_)
448        {
449            this->velocity_ = velocity;
450            this->client_velocity_ = velocity;
451        }
452    }
453
454    void ControllableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
455    {
456        if (Core::isMaster())
457        {
458            this->node_->translate(distance, relativeTo);
459            this->server_position_ = this->node_->getPosition();
460            ++this->server_overwrite_;
461        }
462        else if (this->bHasLocalController_)
463        {
464            this->node_->translate(distance, relativeTo);
465            this->client_position_ = this->node_->getPosition();
466        }
467    }
468
469    void ControllableEntity::setOrientation(const Quaternion& orientation)
470    {
471        if (Core::isMaster())
472        {
473            this->node_->setOrientation(orientation);
474            this->server_orientation_ = orientation;
475            ++this->server_overwrite_;
476        }
477        else if (this->bHasLocalController_)
478        {
479            this->node_->setOrientation(orientation);
480            this->client_orientation_ = orientation;
481        }
482    }
483
484    void ControllableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
485    {
486        if (Core::isMaster())
487        {
488            this->node_->rotate(rotation, relativeTo);
489            this->server_orientation_ = this->node_->getOrientation();
490            ++this->server_overwrite_;
491        }
492        else if (this->bHasLocalController_)
493        {
494            this->node_->rotate(rotation, relativeTo);
495            this->client_orientation_ = this->node_->getOrientation();
496        }
497    }
498
499    void ControllableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
500    {
501        if (Core::isMaster())
502        {
503            this->node_->yaw(angle, relativeTo);
504            this->server_orientation_ = this->node_->getOrientation();
505            ++this->server_overwrite_;
506        }
507        else if (this->bHasLocalController_)
508        {
509            this->node_->yaw(angle, relativeTo);
510            this->client_orientation_ = this->node_->getOrientation();
511        }
512    }
513
514    void ControllableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
515    {
516        if (Core::isMaster())
517        {
518            this->node_->pitch(angle, relativeTo);
519            this->server_orientation_ = this->node_->getOrientation();
520            ++this->server_overwrite_;
521        }
522        else if (this->bHasLocalController_)
523        {
524            this->node_->pitch(angle, relativeTo);
525            this->client_orientation_ = this->node_->getOrientation();
526        }
527    }
528
529    void ControllableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
530    {
531        if (Core::isMaster())
532        {
533            this->node_->roll(angle, relativeTo);
534            this->server_orientation_ = this->node_->getOrientation();
535            ++this->server_overwrite_;
536        }
537        else if (this->bHasLocalController_)
538        {
539            this->node_->roll(angle, relativeTo);
540            this->client_orientation_ = this->node_->getOrientation();
541        }
542    }
543
544    void ControllableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
545    {
546        if (Core::isMaster())
547        {
548            this->node_->lookAt(target, relativeTo, localDirectionVector);
549            this->server_orientation_ = this->node_->getOrientation();
550            ++this->server_overwrite_;
551        }
552        else if (this->bHasLocalController_)
553        {
554            this->node_->lookAt(target, relativeTo, localDirectionVector);
555            this->client_orientation_ = this->node_->getOrientation();
556        }
557    }
558
559    void ControllableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
560    {
561        if (Core::isMaster())
562        {
563            this->node_->setDirection(direction, relativeTo, localDirectionVector);
564            this->server_orientation_ = this->node_->getOrientation();
565            ++this->server_overwrite_;
566        }
567        else if (this->bHasLocalController_)
568        {
569            this->node_->setDirection(direction, relativeTo, localDirectionVector);
570            this->client_orientation_ = this->node_->getOrientation();
571        }
572    }
573}
Note: See TracBrowser for help on using the repository browser.