added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / src / 3dengfx / camera.cpp
1 /*
2 This file is part of the 3dengfx, realtime visualization system.
3
4 Copyright (c) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
5
6 3dengfx is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 3dengfx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with 3dengfx; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "3dengfx_config.h"
22
23 #include "camera.hpp"
24 #include "3denginefx.hpp"
25
26 Camera::Camera(const Vector3 &translation, const Quaternion &rot) 
27         : BaseCamera(translation, rot) {}
28
29 Matrix4x4 Camera::get_camera_matrix(unsigned long msec) const {
30         PRS prs = get_prs(msec);
31
32         Matrix4x4 vmat = prs.rotation.inverse().get_rotation_matrix();
33         vmat.translate(-prs.position);
34
35         // TODO: this does not work...
36         Matrix4x4 flip_matrix;
37         if(flip_view.x) flip_matrix[0][0] = -1;
38         if(flip_view.y) flip_matrix[1][1] = -1;
39         if(flip_view.z) flip_matrix[2][2] = -1;
40
41         return flip_matrix * vmat;
42 }
43 /*
44 void Camera::activate(unsigned long msec) const {
45         set_matrix(XFORM_VIEW, get_camera_matrix(msec));
46
47         Matrix4x4 proj = get_projection_matrix();
48         set_matrix(XFORM_PROJECTION, proj);
49
50         engfx_state::view_mat_camera = this;
51         const_cast<Camera*>(this)->setup_frustum(proj * engfx_state::view_matrix);
52 }
53 */
54
55 TargetCamera::TargetCamera(const Vector3 &trans, const Vector3 &target) : Camera(trans) {
56         set_target(target);
57 }
58
59 TargetCamera::~TargetCamera() {}
60
61 void TargetCamera::set_target(const Vector3 &target) {
62         this->target.set_position(target);
63 }
64
65 Vector3 TargetCamera::get_target(unsigned long msec) const {
66         return target.get_prs(msec).position;
67 }
68
69 Matrix4x4 TargetCamera::get_camera_matrix(unsigned long msec) const {
70         PRS prs = get_prs(msec);
71         Vector3 targ = target.get_prs(msec).position;
72
73         Vector3 pvec = prs.position - targ;
74         pvec.transform(prs.rotation.get_rotation_matrix());
75         Vector3 pos = targ + pvec;
76
77 #ifdef COORD_LHS
78         Vector3 n = (targ - pos).normalized();
79 #else
80         Vector3 n = -(targ - pos).normalized();
81 #endif
82         Vector3 u = cross_product(up, n).normalized();
83         Vector3 v;
84         
85         if(flip_view.y) {
86                 v = cross_product(u, n);
87                 set_front_face(ORDER_CCW);
88         } else {
89                 v = cross_product(n, u);
90                 set_front_face(ORDER_CW);
91         }
92
93         scalar_t tx = -dot_product(u, pos);
94         scalar_t ty = -dot_product(v, pos);
95         scalar_t tz = -dot_product(n, pos);
96         
97         return Matrix4x4(u.x, u.y, u.z, tx,
98                                         v.x, v.y, v.z, ty,
99                                         n.x, n.y, n.z, tz,
100                                         0.0, 0.0, 0.0, 1.0);
101 }
102
103 /*
104 void TargetCamera::activate(unsigned long msec) const {
105         set_matrix(XFORM_VIEW, get_camera_matrix(msec));
106
107         Matrix4x4 proj = get_projection_matrix();
108         set_matrix(XFORM_PROJECTION, proj);
109
110         engfx_state::view_mat_camera = this;
111         const_cast<TargetCamera*>(this)->setup_frustum(proj * engfx_state::view_matrix);
112 }
113 */
114
115 void TargetCamera::zoom(scalar_t factor, unsigned long msec) {
116         Vector3 pos = get_prs(msec).position;
117         Vector3 targ = get_target(msec);
118
119         Vector3 dist_vec = (pos - targ) * factor;
120
121         set_position(targ + dist_vec, msec);
122 }
123
124 void TargetCamera::roll(scalar_t angle, unsigned long msec) {
125         Vector3 axis = target.get_prs(msec).position - get_prs(msec).position;
126         Quaternion q(axis.normalized(), fmod(angle, two_pi));
127         up = Vector3(0, 1, 0);
128         up.transform(q);
129 }