Skip to content

Commit d1e2f2f

Browse files
authored
Merge pull request #1966 from Haydelj/cameraSaveFix
Camera Save Fix/General Fixes
2 parents 1666610 + 5a195b9 commit d1e2f2f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1091
-1103
lines changed

src/Externals/spire/arc-ball/ArcBall.cpp

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@ namespace spire {
44

55
//------------------------------------------------------------------------------
66
ArcBall::ArcBall(const glm::vec3& center, glm::float_t radius, const glm::mat4& screenToTCS) :
7+
mScreenToTCS(screenToTCS),
78
mCenter(center),
8-
mRadius(radius),
9-
mScreenToTCS(screenToTCS)
9+
mRadius(radius)
1010
{
1111
// glm uses the following format for quaternions: w,x,y,z.
1212
// w, x, y, z
1313
glm::quat qOne(1.0, 0.0, 0.0, 0.0);
1414
glm::vec3 vZero(0.0, 0.0, 0.0);
1515

16-
mVDown = vZero;
17-
mVNow = vZero;
18-
mQDown = qOne;
19-
mQNow = qOne;
16+
mQDown = qOne;
17+
mQNow = qOne;
18+
mVSphereDown = mouseOnSphere(vZero);
2019
}
2120

2221
//------------------------------------------------------------------------------
@@ -31,16 +30,12 @@ glm::vec3 ArcBall::mouseOnSphere(const glm::vec3& tscMouse)
3130
glm::float_t mag = glm::dot(ballMouse, ballMouse);
3231
if (mag > 1.0)
3332
{
34-
// Since we are outside of the sphere, map to the visible boundary of
35-
// the sphere.
33+
// Since we are outside of the sphere, map to the visible boundary of the sphere.
3634
ballMouse *= 1.0 / sqrtf(mag);
37-
ballMouse.z = 0.0;
3835
}
3936
else
4037
{
41-
// We are not at the edge of the sphere, we are inside of it.
42-
// Essentially, we are normalizing the vector by adding the missing z
43-
// component.
38+
// Essentially, we are normalizing the vector by adding the missing z component.
4439
ballMouse.z = sqrtf(1.0 - mag);
4540
}
4641

@@ -50,46 +45,25 @@ glm::vec3 ArcBall::mouseOnSphere(const glm::vec3& tscMouse)
5045
//------------------------------------------------------------------------------
5146
void ArcBall::beginDrag(const glm::vec2& msc)
5247
{
53-
// The next two lines are usually a part of end drag. But end drag introduces
54-
// too much statefullness, so we are shortcircuiting it.
55-
mQDown = mQNow;
56-
57-
// Normal 'begin' code.
58-
mVDown = (mScreenToTCS * glm::vec4(msc.x, msc.y, 0.0f, 1.0)).xyz();
48+
mQDown = mQNow;
49+
mVSphereDown = mouseOnSphere((mScreenToTCS * glm::vec4(msc, 0.0f, 1.0)).xyz());
5950
}
6051

6152
//------------------------------------------------------------------------------
6253
void ArcBall::drag(const glm::vec2& msc)
6354
{
64-
// Regular drag code to follow...
65-
mVNow = (mScreenToTCS * glm::vec4(msc.x, msc.y, 0.0, 1.0)).xyz();
66-
mVSphereFrom= mouseOnSphere(mVDown);
67-
mVSphereTo = mouseOnSphere(mVNow);
55+
glm::vec3 mVSphereNow = mouseOnSphere((mScreenToTCS * glm::vec4(msc, 0.0, 1.0)).xyz());
6856

6957
// Construct a quaternion from two points on the unit sphere.
70-
mQDrag = quatFromUnitSphere(mVSphereFrom, mVSphereTo);
58+
glm:: quat mQDrag = quatFromUnitSphere(mVSphereDown, mVSphereNow);
7159
mQNow = mQDrag * mQDown;
72-
73-
// Perform complex conjugate
74-
glm::quat q = mQNow;
75-
q.x = -q.x;
76-
q.y = -q.y;
77-
q.z = -q.z;
78-
q.w = q.w;
79-
mMatNow = glm::mat4_cast(q);
8060
}
8161

8262
//------------------------------------------------------------------------------
8363
void ArcBall::setLocationOnSphere(glm::vec3 location, glm::vec3 up)
8464
{
85-
mMatNow = glm::lookAt(location, glm::vec3(0.0f), up);
86-
glm::quat q = glm::quat_cast(mMatNow);
87-
q.x = -q.x;
88-
q.y = -q.y;
89-
q.z = -q.z;
90-
q.w = q.w;
91-
mQNow = q;
92-
65+
glm::mat4 mMatNow = glm::lookAt(location, glm::vec3(0.0f), up);
66+
mQNow = glm::quat_cast(mMatNow);
9367
}
9468

9569
//------------------------------------------------------------------------------
@@ -106,8 +80,7 @@ glm::quat ArcBall::quatFromUnitSphere(const glm::vec3& from, const glm::vec3& to
10680
//------------------------------------------------------------------------------
10781
glm::mat4 ArcBall::getTransformation() const
10882
{
109-
return mMatNow;
83+
return glm::mat4_cast(mQNow);
11084
}
11185

112-
11386
} // namespace spire

src/Externals/spire/arc-ball/ArcBall.hpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class SCISHARE ArcBall
5757
/// from mQNow.
5858
glm::mat4 getTransformation() const;
5959

60+
glm::quat getQuat() const {return mQNow;}
61+
void setQuat(const glm::quat q) {mQNow = q;}
62+
6063
private:
6164

6265
/// Calculates our position on the ArcBall from 2D mouse position.
@@ -66,25 +69,17 @@ class SCISHARE ArcBall
6669
/// Construct a unit quaternion from two points on the unit sphere.
6770
static glm::quat quatFromUnitSphere(const glm::vec3& from, const glm::vec3& to);
6871

72+
/// Transform from screen coordinates to the target coordinate system.
73+
glm::mat4 mScreenToTCS;
6974
glm::vec3 mCenter; ///< Center of the arcball in target coordinate system.
7075
glm::float_t mRadius; ///< Radius of the arcball in target coordinate system.
7176

77+
glm::vec3 mVSphereDown; ///< vDown mapped to the sphere of 'mRadius' centered at 'mCenter' in TCS.
78+
glm::quat mQDown; ///< State of the rotation since mouse down.
7279
glm::quat mQNow; ///< Current state of the rotation taking into account mouse.
7380
///< Essentially QDrag * QDown (QDown is a applied first, just
7481
///< as in matrix multiplication).
75-
glm::quat mQDown; ///< State of the rotation since mouse down.
76-
glm::quat mQDrag; ///< Dragged transform. Knows nothing of any prior
77-
///< transformations.
7882

79-
glm::vec3 mVNow; ///< Most current TCS position of mouse (during drag).
80-
glm::vec3 mVDown; ///< TCS position of mouse when the drag was begun.
81-
glm::vec3 mVSphereFrom; ///< vDown mapped to the sphere of 'mRadius' centered at 'mCenter' in TCS.
82-
glm::vec3 mVSphereTo; ///< vNow mapped to the sphere of 'mRadius' centered at 'mCenter' in TCS.
83-
84-
glm::mat4 mMatNow; ///< Matrix representing the current rotation.
85-
86-
/// Transform from screen coordinates to the target coordinate system.
87-
glm::mat4 mScreenToTCS;
8883
};
8984

