Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/orxonox/objects/worldentities/ControllableEntity.cc @ 2390

Last change on this file since 2390 was 2245, checked in by scheusso, 16 years ago

most coding is done, still testing now
types should get transfered in platform independent formats now

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