CarCamera.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright © 2009, 2010 James Legg.
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 */
00011 #include "CarCamera.h"
00012 #include <GL/gl.h>
00013 #include <GL/glu.h>
00014 
00015 #include <cmath>
00016 
00017 #include "../Graphics/Window.h"
00018 #include "Audio.h"
00019 
00020 class MyQuaternion : public btQuaternion
00021 {
00022 public:
00023     MyQuaternion(const btQuaternion & quaternion)
00024         :   btQuaternion(quaternion)
00025     {
00026     }
00027     
00028     // This function is based on code from Bullet, released under this license:  
00029     /* Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
00030 
00031     This software is provided 'as-is', without any express or implied warranty.
00032     In no event will the authors be held liable for any damages arising from the use of this software.
00033     Permission is granted to anyone to use this software for any purpose, 
00034     including commercial applications, and to alter it and redistribute it freely, 
00035     subject to the following restrictions:
00036 
00037     1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00038     2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00039     3. This notice may not be removed or altered from any source distribution.
00040     */
00042     btVector3 getAxis() const
00043     {
00044         btScalar s_squared = btScalar(1.) - btPow(m_floats[3], btScalar(2.));
00045         if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero
00046         {
00047             return btVector3(1.0, 0.0, 0.0);  // Arbitrary
00048         }
00049         btScalar s = btSqrt(s_squared);
00050         return btVector3(m_floats[0] / s, m_floats[1] / s, m_floats[2] / s);
00051     }
00052 
00053 };
00054 
00055 namespace Engine
00056 {
00057 
00058 CarCamera::CarCamera(GameObjects::Car & car, Physics::World & world)
00059     :   car(car),
00060         world(world)
00061     ,   m_velocity(btVector3(0.0, 0.0, 0.0))
00062 {
00063     world.add_tick_observer(this);
00064     
00065     // set inital camera position.
00066     btTransform car_transform;
00067     car.get_transform(car_transform);
00068     btTransform car_rotation_transform = car_transform;
00069     car_rotation_transform.setOrigin(btVector3(0, 0, 0));
00070     location = car_transform(btVector3(0.0, -0.70, car.get_camera_height()));
00071     up = car_rotation_transform(btVector3(0.0, 0.0, 1.0));
00072     centre = car_transform(btVector3(0.0, 1.0, 0.1));
00073     // We need the listener set so the sound is right before the game starts.
00074     posttick();
00075 }
00076 
00077 CarCamera::~CarCamera()
00078 {
00079     world.remove_tick_observer(this);
00080 }
00081 
00082 void CarCamera::full_transform()
00083 {
00084     gluLookAt(location.x(), location.y(), location.z(),
00085               centre.x(), centre.y(), centre.z(),
00086               up.x(), up.y(), up.z()); 
00087 }
00088 
00089 void CarCamera::rotation_transform()
00090 {
00091     gluLookAt(0.0, 0.0, 0.0,
00092               centre.x() - location.x(), centre.y() - location.y(), centre.z() - location.z(),
00093               up.x(), up.y(), up.z());
00094 }
00095 
00096 void CarCamera::posttick()
00097 {
00098     const float blend = 0.3;
00099     btTransform car_transform;
00100     car.get_transform(car_transform);
00101     btTransform car_rotation_transform = car_transform;
00102     car_rotation_transform.setOrigin(btVector3(0, 0, 0));
00103     // find a new place behind the car looking at it.
00104     btVector3 new_position(car_transform(btVector3(0.0, -0.70, car.get_camera_height())));
00105     btVector3 new_up(car_rotation_transform(btVector3(0.0, 0.0, 1.0)));
00106     btVector3 new_centre = car_transform(btVector3(0.0, 1.0, 0.1));
00107     
00108     // blend new position with the last camera position to soften motion.
00109     m_velocity = location;
00110     location = location.lerp(new_position, blend);
00111     m_velocity -= location;
00112     up = up.lerp(new_up, blend);
00113     up.normalize();
00114     centre = centre.lerp(new_centre, blend);
00115     
00116     // set sound listener to this position, orientation, and velocity.
00117     m_listener.set_velocity(m_velocity * 100.0);
00118     m_listener.set_position(location, centre - location, up);
00119 }
00120 
00121 void CarCamera::update_occlusion_tester(Track::OcclusionTester & occlusion_tester, btScalar aspect) const
00122 {
00123     // front plane
00125     
00126     btVector3 front_normal = (centre - location).normalized();
00127     // find the distance to it along this normal.
00128     btScalar front_distance = (-location).dot(front_normal);
00129     occlusion_tester.plane_vectors[0] = front_normal;
00130     occlusion_tester.plane_distances[0] = front_distance;
00131     
00132     btVector3 sideways = up.cross(front_normal).normalized();
00133     btVector3 real_up = sideways.cross(front_normal);
00134     
00135     // side planes
00136     // fovy = 65 degrees = 1.134464014 radians.
00137     btScalar half_fovy = 0.567232006;
00138     const Graphics::Window window = Graphics::Window::get_instance();
00139     btScalar half_fovx = std::atan(std::tan(half_fovy) * aspect);
00140 
00141     btVector3 left_normal = real_up.cross(btTransform(btQuaternion(real_up, -half_fovx))(front_normal)).normalized();
00142     occlusion_tester.plane_vectors[1] = left_normal;
00143     occlusion_tester.plane_distances[1] = (-location).dot(left_normal);
00144     
00145     btVector3 right_normal = -real_up.cross(btTransform(btQuaternion(real_up, half_fovx))(front_normal)).normalized();
00146     occlusion_tester.plane_vectors[2] = right_normal;
00147     occlusion_tester.plane_distances[2] = (-location).dot(right_normal);
00148     
00149     btVector3 top_normal = sideways.cross(btTransform(btQuaternion(sideways, -half_fovy))(front_normal)).normalized();
00150     occlusion_tester.plane_vectors[3] = top_normal;
00151     occlusion_tester.plane_distances[3] = (-location).dot(top_normal);
00152     
00153     btVector3 bottom_normal = -sideways.cross(btTransform(btQuaternion(sideways, half_fovy))(front_normal)).normalized();
00154     occlusion_tester.plane_vectors[4] = bottom_normal;
00155     occlusion_tester.plane_distances[4] = (-location).dot(bottom_normal);
00156 }
00157 
00158 const btVector3 & CarCamera::get_location() const
00159 {
00160     return location;
00161 }
00162 
00163 const btVector3 & CarCamera::get_velocity() const
00164 {
00165     return m_velocity;
00166 }
00167 
00168 }

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:12 2010 by Doxygen version 1.4.7 for Racer version svn335.