9085
} // namespace spire

src/Externals/spire/arc-look-at/ArcLookAt.cpp

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,7 @@
3535
namespace spire {
3636

3737
//------------------------------------------------------------------------------
38-
ArcLookAt::ArcLookAt() :
39-
mArcBall(new ArcBall(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)),
40-
mCamLookAt(0.0f),
41-
mCamDistance(3.0f),
42-
mReferenceCamDistance(0.0f)
38+
ArcLookAt::ArcLookAt() : mArcBall(new ArcBall(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))
4339
{
4440
}
4541

@@ -51,10 +47,8 @@ ArcLookAt::~ArcLookAt()
5147
//------------------------------------------------------------------------------
5248
void ArcLookAt::doReferenceDown(const glm::vec2& ssPos)
5349
{
54-
mReferenceLookAt = mCamLookAt;
5550
mReferenceScreenPos = ssPos;
56-
mReferenceTransform = getWorldViewTransform();
57-
mReferenceCamDistance = mCamDistance;
51+
mReferenceLookAt = mCamLookAt;
5852

5953
mArcBall->beginDrag(ssPos);
6054
}
@@ -65,10 +59,10 @@ void ArcLookAt::doPan(const glm::vec2& ssPos)
6559
glm::vec2 delta = mReferenceScreenPos - ssPos;
6660
glm::vec2 trans = delta * mCamDistance / 2.0f;
6761

68-
glm::mat4 camRot = mArcBall->getTransformation();
69-
glm::vec3 translation =
70-
static_cast<glm::vec3>(camRot[0]) * trans.x
71-
+ static_cast<glm::vec3>(camRot[1]) * trans.y;
62+
glm::mat4 camRot = glm::affineInverse(mArcBall->getTransformation());
63+
glm::vec3 translation = static_cast<glm::vec3>(camRot[0]) * trans.x
64+
+ static_cast<glm::vec3>(camRot[1]) * trans.y;
65+
7266
mCamLookAt = mReferenceLookAt + translation;
7367
}
7468

