Skip to content

Commit 136045f

Browse files
author
tpat
committed
Merge remote-tracking branch 'haydelj/cameraSaveFix' into dipole_movement.
Rotate/scale/translate are working. All widget parts update together. Fixed arcball and lighting update while rotating
2 parents 6501e02 + 06f1979 commit 136045f

Some content is hidden

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

57 files changed

+1314
-1236
lines changed
Lines changed: 33 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
#include "ArcBall.hpp"
2+
#include <iostream>
23

34
namespace spire {
45

56
//------------------------------------------------------------------------------
6-
ArcBall::ArcBall(const glm::vec3& center, glm::float_t radius, const glm::mat4& screenToTCS) :
7+
ArcBall::ArcBall(const glm::vec3& center, glm::float_t radius, bool inverted, const glm::mat4& screenToTCS) :
8+
mScreenToTCS(screenToTCS),
9+
invertHemisphere(inverted),
710
mCenter(center),
8-
mRadius(radius),
9-
mScreenToTCS(screenToTCS)
11+
mRadius(radius)
1012
{
1113
// glm uses the following format for quaternions: w,x,y,z.
1214
// w, x, y, z
1315
glm::quat qOne(1.0, 0.0, 0.0, 0.0);
1416
glm::vec3 vZero(0.0, 0.0, 0.0);
1517

16-
mVDown = vZero;
17-
mVNow = vZero;
18-
mQDown = qOne;
19-
mQNow = qOne;
18+
mQDown = qOne;
19+
mQNow = qOne;
20+
mVSphereDown = mouseOnSphere(vZero);
2021
}
2122

2223
//------------------------------------------------------------------------------
@@ -28,86 +29,66 @@ glm::vec3 ArcBall::mouseOnSphere(const glm::vec3& tscMouse)
2829
ballMouse.x = (tscMouse.x - mCenter.x) / mRadius;
2930
ballMouse.y = (tscMouse.y - mCenter.y) / mRadius;
3031

31-
glm::float_t mag = glm::dot(ballMouse, ballMouse);
32-
if (mag > 1.0)
32+
glm::float_t mag_sq = glm::dot(ballMouse, ballMouse);
33+
if (mag_sq > 1.0)
3334
{
34-
// Since we are outside of the sphere, map to the visible boundary of
35-
// the sphere.
36-
ballMouse *= 1.0 / sqrtf(mag);
37-
ballMouse.z = 0.0;
35+
// Since we are outside of the sphere, map to the visible boundary of the sphere.
36+
ballMouse *= 1.0 / sqrtf(mag_sq);
3837
}
3938
else
4039
{
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.
44-
ballMouse.z = sqrtf(1.0 - mag);
40+
// Essentially, we are normalizing the vector by adding the missing z component.
41+
ballMouse.z = sqrtf(1.0 - mag_sq);
4542
}
4643

44+
if(invertHemisphere)
45+
ballMouse.z = -ballMouse.z;
46+
4747
return ballMouse;
4848
}
4949

5050
//------------------------------------------------------------------------------
5151
void ArcBall::beginDrag(const glm::vec2& msc)
5252
{
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();
53+
mQDown = mQNow;
54+
mVSphereDown = mouseOnSphere((mScreenToTCS * glm::vec4(msc, 0.0f, 1.0)).xyz());
5955
}
6056

6157
//------------------------------------------------------------------------------
6258
void ArcBall::drag(const glm::vec2& msc)
6359
{
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);
60+
glm::vec3 mVSphereNow = mouseOnSphere((mScreenToTCS * glm::vec4(msc, 0.0, 1.0)).xyz());
6861

6962
// Construct a quaternion from two points on the unit sphere.
70-
mQDrag = quatFromUnitSphere(mVSphereFrom, mVSphereTo);
63+
glm:: quat mQDrag = quatFromUnitSphere(mVSphereDown, mVSphereNow);
7164
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);
65+
if(glm::dot(mVSphereDown, mVSphereNow) < 0.0)
66+
beginDrag(msc);
8067
}
8168

8269
//------------------------------------------------------------------------------
8370
void ArcBall::setLocationOnSphere(glm::vec3 location, glm::vec3 up)
8471
{
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-
72+
glm::mat4 mMatNow = glm::lookAt(location, glm::vec3(0.0f), up);
73+
mQNow = glm::quat_cast(mMatNow);
9374
}
9475

9576
//------------------------------------------------------------------------------
9677
glm::quat ArcBall::quatFromUnitSphere(const glm::vec3& from, const glm::vec3& to)
9778
{
98-
glm::quat q;
99-
q.x = from.y*to.z - from.z*to.y;
100-
q.y = from.z*to.x - from.x*to.z;
101-
q.z = from.x*to.y - from.y*to.x;
102-
q.w = from.x*to.x + from.y*to.y + from.z*to.z;
103-
return q;
79+
glm::vec3 axis = glm::normalize(glm::cross(from, to));
80+
float angle = std::acos(glm::dot(from, to));
81+
82+
if(angle <= 0.00001)
83+
return glm::quat(1.0, 0.0, 0.0, 0.0);
84+
85+
return glm::angleAxis(angle, axis);
10486
}
10587

10688
//------------------------------------------------------------------------------
10789
glm::mat4 ArcBall::getTransformation() const
10890
{
109-
return mMatNow;
91+
return glm::mat4_cast(mQNow);
11092
}
11193

112-
11394
} // namespace spire

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class SCISHARE ArcBall
3535
/// default is 0.75.
3636
/// \param screenToTCS Transformation from screen coordinates
3737
/// to TCS. \p center and \p radius are given in TCS.
38-
ArcBall(const glm::vec3& center, glm::float_t radius,
39-
const glm::mat4& screenToTCS = glm::mat4());
38+
ArcBall(const glm::vec3& center, glm::float_t radius, bool inverted = false,
39+
const glm::mat4& screenToTCS = glm::mat4());
4040

4141
/// Initiate an arc ball drag given the mouse click in screen coordinates.
4242
/// \param mouseScreenCoords Mouse screen coordinates.
@@ -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,18 @@ 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.
76+
bool invertHemisphere;
7177

78+
glm::vec3 mVSphereDown; ///< vDown mapped to the sphere of 'mRadius' centered at 'mCenter' in TCS.
79+
glm::quat mQDown; ///< State of the rotation since mouse down.
7280
glm::quat mQNow; ///< Current state of the rotation taking into account mouse.
7381
///< Essentially QDrag * QDown (QDown is a applied first, just
7482
///< 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.
7883

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;
8884
};
8985

9086
} // 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

0 commit comments

Comments
 (0)