Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/camera.cc @ 3013

Last change on this file since 3013 was 2636, checked in by patrick, 20 years ago
  • Added a GameLoader to the game. This enables orxonox to load a campaign consisting of multimple worlds and cinematics etc. However, cinematics are not yet implemented.

In the game you can jump from one level to the other by pressing x. Currently there are only two very simple levels defined. (DEBUG_LEVEL_0, DEBUG_LEVEL_1).

  • Added Error Handling structs to signal the error source and code
File size: 7.3 KB
RevLine 
[2068]1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
[2080]14   main-programmer: Christian Meyer
[2068]15   co-programmer: ...
16*/
17
18#include "camera.h"
[2100]19#include "world.h"
20#include "world_entity.h"
[2068]21
22using namespace std;
23
[2096]24/**
25   \brief creates a Camera
26   
27   This standard constructor sets all parameters to zero
28*/
[2636]29Camera::Camera (World* world)
[2068]30{
[2636]31  this->world = world;
[2551]32  bound = NULL;
33  /* give it some physical live */
34  m = 10;
35  a = new Vector(0.0, 0.0, 0.0);
36  v = new Vector(0.0, 0.0, 0.0);
37  fs = new Vector(0.0, 0.0, 0.0);
38  cameraMode = NORMAL;
39  deltaTime = 3000.0;
40  cameraOffset = 1.0;
41  cameraOffsetZ = 10.0;
42  t = 0.0;
43
44  actual_place.r.x = 0.0;
45  actual_place.r.y = 10.0;
46  actual_place.r.z = -5.0;
[2068]47}
48
[2096]49/**
50   \brief default destructor
51*/
[2068]52Camera::~Camera ()
53{
54}
55
[2096]56/**
57   \brief time based actualisation of camera parameters
58   \param deltaT: The amount of time that has passed in milliseconds
59   
60   This is called by the World in every time_slice, use it to do fancy time dependant effects (such
61   as smooth camera movement or swaying).
62*/
[2068]63void Camera::time_slice (Uint32 deltaT)
64{
[2551]65  if(t <= deltaTime)
66    {t += deltaT;}
67  //printf("time is: t=%f\n", t );
68  update_desired_place ();
69  jump (NULL);
[2068]70}
71
[2096]72/**
[2551]73   \brief this calculates the location where the track wants the camera to be
[2096]74   
[2551]75   This refreshes the placement the camera should have according to the
76   bound entity's position on the track.
[2096]77*/
[2068]78void Camera::update_desired_place ()
79{
[2551]80  switch(cameraMode)
81    {
82     
83    case ELLIPTICAL:
84      {
85        //r = actual_place.r
86        Orxonox *orx = Orxonox::getInstance();
87        Location lookat; 
88        Placement plFocus;
89        if( bound != NULL)
90          {
91            bound->get_lookat (&lookat);
92            orx->get_world()->calc_camera_pos (&lookat, &plFocus);
93            Quaternion *fr;
94            if(t < 20.0)
95              {
96                Vector *start = new Vector(0.0, 1.0, 0.0);
97                //r = /*actual_place.r*/ *start - plFocus.r;
98                r = *(new Vector(0.0, 5.0, 0.0));
99
100                Vector up(0.0, 0.0, 1.0);
[2068]101               
[2551]102                Vector op(1.0, 0.0, 0.0);
103                float angle = angle_deg(op, *start);
104                printf("angle is: %f\n", angle);
105
106                //if in one plane
107                from = new Quaternion(angle, up);
108
109                //from = new Quaternion(*start, *up);
110                //&from = &plFocus.w;
111                //fr = &plFocus.w; real quaternion use
112               
113
114
115                Vector vDirection(1.0, 0.0, 0.0);
116                //vDirection = plFocus.w.apply(vDirection);
117                to = new Quaternion(vDirection, *start);
118                res = new Quaternion();
119              }
120            //printf("vector r = %f, %f, %f\n",r.x, r.y, r.z );
121            rAbs = r.len();
122            if(t < 30.0) /* FIXME!!*/
123              {
124                ka = rAbs / deltaTime*deltaTime;
125              }
126            /* this is the new length of the vector */
127            //float len = ka * powf((deltaTime - t), 2);
128           
129            /* calc the rotation */
130            /*
131            Vector axis(0.0, 0.0, 1.0);
132            if(t < 30.0)
133              a0 = PI/4 - atanf(fabs(r.x) / fabs(r.y));
134            printf("a0 = %f\n", a0);
135            float angle = a0/deltaTime * (deltaTime - t);
136            printf("angle is: %f\n", angle);
137            Quaternion q(angle, axis);
138            */
139            //r = q.apply(r);
140            //r = r * (len/r.len());
141           
142            //res->quatSlerp(from, to, t/deltaTime, res);
143            res->quatSlerp(to, from, t/deltaTime, res);
144
145            Vector ursp(0.0, 0.0, 0.0);
146            desired_place.r = /*plFocus.r -*/ ursp - res->apply(r); 
147
148            printf("desired place is: %f, %f, %f\n", desired_place.r.x, desired_place.r.y, desired_place.r.z);
149            //plLastBPlace = *bound->get_placement();
150          } 
151      }
152      break;
153    case SMOTH_FOLLOW:
154      {
155        Placement *plBound = bound->get_placement();
156        Location lcBound;
157        if(bound != null)
158          {
159            bound->get_lookat(&lcBound);
160            Vector vDirection(0.0, 0.0, 1.0);
161            vDirection = plBound->w.apply(vDirection);
162            desired_place.r = (vDirection * ((lcBound.dist-10.0)/* / l*/)) + Vector(0,0,5.0);
163          }
164        break;
165      }
166      /* this is a camera mode that tries just to follow the entity. */
167    case STICKY:
168      {
169        if(bound != null)
170          {
171            Placement *plBound = bound->get_placement();
172            Vector vDirection(0.0, 0.0, 1.0);
173            Vector eclipticOffset(0.0, 0.0, 5.0);
174            vDirection = plBound->w.apply(vDirection);
175            desired_place.r = plBound->r - vDirection*10 + eclipticOffset;
176          }
177        break;
178      }
179      /* the camera is handled like an entity and rolls on the track */
180    case NORMAL:
181      Location lookat; 
[2636]182      if( bound != NULL && world != NULL )
[2551]183        {
184          bound->get_lookat (&lookat);
[2636]185          world->calc_camera_pos (&lookat, &desired_place);
[2551]186        } 
187      else
188        {
189          desired_place.r = Vector (0,0,0);
190          desired_place.w = Quaternion (); 
191        }
192      break;
193    }
[2068]194}
195
[2096]196/**
[2551]197   \brief initialize rendering perspective according to this camera
[2096]198   
[2551]199   This is called immediately before the rendering cycle starts, it sets all global
200   rendering options as well as the GL_PROJECTION matrix according to the camera.
[2096]201*/
[2068]202void Camera::apply ()
203{
[2551]204  glMatrixMode (GL_PROJECTION);
[2112]205  glLoadIdentity ();
[2551]206  // view
207  // TO DO: implement options for frustum generation
208  glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 250.0);
209  //Vector up(0,0,1);
210  //Vector dir(1,0,0);
211  //Quaternion q(dir,up);
212  //float matrix[4][4];
213  //q.conjugate().matrix (matrix);
214  //glMultMatrixf ((float*)matrix);
215  //glTranslatef (10,0,-5);
216  //
217  //dir = Vector(-1,-1,0);
218  //q = Quaternion( dir, up);
219  //glMatrixMode (GL_MODELVIEW);
220  //glLoadIdentity ();
221  //q.matrix (matrix);
222  //glMultMatrixf ((float*)matrix);
223  //glTranslatef (2,2,0);
224  //
225  //glBegin(GL_TRIANGLES);
226  //glColor3f(1,0,0);
227  //glVertex3f(0,0,0.5);
228  //glColor3f(0,1,0);
229  //glVertex3f(-0.5,0,-1);
230  //glColor3f(0,0,1);
231  //glVertex3f(0.5,0,-1);
232  //glEnd();   
[2115]233
[2551]234  // ===== first camera control calculation option
235  // rotation
[2112]236  float matrix[4][4];
237  actual_place.w.conjugate().matrix (matrix);
[2551]238  /* orientation and */
[2112]239  glMultMatrixf ((float*)matrix);
[2551]240  /*  translation */
[2112]241  glTranslatef (-actual_place.r.x, -actual_place.r.y,- actual_place.r.z);
[2551]242  //Placement *plBound = bound->get_placement();
243
244  // ===== second camera control calculation option
245  /*
246    gluLookAt(actual_place.r.x, actual_place.r.y, actual_place.r.z,
247              plBound->r.x, plBound->r.y, plBound->r.z,
248              0.0, 0.0, 1.0);
249  */
250
[2068]251  glMatrixMode (GL_MODELVIEW);
[2080]252  glLoadIdentity ();
[2068]253}
254
[2096]255/**
256  \brief set the camera position
257  \param plc: The Placement to set the camera to
258       
259        This will set the actual and desired placement of the camera to plc
260*/
[2068]261void Camera::jump (Placement* plc = NULL)
262{
[2551]263  if( plc == NULL)
264    {
265      actual_place = desired_place;
266      //printf("Camera|jump: camer@ %f, %f, %f\n\n", actual_place.r.x, actual_place.r.y, actual_place.r.z);
267    }
268  else
269    {
270      desired_place = *plc;
271      actual_place = *plc;
272    }
[2068]273}
274
[2096]275/**
276  \brief bind the camera to an entity
277  \param entity: The enitity to bind the camera to
278       
279        This sets the focus of the camera to the given entity. This means that it will use the given WorldEntity's
280        Location and get_lookat() to determine the viewpoint the camera will render from.
281        Note that you cannot bind a camera to a free entity.
282*/
[2068]283void Camera::bind (WorldEntity* entity)
284{
[2551]285  if( entity != NULL)
286    {
287      if( entity->isFree ()) printf("Cannot bind camera to free entity");
288      else 
[2080]289        {
[2551]290          bound = entity;
291        }
292    } 
[2068]293}
[2636]294
295
296void Camera::setWorld(World* world)
297{
298  this->world = world;
299}
Note: See TracBrowser for help on using the repository browser.