Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/plehmannFS16/src/orxonox/controllers/ScriptController.cc @ 11165

Last change on this file since 11165 was 11152, checked in by plehmann, 8 years ago

took the event functions out of the tick function

  • Property svn:eol-style set to native
File size: 12.9 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 *      ...
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29 /*
30  * Currently available lua commands:
31  *
32  * IMPORTANT: ALL COMMANDS DO REQUIRE 7 PARAMETERS TO BE PROVIDED. FILL UP WITH ZEROES IN UNIMPORTANT PLACES.
33  *
34  * Command             | Abbreviation | Parameter 1          | '' 2     | '' 3    | '' 4                 | '' 5     | '' 6     | '' 7
35  *
36  * "Move And Look"     | mal          | GoTo X Coordinate    |  '' Y ''  | '' Z '' | LookAt X Coordinate  |  '' Y '' |  '' Y '' | Duration
37  * "Rotate And Look"   | ral          | GoTo X Coordinate    |  '' Y ''  | '' Z '' | Axis (1=x, 2=y, 3=z) |     -    |     -    | Duration
38  * "Spiral"            | spi          | GoTo X Coordinate    |  '' Y ''  | '' Z '' |          -           |     -    |     -    | Duration
39  * "Transition Look"   | chl          | From X Coordinate    |  '' Y ''  | '' Z '' | To X Coordinate      |  '' Y '' |  '' Y '' | Duration
40  * "rotate round X crd"| rotX         | anchor coordinate    | angle(rad)|    -    |                      |          |          | Duration
41  * "Idle (Do nothing)" | idle         | Duration
42  */
43
44#include "ScriptController.h"
45#include "infos/PlayerInfo.h"
46#include "core/CoreIncludes.h"
47#include "worldentities/ControllableEntity.h"
48#include "core/LuaState.h"
49#include "core/LuaState.h"
50#include "util/Math.h"
51
52namespace orxonox
53{
54    RegisterClass(ScriptController);
55
56    ScriptController::ScriptController(Context* context) : ArtificialController(context)
57    {
58        RegisterObject(ScriptController);
59
60        /* By default, this controller has ID 0, which means it is not assigned
61         * to anything yet.
62         */
63        this->ctrlid_ = 0;
64
65        /* Set default values for all variables */
66        /* - pointers to zero */
67        this->player_ = nullptr;
68        this->entity_ = nullptr;
69
70        /* - times */
71        this->scTime = 0.0f;
72        this->eventTime = 0.0f;
73
74        /* - Points in space */
75        this->startpos = Vector3(0,0,0);
76        //this->lookAtPosition = Vector3(0,0,0);
77
78        /* - Processing flag */
79        this->processing = false;
80
81        /* - Counters */
82        this->eventno = 0;
83
84        /* - First "previous event" scheduled at t=0 */
85        /* - Needed for automatically updating event times */
86        this->prevEventTime = 0;
87    }
88
89    void ScriptController::takeControl(int ctrlid)
90    {
91        /* Output some debugging information */
92        orxout(verbose) << "ScriptController: Taking control" << endl;
93        orxout(verbose) << "This-pointer: " << this << endl; 
94
95        /* Set the controller ID (the argument here should be nonzero) */
96        this->ctrlid_ = ctrlid;
97
98        /* Store the entity pointer in a private variable */
99        this->entity_ = this->player_->getControllableEntity();
100        assert(this->entity_);
101         
102        /* Add the controller here to this entity. Apparently this still leaves
103         * any preexisting human controllers in place.
104         */
105        this->entity_->setDestroyWhenPlayerLeft(false);
106        this->player_->stopTemporaryControl();
107        this->entity_->setController(this);
108        this->setControllableEntity(this->entity_);
109        //this->entity_->mouseLook();
110        //this->entity_->setVisible(false);
111       
112        // TODO take the human Controllers control  dont forget to give it back in the destructor
113    }
114
115    const Vector3& ScriptController::getPosition()
116    {
117      return this->entity_->getPosition();
118    }
119
120    ScriptController* ScriptController::getScriptController()
121    {
122      /* Output a message that confirms this function was called */
123      orxout(verbose) << "Great success!" << std::endl;
124
125      /* Debugging: print all the scriptcontroller object pointers */
126      for(ScriptController* controller : ObjectList<ScriptController>())
127      { orxout(verbose) << "Have object in list: " << controller << endl; }
128
129      /* Find the first one with a nonzero ID */
130      for(ScriptController* controller : ObjectList<ScriptController>())
131      { 
132        // TODO: do some selection here. Currently just returns the first one
133        if( controller->getID() > 0 )
134        { orxout(verbose) << "Controller to return: " << controller << endl;
135          return controller;
136        }
137     
138      }
139      return nullptr;
140    }
141
142    void ScriptController::execute(event ev)
143    {
144        /* Debugging output */
145        //orxout() << "Executing event " << ev.fctName
146          //<< " with parameters:\n "
147          //<< ev.x1 << " " << ev.y1 << " " << ev.z1 << "\n"
148          //<< ev.x2 << " " << ev.y2 << " " << ev.z2 << "\n"
149          //<< ev.duration << endl;
150
151        /* Event is starting, hence set the time to 0 */
152        this->eventTime = 0.0f;
153        this->processing = true;
154
155        /* Copy the event into the currentEvent holder */
156        this->currentEvent = ev;
157
158        /* Store starting position */
159        this->startpos = this->entity_->getPosition();
160    }
161
162
163    void ScriptController::tick(float dt)
164    {
165        /* Call the tick function of the classes we derive from */
166        SUPER(ScriptController, tick, dt);
167
168        /* If this controller has no entity entry, do nothing */
169        if( !(this->entity_) ) return;
170
171        /* See if time has come for the next event to be run */
172        if(this->eventList.size() > 0 && this->eventList[0].eventTime <= scTime)
173        { /* Execute the next event on the list */
174          this->execute(this->eventList[0]);
175          this->eventList.erase(this->eventList.begin());
176          this->eventno -= 1;
177        }
178
179        /* Update the local timers in this object */
180        scTime += dt; eventTime += dt;
181
182        /* If we've arrived at the target, stop processing */
183        if( eventTime > currentEvent.duration && this->processing == true)
184        { this->processing = false;
185
186          /* If we reached the last event, also reenable the normal movement
187           * and make the model visible again
188           */
189          if( this->eventno == 0 )
190          {
191            this->entity_->mouseLook();
192            this->entity_->setVisible(true);
193          }
194        }
195
196        /* Get a variable that specifies how far along the trajectory
197         * we are currently.
198         */
199        float dl = eventTime / currentEvent.duration; 
200
201        /* Depending on command */
202        /* Do some moving */
203        if( this->processing )
204        {
205          // Abbreviation for "spiral" (rotation + translation)
206          if (this->currentEvent.fctName == "spi") 
207          {
208              spi(dl); // call the external function
209          }
210
211          // Abbreviation for "rotate and look"
212          else if (this->currentEvent.fctName == "ral")
213          { 
214              ral(dl); 
215          }
216          else if( this->currentEvent.fctName == "mal" )
217          {
218              mal(dl);
219          }
220          else if( this->currentEvent.fctName == "chl" )
221          {
222              chl(dl);
223          }
224
225
226          /* Force mouse look */
227          if( this->entity_->isInMouseLook() == false )
228            this->entity_->mouseLook();
229        }
230    }
231
232    void ScriptController::eventScheduler(std::string instruction, 
233      float x1, float y1, float z1, 
234      float x2, float y2, float z2, 
235      float duration, float executionTime)
236    {
237      /* put data (from LUA) into time-sorted eventList*/ 
238      /* Nimmt den befehl und die argumente aus luascript und ertellt einen
239       * struct pro event, diese structs werden sortiert nach eventTime
240       */
241      struct event tmp;
242
243      /* Fill the structure with all the provided information */
244      tmp.fctName = instruction;
245
246      //tmp.x1 = x1; tmp.y1 = y1; tmp.z1 = z1;
247      //tmp.x2 = x2; tmp.y2 = y2; tmp.z2 = z2;
248      tmp.v1 = Vector3(x1,y1,z1);
249      tmp.v2 = Vector3(x2,y2,z2);
250
251      // the parameters are not required to be vector coordinates!
252      // for convenience they are however stored twice if they have some kind of different meaning
253      tmp.a = x1;
254      tmp.b = y1;
255      tmp.c = z1;
256      tmp.d = x2;
257      tmp.e = y2;
258      tmp.f = z2;
259
260      tmp.duration = duration;
261
262      /* This is kind of a hack. If we hit the function idle all we want to do is
263         advance event execution time, not schedule anything */
264      if (instruction == "idle") {
265        tmp.eventTime = this->prevEventTime;
266        this->prevEventTime += x1;
267        return;
268      } else {
269        tmp.eventTime = this->prevEventTime;
270        this->prevEventTime += duration;
271      }
272
273      /* Add the created event to the event list */
274      if(eventList.size()==0)
275      { /* The list is still empty, just add it */
276        orxout(verbose) << "eventList empty (01)" << endl;
277        eventList.insert(eventList.begin(), tmp);
278        this->eventno += 1;
279        return; /* Nothing more to do, the event was added */
280      }
281
282      /* Event was not added yet since the list was not empty. Walk through
283       * the list of events and add it so that the events are correctly in
284       * order.
285       */
286      for (std::vector<event>::iterator it=eventList.begin(); it<eventList.end(); it++)
287      { if(tmp.eventTime < it->eventTime)
288        { eventList.insert(it,tmp);
289          this->eventno += 1;
290          //orxout()<<"new event added"<<endl;
291          return;
292        }
293      }
294
295      /* If the event was still not added here, it belongs in the end of the list */
296      eventList.insert(eventList.end(), tmp);
297      this->eventno += 1;
298
299    }
300
301    // Event Functions
302
303    void ScriptController::spi(float dl) 
304    {
305   
306                // Need to know a perpendicular basis to the translation vector:
307            // Given (a, b, c) we chose (b, -a, 0)norm and (0, c, -b)norm
308            // Currently we set a fix rotational radius of 400
309            // TODO: Add an option to adjust radius of spiral movement
310            Vector3 direction = this->currentEvent.v1 - startpos;
311
312            Vector3* ortho1 = new Vector3(direction.y, -direction.x, 0);
313            float absOrtho1 = sqrt(direction.y * direction.y + direction.x * direction.x);
314            *ortho1 = 400 * cos(2 * math::pi * dl) * (*ortho1)/absOrtho1;
315
316            Vector3* ortho2 = new Vector3(0, direction.z, -direction.y);
317            float absOrtho2 = sqrt(direction.y * direction.y + direction.z * direction.z);
318            *ortho2 = 400 * sin(2 * math::pi * dl) * (*ortho2)/absOrtho2;
319
320            this->entity_->setPosition( (1-dl)*startpos + dl * this->currentEvent.v1 + *ortho1 + *ortho2);
321
322            delete ortho1;
323            delete ortho2;
324
325    }
326
327    void ScriptController::ral(float dl)
328    {
329            // Specify the axis
330            Vector3 a;
331              switch ((int) currentEvent.d) {
332                case 3:
333                  a = Vector3(this->currentEvent.v1.x + this->currentEvent.e*cos(2*math::pi*dl),
334                                  this->currentEvent.v1.y + this->currentEvent.e*sin(2*math::pi*dl),
335                                  this->currentEvent.v1.z);
336                break;
337                case 2:
338                  a = Vector3(this->currentEvent.v1.x + this->currentEvent.e*sin(2*math::pi*dl),
339                                  this->currentEvent.v1.y,
340                                  this->currentEvent.v1.z + this->currentEvent.e*cos(2*math::pi*dl));
341                break;
342                case 1:
343                  a = Vector3(this->currentEvent.v1.x,
344                                  this->currentEvent.v1.y + this->currentEvent.e*sin(2*math::pi*dl),
345                                  this->currentEvent.v1.z + this->currentEvent.e*cos(2*math::pi*dl));
346                break;
347              }
348
349            this->entity_->setPosition(a);
350
351            /* Look at the specified position */
352            this->entity_->lookAt(this->currentEvent.v1);
353     
354    }
355
356    void ScriptController::mal(float dl)
357    {
358            /* Set the position to the correct place in the trajectory */
359            this->entity_->setPosition( (1-dl)*startpos + dl * this->currentEvent.v1);
360
361            /* Look at the specified position */
362            this->entity_->lookAt(this->currentEvent.v2);
363
364    }
365
366    void ScriptController::chl(float dl)
367    {
368            /* Sweep the look from v1 to v2 */
369            this->entity_->lookAt( (1-dl)*this->currentEvent.v1 + 
370              dl * this->currentEvent.v2 );
371
372    }
373
374    void ScriptController::rotX(float dl)
375    {
376
377
378    }
379}
Note: See TracBrowser for help on using the repository browser.