Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3228 was 3228, checked in by patrick, 19 years ago

orxonox/trunk: unstable - cleaned up vector.h

File size: 7.5 KB
Line 
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:
14   main-programmer: Christian Meyer
15   co-programmer: ...
16*/
17
18#include "camera.h"
19#include "world.h"
20#include "world_entity.h"
21
22using namespace std;
23
24/**
25   \brief creates a Camera
26   
27   This standard constructor sets all parameters to zero
28*/
29Camera::Camera (World* world)
30{
31  this->world = world;
32  this->bound = NULL;
33  /* give it some physical live */
34  this->m = 10;
35  this->a = new Vector(0.0, 0.0, 0.0);
36  this->v = new Vector(0.0, 0.0, 0.0);
37  this->fs = new Vector(0.0, 0.0, 0.0);
38  this->cameraMode = NORMAL;
39  this->deltaTime = 3000.0;
40  this->cameraOffset = 1.0;
41  this->cameraOffsetZ = 10.0;
42  this->t = 0.0;
43
44  this->actual_place.r.x = 0.0;
45  this->actual_place.r.y = 10.0;
46  this->actual_place.r.z = -5.0;
47}
48
49/**
50   \brief default destructor
51*/
52Camera::~Camera ()
53{
54}
55
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*/
63void Camera::timeSlice (Uint32 deltaT)
64{
65  if( this->t <= deltaTime)
66    {this->t += deltaT;}
67  //printf("time is: t=%f\n", t );
68  update_desired_place();
69  jump(NULL);
70}
71
72/**
73   \brief this calculates the location where the track wants the camera to be
74   
75   This refreshes the placement the camera should have according to the
76   bound entity's position on the track.
77*/
78void Camera::updateDesiredPlace ()
79{
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->getWorld()->calcCameraPos (&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);
101               
102                Vector op(1.0, 0.0, 0.0);
103                float angle = angleDeg(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            desiredPlace.r = /*plFocus.r -*/ ursp - res->apply(r); 
147
148            printf("desired place is: %f, %f, %f\n", desiredPlace.r.x, desiredPlace.r.y, desiredPlace.r.z);
149            //plLastBPlace = *bound->get_placement();
150          } 
151      }
152      break;
153    case SMOTH_FOLLOW:
154      {
155        Placement *plBound = bound->getPlacement();
156        Location lcBound;
157        if(bound != null)
158          {
159            bound->getLookat(&lcBound);
160            Vector vDirection(0.0, 0.0, 1.0);
161            vDirection = plBound->w.apply(vDirection);
162            desiredPlace.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            desiredPlace.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; 
182      if( bound != NULL && world != NULL )
183        {
184          bound->getLookat (&lookat);
185          world->calcCameraPos (&lookat, &desiredPlace);
186        } 
187      else
188        {
189          desiredPlace.r = Vector (0,0,0);
190          desiredPlace.w = Quaternion (); 
191        }
192      break;
193    }
194}
195
196/**
197   \brief initialize rendering perspective according to this camera
198   
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.
201*/
202void Camera::apply ()
203{
204  glMatrixMode (GL_PROJECTION);
205  glLoadIdentity ();
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  gluPerspective(60, 1.2f, 0.1, 250);
210 
211  //Vector up(0,0,1);
212  //Vector dir(1,0,0);
213  //Quaternion q(dir,up);
214  //float matrix[4][4];
215  //q.conjugate().matrix (matrix);
216  //glMultMatrixf ((float*)matrix);
217  //glTranslatef (10,0,-5);
218  //
219  //dir = Vector(-1,-1,0);
220  //q = Quaternion( dir, up);
221  //glMatrixMode (GL_MODELVIEW);
222  //glLoadIdentity ();
223  //q.matrix (matrix);
224  //glMultMatrixf ((float*)matrix);
225  //glTranslatef (2,2,0);
226  //
227  //glBegin(GL_TRIANGLES);
228  //glColor3f(1,0,0);
229  //glVertex3f(0,0,0.5);
230  //glColor3f(0,1,0);
231  //glVertex3f(-0.5,0,-1);
232  //glColor3f(0,0,1);
233  //glVertex3f(0.5,0,-1);
234  //glEnd();   
235
236  // ===== first camera control calculation option
237  // rotation
238  float matrix[4][4];
239  actual_place.w.conjugate().matrix (matrix);
240  /* orientation and */
241  glMultMatrixf ((float*)matrix);
242  /*  translation */
243  glTranslatef (-actual_place.r.x, -actual_place.r.y,- actual_place.r.z);
244//Placement *plBound = bound->get_placement();
245
246  // ===== second camera control calculation option
247  /*
248   gluLookAt(actual_place.r.x, actual_place.r.y, actual_place.r.z,
249              plBound->r.x, plBound->r.y, plBound->r.z,
250              0.0, 0.0, 1.0);
251  */
252
253  glMatrixMode (GL_MODELVIEW);
254  glLoadIdentity ();
255}
256
257/**
258  \brief set the camera position
259  \param plc: The Placement to set the camera to
260       
261        This will set the actual and desired placement of the camera to plc
262*/
263void Camera::jump (Placement* plc = NULL)
264{
265  if( plc == NULL)
266    {
267      actualPlace = desiredPlace;
268      //printf("Camera|jump: camer@ %f, %f, %f\n\n", actual_place.r.x, actual_place.r.y, actual_place.r.z);
269    }
270  else
271    {
272      desiredPlace = *plc;
273      actualPlace = *plc;
274    }
275}
276
277/**
278  \brief bind the camera to an entity
279  \param entity: The enitity to bind the camera to
280       
281  This sets the focus of the camera to the given entity. This means that it will use the given WorldEntity's
282  Location and get_lookat() to determine the viewpoint the camera will render from.
283  Note that you cannot bind a camera to a free entity.
284*/
285void Camera::bind (WorldEntity* entity)
286{
287  if( entity != NULL)
288    {
289      if( entity->isFree()) printf("Cannot bind camera to free entity");
290      else 
291        {
292          this->bound = entity;
293        }
294    } 
295}
296
297
298void Camera::setWorld(World* world)
299{
300  this->world = world;
301}
302
303
304/**
305   \brief destroy, reset the camera so that it doesn't perform anything anymore
306
307*/
308void Camera::destroy()
309{
310  this->bound = NULL;
311  this->world = NULL;
312}
Note: See TracBrowser for help on using the repository browser.