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
RevLine 
[608]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
[1056]3 *                    > www.orxonox.net <
[608]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:
[670]23 *      Fabian 'x3n' Landau
[608]24 *   Co-authors:
[1293]25 *      Benjamin Knecht
[608]26 *
27 */
28
[786]29#include "OrxonoxStableHeaders.h"
[1039]30#include "SpaceShip.h"
[784]31
[708]32#include <OgreCamera.h>
33#include <OgreRenderWindow.h>
34#include <OgreParticleSystem.h>
35#include <OgreSceneNode.h>
[608]36
[1293]37#include "CameraHandler.h"
[1362]38#include "util/Convert.h"
[742]39#include "util/Math.h"
[1021]40#include "core/CoreIncludes.h"
[1052]41#include "core/ConfigValueIncludes.h"
[1021]42#include "core/Debug.h"
[1032]43#include "GraphicsEngine.h"
[1024]44#include "core/InputManager.h"
[1021]45#include "particle/ParticleInterface.h"
[708]46#include "Projectile.h"
[871]47#include "core/XMLPort.h"
[1052]48#include "core/ConsoleCommand.h"
[1293]49#include "network/Client.h"
[608]50
51namespace orxonox
52{
[1386]53    ConsoleCommand(SpaceShip, setMaxSpeedTest, AccessLevel::Debug, false);
[1362]54    ConsoleCommand(SpaceShip, whereAmI, AccessLevel::User, true);
[1391]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);
[1052]61    ConsoleCommandGeneric(test1, SpaceShip, createExecutor(createFunctor(&SpaceShip::setMaxSpeedTest), "setMaxSpeed", AccessLevel::Debug), false);
62    ConsoleCommandGeneric(test2, SpaceShip, createExecutor(createFunctor(&SpaceShip::setMaxSpeedTest), "setMaxBlubber", AccessLevel::Debug), false);
[1386]63    ConsoleCommandGeneric(test3, SpaceShip, createExecutor(createFunctor(&SpaceShip::setMaxSpeedTest), "setRofl", AccessLevel::Debug), false);
[1052]64
[608]65    CreateFactory(SpaceShip);
66
[1052]67    SpaceShip* SpaceShip::instance_s;
68
[1360]69    SpaceShip *SpaceShip::getLocalShip(){
70      Iterator<SpaceShip> it;
71      for(it = ObjectList<SpaceShip>::start(); it; ++it){
[1425]72        if( (it)->myShip_ )
[1360]73          return *it;
74      }
75      return NULL;
76    }
[1406]77
[1293]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),
[1425]111      myShip_(false)
[608]112    {
113        RegisterObject(SpaceShip);
[1021]114        this->registerAllVariables();
[608]115
[1052]116        SpaceShip::instance_s = this;
117
[1425]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);
[1406]123        currentOrth_ = initialOrth_;
[608]124
[647]125        this->setRotationAxis(1, 0, 0);
126        this->setStatic(false);
[608]127
128        COUT(3) << "Info: SpaceShip was loaded" << std::endl;
129    }
130
131    SpaceShip::~SpaceShip()
132    {
[647]133        if (this->tt_)
134            delete this->tt_;
[1293]135        if(setMouseEventCallback_)
136          InputManager::removeMouseHandler("SpaceShip");
137        if (this->cam_)
138          delete this->cam_;
[608]139    }
140
[1021]141    bool SpaceShip::create(){
[1425]142      if(!myShip_){
143        if(network::Client::getSingleton() && objectID == network::Client::getSingleton()->getShipID())
144          myShip_=true;
145      }
[1021]146      if(Model::create())
147        this->init();
148      else
149        return false;
150      return true;
151    }
[1056]152
[1021]153    void SpaceShip::registerAllVariables(){
[1293]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);
[1056]164
[1021]165    }
[1056]166
[871]167    void SpaceShip::init()
[697]168    {
[633]169        // START CREATING THRUSTER
[1032]170        this->tt_ = new ParticleInterface(GraphicsEngine::getSingleton().getSceneManager(),"twinthruster" + this->getName(),"Orxonox/engineglow");
[647]171        this->tt_->getParticleSystem()->setParameter("local_space","true");
[978]172        this->tt_->newEmitter();
[608]173/*
[647]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));
[608]177*/
[647]178        this->tt_->setDirection(Vector3(-1,0,0));
[978]179        this->tt_->setPositionOfEmitter(0, Vector3(-15,20,-1));
180        this->tt_->setPositionOfEmitter(1, Vector3(-15,-20,-1));
[647]181        this->tt_->setVelocity(50);
[608]182
[633]183        emitterRate_ = tt_->getRate();
[626]184
[633]185        Ogre::SceneNode* node2 = this->getNode()->createChildSceneNode(this->getName() + "particle2");
186        node2->setInheritScale(false);
187        tt_->addToSceneNode(node2);
188        // END CREATING THRUSTER
[608]189
[633]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);
[608]193
[1293]194        this->redNode_ = this->getNode()->createChildSceneNode(this->getName() + "red", Vector3(0.3, 4.0, -0.3));
[633]195        this->redNode_->setInheritScale(false);
[1293]196        this->greenNode_ = this->getNode()->createChildSceneNode(this->getName() + "green", Vector3(0.3, -4.0, -0.3));
[633]197        this->greenNode_->setInheritScale(false);
[608]198
[633]199        this->redNode_->attachObject(this->redBillboard_.getBillboardSet());
200        this->redNode_->setScale(0.3, 0.3, 0.3);
[608]201
[633]202        this->greenNode_->attachObject(this->greenBillboard_.getBillboardSet());
203        this->greenNode_->setScale(0.3, 0.3, 0.3);
204        // END CREATING BLINKING LIGHTS
[608]205
[661]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);
[608]209
[661]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
[1293]221        createCamera();
[661]222        // END of testing crosshair
[871]223    }
[661]224
[871]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    {
[1293]234      camName_=camera;
235      // change camera attributes here, if you want to ;)
236    }
[1362]237
[1293]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_);
[1362]242
[1293]243    }
[1362]244
[1425]245    Camera* SpaceShip::getCamera(){
246        return cam_;
247    }
248
[1293]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));
[1362]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);
[1293]257      COUT(4) << "position: (cam)" << this->camNode_->getPosition() << std::endl;
258      cam_ = new Camera(this->camNode_);
[608]259
[1293]260      cam_->setTargetNode(this->getNode());
[1386]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));
[1362]264      camNode_->setOrientation(q2*q1);
[1293]265      if(network::Client::getSingleton()!=0 && network::Client::getSingleton()->getShipID()==objectID){
266        this->setBacksync(true);
267        CameraHandler::getInstance()->requestFocus(cam_);
268      }
[608]269
270    }
271
[871]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    */
[1052]293    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
[871]294    {
[1052]295        Model::XMLPort(xmlelement, mode);
[871]296
[1052]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);
[1425]305        myShip_=true; // TODO: this is only a hack
[1293]306        SpaceShip::create();
307        getFocus();
[871]308    }
309
[647]310    int sgn(float x)
311    {
312        if (x >= 0)
313            return 1;
314        else
315            return -1;
316    }
317
[1386]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
[1425]324    Vector3 SpaceShip::getDir() {
325        return currentDir_;
326    }
327
328    Vector3 SpaceShip::getOrth(){
329        return currentOrth_;
330    }
331
[1386]332    float SpaceShip::getMaxSpeed() { return maxSpeed_; }
333
[608]334    void SpaceShip::tick(float dt)
[1425]335    {
336        currentDir_ = getOrientation()*initialDir_;
337                currentOrth_ = getOrientation()*initialOrth_;
[1406]338
[1293]339        if (this->cam_)
340            this->cam_->tick(dt);
[608]341
[633]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
[643]351        if (this->timeToReload_ > 0)
352            this->timeToReload_ -= dt;
353        else
354            this->timeToReload_ = 0;
355
[644]356        if (this->bLMousePressed_ && this->timeToReload_ <= 0)
[643]357        {
[1406]358
[1293]359            Projectile *p = new Projectile(this);
[1425]360            p->create();
[1406]361
[1293]362            p->setBacksync(true);
[643]363            this->timeToReload_ = this->reloadTime_;
364        }
365
[608]366
[647]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);
[1391]445
[1425]446        if( myShip_ )
[1391]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;*/
[608]457    }
[1391]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    }
[608]468
[1391]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    }
[608]503}
Note: See TracBrowser for help on using the repository browser.