def interpolate( self, previous, next, segmentFraction ): """Interpolate between first and second by given fragment""" previous = quaternion.fromXYZR( * previous ) next = quaternion.fromXYZR( * next ) new = previous.slerp( next, segmentFraction ) return new.XYZR()
def update(self, newX, newY): """Update with new x,y drag coordinates newX, newY -- the new screen coordinates for the drag returns a new position and quaternion orientation """ # get the drag fractions x, y = self.watcher.fractions(newX, newY) # multiply by the maximum drag angle # note that movement in x creates rotation about y & vice-versa # note that OpenGL coordinates make y reversed from "normal" rotation yRotation, xRotation = x * self.dragAngle, -y * self.dragAngle # calculate the results, keeping in mind that translation in one axis is rotation around the other xRot = quaternion.fromXYZR(*(self.xAxis + (xRotation, ))) yRot = quaternion.fromXYZR(*(self.yAxis + (yRotation, ))) # the vector is already rotated by originalQuaternion # and positioned at the origin, so just needs # the adjusted x + y rotations + un-positioning a = ((xRot * yRot) * self.vector) + self.center b = self.originalQuaternion * xRot * yRot return a, b
def quaternion( self ): """Get summary quaternion for all rotations in stack""" nodes = [ node for node in self if ( isinstance(node, nodetypes.Transforming) and hasattr( node, "orientation") ) ] q = quaternion.Quaternion() for node in nodes: q = q * quaternion.fromXYZR( *node.orientation ) return q
def moveTo(cls, path, context): """Given a node-path to a viewpoint, move context's platform there""" matrix = path.transformMatrix() node = path[-1] platform = context.platform if not platform: platform = context.platform = context.getViewPlatform() if node.jump: position = list(node.position) + [1] newPosition = arrays.dot(position, matrix) newOrientation = (path.quaternion() * quaternion.fromXYZR(*node.orientation)).XYZR() platform.setPosition(newPosition) platform.setOrientation(newOrientation) platform.setFrustum(node.fieldOfView)
def moveTo( cls, path, context ): """Given a node-path to a viewpoint, move context's platform there""" matrix = path.transformMatrix( ) node = path[-1] platform = context.platform if not platform: platform = context.platform = context.getViewPlatform() if node.jump: position = list(node.position)+[1] newPosition = arrays.dot( position, matrix ) newOrientation = ( path.quaternion() * quaternion.fromXYZR( *node.orientation ) ).XYZR() platform.setPosition( newPosition ) platform.setOrientation( newOrientation ) platform.setFrustum( node.fieldOfView )
def setOrientation(self, orientation): """Set the current "camera orientation" orientation -- VRML97-style 4-component orientation, that is, axis as three floats followed by radian rotation as a single float. Alternately, a quaternion.Quaternion instance representing the orientation. Note that the orientation will likely be 180 degrees from what you expect, this method reverses the rotation value when passed a VRML97-style orientation. """ if not isinstance(orientation, quaternion.Quaternion): (x, y, z, r) = orientation orientation = quaternion.fromXYZR(x, y, z, -r) self.quaternion = orientation
def relativeOrientation(self, deltaOrientation=(0, 1, 0, math.pi / 4)): """Calculate rotation within the current orientation In essence, this allows you to "turn your head" which gives you the commonly useful ability to function from your own frame of reference. For example: turn( 1,0,0,angle ) will rotate the camera up from its current view orientation turn( 0,1,0,angle ) will rotate the camera about the current horizon This method is implemented almost entirely within the quaternion class. Quaternion's have considerable advantages for this type of work, as they do not become "warped" with successive rotations. """ x, y, z, r = deltaOrientation x, y, z, garbage = self.quaternion * [x, y, z, 0] return self.quaternion * quaternion.fromXYZR(x, y, z, -r)
def interpolate(self, previous, next, segmentFraction): """Interpolate between first and second by given fragment""" previous = quaternion.fromXYZR(*previous) next = quaternion.fromXYZR(*next) new = previous.slerp(next, segmentFraction) return new.XYZR()