Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.cc @ 1994

Last change on this file since 1994 was 1994, checked in by rgrieder, 16 years ago

updated msvc files.

File size: 13.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/Camera.h"
39#include "overlays/OverlayGroup.h"
40
41namespace orxonox
42{
43    CreateFactory(ControllableEntity);
44
45    ControllableEntity::ControllableEntity()
46    {
47        RegisterObject(ControllableEntity);
48
49        this->bControlled_ = false;
50        this->server_overwrite_ = 0;
51        this->client_overwrite_ = 0;
52        this->player_ = 0;
53        this->playerID_ = network::OBJECTID_UNKNOWN;
54        this->hud_ = 0;
55        this->camera_ = 0;
56        this->bDestroyWhenPlayerLeft_ = false;
57
58        this->velocity_ = Vector3::ZERO;
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() && this->bControlled_)
74            this->stopLocalControl();
75    }
76
77    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
78    {
79        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
80
81        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
82    }
83
84    void ControllableEntity::setPlayer(PlayerInfo* player)
85    {
86        if (!player)
87        {
88            this->removePlayer();
89            return;
90        }
91
92        this->player_ = player;
93        this->playerID_ = player->getObjectID();
94        this->bControlled_ = player->isLocalPlayer();
95
96        if (this->bControlled_)
97        {
98            this->startLocalControl();
99            this->setObjectMode(network::direction::bidirectional);
100        }
101    }
102
103    void ControllableEntity::removePlayer()
104    {
105        if (this->bControlled_)
106            this->stopLocalControl();
107
108        this->player_ = 0;
109        this->playerID_ = network::OBJECTID_UNKNOWN;
110        this->bControlled_ = false;
111        this->setObjectMode(network::direction::toclient);
112
113        if (this->bDestroyWhenPlayerLeft_)
114            delete this;
115    }
116
117    void ControllableEntity::updatePlayer()
118    {
119        if (this->playerID_ != network::OBJECTID_UNKNOWN)
120        {
121            this->player_ = dynamic_cast<PlayerInfo*>(network::Synchronisable::getSynchronisable(this->playerID_));
122            if (this->player_ && (this->player_->getPawn() != this))
123                this->player_->startControl(this);
124        }
125    }
126
127    void ControllableEntity::startLocalControl()
128    {
129        std::cout << "###### start local control" << std::endl;
130        this->camera_ = new Camera();
131        this->camera_->requestFocus();
132        this->attach(this->camera_);
133
134        if (this->hudtemplate_ != "")
135        {
136            this->hud_ = new OverlayGroup();
137            this->hud_->addTemplate(this->hudtemplate_);
138        }
139    }
140
141    void ControllableEntity::stopLocalControl()
142    {
143        std::cout << "###### stop local control" << std::endl;
144        this->detach(this->camera_);
145        delete this->camera_;
146        this->camera_ = 0;
147
148        delete this->hud_;
149        this->hud_ = 0;
150    }
151
152    void ControllableEntity::tick(float dt)
153    {
154        if (this->isActive())
155        {
156            this->velocity_ += (dt * this->acceleration_);
157            this->node_->translate(dt * this->velocity_, Ogre::Node::TS_PARENT);
158
159            if (Core::isMaster())
160            {
161                this->server_velocity_ = this->velocity_;
162                this->server_position_ = this->node_->getPosition();
163            }
164            else if (this->bControlled_)
165            {
166                this->client_velocity_ = this->velocity_;
167                this->client_position_ = this->node_->getPosition();
168            }
169        }
170    }
171
172    void ControllableEntity::registerVariables()
173    {
174        REGISTERDATA(this->server_position_,    network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
175        REGISTERDATA(this->server_velocity_,    network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));
176        REGISTERDATA(this->server_orientation_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
177
178        REGISTERDATA(this->server_overwrite_,   network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
179
180        REGISTERDATA(this->client_position_,    network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
181        REGISTERDATA(this->client_velocity_,    network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));
182        REGISTERDATA(this->client_orientation_, network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
183
184        REGISTERDATA(this->client_overwrite_,   network::direction::toserver);
185
186        REGISTERDATA(this->playerID_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::updatePlayer));
187    }
188
189    void ControllableEntity::processServerPosition()
190    {
191        if (!this->bControlled_)
192            this->node_->setPosition(this->server_position_);
193    }
194
195    void ControllableEntity::processServerVelocity()
196    {
197        if (!this->bControlled_)
198            this->velocity_ = this->server_velocity_;
199    }
200
201    void ControllableEntity::processServerOrientation()
202    {
203        if (!this->bControlled_)
204            this->node_->setOrientation(this->server_orientation_);
205    }
206
207    void ControllableEntity::processOverwrite()
208    {
209        if (this->bControlled_)
210        {
211            this->setPosition(this->server_position_);
212            this->setVelocity(this->server_velocity_);
213            this->setOrientation(this->server_orientation_);
214
215            this->client_overwrite_ = this->server_overwrite_;
216        }
217    }
218
219    void ControllableEntity::processClientPosition()
220    {
221        if (this->server_overwrite_ == this->client_overwrite_)
222        {
223            this->node_->setPosition(this->client_position_);
224            this->server_position_ = this->client_position_;
225        }
226    }
227
228    void ControllableEntity::processClientVelocity()
229    {
230        if (this->server_overwrite_ == this->client_overwrite_)
231        {
232            this->velocity_ = this->client_velocity_;
233            this->server_velocity_ = this->client_velocity_;
234        }
235    }
236
237    void ControllableEntity::processClientOrientation()
238    {
239        if (this->server_overwrite_ == this->client_overwrite_)
240        {
241            this->node_->setOrientation(this->client_orientation_);
242            this->server_orientation_ = this->client_orientation_;
243        }
244    }
245
246
247    void ControllableEntity::setPosition(const Vector3& position)
248    {
249        if (Core::isMaster())
250        {
251            this->node_->setPosition(position);
252            this->server_position_ = position;
253            ++this->server_overwrite_;
254        }
255        else if (this->bControlled_)
256        {
257            this->node_->setPosition(position);
258            this->client_position_ = position;
259        }
260    }
261
262    void ControllableEntity::setVelocity(const Vector3& velocity)
263    {
264        if (Core::isMaster())
265        {
266            this->velocity_ = velocity;
267            this->server_velocity_ = velocity;
268            ++this->server_overwrite_;
269        }
270        else if (this->bControlled_)
271        {
272            this->velocity_ = velocity;
273            this->client_velocity_ = velocity;
274        }
275    }
276
277    void ControllableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
278    {
279        if (Core::isMaster())
280        {
281            this->node_->translate(distance, relativeTo);
282            this->server_position_ = this->node_->getPosition();
283            ++this->server_overwrite_;
284        }
285        else if (this->bControlled_)
286        {
287            this->node_->translate(distance, relativeTo);
288            this->client_position_ = this->node_->getPosition();
289        }
290    }
291
292    void ControllableEntity::setOrientation(const Quaternion& orientation)
293    {
294        if (Core::isMaster())
295        {
296            this->node_->setOrientation(orientation);
297            this->server_orientation_ = orientation;
298            ++this->server_overwrite_;
299        }
300        else if (this->bControlled_)
301        {
302            this->node_->setOrientation(orientation);
303            this->client_orientation_ = orientation;
304        }
305    }
306
307    void ControllableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
308    {
309        if (Core::isMaster())
310        {
311            this->node_->rotate(rotation, relativeTo);
312            this->server_orientation_ = this->node_->getOrientation();
313            ++this->server_overwrite_;
314        }
315        else if (this->bControlled_)
316        {
317            this->node_->rotate(rotation, relativeTo);
318            this->client_orientation_ = this->node_->getOrientation();
319        }
320    }
321
322    void ControllableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
323    {
324        if (Core::isMaster())
325        {
326            this->node_->yaw(angle, relativeTo);
327            this->server_orientation_ = this->node_->getOrientation();
328            ++this->server_overwrite_;
329        }
330        else if (this->bControlled_)
331        {
332            this->node_->yaw(angle, relativeTo);
333            this->client_orientation_ = this->node_->getOrientation();
334        }
335    }
336
337    void ControllableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
338    {
339        if (Core::isMaster())
340        {
341            this->node_->pitch(angle, relativeTo);
342            this->server_orientation_ = this->node_->getOrientation();
343            ++this->server_overwrite_;
344        }
345        else if (this->bControlled_)
346        {
347            this->node_->pitch(angle, relativeTo);
348            this->client_orientation_ = this->node_->getOrientation();
349        }
350    }
351
352    void ControllableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
353    {
354        if (Core::isMaster())
355        {
356            this->node_->roll(angle, relativeTo);
357            this->server_orientation_ = this->node_->getOrientation();
358            ++this->server_overwrite_;
359        }
360        else if (this->bControlled_)
361        {
362            this->node_->roll(angle, relativeTo);
363            this->client_orientation_ = this->node_->getOrientation();
364        }
365    }
366
367    void ControllableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
368    {
369        if (Core::isMaster())
370        {
371            this->node_->lookAt(target, relativeTo, localDirectionVector);
372            this->server_orientation_ = this->node_->getOrientation();
373            ++this->server_overwrite_;
374        }
375        else if (this->bControlled_)
376        {
377            this->node_->lookAt(target, relativeTo, localDirectionVector);
378            this->client_orientation_ = this->node_->getOrientation();
379        }
380    }
381
382    void ControllableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
383    {
384        if (Core::isMaster())
385        {
386            this->node_->setDirection(direction, relativeTo, localDirectionVector);
387            this->server_orientation_ = this->node_->getOrientation();
388            ++this->server_overwrite_;
389        }
390        else if (this->bControlled_)
391        {
392            this->node_->setDirection(direction, relativeTo, localDirectionVector);
393            this->client_orientation_ = this->node_->getOrientation();
394        }
395    }
396}
Note: See TracBrowser for help on using the repository browser.