Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

/orxonox/trunk: discovered a minor bug and fixed some code style issues…

File size: 7.6 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;
[3215]32  this->bound = NULL;
[2551]33  /* give it some physical live */
[3215]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;
[2551]43
[3215]44  this->actual_place.r.x = 0.0;
45  this->actual_place.r.y = 10.0;
46  this->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{
[3215]65  if( this->t <= deltaTime)
66    {this->t += deltaT;}
[2551]67  //printf("time is: t=%f\n", t );
[3215]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
[3175]208  //glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 250.0);
209  gluPerspective(60, 1.2f, 0.1, 250);
210 
[2551]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();   
[2115]235
[2551]236  // ===== first camera control calculation option
237  // rotation
[2112]238  float matrix[4][4];
239  actual_place.w.conjugate().matrix (matrix);
[2551]240  /* orientation and */
[2112]241  glMultMatrixf ((float*)matrix);
[2551]242  /*  translation */
[2112]243  glTranslatef (-actual_place.r.x, -actual_place.r.y,- actual_place.r.z);
[3215]244//Placement *plBound = bound->get_placement();
[2551]245
246  // ===== second camera control calculation option
247  /*
[3215]248   gluLookAt(actual_place.r.x, actual_place.r.y, actual_place.r.z,
[2551]249              plBound->r.x, plBound->r.y, plBound->r.z,
250              0.0, 0.0, 1.0);
251  */
252
[2068]253  glMatrixMode (GL_MODELVIEW);
[2080]254  glLoadIdentity ();
[2068]255}
256
[2096]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*/
[2068]263void Camera::jump (Placement* plc = NULL)
264{
[2551]265  if( plc == NULL)
266    {
267      actual_place = desired_place;
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      desired_place = *plc;
273      actual_place = *plc;
274    }
[2068]275}
276
[2096]277/**
278  \brief bind the camera to an entity
279  \param entity: The enitity to bind the camera to
280       
[3213]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.
[2096]284*/
[2068]285void Camera::bind (WorldEntity* entity)
286{
[2551]287  if( entity != NULL)
288    {
[3213]289      if( entity->isFree()) printf("Cannot bind camera to free entity");
[2551]290      else 
[2080]291        {
[3213]292          this->bound = entity;
[2551]293        }
294    } 
[2068]295}
[2636]296
297
298void Camera::setWorld(World* world)
299{
300  this->world = world;
301}
[3213]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.