Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/Racingbot/src/modules/gametypes/SpaceRaceController.cc @ 9490

Last change on this file since 9490 was 9490, checked in by purgham, 11 years ago

Still doesn't work

File size: 17.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 *  Created on: Oct 8, 2012
23 *      Author: purgham
24 */
25
26/**
27 * Conventions:
28 * -first Checkpoint has index 0
29 * -staticCheckPoint= static Point (see def over = constructor)
30 */
31
32
33/*TODO:
34 * tICK KORRIGIEREN
35 *
36 *
37 */
38#include <gametypes/SpaceRaceController.h>
39#include "core/CoreIncludes.h"
40#include "core/XMLPort.h"
41#include "gametypes/SpaceRaceManager.h"
42#include "collisionshapes/CollisionShape.h"
43#include "BulletCollision/CollisionShapes/btCollisionShape.h"
44
45namespace orxonox
46{
47    CreateFactory(SpaceRaceController);
48
49    const int ADJUSTDISTANCE = 500;
50    const int MINDISTANCE=5;
51    /*
52     * Idea: Find static Point (checkpoints the spaceship has to reach)
53     */
54    SpaceRaceController::SpaceRaceController(BaseObject* creator) :
55        ArtificialController(creator)
56    {
57        RegisterObject(SpaceRaceController);
58        std::vector<RaceCheckPoint*> checkpoints;
59        for (ObjectList<SpaceRaceManager>::iterator it = ObjectList<SpaceRaceManager>::begin(); it!= ObjectList<SpaceRaceManager>::end(); ++it)
60        {
61            checkpoints = it->getAllCheckpoints();
62            nextRaceCheckpoint_=it->findCheckpoint(0);
63        }
64
65        OrxAssert(!checkpoints.empty(), "No Checkpoints in Level");
66        checkpoints_=checkpoints;
67        for( std::vector<RaceCheckPoint*>::iterator it = checkpoints.begin(); it!=checkpoints.end(); ++it){
68            for (std::set<int>::iterator numb = ((*it)->getNextCheckpoints()).begin(); numb!=((*it)->getNextCheckpoints()).end(); ++numb)
69                placeVirtualCheckpoints((*it), findCheckpoint((*numb)));
70        }
71        staticRacePoints_ = findStaticCheckpoints(checkpoints);
72        // initialisation of currentRaceCheckpoint_
73        currentRaceCheckpoint_ = NULL;
74        /*
75         // find first Checkpoint
76         for (int i=0; true; i++){
77         if(checkpoints_[i]->getCheckpointIndex()==0){
78         nextRaceCheckpoint_=checkpoints_[i];
79         break;
80         }
81         }*/
82
83        virtualCheckPointIndex=-1;
84    }
85
86
87    //------------------------------
88    // functions for initialisation
89
90    void SpaceRaceController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
91    {
92        SUPER(SpaceRaceController, XMLPort, xmlelement, mode);
93        XMLPortParam(ArtificialController, "accuracy", setAccuracy, getAccuracy, xmlelement, mode).defaultValues(100.0f);
94        XMLPortObject(ArtificialController, WorldEntity, "waypoints", addWaypoint, getWaypoint, xmlelement, mode);
95
96    }
97
98    /*
99     * called from constructor 'SpaceRaceController'
100     * returns a vector of static Point (checkpoints the spaceship has to reach)
101     */
102    std::vector<RaceCheckPoint*> SpaceRaceController::findStaticCheckpoints(std::vector<RaceCheckPoint*> allCheckpoints)
103    {
104        std::map<RaceCheckPoint*, int> * zaehler = new std::map<
105        RaceCheckPoint*, int>(); // counts how many times the checkpoit was reached (for simulation)
106        for (unsigned int i = 0; i < allCheckpoints.size(); i++)
107        {
108            zaehler->insert(std::pair<RaceCheckPoint*, int>(allCheckpoints[i],0));
109        }
110        int maxWays = rekSimulationCheckpointsReached(zaehler->begin()->first, zaehler);
111
112        std::vector<RaceCheckPoint*> returnVec;
113        returnVec.clear();
114        for (std::map<RaceCheckPoint*, int>::iterator iter = zaehler->begin(); iter!= zaehler->end(); iter++)
115        {
116            if (iter->second == maxWays)
117            {
118                //returnVec.insert(allCheckpoints[1]);
119                returnVec.insert(returnVec.end(), iter->first);
120            }
121        }
122        delete zaehler;
123        return returnVec;
124    }
125
126    /*
127     * called from 'findStaticCheckpoints'
128     * return how many ways go from the given Checkpoint to the last Checkpoint (of the Game)
129     */
130    int SpaceRaceController::rekSimulationCheckpointsReached(RaceCheckPoint* currentCheckpoint, std::map<RaceCheckPoint*, int>* zaehler)
131    {
132        if (currentCheckpoint->isLast())
133        {// last point reached
134            (*zaehler)[currentCheckpoint] += 1;
135            return 1; // 1 Way form the last point to this one
136        }
137        else
138        {
139            int numberOfWays = 0; // counts number of ways from this Point to the last point
140            for (std::set<int>::iterator it = currentCheckpoint->getNextCheckpoints().begin(); it!= currentCheckpoint->getNextCheckpoints().end(); ++it)
141            {
142                numberOfWays += rekSimulationCheckpointsReached(findCheckpoint(*it), zaehler);
143            }
144            (*zaehler)[currentCheckpoint] += numberOfWays;
145            return numberOfWays; // returns the number of ways from this point to the last one
146        }
147    }
148
149
150
151    //-------------------------------------
152    // functions for dynamic Way-search
153
154    int SpaceRaceController::distanceSpaceshipToCheckPoint(RaceCheckPoint* CheckPoint)
155    {
156        if (this->getControllableEntity() != NULL)
157        {
158            return (CheckPoint->getPosition()- this->getControllableEntity()->getPosition()).length();
159        }
160        return -1;
161    }
162
163    /*
164     * called by: 'tick' or  'adjustNextPoint'
165     * returns the next Checkpoint which the shortest way contains
166     */
167    RaceCheckPoint* SpaceRaceController::nextPointFind(RaceCheckPoint* raceCheckpoint)
168    {
169        int distances[] = {   -1, -1, -1};
170        int temp_i = 0;
171        for (std::set<int>::iterator it =raceCheckpoint->getNextCheckpoints().begin(); it!= raceCheckpoint->getNextCheckpoints().end(); ++it)
172        {
173            distances[temp_i] = recCalculateDistance(findCheckpoint(*it), this->getControllableEntity()->getPosition());
174            temp_i++;
175        }
176        if (distances[0] > distances[1] && distances[1] != -1)
177        {
178            if (distances[2] < distances[1] && distances[2] != -1)
179            {
180                return findCheckpoint(*raceCheckpoint->getNextCheckpoints().end()); // return checkpoint with ID of raceCheckpoint->getNextCheckpoints() [2]
181            }
182            else
183            {
184                std::set<int>::iterator temp = raceCheckpoint->getNextCheckpoints().begin();
185                return findCheckpoint(*(++temp)); // return [1]
186            }
187        }
188        else
189        {
190            if (distances[2] < distances[0] && distances[2] != -1)
191            {
192                return findCheckpoint(*raceCheckpoint->getNextCheckpoints().end()); // return [2]
193            }
194            else
195            {
196                return findCheckpoint(*raceCheckpoint->getNextCheckpoints().begin()); // return [0]
197            }
198        }
199    }
200
201    /*
202     * called from 'nextPointFind'
203     * returns the distance between "currentPosition" and the next static checkpoint that can be reached from "currentCheckPoint"
204     */
205    int SpaceRaceController::recCalculateDistance(RaceCheckPoint* currentCheckPoint, Vector3 currentPosition)
206    {
207        // find: looks if the currentCheckPoint is a staticCheckPoint (staticCheckPoint is the same as: static Point)
208        if (std::find(staticRacePoints_.begin(), staticRacePoints_.end(), currentCheckPoint) != staticRacePoints_.end())
209        {
210            return (currentCheckPoint->getPosition() - currentPosition).length();
211        }
212        else
213        {
214            int minimum = std::numeric_limits<int>::max();
215            for (std::set<int>::iterator it = currentCheckPoint->getNextCheckpoints().begin(); it!= currentCheckPoint->getNextCheckpoints().end(); ++it)
216            {
217                int dist_currentCheckPoint_currentPosition = static_cast<int> ((currentPosition- currentCheckPoint->getPosition()).length());
218
219                minimum= std::min(minimum, dist_currentCheckPoint_currentPosition + recCalculateDistance(findCheckpoint(*it), currentCheckPoint->getPosition()));
220                // minimum of distanz from 'currentPosition' to the next static Checkpoint
221            }
222            return minimum;
223        }
224    }
225
226    /*called by 'tick'
227     *adjust chosen way of the Spaceship every "AdjustDistance" because spaceship could be displaced through an other one
228     */
229    RaceCheckPoint* SpaceRaceController::adjustNextPoint()
230    {
231        if (currentRaceCheckpoint_ == NULL) // no Adjust possible
232
233        {
234            return nextRaceCheckpoint_;
235        }
236        if ((currentRaceCheckpoint_->getNextCheckpoints()).size() == 1) // no Adjust possible
237
238        {
239            return nextRaceCheckpoint_;
240        }
241
242        //Adjust possible
243
244        return nextPointFind(currentRaceCheckpoint_);
245    }
246
247    RaceCheckPoint* SpaceRaceController::findCheckpoint(int index) const
248       {
249           for (size_t i = 0; i < this->checkpoints_.size(); ++i)
250           if (this->checkpoints_[i]->getCheckpointIndex() == index)
251           return this->checkpoints_[i];
252           return NULL;
253       }
254
255    RaceCheckPoint* SpaceRaceController::addVirtualCheckPoint( RaceCheckPoint* previousCheckpoint, int indexFollowingCheckPoint , Vector3 virtualCheckPointPosition ){
256
257        RaceCheckPoint* newTempRaceCheckPoint = new RaceCheckPoint(this);
258        newTempRaceCheckPoint->setPosition(virtualCheckPointPosition);
259        newTempRaceCheckPoint->setCheckpointIndex(virtualCheckPointIndex);
260        newTempRaceCheckPoint->setLast(false);
261        newTempRaceCheckPoint->setNextCheckpointsAsVector3(Vector3(indexFollowingCheckPoint,-1,-1));
262
263        Vector3 temp = previousCheckpoint->getNextCheckpointsAsVector3();
264        checkpoints_.insert(checkpoints_.end(), newTempRaceCheckPoint);
265        int positionInNextCheckPoint;
266        for (int i = 0; i <3 ; i++){
267            if(previousCheckpoint->getNextCheckpointsAsVector3()[i]==indexFollowingCheckPoint)
268                positionInNextCheckPoint=i;
269        }
270        switch(positionInNextCheckPoint){
271            case 0: temp.x=virtualCheckPointIndex; break;
272            case 1: temp.y=virtualCheckPointIndex; break;
273            case 2: temp.z=virtualCheckPointIndex; break;
274        }
275        previousCheckpoint->setNextCheckpointsAsVector3(temp);
276        virtualCheckPointIndex--;
277        return newTempRaceCheckPoint;
278    }
279
280
281
282    SpaceRaceController::~SpaceRaceController()
283    {
284        for (int i =-1; i>virtualCheckPointIndex ; i--){
285            delete findCheckpoint(i);
286        }
287    }
288
289    void SpaceRaceController::tick(float dt)
290    {
291        if (this->getControllableEntity() == NULL || this->getControllableEntity()->getPlayer() == NULL )
292        {   orxout()<<this->getControllableEntity()<< " in tick"<<endl; return;}
293        //FOR virtual Checkpoints
294        if(nextRaceCheckpoint_->getCheckpointIndex() < 0){
295            if( distanceSpaceshipToCheckPoint(nextRaceCheckpoint_) < 30){
296                currentRaceCheckpoint_=nextRaceCheckpoint_;
297                nextRaceCheckpoint_ = nextPointFind(nextRaceCheckpoint_);
298                lastPositionSpaceship=this->getControllableEntity()->getPosition();
299            }
300        }
301
302        if (nextRaceCheckpoint_->playerWasHere(this->getControllableEntity()->getPlayer()))
303        {//Checkpoint erreicht
304            currentRaceCheckpoint_=nextRaceCheckpoint_;
305            OrxAssert(nextRaceCheckpoint_, "next race checkpoint undefined");
306            nextRaceCheckpoint_ = nextPointFind(nextRaceCheckpoint_);
307            lastPositionSpaceship=this->getControllableEntity()->getPosition();
308        }
309        else if ((lastPositionSpaceship-this->getControllableEntity()->getPosition()).length()/dt > ADJUSTDISTANCE)
310        {
311            nextRaceCheckpoint_ = adjustNextPoint();
312            lastPositionSpaceship=this->getControllableEntity()->getPosition();
313        }
314        //TODO: korrigieren!
315        else if((lastPositionSpaceship-this->getControllableEntity()->getPosition()).length()/dt< MINDISTANCE  ){
316            this->moveToPosition(Vector3(rnd()*100,rnd()*100,rnd()*100));
317            this->spin();
318            //orxout(user_status) << "Mindistance reached" << std::endl;
319            return;
320        }
321        //orxout(user_status) << "dt= " << dt << ";  distance= " << (lastPositionSpaceship-this->getControllableEntity()->getPosition()).length() <<std::endl;
322        lastPositionSpaceship=this->getControllableEntity()->getPosition();
323        this->moveToPosition(nextRaceCheckpoint_->getPosition());
324    }
325
326    // True if a coordinate of 'pointToPoint' is smaller then the corresponding coordinate of 'groesse'
327    bool SpaceRaceController::vergleicheQuader(Vector3 pointToPoint, Vector3 groesse){
328        if(abs(pointToPoint.x)<groesse.x)
329            return true;
330        if(abs(pointToPoint.y)<groesse.y)
331                    return true;
332        if(abs(pointToPoint.z)<groesse.z)
333                    return true;
334
335    }
336
337    void SpaceRaceController::placeVirtualCheckpoints(RaceCheckPoint* racepoint1, RaceCheckPoint* racepoint2){
338        Vector3 point1 = racepoint1->getPosition();
339        Vector3 point2 = racepoint2->getPosition();
340        std::vector<StaticEntity*> problematicObjects;
341
342        for (ObjectList<StaticEntity>::iterator it = ObjectList<StaticEntity>::begin(); it!= ObjectList<StaticEntity>::end(); ++it)
343                        {
344
345                            if (dynamic_cast<RaceCheckPoint*>(*it)!=NULL){continue;} // does not work jet
346
347                            problematicObjects.insert(problematicObjects.end(), *it);
348                            //it->getScale3D();// vector fuer halbe wuerfellaenge
349                        }
350        Vector3 richtungen [6];
351        richtungen[0]= Vector3(1,0,0);
352        richtungen[1]= Vector3(-1,0,0);
353        richtungen[2]= Vector3(0,1,0);
354        richtungen[3]= Vector3(0,-1,0);
355        richtungen[4]= Vector3(0,0,1);
356        richtungen[5]= Vector3(0,0,-1);
357
358        for (int i = 0; i< 6; i++){
359            const int STEPS=100;
360            const float PHI=1.1;
361            bool collision=false;
362
363            for (int j =0; j<STEPS; j++){
364                Vector3 tempPosition=(point1 - (point2-point1+richtungen[i]*PHI)*(float)j/STEPS);
365                for (std::vector<StaticEntity*>::iterator it = problematicObjects.begin(); it!=problematicObjects.end(); ++it){
366                    btVector3 positionObject;
367                    btScalar radiusObject;
368                    //TODO: Probably it points on a wrong object
369                    for (int everyShape=0; (*it)->getAttachedCollisionShape(everyShape)!=0; everyShape++){
370                        (*it)->getAttachedCollisionShape(everyShape)->getCollisionShape()->getBoundingSphere(positionObject,radiusObject);
371                        Vector3 positionObjectNonBT(positionObject.x(), positionObject.y(), positionObject.z());
372                        if (((tempPosition - positionObjectNonBT).length()<radiusObject) && (vergleicheQuader((tempPosition-positionObjectNonBT),(*it)->getScale3D()))){
373                            collision=true; break;
374                        }
375                    }
376                    if(collision) break;
377                }
378                if(collision)break;
379            }
380            if(collision) continue;
381            // no collision => possible Way
382            for (float j =0; j<STEPS; j++){
383                Vector3 possiblePosition=(point1 - (point2-point1+richtungen[i]*PHI)*j/STEPS);
384                collision=false;
385                for(int ij=0; ij<STEPS; j++){
386                    Vector3 tempPosition=(possiblePosition - (point2-possiblePosition)*(float)ij/STEPS);
387                            for (std::vector<StaticEntity*>::iterator it = problematicObjects.begin(); it!=problematicObjects.end(); ++it){
388                                btVector3 positionObject;
389                                btScalar radiusObject;
390                                for (int everyShape=0; (*it)->getAttachedCollisionShape(everyShape)!=0; everyShape++){
391                                    (*it)->getAttachedCollisionShape(everyShape)->getCollisionShape()->getBoundingSphere(positionObject,radiusObject);
392                                    Vector3 positionObjectNonBT(positionObject.x(), positionObject.y(), positionObject.z());
393                                    if (((tempPosition-positionObjectNonBT).length()<radiusObject) && (vergleicheQuader((tempPosition-positionObjectNonBT),(*it)->getScale3D()))){
394                                        collision=true; break;
395                                    }
396                                }
397                            if(collision) break;
398                            }
399                    if(collision)break;
400                    addVirtualCheckPoint(racepoint1, racepoint2->getCheckpointIndex(), possiblePosition);
401                    return;
402                }
403
404            }
405        }
406
407
408    }
409}
Note: See TracBrowser for help on using the repository browser.