Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/orxonox/objects/SpaceShip.cc @ 1428

Last change on this file since 1428 was 1425, checked in by scheusso, 17 years ago

implemented some sort of buffer for the spaceship movements (makes the movements on the client smoother)

File size: 19.0 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 *      Benjamin Knecht
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "SpaceShip.h"
31
32#include <OgreCamera.h>
33#include <OgreRenderWindow.h>
34#include <OgreParticleSystem.h>
35#include <OgreSceneNode.h>
36
37#include "CameraHandler.h"
38#include "util/Convert.h"
39#include "util/Math.h"
40#include "core/CoreIncludes.h"
41#include "core/ConfigValueIncludes.h"
42#include "core/Debug.h"
43#include "GraphicsEngine.h"
44#include "core/InputManager.h"
45#include "particle/ParticleInterface.h"
46#include "Projectile.h"
47#include "core/XMLPort.h"
48#include "core/ConsoleCommand.h"
49#include "network/Client.h"
50
51namespace orxonox
52{
53    ConsoleCommand(SpaceShip, setMaxSpeedTest, AccessLevel::Debug, false);
54    ConsoleCommand(SpaceShip, whereAmI, AccessLevel::User, true);
55    ConsoleCommand(SpaceShip, moveLongitudinal, AccessLevel::User, true).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
56    ConsoleCommand(SpaceShip, moveLateral, AccessLevel::User, true).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
57    ConsoleCommand(SpaceShip, moveYaw, AccessLevel::User, true).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
58    ConsoleCommand(SpaceShip, movePitch, AccessLevel::User, true).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
59    ConsoleCommand(SpaceShip, moveRoll, AccessLevel::User, true).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
60    ConsoleCommand(SpaceShip, fire, AccessLevel::User, true).setKeybindMode(KeybindMode::OnHold);
61    ConsoleCommandGeneric(test1, SpaceShip, createExecutor(createFunctor(&SpaceShip::setMaxSpeedTest), "setMaxSpeed", AccessLevel::Debug), false);
62    ConsoleCommandGeneric(test2, SpaceShip, createExecutor(createFunctor(&SpaceShip::setMaxSpeedTest), "setMaxBlubber", AccessLevel::Debug), false);
63    ConsoleCommandGeneric(test3, SpaceShip, createExecutor(createFunctor(&SpaceShip::setMaxSpeedTest), "setRofl", AccessLevel::Debug), false);
64
65    CreateFactory(SpaceShip);
66
67    SpaceShip* SpaceShip::instance_s;
68
69    SpaceShip *SpaceShip::getLocalShip(){
70      Iterator<SpaceShip> it;
71      for(it = ObjectList<SpaceShip>::start(); it; ++it){
72        if( (it)->myShip_ )
73          return *it;
74      }
75      return NULL;
76    }
77
78    SpaceShip::SpaceShip() :
79      //testvector_(0,0,0),
80      //bInvertYAxis_(false),
81      setMouseEventCallback_(false),
82      bLMousePressed_(false),
83      bRMousePressed_(false),
84      camNode_(0),
85      cam_(0),
86      camName_("CamNode"),
87      tt_(0),
88      redNode_(0),
89      greenNode_(0),
90      blinkTime_(0.0f),
91      chNearNode_(0),
92      chFarNode_(0),
93      timeToReload_(0.0f),
94      //reloadTime_(0.0f),
95      maxSideAndBackSpeed_(0.0f),
96      maxSpeed_(0.0f),
97      maxRotation_(0.0f),
98      translationAcceleration_(0.0f),
99      rotationAcceleration_(0.0f),
100      translationDamping_(0.0f),
101      rotationDamping_(0.0f),
102      maxRotationRadian_(0),
103      rotationAccelerationRadian_(0),
104      rotationDampingRadian_(0),
105      zeroRadian_(0),
106      mouseXRotation_(0),
107      mouseYRotation_(0),
108      mouseX_(0.0f),
109      mouseY_(0.0f),
110      emitterRate_(0.0f),
111      myShip_(false)
112    {
113        RegisterObject(SpaceShip);
114        this->registerAllVariables();
115
116        SpaceShip::instance_s = this;
117
118        this->setConfigValues();
119
120        initialDir_ = Vector3(1.0, 0.0, 0.0);
121        currentDir_ = initialDir_;
122        initialOrth_ = Vector3(0.0, 0.0, 1.0);
123        currentOrth_ = initialOrth_;
124
125        this->setRotationAxis(1, 0, 0);
126        this->setStatic(false);
127
128        COUT(3) << "Info: SpaceShip was loaded" << std::endl;
129    }
130
131    SpaceShip::~SpaceShip()
132    {
133        if (this->tt_)
134            delete this->tt_;
135        if(setMouseEventCallback_)
136          InputManager::removeMouseHandler("SpaceShip");
137        if (this->cam_)
138          delete this->cam_;
139    }
140
141    bool SpaceShip::create(){
142      if(!myShip_){
143        if(network::Client::getSingleton() && objectID == network::Client::getSingleton()->getShipID())
144          myShip_=true;
145      }
146      if(Model::create())
147        this->init();
148      else
149        return false;
150      return true;
151    }
152
153    void SpaceShip::registerAllVariables(){
154      registerVar( &camName_, camName_.length()+1, network::STRING, 0x1);
155      registerVar( &maxSpeed_, sizeof(maxSpeed_), network::DATA, 0x1);
156      registerVar( &maxSideAndBackSpeed_, sizeof(maxSideAndBackSpeed_), network::DATA, 0x1);
157      registerVar( &maxRotation_, sizeof(maxRotation_), network::DATA, 0x1);
158      registerVar( &translationAcceleration_, sizeof(translationAcceleration_), network::DATA, 0x1);
159      registerVar( &rotationAcceleration_, sizeof(rotationAcceleration_), network::DATA, 0x1);
160      registerVar( &rotationAccelerationRadian_, sizeof(rotationAccelerationRadian_), network::DATA, 0x1);
161      registerVar( &translationDamping_, sizeof(translationDamping_), network::DATA, 0x1);
162      registerVar( &rotationDamping_, sizeof(rotationDamping_), network::DATA, 0x1);
163      registerVar( &rotationDampingRadian_, sizeof(rotationDampingRadian_), network::DATA, 0x1);
164
165    }
166
167    void SpaceShip::init()
168    {
169        // START CREATING THRUSTER
170        this->tt_ = new ParticleInterface(GraphicsEngine::getSingleton().getSceneManager(),"twinthruster" + this->getName(),"Orxonox/engineglow");
171        this->tt_->getParticleSystem()->setParameter("local_space","true");
172        this->tt_->newEmitter();
173/*
174        this->tt_->setDirection(Vector3(0,0,1));
175        this->tt_->setPositionOfEmitter(0, Vector3(20,-1,-15));
176        this->tt_->setPositionOfEmitter(1, Vector3(-20,-1,-15));
177*/
178        this->tt_->setDirection(Vector3(-1,0,0));
179        this->tt_->setPositionOfEmitter(0, Vector3(-15,20,-1));
180        this->tt_->setPositionOfEmitter(1, Vector3(-15,-20,-1));
181        this->tt_->setVelocity(50);
182
183        emitterRate_ = tt_->getRate();
184
185        Ogre::SceneNode* node2 = this->getNode()->createChildSceneNode(this->getName() + "particle2");
186        node2->setInheritScale(false);
187        tt_->addToSceneNode(node2);
188        // END CREATING THRUSTER
189
190        // START CREATING BLINKING LIGHTS
191        this->redBillboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
192        this->greenBillboard_.setBillboardSet("Examples/Flare", ColourValue(0.0, 1.0, 0.0), 1);
193
194        this->redNode_ = this->getNode()->createChildSceneNode(this->getName() + "red", Vector3(0.3, 4.0, -0.3));
195        this->redNode_->setInheritScale(false);
196        this->greenNode_ = this->getNode()->createChildSceneNode(this->getName() + "green", Vector3(0.3, -4.0, -0.3));
197        this->greenNode_->setInheritScale(false);
198
199        this->redNode_->attachObject(this->redBillboard_.getBillboardSet());
200        this->redNode_->setScale(0.3, 0.3, 0.3);
201
202        this->greenNode_->attachObject(this->greenBillboard_.getBillboardSet());
203        this->greenNode_->setScale(0.3, 0.3, 0.3);
204        // END CREATING BLINKING LIGHTS
205
206        // START of testing crosshair
207        this->crosshairNear_.setBillboardSet("Orxonox/Crosshair", ColourValue(1.0, 1.0, 0.0), 1);
208        this->crosshairFar_.setBillboardSet("Orxonox/Crosshair", ColourValue(1.0, 1.0, 0.0), 1);
209
210        this->chNearNode_ = this->getNode()->createChildSceneNode(this->getName() + "near", Vector3(50.0, 0.0, 0.0));
211        this->chNearNode_->setInheritScale(false);
212        this->chFarNode_ = this->getNode()->createChildSceneNode(this->getName() + "far", Vector3(200.0, 0.0, 0.0));
213        this->chFarNode_->setInheritScale(false);
214
215        this->chNearNode_->attachObject(this->crosshairNear_.getBillboardSet());
216        this->chNearNode_->setScale(0.2, 0.2, 0.2);
217
218        this->chFarNode_->attachObject(this->crosshairFar_.getBillboardSet());
219        this->chFarNode_->setScale(0.4, 0.4, 0.4);
220
221        createCamera();
222        // END of testing crosshair
223    }
224
225    void SpaceShip::setConfigValues()
226    {
227        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
228        SetConfigValue(reloadTime_, 0.125).description("The reload time of the weapon in seconds");
229        SetConfigValue(testvector_, Vector3()).description("asdfblah");
230    }
231
232    void SpaceShip::setCamera(const std::string& camera)
233    {
234      camName_=camera;
235      // change camera attributes here, if you want to ;)
236    }
237
238    void SpaceShip::getFocus(){
239      COUT(4) << "requesting focus" << std::endl;
240      if(network::Client::getSingleton()==0 || network::Client::getSingleton()->getShipID()==objectID)
241        CameraHandler::getInstance()->requestFocus(cam_);
242
243    }
244
245    Camera* SpaceShip::getCamera(){
246        return cam_;
247    }
248
249    void SpaceShip::createCamera(){
250//       COUT(4) << "begin camera creation" << std::endl;
251      this->camNode_ = this->getNode()->createChildSceneNode(camName_);
252      COUT(4) << "position: (this)" << this->getNode()->getPosition() << std::endl;
253      this->camNode_->setPosition(Vector3(-50,0,10));
254//      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
255//      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(0,0,-1));
256//      camNode_->setOrientation(q1*q2);
257      COUT(4) << "position: (cam)" << this->camNode_->getPosition() << std::endl;
258      cam_ = new Camera(this->camNode_);
259
260      cam_->setTargetNode(this->getNode());
261//        cam->setPosition(Vector3(0,-350,0));
262      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
263      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(1,0,0));
264      camNode_->setOrientation(q2*q1);
265      if(network::Client::getSingleton()!=0 && network::Client::getSingleton()->getShipID()==objectID){
266        this->setBacksync(true);
267        CameraHandler::getInstance()->requestFocus(cam_);
268      }
269
270    }
271
272    void SpaceShip::setMaxSpeed(float value)
273    { this->maxSpeed_ = value; }
274    void SpaceShip::setMaxSideAndBackSpeed(float value)
275    { this->maxSideAndBackSpeed_ = value; }
276    void SpaceShip::setMaxRotation(float value)
277    { this->maxRotation_ = value; this->maxRotationRadian_ = Radian(value); }
278    void SpaceShip::setTransAcc(float value)
279    { this->translationAcceleration_ = value; }
280    void SpaceShip::setRotAcc(float value)
281    { this->rotationAcceleration_ = value; this->rotationAccelerationRadian_ = Radian(value); }
282    void SpaceShip::setTransDamp(float value)
283    { this->translationDamping_ = value; }
284    void SpaceShip::setRotDamp(float value)
285    { this->rotationDamping_ = value; this->rotationDampingRadian_ = Radian(value); }
286
287    /**
288        @brief XML loading and saving.
289        @param xmlelement The XML-element
290        @param loading Loading (true) or saving (false)
291        @return The XML-element
292    */
293    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
294    {
295        Model::XMLPort(xmlelement, mode);
296
297        XMLPortParamLoadOnly(SpaceShip, "camera", setCamera, xmlelement, mode);
298        XMLPortParamLoadOnly(SpaceShip, "maxSpeed", setMaxSpeed, xmlelement, mode);
299        XMLPortParamLoadOnly(SpaceShip, "maxSideAndBackSpeed", setMaxSideAndBackSpeed, xmlelement, mode);
300        XMLPortParamLoadOnly(SpaceShip, "maxRotation", setMaxRotation, xmlelement, mode);
301        XMLPortParamLoadOnly(SpaceShip, "transAcc", setTransAcc, xmlelement, mode);
302        XMLPortParamLoadOnly(SpaceShip, "rotAcc", setRotAcc, xmlelement, mode);
303        XMLPortParamLoadOnly(SpaceShip, "transDamp", setTransDamp, xmlelement, mode);
304        XMLPortParamLoadOnly(SpaceShip, "rotDamp", setRotDamp, xmlelement, mode);
305        myShip_=true; // TODO: this is only a hack
306        SpaceShip::create();
307        getFocus();
308    }
309
310    int sgn(float x)
311    {
312        if (x >= 0)
313            return 1;
314        else
315            return -1;
316    }
317
318    std::string SpaceShip::whereAmI() {
319        return getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().x)
320        + "  " + getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().y)
321        + "  " + getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().z);
322    }
323
324    Vector3 SpaceShip::getDir() {
325        return currentDir_;
326    }
327
328    Vector3 SpaceShip::getOrth(){
329        return currentOrth_;
330    }
331
332    float SpaceShip::getMaxSpeed() { return maxSpeed_; }
333
334    void SpaceShip::tick(float dt)
335    {
336        currentDir_ = getOrientation()*initialDir_;
337                currentOrth_ = getOrientation()*initialOrth_;
338
339        if (this->cam_)
340            this->cam_->tick(dt);
341
342        if (this->redNode_ && this->greenNode_)
343        {
344            this->blinkTime_ += dt;
345            float redScale = 0.15 + 0.15 * sin(this->blinkTime_ * 10.0);
346            float greenScale = 0.15 - 0.15 * sin(this->blinkTime_ * 10.0);
347            this->redNode_->setScale(redScale, redScale, redScale);
348            this->greenNode_->setScale(greenScale, greenScale, greenScale);
349        }
350
351        if (this->timeToReload_ > 0)
352            this->timeToReload_ -= dt;
353        else
354            this->timeToReload_ = 0;
355
356        if (this->bLMousePressed_ && this->timeToReload_ <= 0)
357        {
358
359            Projectile *p = new Projectile(this);
360            p->create();
361
362            p->setBacksync(true);
363            this->timeToReload_ = this->reloadTime_;
364        }
365
366
367        // #####################################
368        // ############# STEERING ##############
369        // #####################################
370
371        if (this->velocity_.x > this->maxSpeed_)
372            this->velocity_.x = this->maxSpeed_;
373        if (this->velocity_.x < -this->maxSideAndBackSpeed_)
374            this->velocity_.x = -this->maxSideAndBackSpeed_;
375        if (this->velocity_.y > this->maxSideAndBackSpeed_)
376            this->velocity_.y = this->maxSideAndBackSpeed_;
377        if (this->velocity_.y < -this->maxSideAndBackSpeed_)
378            this->velocity_.y = -this->maxSideAndBackSpeed_;
379        if (this->rotationRate_ > this->maxRotationRadian_)
380            this->rotationRate_ = this->maxRotationRadian_;
381        if (this->rotationRate_ < -this->maxRotationRadian_)
382            this->rotationRate_ = -this->maxRotationRadian_;
383
384        if (this->acceleration_.x == 0)
385        {
386            if (this->velocity_.x > 0)
387            {
388                this->velocity_.x -= (this->translationDamping_ * dt);
389                if (this->velocity_.x < 0)
390                    this->velocity_.x = 0;
391            }
392            else if (this->velocity_.x < 0)
393            {
394                this->velocity_.x += (this->translationDamping_ * dt);
395                if (this->velocity_.x > 0)
396                    this->velocity_.x = 0;
397            }
398        }
399
400        if (this->acceleration_.y == 0)
401        {
402            if (this->velocity_.y > 0)
403            {
404                this->velocity_.y -= (this->translationDamping_ * dt);
405                if (this->velocity_.y < 0)
406                    this->velocity_.y = 0;
407            }
408            else if (this->velocity_.y < 0)
409            {
410                this->velocity_.y += (this->translationDamping_ * dt);
411                if (this->velocity_.y > 0)
412                    this->velocity_.y = 0;
413            }
414        }
415
416        if (this->momentum_ == this->zeroRadian_)
417        {
418            if (this->rotationRate_ > this->zeroRadian_)
419            {
420                this->rotationRate_ -= (this->rotationDampingRadian_ * dt);
421                if (this->rotationRate_ < this->zeroRadian_)
422                    this->rotationRate_ = 0;
423            }
424            else if (this->rotationRate_ < this->zeroRadian_)
425            {
426                this->rotationRate_ += (this->rotationDampingRadian_ * dt);
427                if (this->rotationRate_ > this->zeroRadian_)
428                    this->rotationRate_ = 0;
429            }
430        }
431
432
433        WorldEntity::tick(dt);
434
435        this->roll(this->mouseXRotation_ * dt);
436        if (this->bInvertYAxis_)
437            this->yaw(Radian(-this->mouseYRotation_ * dt));
438        else
439            this->yaw(Radian(this->mouseYRotation_ * dt));
440
441        if (this->acceleration_.x > 0)
442            this->tt_->setRate(emitterRate_);
443        else
444            this->tt_->setRate(0);
445
446        if( myShip_ )
447        {
448          COUT(4) << "steering our ship: " << objectID << std::endl;
449          this->acceleration_.x = 0;
450          this->acceleration_.y = 0;
451          this->momentum_ = 0;
452          this->mouseXRotation_ = Radian(0);
453          this->mouseYRotation_ = Radian(0);
454          this->bLMousePressed_ = false;
455        }/*else
456          COUT(4) << "not steering ship: " << objectID << " our ship: " << network::Client::getSingleton()->getShipID() << std::endl;*/
457    }
458    void SpaceShip::movePitch(float val)
459    {
460        SpaceShip* this_ = getLocalShip();
461        val = -val * val * sgn(val) * this_->rotationAcceleration_;
462        if (val > this_->maxRotation_)
463            val = this_->maxRotation_;
464        if (val < -this_->maxRotation_)
465            val = -this_->maxRotation_;
466        this_->mouseYRotation_ = Radian(val);
467    }
468
469    void SpaceShip::moveYaw(float val)
470    {
471        SpaceShip* this_ = getLocalShip();
472        val = -val * val * sgn(val) * this_->rotationAcceleration_;
473        if (val > this_->maxRotation_)
474            val = this_->maxRotation_;
475        if (val < -this_->maxRotation_)
476            val = -this_->maxRotation_;
477        this_->mouseXRotation_ = Radian(val);
478    }
479
480    void SpaceShip::moveRoll(float val)
481    {
482        SpaceShip* this_ = getLocalShip();
483        this_->momentum_ = Radian(-this_->rotationAccelerationRadian_ * val);
484    }
485
486    void SpaceShip::moveLongitudinal(float val)
487    {
488        SpaceShip* this_ = getLocalShip();
489        this_->acceleration_.x = this_->translationAcceleration_ * val;
490    }
491
492    void SpaceShip::moveLateral(float val)
493    {
494        SpaceShip* this_ = getLocalShip();
495        this_->acceleration_.y = -this_->translationAcceleration_ * val;
496    }
497
498    void SpaceShip::fire()
499    {
500        SpaceShip* this_ = getLocalShip();
501        this_->bLMousePressed_ = true;
502    }
503}
Note: See TracBrowser for help on using the repository browser.