@@ -78,21 +72,6 @@ void ArcLookAt::doRotation(const glm::vec2& ssPos)
7872
mArcBall->drag(ssPos);
7973
}
8074

81-
//------------------------------------------------------------------------------
82-
void ArcLookAt::doZoom(glm::float_t camZoom)
83-
{
84-
//mCamDistance += camZoom;
85-
86-
glm::float_t prevDistance = mCamDistance;
87-
camZoom /= 65;
88-
camZoom *= prevDistance;
89-
mCamDistance += camZoom;
90-
if (mCamDistance <= 0)
91-
{
92-
mCamDistance = prevDistance;
93-
}
94-
}
95-
9675
//------------------------------------------------------------------------------
9776
void ArcLookAt::doZoom(glm::float_t camZoom, int zoomSpeed)
9877
{
@@ -102,9 +81,7 @@ void ArcLookAt::doZoom(glm::float_t camZoom, int zoomSpeed)
10281
camZoom *= prevDistance;
10382
mCamDistance += camZoom;
10483
if (mCamDistance <= 0)
105-
{
10684
mCamDistance = prevDistance;
107-
}
10885
}
10986

11087
//------------------------------------------------------------------------------
@@ -115,30 +92,22 @@ void ArcLookAt::doZoom(const glm::vec2& ssPos)
11592
glm::vec2 delta = ssPos - mReferenceScreenPos;
11693
glm::float_t xScale = 4.0f;
11794
glm::float_t yScale = 4.0f;
118-
//mCamDistance = mReferenceCamDistance + (delta.x) * xScale + (-delta.y) * yScale;
11995

12096
glm::float_t prevDistance = mCamDistance;
12197
glm::float_t camZoom = mCamDistance + (delta.x) * xScale + (-delta.y) * yScale;
12298
mCamDistance = camZoom;
12399
if (mCamDistance <= 0)
124-
{
125100
mCamDistance = prevDistance;
126-
}
127101
}
128102

129103
//------------------------------------------------------------------------------
130104
glm::mat4 ArcLookAt::getWorldViewTransform() const
131105
{
132-
glm::mat4 camRot = mArcBall->getTransformation();
133-
glm::mat4 finalTrafo = camRot;
134-
135-
// Translation is a post rotation operation where as zoom is a pre transform
136-
// operation. We should probably ensure the user doesn't scroll passed zero.
137-
// Remember, we are looking down NEGATIVE z.
138-
// NOTE: We are translating both the lookat and the eye point.
139-
// Eyepoint is a function of the lookat, the camera transform, and the
140-
// camera distance.
141-
finalTrafo[3].xyz() = mCamLookAt + static_cast<glm::vec3>(camRot[2]) * mCamDistance;
106+
glm::mat4 finalTrafo;
107+
finalTrafo[3].xyz() = -mCamLookAt;
108+
finalTrafo = mArcBall->getTransformation() * finalTrafo;
109+
finalTrafo[3][2] += -mCamDistance;
110+
142111
return finalTrafo;
143112
}
144113

@@ -161,27 +130,19 @@ void ArcLookAt::autoview(const spire::AABB& bbox, float fov)
161130
}
162131

163132
mCamLookAt = bbox.getCenter();
164-
165-
// We are calculating the distance the camera would need to be away from
166-
// the length of the diagonal of the bbox. See Van Dam, Foley, third edition
167-
// page 304:
168-
169-
// AC = f*tan(O(v)/2)
170-
// => f = AC / tan(O(v)/2)
171-
// Where AC is half the size of the diagonal.
172-
// So, takning into account half the size:
173-
// => f = AC / (2 * tan(O(v) / 2)
174-
175133
mCamDistance = w / (2 * tan(fov / 2.0));
176134
}
177135

178136
//------------------------------------------------------------------------------
179137
void ArcLookAt::setView(const glm::vec3& view, const glm::vec3& up)
180138
{
181139
mReferenceLookAt = mCamLookAt;
182-
glm::vec3 location = mCamDistance * view;
140+
glm::vec3 location = mCamDistance * -view;
183141
mArcBall->setLocationOnSphere(location, up);
184142
mCamLookAt = mReferenceLookAt;
185143
}
186144

145+
glm::quat ArcLookAt::getRotation() const {return mArcBall->getQuat();}
146+
void ArcLookAt::setRotation(const glm::quat q) {mArcBall->setQuat(q);}
147+
187148
} // namespace spire

