Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix camera rotation

  • Loading branch information...
commit 46beac4e839d73995ef77e2259e8f5c1c7e755d1 1 parent 97c7c32
@tenko authored
Showing with 36 additions and 22 deletions.
  1. +13 −20 geotools/@src/Camera.pxi
  2. +23 −2 geotools/@src/Transform.pxi
View
33 geotools/@src/Camera.pxi
@@ -182,16 +182,19 @@ cdef class Camera:
'''
Rotate camera and update frame.
'''
- cdef Transform rot = Transform()
-
if center is None:
center = self.target
-
- rot.rotateAxisCenter(angle, axis, center)
- self.loc.set(rot.map(self.loc))
- self.dir.set(rot.map(-self.Z))
+ cdef double d = self.loc.distanceTo(center)
+ cdef Quaternion rot = Quaternion.fromAngleAxis(angle, axis)
+
self.up.set(rot.map(self.Y))
+ self.up.unit()
+
+ self.dir.set(rot.map(-self.Z))
+ self.dir.unit()
+
+ self.loc.set(center - d*self.dir)
self.updateFrame()
cpdef rotateDeltas(self, double dx, double dy, double speed = 400, Point target = None):
@@ -199,22 +202,12 @@ cdef class Camera:
Rotate camera according to dx, dy
mouse motion.
'''
- cdef Transform r1
- cdef Transform r2
-
if target is None:
target = self.target
-
- # limit motion
- cdef double sx = copysign(1., dx)
- dx = sx*fmin(15., fabs(dx))
- cdef double sy = copysign(1., dy)
- dy = sy*fmin(15., fabs(dy))
-
- r1 = Transform().rotateAxisCenter(dx/speed*M_PI, Zaxis, target)
- r2 = Transform().rotateAxisCenter(dy/speed*M_PI, self.X, target)
- cdef Transform rot = r1 * r2
+ cdef Quaternion q1 = Quaternion.fromAngleAxis(dx/speed*M_PI, Zaxis)
+ cdef Quaternion q2 = Quaternion.fromAngleAxis(dy/speed*M_PI, self.X)
+ cdef Quaternion rot = q1 * q2
cdef double d = self.loc.distanceTo(target)
@@ -226,7 +219,7 @@ cdef class Camera:
self.loc.set(target - d*self.dir)
self.updateFrame()
-
+
cpdef pan(self, int lastx, int lasty, int x, int y, Point target = None):
'''
Pan camera due to mouse motion.
View
25 geotools/@src/Transform.pxi
@@ -1008,15 +1008,36 @@ cdef class Transform:
#cdef Point axis, center
cdef double sin_angle, cos_angle, one_minus_cos_angle
+ self.identity()
+
sin_angle = sin(angle)
cos_angle = cos(angle)
+
+ if abs(sin_angle) >= 1. - SQRT_EPSILON and fabs(cos_angle) <= SQRT_EPSILON:
+ cos_angle = 0.
+ if sin_angle < 0.:
+ sin_angle = -1.
+ else:
+ sin_angle = 1.
+ elif abs(cos_angle) >= 1. - SQRT_EPSILON and fabs(sin_angle) <= SQRT_EPSILON:
+ sin_angle = 0.
+ if cos_angle < 0.:
+ cos_angle = -1.
+ else:
+ cos_angle = 1.
+ elif fabs(cos_angle*cos_angle + sin_angle*sin_angle - 1.0) > SQRT_EPSILON:
+ cs = Vector(cos_angle, sin_angle, 0.)
+ cs.unit()
+ cos_angle = cs.x
+ sin_angle = cs.y
+
one_minus_cos_angle = 1. - cos_angle
center = Point(_center)
axis = Vector(_axis)
- if angle != 0.:
- if abs(axis.lengthSquared - 1.) > EPSILON:
+ if sin_angle != 0. or cos_angle != 1.:
+ if fabs(axis.lengthSquared - 1.) > EPSILON:
axis.unit()
self.m[0][0] = axis.x*axis.x*one_minus_cos_angle + cos_angle

0 comments on commit 46beac4

Please sign in to comment.
Something went wrong with that request. Please try again.