Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/buerli/src/camera.cc @ 2664

Last change on this file since 2664 was 2551, checked in by patrick, 20 years ago

orxonox/trunk: minor changes - enhanced sc controll, fixed uncontrolled rotation effect, added some debug outputs for testing purposes, reformatted some src files from win style but not all

File size: 7.2 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 ()
30{
31  bound = NULL;
32  /* give it some physical live */
33  m = 10;
34  a = new Vector(0.0, 0.0, 0.0);
35  v = new Vector(0.0, 0.0, 0.0);
36  fs = new Vector(0.0, 0.0, 0.0);
37  cameraMode = NORMAL;
38
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;
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::time_slice (Uint32 deltaT)
64{
65  if(t <= deltaTime)
66    {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::update_desired_place ()
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->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);
101               
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      Orxonox *orx = Orxonox::getInstance();
182      Location lookat; 
183      if( bound != NULL)
184        {
185          bound->get_lookat (&lookat);
186          orx->get_world()->calc_camera_pos (&lookat, &desired_place);
187        } 
188      else
189        {
190          desired_place.r = Vector (0,0,0);
191          desired_place.w = Quaternion (); 
192        }
193      break;
194    }
195}
196
197/**
198   \brief initialize rendering perspective according to this camera
199   
200   This is called immediately before the rendering cycle starts, it sets all global
201   rendering options as well as the GL_PROJECTION matrix according to the camera.
202*/
203void Camera::apply ()
204{
205  glMatrixMode (GL_PROJECTION);
206  glLoadIdentity ();
207  // view
208  // TO DO: implement options for frustum generation
209  glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 250.0);
210  //Vector up(0,0,1);
211  //Vector dir(1,0,0);
212  //Quaternion q(dir,up);
213  //float matrix[4][4];
214  //q.conjugate().matrix (matrix);
215  //glMultMatrixf ((float*)matrix);
216  //glTranslatef (10,0,-5);
217  //
218  //dir = Vector(-1,-1,0);
219  //q = Quaternion( dir, up);
220  //glMatrixMode (GL_MODELVIEW);
221  //glLoadIdentity ();
222  //q.matrix (matrix);
223  //glMultMatrixf ((float*)matrix);
224  //glTranslatef (2,2,0);
225  //
226  //glBegin(GL_TRIANGLES);
227  //glColor3f(1,0,0);
228  //glVertex3f(0,0,0.5);
229  //glColor3f(0,1,0);
230  //glVertex3f(-0.5,0,-1);
231  //glColor3f(0,0,1);
232  //glVertex3f(0.5,0,-1);
233  //glEnd();   
234
235  // ===== first camera control calculation option
236  // rotation
237  float matrix[4][4];
238  actual_place.w.conjugate().matrix (matrix);
239  /* orientation and */
240  glMultMatrixf ((float*)matrix);
241  /*  translation */
242  glTranslatef (-actual_place.r.x, -actual_place.r.y,- actual_place.r.z);
243  //Placement *plBound = bound->get_placement();
244
245  // ===== second camera control calculation option
246  /*
247    gluLookAt(actual_place.r.x, actual_place.r.y, actual_place.r.z,
248              plBound->r.x, plBound->r.y, plBound->r.z,
249              0.0, 0.0, 1.0);
250  */
251
252  glMatrixMode (GL_MODELVIEW);
253  glLoadIdentity ();
254}
255
256/**
257  \brief set the camera position
258  \param plc: The Placement to set the camera to
259       
260        This will set the actual and desired placement of the camera to plc
261*/
262void Camera::jump (Placement* plc = NULL)
263{
264  if( plc == NULL)
265    {
266      actual_place = desired_place;
267      //printf("Camera|jump: camer@ %f, %f, %f\n\n", actual_place.r.x, actual_place.r.y, actual_place.r.z);
268    }
269  else
270    {
271      desired_place = *plc;
272      actual_place = *plc;
273    }
274}
275
276/**
277  \brief bind the camera to an entity
278  \param entity: The enitity to bind the camera to
279       
280        This sets the focus of the camera to the given entity. This means that it will use the given WorldEntity's
281        Location and get_lookat() to determine the viewpoint the camera will render from.
282        Note that you cannot bind a camera to a free entity.
283*/
284void Camera::bind (WorldEntity* entity)
285{
286  if( entity != NULL)
287    {
288      if( entity->isFree ()) printf("Cannot bind camera to free entity");
289      else 
290        {
291          bound = entity;
292        }
293    } 
294}
Note: See TracBrowser for help on using the repository browser.