PeriDyno 1.0.0
Loading...
Searching...
No Matches
OrbitCamera.cpp
Go to the documentation of this file.
1#include "OrbitCamera.h"
2
3#include <iostream>
4#include <math.h>
5
6#include <glm/gtc/matrix_transform.hpp>
7#include <glm/gtx/rotate_vector.hpp>
8
9
10namespace dyno
11{
13 : Camera()
14 {
15 mFocusDist = 3.0f;
16 mEyePos = Vec3f(0.0f, 0.0f, 3.0f);
17 mFov = 0.90f;
18
19 this->setClipFar(20.0f);
20 }
21
23 return mEyePos;
24 }
25
27 {
28 return mEyePos + mFocusDist * getViewDir();
29 }
30
32 {
33 Quat1f q(0.0f, mRotAxis);
34 q.w = -q.w;
35
36 //Camera coordinate system
37 Vec3f view = q.rotate(Vec3f(0, 0, 1));
38 Vec3f up = q.rotate(Vec3f(0, 1, 0));
39 Vec3f right = q.rotate(Vec3f(1, 0, 0));
40
41 Vec3f tarPos = getTargetPos();
42
43 Vec3f ND = p - tarPos;
44
45 float d = ND.norm();
46 ND.normalize();
47 if (d > mFocusDistMax) {
48 mEyePos = tarPos - mFocusDistMax * ND;
49 }
50 else {
51 mEyePos = p;
52 }
53
54 mFocusDist = (mEyePos - tarPos).norm();
55 mPitch = acosf(-ND.dot(up)) - M_PI / 2.0f;
56 mYaw = -atan2f(ND.dot(right), ND.dot(view));
57 }
58
60 {
61 Quat1f q(0.0f, mRotAxis);
62 q.w = -q.w;
63
64 //Camera coordinate system
65 Vec3f view = q.rotate(Vec3f(0, 0, 1));
66 Vec3f up = q.rotate(Vec3f(0, 1, 0));
67 Vec3f right = q.rotate(Vec3f(1, 0, 0));
68
69 Vec3f tarPos = p;
70
71 Vec3f ND = mEyePos - tarPos;
72
73 float d = ND.norm();
74 ND.normalize();
75
76 mFocusDist = std::min(mFocusDistMax, (mEyePos - tarPos).norm());
77 mPitch = acosf(-ND.dot(up)) - M_PI / 2.0f;
78 mYaw = -atan2f(ND.dot(right), ND.dot(view));
79 }
80
81 void OrbitCamera::rotate(float dx, float dy)
82 {
83 float newYaw = mYaw + dx;
84 float newPitch = mPitch + dy;
85
86 Quat1f oldQuat = getQuaternion(mYaw, mPitch);
87 oldQuat.w = -oldQuat.w;
88 Vec3f curViewdir = oldQuat.rotate(Vec3f(0, 0, -1));
89 Vec3f eyeCenter = mEyePos + mFocusDist * curViewdir;
90
91 Quat1f newQuat = getQuaternion(newYaw, newPitch);
92 Quat1f q2 = newQuat;
93 q2.w = -q2.w;
94 Quat1f qFinal = q2;
95 //Quat1f qFinal = Quat1f(newPitch, vecX) * q;
96
97 Vec3f newViewdir = q2.rotate(Vec3f(0, 0, -1));
98
99 mEyePos = eyeCenter - mFocusDist * newViewdir;
100
101 mYaw = newYaw;
102 mPitch = newPitch;
103 }
104
107 q.w = -q.w;
108
109 Vec3f viewdir = q.rotate(Vec3f(0, 0, -1));
110 return viewdir;
111 }
112
113 void OrbitCamera::getCoordSystem(Vec3f &view, Vec3f &up, Vec3f &right) const {
115 q.w = -q.w;
116
117 view = q.rotate(Vec3f(0, 0, -1));
118 up = q.rotate(Vec3f(0, 1, 0));
119 right = view.cross(up);
120 }
121
122 void OrbitCamera::translate(const Vec3f translation) {
124 q.w = -q.w;
125
126 Vec3f xax = q.rotate(Vec3f(1, 0, 0));
127 Vec3f yax = q.rotate(Vec3f(0, 1, 0));
128 Vec3f zax = q.rotate(Vec3f(0, 0, 1));
129
130 mEyePos += translation[0] * xax +
131 translation[1] * yax +
132 translation[2] * zax;
133 }
134
135 void OrbitCamera::zoom(float amount) {
136 Quat1f oldQuat = getQuaternion(mYaw, mPitch);
137
138 // calculate the view direction
139 //Quat1f oldQuat(mRotAngle, mRotAxis);
140 oldQuat.w = -oldQuat.w;
141 Vec3f curViewdir = oldQuat.rotate(Vec3f(0, 0, -1));
142
143 Vec3f eyeCenter = mEyePos + mFocusDist * curViewdir;
144
145 float logDist = std::log10(mFocusDist);
146 float logMin = std::log10(mFocusDistMin);
147 float logMax = std::log10(mFocusDistMax);
148 float frac = (logDist - logMax) / (logMax - logMin);
149
150 mFocusDist += mZoomSpeed * amount * std::pow(10.0f, frac);
151 mFocusDist = std::min(std::max(mFocusDist, mFocusDistMin), mFocusDistMax);
152 mEyePos = eyeCenter - mFocusDist * curViewdir;
153 }
154
155 Vec3f OrbitCamera::getPosition(float x, float y) {
156 float r = x*x + y*y;
157 float t = 0.5f * 1 * 1;
158 if (r < t) {
159 Vec3f result(x, y, sqrt(2.0f*t - r));
160 result.normalize();
161 return result;
162 }
163 else {
164 Vec3f result(x, y, t / sqrt(r));
165 result.normalize();
166 return result;
167 }
168 }
169
170 Quat1f OrbitCamera::getQuaternion(float x1, float y1, float x2, float y2) {
171 if ((x1 == x2) && (y1 == y2)) {
172 return Quat1f();
173 }
174 Vec3f pos1 = getPosition(x1, y1);
175 Vec3f pos2 = getPosition(x2, y2);
176 Vec3f rotaxis = pos1.cross(pos2);
177 rotaxis.normalize();
178 float rotangle = 2 * sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
179 return Quat1f(rotangle, rotaxis);
180 }
181
182 Quat1f OrbitCamera::getQuaternion(float yaw, float pitch) const
183 {
184 Quat1f oldQuat = Quat1f(pitch, Vec3f(1.0f, 0.0f, 0.0f)) * Quat1f(yaw, Vec3f(0.0f, 1.0f, 0.0f));
185
186 float rotAngle = mRotAngle;
187 Vec3f rotAxis = mRotAxis;
188
189 oldQuat.toRotationAxis(rotAngle, rotAxis);
190
191 return oldQuat;
192 }
193
194 void OrbitCamera::registerPoint(float x, float y) {
195// mRegX = x;
196// mRegY = y;
197 mRegX = float(x) / float(mViewportWidth);
198 mRegY = float(mViewportHeight - y) / float(mViewportHeight);
199 }
200
202 {
203 Vec3f upDir;// = Vec3f(0, 1, 0);
204 Vec3f viewDir;// = getViewDir();
205 Vec3f rightDir;// = upDir.cross(viewDir).normalize();
206
207 getCoordSystem(viewDir, upDir, rightDir);
208 Vec3f targetPos = mEyePos + mFocusDist * viewDir;
209
210 return glm::lookAt(mEyePos.data_ * mUnitScale, targetPos.data_ * mUnitScale, upDir.data_);
211 }
212
214 {
215 float aspect = std::max(float(mViewportWidth), 1.0f) / std::max(float(mViewportHeight), 1.0f);
216
217 glm::mat4 projection;
218
220 {
221 projection = glm::perspective(mFov, aspect, mNear * mUnitScale, mFar * mUnitScale);
222 }
223 else
224 {
225 float half_depth = (mEyePos - mTargetPos).norm() * mUnitScale;
226 projection = glm::ortho(-half_depth * aspect, half_depth * aspect, -half_depth, half_depth, -5.0f * half_depth, 5.0f* half_depth);
227 }
228
229 return projection;
230 }
231
232
233
234 void OrbitCamera::rotateToPoint(float x, float y) {
235 float tx = float(x) / float(mViewportWidth);
236 float ty = float(mViewportHeight - y) / float(mViewportHeight);
237
238 float dx = tx - mRegX;
239 float dy = ty - mRegY;
240 Quat1f q = getQuaternion(mRegX, mRegY, tx, ty);
241 rotate(mSpeed*dx, -mSpeed * dy);
242
243 registerPoint(x, y);
244 }
245
246 void OrbitCamera::translateToPoint(float x, float y) {
247 float tx = float(x) / float(mViewportWidth);
248 float ty = float(mViewportHeight - y) / float(mViewportHeight);
249
250 float dx = tx - mRegX;
251 float dy = ty - mRegY;
252 float dz = 0;
253 translate(mSpeed*Vec3f(-dx, -dy, -dz));
254
255 registerPoint(x, y);
256 }
257}
#define M_PI
Definition Typedef.inl:36
void setClipFar(float zFar)
Definition Camera.h:39
ProjectionType mProjectionType
Definition Camera.h:70
int mViewportHeight
Definition Camera.h:68
float mNear
Definition Camera.h:63
float mFar
Definition Camera.h:64
float mUnitScale
Definition Camera.h:73
int mViewportWidth
Definition Camera.h:67
@ Perspective
Definition Camera.h:22
float mFov
Definition Camera.h:65
Vec3f getViewDir() const
glm::mat4 getViewMat() override
void getCoordSystem(Vec3f &view, Vec3f &up, Vec3f &right) const
Vec3f getPosition(float x, float y)
Vec3f getEyePos() const override
void rotateToPoint(float x, float y) override
void translate(const Vec3f translation)
glm::mat4 getProjMat() override
void zoom(float amount) override
void translateToPoint(float x, float y) override
void registerPoint(float x, float y) override
void setTargetPos(const Vec3f &p) override
void setEyePos(const Vec3f &p) override
void rotate(float dx, float dy)
Vec3f getTargetPos() const override
Quat1f getQuaternion(float x1, float y1, float x2, float y2)
DYN_FUNC void toRotationAxis(Real &rot, Vector< Real, 3 > &axis) const
Definition Quat.inl:392
Real w
Definition Quat.h:123
DYN_FUNC Vector< Real, 3 > rotate(const Vector< Real, 3 > &v) const
Rotate a vector by the quaternion, guarantee the quaternion is normalized before rotating the vector.
Definition Quat.inl:259
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
Quat< float > Quat1f
Definition Quat.h:136
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
DYN_FUNC Complex< Real > sqrt(const Complex< Real > &)
Definition Complex.inl:321