src/Externals/spire/arc-look-at/ArcLookAt.hpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,9 @@ class SCISHARE ArcLookAt
7575
/// Rotates about the look at position.
7676
void doRotation(const glm::vec2& ssPos);
7777

78-
/// Dollys the camera towards(negative) / away(positive) from the look at
79-
/// point.
80-
void doZoom(glm::float_t camZoom);
81-
8278
/// Dollys the camera towards(negative) / away(positive) from the look at
8379
/// point. With vairiable zoomspeed.
84-
void doZoom(glm::float_t camZoom, int zoomSpeed);
80+
void doZoom(glm::float_t camZoom, int zoomSpeed = 65);
8581

8682
/// Uses a custom function to determine camera zoom. Downwards and to the
8783
/// right increases size, upwards or to the left decreases size
@@ -98,10 +94,15 @@ class SCISHARE ArcLookAt
9894
void setView(const glm::vec3& view, const glm::vec3& up);
9995

10096
/// Retrieves the camera's distance away from the look at point.
101-
glm::float_t getCamDistance() const {return mCamDistance;}
97+
glm::float_t getDistance() const {return mCamDistance;}
98+
void setDistance(const glm::float_t f) {mCamDistance = f;}
10299

103100
/// Retrieves the current lookat point.
104-
glm::vec3 getLookAt() const {return mCamLookAt;}
101+
glm::vec3 getLookAt() const {return mCamLookAt;}
102+
void setLookAt(const glm::vec3 v) {mCamLookAt = v;}
103+
104+
glm::quat getRotation() const;
105+
void setRotation(const glm::quat q);
105106

106107
/// Retrieves the world transformation for the camera (looking down
107108
/// negative z).
@@ -110,14 +111,12 @@ class SCISHARE ArcLookAt
110111
private:
111112
std::unique_ptr<spire::ArcBall> mArcBall;
112113

113-
glm::vec3 mCamLookAt; ///< Current lookat position.
114-
glm::float_t mCamDistance; ///< Distance from look-at.
114+
glm::vec3 mCamLookAt {0.0f}; ///< Current lookat position.
115+
glm::float_t mCamDistance {3.0f}; ///< Distance from look-at.
115116

116117
// The following are reference variables set when doReferenceDown is called.
117118
glm::vec2 mReferenceScreenPos;
118119
glm::vec3 mReferenceLookAt;
119-
glm::mat4 mReferenceTransform;
120-
glm::float_t mReferenceCamDistance;
121120
};
122121

123122
} // namespace spire

src/Externals/spire/es-general/comp/StaticCamera.hpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ namespace gen {
1515
// care anything about the camera itself.
1616
struct StaticCameraData
1717
{
18-
glm::mat4 projIV; // projection * iv
19-
glm::mat4 worldToView; // Inverse view (iv)
20-
glm::mat4 projection; // Projection matrix.
18+
glm::mat4 view;
19+
glm::mat4 projection;
20+
glm::mat4 viewProjection;
2121

2222
// Misc variables. fovy only applies to perspective matrices.
2323
float fovy;
@@ -51,24 +51,23 @@ struct StaticCameraData
5151
winWidth = 0.0f;
5252
}
5353

54-
void setView(const glm::mat4& view)
54+
void setView(const glm::mat4& view_in)
5555
{
56-
worldToView = glm::affineInverse(view);
57-
projIV = projection * worldToView;
56+
view = view_in;
57+
viewProjection = projection * view;
5858
}
5959

60-
void setProjection(const glm::mat4& projectionIn, float fovy_in, float aspect_in,
60+
void setProjection(const glm::mat4& projection_in, float fovy_in, float aspect_in,
6161
float znear_in, float zfar_in)
6262
{
63-
fovy = fovy_in;
64-
aspect = aspect_in;
65-
znear = znear_in;
66-
zfar = zfar_in;
67-
68-
projection = projectionIn;
63+
projection = projection_in;
64+
fovy = fovy_in;
65+
aspect = aspect_in;
66+
znear = znear_in;
67+
zfar = zfar_in;
6968

7069
// Setup frustum details.
71-
float zDist = fabs(zfar - znear);
70+
float zDist = fabs(zfar - znear);
7271
float tanVal = tanf(0.5f * (fovy));
7372
//for (int i = 0; i < mNumFrustumSections + 1; i++)
7473

@@ -214,9 +213,9 @@ struct StaticCameraData
214213
zppHHeight = std::get<1>(halfWH);
215214
}
216215

217-
glm::mat4 getView() const
216+
glm::mat4 getInverseView() const
218217
{
219-
return glm::affineInverse(worldToView);
218+
return glm::affineInverse(view);
220219
}
221220
};
222221

0 commit comments

Comments
 (0)