Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.cc @ 3050

Last change on this file since 3050 was 3004, checked in by scheusso, 16 years ago

reverted changes of ControllableEntity
synchronisation now again with server and client values and overwrites (unidirectional)
problem with bidirectional synchronisation was the combination with bullet (lots of changes of client ships on the server side and thus lag in synchronisation)

  • Property svn:eol-style set to native
File size: 18.1 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 *      Reto Grieder
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/GameMode.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 "overlays/OverlayGroup.h"
45
46namespace orxonox
47{
48    CreateFactory(ControllableEntity);
49
50    ControllableEntity::ControllableEntity(BaseObject* creator) : MobileEntity(creator)
51    {
52        RegisterObject(ControllableEntity);
53
54        this->bHasLocalController_ = false;
55        this->bHasHumanController_ = false;
56
57        this->server_overwrite_ = 0;
58        this->client_overwrite_ = 0;
59        this->player_ = 0;
60        this->playerID_ = OBJECTID_UNKNOWN;
61        this->hud_ = 0;
62        this->camera_ = 0;
63        this->bDestroyWhenPlayerLeft_ = false;
64        this->cameraPositionRootNode_ = this->node_->createChildSceneNode();
65        this->bMouseLook_ = false;
66        this->mouseLookSpeed_ = 200;
67
68        this->server_position_         = Vector3::ZERO;
69        this->client_position_         = Vector3::ZERO;
70        this->server_linear_velocity_  = Vector3::ZERO;
71        this->client_linear_velocity_  = Vector3::ZERO;
72        this->server_orientation_      = Quaternion::IDENTITY;
73        this->client_orientation_      = Quaternion::IDENTITY;
74        this->server_angular_velocity_ = Vector3::ZERO;
75        this->client_angular_velocity_ = Vector3::ZERO;
76
77
78        this->setConfigValues();
79        this->setPriority( priority::very_high );
80        this->registerVariables();
81    }
82
83    ControllableEntity::~ControllableEntity()
84    {
85        if (this->isInitialized())
86        {
87            this->bDestroyWhenPlayerLeft_ = false;
88
89            if (this->bHasLocalController_ && this->bHasHumanController_)
90                this->stopLocalHumanControl();
91
92            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
93                this->getPlayer()->stopControl(this, false);
94
95            if (this->hud_)
96                delete this->hud_;
97
98            if (this->camera_)
99                delete this->camera_;
100
101            for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
102                delete (*it);
103
104            if (this->getScene()->getSceneManager())
105                this->getScene()->getSceneManager()->destroySceneNode(this->cameraPositionRootNode_->getName());
106        }
107    }
108
109    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
110    {
111        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
112
113        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
114        XMLPortParam(ControllableEntity, "camerapositiontemplate", setCameraPositionTemplate, getCameraPositionTemkplate, xmlelement, mode);
115
116        XMLPortObject(ControllableEntity, CameraPosition, "camerapositions", addCameraPosition, getCameraPosition, xmlelement, mode);
117    }
118
119    void ControllableEntity::setConfigValues()
120    {
121        SetConfigValue(mouseLookSpeed_, 3.0f);
122    }
123
124    void ControllableEntity::addCameraPosition(CameraPosition* position)
125    {
126        if (!position->getIsAbsolute())
127        {
128            if (position->getAllowMouseLook())
129                position->attachToNode(this->cameraPositionRootNode_);
130            else
131                this->attach(position);
132        }
133        else
134        {
135            WorldEntity* parent = this->getParent();
136            if (parent)
137                parent->attach(position);
138        }
139        this->cameraPositions_.push_back(position);
140    }
141
142    CameraPosition* ControllableEntity::getCameraPosition(unsigned int index) const
143    {
144        unsigned int i = 0;
145        for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
146        {
147            if (i == index)
148                return (*it);
149            ++i;
150        }
151        return 0;
152    }
153
154    void ControllableEntity::switchCamera()
155    {
156        if (this->camera_)
157        {
158            if (this->camera_->getParent() == this && this->cameraPositions_.size() > 0)
159            {
160                this->cameraPositions_.front()->attachCamera(this->camera_);
161            }
162            else if (this->cameraPositions_.size() > 0)
163            {
164                for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
165                {
166                    if ((*it) == this->camera_->getParent())
167                    {
168                        ++it;
169                        if (it != this->cameraPositions_.end())
170                            (*it)->attachCamera(this->camera_);
171                        else
172                            (*this->cameraPositions_.begin())->attachCamera(this->camera_);
173                        break;
174                    }
175                }
176            }
177            else
178            {
179                this->camera_->attachToNode(this->cameraPositionRootNode_);
180            }
181        }
182    }
183
184    void ControllableEntity::mouseLook()
185    {
186        this->bMouseLook_ = !this->bMouseLook_;
187
188        if (!this->bMouseLook_)
189            this->cameraPositionRootNode_->setOrientation(Quaternion::IDENTITY);
190    }
191
192    void ControllableEntity::rotateYaw(const Vector2& value)
193    {
194        if (this->bMouseLook_)
195            this->cameraPositionRootNode_->yaw(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
196    }
197
198    void ControllableEntity::rotatePitch(const Vector2& value)
199    {
200        if (this->bMouseLook_)
201            this->cameraPositionRootNode_->pitch(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
202    }
203
204    void ControllableEntity::rotateRoll(const Vector2& value)
205    {
206        if (this->bMouseLook_)
207            this->cameraPositionRootNode_->roll(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
208    }
209
210    void ControllableEntity::setPlayer(PlayerInfo* player)
211    {
212        if (!player)
213        {
214            this->removePlayer();
215            return;
216        }
217
218        this->player_ = player;
219        this->playerID_ = player->getObjectID();
220        this->bHasLocalController_ = player->isLocalPlayer();
221        this->bHasHumanController_ = player->isHumanPlayer();
222
223        if (this->bHasLocalController_ && this->bHasHumanController_)
224        {
225            this->startLocalHumanControl();
226
227            if (!GameMode::isMaster())
228            {
229                this->client_overwrite_ = this->server_overwrite_;
230                this->setObjectMode(objectDirection::bidirectional);
231            }
232        }
233
234        this->changedPlayer();
235    }
236
237    void ControllableEntity::removePlayer()
238    {
239        if (this->bHasLocalController_ && this->bHasHumanController_)
240            this->stopLocalHumanControl();
241
242        this->player_ = 0;
243        this->playerID_ = OBJECTID_UNKNOWN;
244        this->bHasLocalController_ = false;
245        this->bHasHumanController_ = false;
246        this->setObjectMode(objectDirection::toclient);
247
248        this->changedPlayer();
249
250        if (this->bDestroyWhenPlayerLeft_)
251            delete this;
252    }
253
254    void ControllableEntity::networkcallback_changedplayerID()
255    {
256        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
257        if (this->playerID_ != OBJECTID_UNKNOWN)
258        {
259            this->player_ = dynamic_cast<PlayerInfo*>(Synchronisable::getSynchronisable(this->playerID_));
260            if (this->player_ && (this->player_->getControllableEntity() != this))
261                this->player_->startControl(this);
262        }
263    }
264
265    void ControllableEntity::startLocalHumanControl()
266    {
267        if (!this->camera_)
268        {
269            this->camera_ = new Camera(this);
270            this->camera_->requestFocus();
271            if (this->cameraPositionTemplate_ != "")
272                this->addTemplate(this->cameraPositionTemplate_);
273            if (this->cameraPositions_.size() > 0)
274                this->cameraPositions_.front()->attachCamera(this->camera_);
275            else
276                this->camera_->attachToNode(this->cameraPositionRootNode_);
277        }
278
279        if (!this->hud_)
280        {
281            if (this->hudtemplate_ != "")
282            {
283                this->hud_ = new OverlayGroup(this);
284                this->hud_->addTemplate(this->hudtemplate_);
285                this->hud_->setOwner(this);
286            }
287        }
288    }
289
290    void ControllableEntity::stopLocalHumanControl()
291    {
292        if (this->camera_)
293        {
294            this->camera_->detachFromParent();
295            delete this->camera_;
296            this->camera_ = 0;
297        }
298
299        if (this->hud_)
300        {
301            delete this->hud_;
302            this->hud_ = 0;
303        }
304    }
305
306    void ControllableEntity::parentChanged()
307    {
308        WorldEntity::parentChanged();
309
310        WorldEntity* parent = this->getParent();
311        if (parent)
312        {
313            for (std::list<CameraPosition*>::iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
314                if ((*it)->getIsAbsolute())
315                    parent->attach((*it));
316        }
317    }
318
319    void ControllableEntity::tick(float dt)
320    {
321        MobileEntity::tick(dt);
322
323        if (this->isActive())
324        {
325            // Check whether Bullet doesn't do the physics for us
326            if (!this->isDynamic())
327            {
328                if (GameMode::isMaster())
329                {
330                    this->server_position_ = this->getPosition();
331                    this->server_orientation_ = this->getOrientation();
332                    this->server_linear_velocity_ = this->getVelocity();
333                    this->server_angular_velocity_ = this->getAngularVelocity();
334                }
335                else if (this->bHasLocalController_)
336                {
337                    this->client_position_ = this->getPosition();
338                    this->client_orientation_ = this->getOrientation();
339                    this->client_linear_velocity_ = this->getVelocity();
340                    this->client_angular_velocity_ = this->getAngularVelocity();
341                }
342            }
343        }
344    }
345
346    void ControllableEntity::registerVariables()
347    {
348        registerVariable(this->cameraPositionTemplate_,  variableDirection::toclient);
349        registerVariable(this->hudtemplate_,             variableDirection::toclient);
350
351        registerVariable(this->server_position_,         variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
352        registerVariable(this->server_linear_velocity_,  variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity));
353        registerVariable(this->server_orientation_,      variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
354        registerVariable(this->server_angular_velocity_, variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity));
355
356        registerVariable(this->server_overwrite_,        variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
357        registerVariable(this->client_overwrite_,        variableDirection::toserver);
358
359        registerVariable(this->client_position_,         variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
360        registerVariable(this->client_linear_velocity_,  variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientLinearVelocity));
361        registerVariable(this->client_orientation_,      variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
362        registerVariable(this->client_angular_velocity_, variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientAngularVelocity));
363       
364
365        registerVariable(this->playerID_,                variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
366    }
367
368    void ControllableEntity::processServerPosition()
369    {
370        if (!this->bHasLocalController_)
371            MobileEntity::setPosition(this->server_position_);
372    }
373
374    void ControllableEntity::processServerLinearVelocity()
375    {
376        if (!this->bHasLocalController_)
377            MobileEntity::setVelocity(this->server_linear_velocity_);
378    }
379
380    void ControllableEntity::processServerOrientation()
381    {
382        if (!this->bHasLocalController_)
383            MobileEntity::setOrientation(this->server_orientation_);
384    }
385
386    void ControllableEntity::processServerAngularVelocity()
387    {
388        if (!this->bHasLocalController_)
389            MobileEntity::setAngularVelocity(this->server_angular_velocity_);
390    }
391
392    void ControllableEntity::processOverwrite()
393    {
394        if (this->bHasLocalController_)
395        {
396            this->setPosition(this->server_position_);
397            this->setOrientation(this->server_orientation_);
398            this->setVelocity(this->server_linear_velocity_);
399            this->setAngularVelocity(this->server_angular_velocity_);
400
401            this->client_overwrite_ = this->server_overwrite_;
402        }
403    }
404
405    void ControllableEntity::processClientPosition()
406    {
407        if (this->server_overwrite_ == this->client_overwrite_)
408        {
409            MobileEntity::setPosition(this->client_position_);
410            this->server_position_ = this->getPosition();
411        }
412    }
413
414    void ControllableEntity::processClientLinearVelocity()
415    {
416        if (this->server_overwrite_ == this->client_overwrite_)
417        {
418            MobileEntity::setVelocity(this->client_linear_velocity_);
419            this->server_linear_velocity_ = this->getVelocity();
420        }
421    }
422
423    void ControllableEntity::processClientOrientation()
424    {
425        if (this->server_overwrite_ == this->client_overwrite_)
426        {
427            MobileEntity::setOrientation(this->client_orientation_);
428            this->server_orientation_ = this->getOrientation();
429        }
430    }
431
432    void ControllableEntity::processClientAngularVelocity()
433    {
434        if (this->server_overwrite_ == this->client_overwrite_)
435        {
436            MobileEntity::setAngularVelocity(this->client_angular_velocity_);
437            this->server_angular_velocity_ = this->getAngularVelocity();
438        }
439    }
440
441    void ControllableEntity::setPosition(const Vector3& position)
442    {
443        if (GameMode::isMaster())
444        {
445            MobileEntity::setPosition(position);
446            this->server_position_ = this->getPosition();
447            ++this->server_overwrite_;
448        }
449        else if (this->bHasLocalController_)
450        {
451            MobileEntity::setPosition(position);
452            this->client_position_ = this->getPosition();
453        }
454    }
455
456    void ControllableEntity::setOrientation(const Quaternion& orientation)
457    {
458        if (GameMode::isMaster())
459        {
460            MobileEntity::setOrientation(orientation);
461            this->server_orientation_ = this->getOrientation();
462            ++this->server_overwrite_;
463        }
464        else if (this->bHasLocalController_)
465        {
466            MobileEntity::setOrientation(orientation);
467            this->client_orientation_ = this->getOrientation();
468        }
469    }
470
471    void ControllableEntity::setVelocity(const Vector3& velocity)
472    {
473        if (GameMode::isMaster())
474        {
475            MobileEntity::setVelocity(velocity);
476            this->server_linear_velocity_ = this->getVelocity();
477            ++this->server_overwrite_;
478        }
479        else if (this->bHasLocalController_)
480        {
481            MobileEntity::setVelocity(velocity);
482            this->client_linear_velocity_ = this->getVelocity();
483        }
484    }
485
486    void ControllableEntity::setAngularVelocity(const Vector3& velocity)
487    {
488        if (GameMode::isMaster())
489        {
490            MobileEntity::setAngularVelocity(velocity);
491            this->server_angular_velocity_ = this->getAngularVelocity();
492            ++this->server_overwrite_;
493        }
494        else if (this->bHasLocalController_)
495        {
496            MobileEntity::setAngularVelocity(velocity);
497            this->client_angular_velocity_ = this->getAngularVelocity();
498        }
499    }
500
501    void ControllableEntity::setWorldTransform(const btTransform& worldTrans)
502    {
503        MobileEntity::setWorldTransform(worldTrans);
504        if (GameMode::isMaster())
505        {
506            this->server_position_ = this->getPosition();
507            this->server_orientation_ = this->getOrientation();
508            this->server_linear_velocity_ = this->getVelocity();
509            this->server_angular_velocity_ = this->getAngularVelocity();
510        }
511        else if (this->bHasLocalController_)
512        {
513            this->client_position_ = this->getPosition();
514            this->client_orientation_ = this->getOrientation();
515            this->client_linear_velocity_ = this->getVelocity();
516            this->client_angular_velocity_ = this->getAngularVelocity();
517        }
518    }
519}
Note: See TracBrowser for help on using the repository browser.