Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/old.dave/src/camera.cc @ 3279

Last change on this file since 3279 was 3279, checked in by dave, 20 years ago

branches/old.dave: Die Neigung des Raumschiffes ist jetzt nicht mehr so stark, und jetzt kann man auch 2 Tasten aufs mal drücken, ohne dass das Raumschiffsche jedes mal anhält:)

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
[3279]208  glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 400.0);
[2551]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.