1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
2 | /* |
---|
3 | * ---------------------------------------------------------------------- |
---|
4 | * NvCamera.cpp : NvCamera class |
---|
5 | * |
---|
6 | * ====================================================================== |
---|
7 | * AUTHOR: Wei Qiao <qiaow@purdue.edu> |
---|
8 | * Purdue Rendering and Perceptualization Lab (PURPL) |
---|
9 | * |
---|
10 | * Copyright (c) 2004-2012 HUBzero Foundation, LLC |
---|
11 | * |
---|
12 | * See the file "license.terms" for information on usage and |
---|
13 | * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
14 | * ====================================================================== |
---|
15 | */ |
---|
16 | #include <stdio.h> |
---|
17 | #include <math.h> |
---|
18 | #include <float.h> |
---|
19 | |
---|
20 | #include <GL/glew.h> |
---|
21 | #include <GL/glu.h> |
---|
22 | |
---|
23 | #include <vrmath/vrQuaternion.h> |
---|
24 | #include <vrmath/vrRotation.h> |
---|
25 | #include <vrmath/vrMatrix4x4f.h> |
---|
26 | |
---|
27 | #include "NvCamera.h" |
---|
28 | #include "Trace.h" |
---|
29 | |
---|
30 | static inline float deg2rad(float deg) |
---|
31 | { |
---|
32 | return ((deg * M_PI) / 180.); |
---|
33 | } |
---|
34 | |
---|
35 | static inline float rad2deg(float rad) |
---|
36 | { |
---|
37 | return ((rad * 180.) / M_PI); |
---|
38 | } |
---|
39 | |
---|
40 | NvCamera::NvCamera(int startx, int starty, int w, int h, |
---|
41 | float loc_x, float loc_y, float loc_z) : |
---|
42 | _location(loc_x, loc_y, loc_z), |
---|
43 | _fov(30.0), |
---|
44 | _near(0.1), |
---|
45 | _far(50.0), |
---|
46 | _width(w), |
---|
47 | _height(h), |
---|
48 | _startX(startx), |
---|
49 | _startY(starty) |
---|
50 | { |
---|
51 | } |
---|
52 | |
---|
53 | void |
---|
54 | NvCamera::setClippingRange(const Vector3& bboxMin, const Vector3& bboxMax) |
---|
55 | { |
---|
56 | // Transform bounds by modelview matrix |
---|
57 | GLfloat mv[16]; |
---|
58 | glGetFloatv(GL_MODELVIEW_MATRIX, mv); |
---|
59 | Mat4x4 modelView = Mat4x4(mv); |
---|
60 | Vector4 bboxEye[8]; |
---|
61 | bboxEye[0] = Vector4(bboxMin.x, bboxMin.y, bboxMin.z, 1); |
---|
62 | bboxEye[1] = Vector4(bboxMax.x, bboxMin.y, bboxMin.z, 1); |
---|
63 | bboxEye[2] = Vector4(bboxMin.x, bboxMax.y, bboxMin.z, 1); |
---|
64 | bboxEye[3] = Vector4(bboxMin.x, bboxMin.y, bboxMax.z, 1); |
---|
65 | bboxEye[4] = Vector4(bboxMax.x, bboxMax.y, bboxMin.z, 1); |
---|
66 | bboxEye[5] = Vector4(bboxMax.x, bboxMin.y, bboxMax.z, 1); |
---|
67 | bboxEye[6] = Vector4(bboxMin.x, bboxMax.y, bboxMax.z, 1); |
---|
68 | bboxEye[7] = Vector4(bboxMax.x, bboxMax.y, bboxMax.z, 1); |
---|
69 | double zMin = DBL_MAX; |
---|
70 | double zMax = -DBL_MAX; |
---|
71 | for (int i = 0; i < 8; i++) { |
---|
72 | Vector4 eyeVert = modelView.transform(bboxEye[i]); |
---|
73 | if (eyeVert.z < zMin) zMin = eyeVert.z; |
---|
74 | if (eyeVert.z > zMax) zMax = eyeVert.z; |
---|
75 | } |
---|
76 | if (zMax > 0.0) { |
---|
77 | zMax = -.001; |
---|
78 | } |
---|
79 | if (zMin > 0.0) { |
---|
80 | zMin = -50.0; |
---|
81 | } |
---|
82 | _near = -zMax; |
---|
83 | _far = -zMin; |
---|
84 | |
---|
85 | TRACE("Resetting camera clipping range to: near: %g, far: %g\n", _near, _far); |
---|
86 | |
---|
87 | glMatrixMode(GL_PROJECTION); |
---|
88 | glLoadIdentity(); |
---|
89 | gluPerspective(_fov, |
---|
90 | (GLdouble)(_width - _startX)/(GLdouble)(_height - _startY), |
---|
91 | _near, _far); |
---|
92 | glMatrixMode(GL_MODELVIEW); |
---|
93 | } |
---|
94 | |
---|
95 | void |
---|
96 | NvCamera::initialize() |
---|
97 | { |
---|
98 | TRACE("camera: %d, %d\n", _width, _height); |
---|
99 | glViewport(_startX, _startY, _width, _height); |
---|
100 | glMatrixMode(GL_PROJECTION); |
---|
101 | glLoadIdentity(); |
---|
102 | gluPerspective(_fov, |
---|
103 | (GLdouble)(_width - _startX)/(GLdouble)(_height - _startY), |
---|
104 | _near, _far); |
---|
105 | |
---|
106 | glMatrixMode(GL_MODELVIEW); |
---|
107 | glLoadIdentity(); |
---|
108 | |
---|
109 | glTranslatef(-_location.x, -_location.y, -_location.z); |
---|
110 | glMultMatrixf((const GLfloat *)_cameraMatrix.get()); |
---|
111 | } |
---|
112 | |
---|
113 | void NvCamera::rotate(double *quat) |
---|
114 | { |
---|
115 | vrQuaternion q(quat[0], quat[1], quat[2], quat[3]); |
---|
116 | vrRotation rot; |
---|
117 | rot.set(q); |
---|
118 | _cameraMatrix.makeRotation(rot); |
---|
119 | _cameraMatrix.transpose(); |
---|
120 | TRACE("Set rotation to quat: %g %g %g %g\n", |
---|
121 | quat[0], quat[1], quat[2], quat[3]); |
---|
122 | } |
---|
123 | |
---|
124 | void NvCamera::rotate(float angleX, float angleY, float angleZ) |
---|
125 | { |
---|
126 | angleX = -angleX; |
---|
127 | angleY = angleY - 180.; |
---|
128 | |
---|
129 | _cameraMatrix.makeRotation(1, 0, 0, deg2rad(angleX)); |
---|
130 | vrMatrix4x4f mat; |
---|
131 | mat.makeRotation(0, 1, 0, deg2rad(angleY)); |
---|
132 | _cameraMatrix.multiply(mat); |
---|
133 | mat.makeRotation(0, 0, 1, deg2rad(angleZ)); |
---|
134 | _cameraMatrix.multiply(mat); |
---|
135 | //_cameraMatrix.transpose(); |
---|
136 | |
---|
137 | TRACE("Set rotation to angles: %g %g %g\n", |
---|
138 | angleX, angleY, angleZ); |
---|
139 | } |
---|