From a185c11f2397c0296a4b62cc266b4fa00a63c1e2 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 14 May 2008 21:07:10 +0000 Subject: console, camera & interpolation --- src/client/camera.cc | 129 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 28 deletions(-) (limited to 'src/client/camera.cc') diff --git a/src/client/camera.cc b/src/client/camera.cc index 29310fc..21bf930 100644 --- a/src/client/camera.cc +++ b/src/client/camera.cc @@ -28,6 +28,7 @@ math::Vector3f target; math::Vector3f eye; math::Axis axis; +const float MIN_DELTA = 10e-10; // current camera mode Mode mode; @@ -86,10 +87,18 @@ void set_mode(Mode newmode) { target_pitch = 0.0f; distance = 0.4f; + axis.clear(); + switch(newmode) { case Track: // switch camera to Track mode mode = Track; + if (core::localcontrol()) { + if (core::localcontrol()->state()) + axis.assign(core::localcontrol()->state()->axis()); + else + axis.assign(core::localcontrol()->axis()); + } break; case Free: @@ -148,7 +157,7 @@ void next_mode() void draw(float seconds) { math::Matrix4f matrix; - + math::Axis target_axis; float d = 0; if (!core::localcontrol()) { @@ -165,37 +174,102 @@ void draw(float seconds) distance = 20.0f; } else { - if (mode == Overview) set_mode(Track); if (core::localcontrol()->state()) { target.assign(core::localcontrol()->state()->location()); - axis.assign(core::localcontrol()->state()->axis()); + target_axis.assign(core::localcontrol()->state()->axis()); } else { target.assign(core::localcontrol()->location()); - axis.assign(core::localcontrol()->axis()); + target_axis.assign(core::localcontrol()->axis()); } - + if (mode == Track) { - if (core::localcontrol()->state() && core::localcontrol()->model()) { - target -= (core::localcontrol()->model()->maxbbox().x + 0.15f) * core::localcontrol()->state()->axis().forward(); - - target += (core::localcontrol()->model()->maxbbox().z + 0.3f ) * - core::localcontrol()->state()->axis().up(); + float cosangle; + float angle; + float side; + float u; + const float cam_speed = seconds * 4 ; + + math::Vector3f n; + math::Vector3f p; + + // camera axis: pitch + + // project target_axis.up() into the plane with axis->left() normal + n = axis.left(); + p = target_axis.up(); + u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]); + p = target_axis.up() + u * n; + + side = axis.forward().x * p.x + + axis.forward().y * p.y + + axis.forward().z * p.z; + + if ((fabs(side) - MIN_DELTA > 0)) { + + cosangle = math::dotproduct(p, axis.up()); + if (fabs(cosangle) + MIN_DELTA < 1 ) { + angle = acos(cosangle) * 180.0f / M_PI; + angle = math::sgnf(side) * angle * cam_speed; + axis.change_pitch(-angle); + } } - // make the camera swing while turning - target_direction = core::localcontrol()->target_direction; - target_pitch = core::localcontrol()->target_pitch; + // camera axis: direction + + // project target_axis.forward() into the plane with axis.up() normal + n = axis.up(); + p = target_axis.forward(); + u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]); + p = target_axis.forward() + u * n; + + side = axis.left().x * p.x + + axis.left().y * p.y + + axis.left().z * p.z; + + if ((fabs(side) - MIN_DELTA > 0)) { + + cosangle = math::dotproduct(p, axis.forward()); + if (fabs(cosangle) + MIN_DELTA < 1 ) { + angle = acos(cosangle) * 180.0f / M_PI; + angle = math::sgnf(side) * angle * cam_speed; + axis.change_direction(angle); + } + } - yaw_target = - 30 * target_direction; - pitch_target = - 30 * target_pitch; - //pitch_target = pitch_track - 30 * target_pitch; + // camera axis: roll + + // project target_axis.up() into the plane with axis.forward() normal + n = axis.forward(); + p = target_axis.up(); + u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]); + p = target_axis.up() + u * n; + + side = axis.left().x * p.x + + axis.left().y * p.y + + axis.left().z * p.z; + + if ((fabs(side) - MIN_DELTA > 0)) { + + cosangle = math::dotproduct(p, axis.up()); + if (fabs(cosangle) + MIN_DELTA < 1 ) { + angle = acos(cosangle) * 180.0f / M_PI; + angle = math::sgnf(side) * angle * cam_speed; + axis.change_roll(angle); + } + } distance = 0.0f; + if (core::localcontrol()->model()) { + target -= (core::localcontrol()->model()->maxbbox().x + 0.1f) * axis.forward(); + target += (core::localcontrol()->model()->maxbbox().z + 0.1f ) * axis.up(); + } + } else if (mode == Free) { + axis.assign(target_axis); yaw_target = yaw_current - 90 * target_direction; pitch_target = pitch_current - 90 * target_pitch; @@ -205,26 +279,25 @@ void draw(float seconds) } else { distance = 1.0f; } - - } else if (mode == Cockpit) { - if (core::localcontrol()->state() && core::localcontrol()->model()) - target += (core::localcontrol()->model()->maxbbox().x+0.05) * - core::localcontrol()->state()->axis().forward(); - - distance = 0.0f; - } - - if (mode != Cockpit) { // adjust direction d = degrees180f(yaw_current - yaw_target); yaw_current = degrees360f( yaw_current - d * seconds); axis.change_direction(yaw_current); - // adjust pitch target + // adjust pitch d = degrees180f(pitch_current - pitch_target); - pitch_current = degrees360f(pitch_current - d *seconds); + pitch_current = degrees360f(pitch_current - d * seconds); axis.change_pitch(pitch_current); + + } else if (mode == Cockpit) { + axis.assign(target_axis); + + if (core::localcontrol()->state() && core::localcontrol()->model()) + target += (core::localcontrol()->model()->maxbbox().x+0.05) * + core::localcontrol()->state()->axis().forward(); + + distance = 0.0f; } } -- cgit v1.2.3