📄 wandviewbehavior.java
字号:
vpToVirtualScale = Math.sqrt(m16Tmp[0]*m16Tmp[0] + m16Tmp[1]*m16Tmp[1] + m16Tmp[2]*m16Tmp[2]) ; return getPhysicalToVirtualScale() / vpToVirtualScale ; } /** * Translates a coordinate system. * * @param transform the coordinate system to be translated * @param translation the vector by which to translate */ protected void translateTransform(Transform3D transform, Vector3d translation) { transform.get(v3dTmp) ; v3dTmp.add(translation) ; transform.setTranslation(v3dTmp) ; } /** * Transforms the target coordinate system about a center point. * This can be used for rotation and scaling. * * @param target the coordinate system to transform * @param center the center point about which to transform * @param transform the transform to apply */ protected void transformAboutCenter (Transform3D target, Point3d center, Transform3D transform) { // Translate to the center. target.get(v3dTmp) ; v3dTmp.sub(center) ; target.setTranslation(v3dTmp) ; // Apply the transform. target.mul(transform, target) ; // Translate back. target.get(v3dTmp) ; v3dTmp.add(center) ; target.setTranslation(v3dTmp) ; } /** * Equalizes the scale factors in the view tranform, which must be * congruent. If successful, the <code>ViewingPlatform * TransformGroup</code> is updated; otherwise, its transform is reset * to the home transform. This should be called if multiple * incremental scale factors are applied to the view transform. * * @param viewPlatformToVworld the view transform */ protected void conditionViewScale(Transform3D viewPlatformToVworld) { viewPlatformToVworld.normalize() ; viewPlatformToVworld.get(m16Tmp) ; s3Tmp[0] = m16Tmp[0]*m16Tmp[0] + m16Tmp[4]*m16Tmp[4] + m16Tmp[8]*m16Tmp[8] ; s3Tmp[1] = m16Tmp[1]*m16Tmp[1] + m16Tmp[5]*m16Tmp[5] + m16Tmp[9]*m16Tmp[9] ; s3Tmp[2] = m16Tmp[2]*m16Tmp[2] + m16Tmp[6]*m16Tmp[6] + m16Tmp[10]*m16Tmp[10] ; if (s3Tmp[0] == s3Tmp[1] && s3Tmp[0] == s3Tmp[2]) return ; s3Tmp[0] = Math.sqrt(s3Tmp[0]) ; s3Tmp[1] = Math.sqrt(s3Tmp[1]) ; s3Tmp[2] = Math.sqrt(s3Tmp[2]) ; int closestToOne = 0 ; if (Math.abs(s3Tmp[1] - 1.0) < Math.abs(s3Tmp[0] - 1.0)) closestToOne = 1 ; if (Math.abs(s3Tmp[2] - 1.0) < Math.abs(s3Tmp[closestToOne] - 1.0)) closestToOne = 2 ; double scale ; for (int i = 0 ; i < 3 ; i++) { if (i == closestToOne) continue ; scale = s3Tmp[closestToOne] / s3Tmp[i] ; m16Tmp[i+0] *= scale ; m16Tmp[i+4] *= scale ; m16Tmp[i+8] *= scale ; } // Set the view transform and bail out if unsuccessful. viewPlatformToVworld.set(m16Tmp) ; if ((viewPlatformToVworld.getType() & Transform3D.CONGRUENT) == 0) goHome() ; else targetTG.setTransform(viewPlatformToVworld) ; } } /** * Implements a 6DOF sensor button listener to directly manipulate the * view platform transform. The view platform moves in inverse response * to the sensor's position and orientation to give the effect of * attaching the virtual world to the sensor's echo. * @see #setButtonAction6D */ public class GrabViewListener6D extends ListenerBase { private Transform3D t3d = new Transform3D() ; private Transform3D initialVworldToSensor = new Transform3D() ; public void pressed(SensorEvent e) { initAction(e.getSensor()) ; // Save the inverse of the initial sensorToVworld. initialVworldToSensor.invert(sensorToVworld) ; } public void dragged(SensorEvent e) { // Get sensor read relative to the static view at the time of the // button-down. Sensor s = e.getSensor() ; s.getRead(sensorToTracker) ; sensorToVworld.mul(trackerToVworld, sensorToTracker) ; // Solve for T, where T x initialSensorToVworld = sensorToVworld t3d.mul(sensorToVworld, initialVworldToSensor) ; // Move T to the view side by inverting it, and then applying it // to the static view transform. t3d.invert() ; t3d.mul(viewPlatformToVworld) ; targetTG.setTransform(t3d) ; } } /** * Implements a 6DOF sensor button listener that translates the view * platform along the direction the sensor is pointing. * @see #setButtonAction6D * @see #setTranslationSpeed * @see #setAccelerationTime * @see #setConstantSpeedTime * @see #setFastSpeedFactor */ public class TranslationListener6D extends ListenerBase { private long buttonDownTime ; private double speedScaled ; private double interval0 ; private double interval1 ; private double interval2 ; private Vector3d v3d = new Vector3d() ; /** * Construct a new translation button listener for a 6DOF sensor. * * @param reverse if true, translate the view platform backwards; * otherwise, translate the view platform forwards */ public TranslationListener6D(boolean reverse) { // Compute translation speed intervals. interval0 = accelerationTime ; interval1 = interval0 + constantSpeedTime ; interval2 = interval1 + accelerationTime ; // Apply virtual to physical scale if needed. if (translationUnits == VIRTUAL_UNITS) speedScaled = translationSpeed / getPhysicalToVirtualScale() ; else speedScaled = translationSpeed ; if (reverse) { speedScaled = -speedScaled ; } } public void pressed(SensorEvent e) { initAction(e.getSensor()) ; buttonDownTime = e.getTime() ; } public void dragged(SensorEvent e) { long time = e.getTime() ; long lastTime = e.getLastTime() ; double currSpeed, transTime ; double frameTime = 1.0 ; if (translationTimeBase == PER_SECOND) frameTime = (time - lastTime) / 1e9 ; // Compute speed based on acceleration intervals. transTime = (time - buttonDownTime) / 1e9 ; if (transTime <= interval0) { currSpeed = (transTime / accelerationTime) * speedScaled ; } else if (transTime > interval1 && transTime < interval2) { currSpeed = ((((transTime-interval1) / accelerationTime) * (fastSpeedFactor-1.0)) + 1.0) * speedScaled ; } else if (transTime >= interval2) { currSpeed = fastSpeedFactor * speedScaled ; } else { currSpeed = speedScaled ; } // Transform the translation direction (0, 0, -1). v3d.set(0.0, 0.0, -1.0) ; if (nominalSensorRotation != null) nominalSensorRotation.transform(v3d) ; // To avoid echo frame lag, compute sensorToVworld based on // computed trackerToVworld. getSensorToVworld() isn't // current for this frame. Sensor s = e.getSensor() ; s.getRead(sensorToTracker) ; sensorToVworld.mul(trackerToVworld, sensorToTracker) ; sensorToVworld.transform(v3d) ; // Translate the view platform. v3d.scale(frameTime * currSpeed) ; translateTransform(viewPlatformToVworld, v3d) ; targetTG.setTransform(viewPlatformToVworld) ; // Translate trackerToVworld. translateTransform(trackerToVworld, v3d) ; if (readAction6D == ECHO) { // Translate sensor echo to compensate for the new view // platform movement. translateTransform(sensorToVworld, v3d) ; updateEcho(s, sensorToVworld) ; } } } /** * Implements a 6DOF sensor button listener that rotates the view platform * about a Y axis. This axis can be relative to the sensor, user head, or * view platform. The rotation center can be the sensor hotspot or a * fixed point in virtual world coordinates. * * @see #setButtonAction6D * @see #setRotationCoords * @see #setTransformCenterSource * @see #setTransformCenter * @see #setRotationSpeed * @see #setAccelerationTime */ public class RotationListener6D extends ListenerBase { private boolean reverse ; private long buttonDownTime ; private Vector3d axis = new Vector3d() ; private Point3d center = new Point3d() ; private Transform3D t3d = new Transform3D() ; private AxisAngle4d aa4d = new AxisAngle4d() ; private Transform3D headToVworld = new Transform3D() ; private double speedScaled ; protected void initAction(Sensor s) { super.initAction(s) ; if (rotationCoords == HEAD) { view.setUserHeadToVworldEnable(true) ; } } protected void endAction(Sensor s) { super.endAction(s) ; viewPlatformToVworld.normalize() ; targetTG.setTransform(viewPlatformToVworld) ; if (rotationCoords == HEAD) { view.setUserHeadToVworldEnable(false) ; } } /** * Construct a new rotation button listener for a 6DOF sensor. * * @param reverse if true, rotate clockwise; otherwise, rotate * counter-clockwise */ public RotationListener6D(boolean reverse) { this.reverse = reverse ; if (rotationUnits == DEGREES) speedScaled = rotationSpeed * Math.PI / 180.0 ; else speedScaled = rotationSpeed ; } public void pressed(SensorEvent e) { initAction(e.getSensor()) ; buttonDownTime = e.getTime() ; } public void dragged(SensorEvent e) { long time = e.getTime() ; long lastTime = e.getLastTime() ; double currSpeed, transTime ; double frameTime = 1.0 ; if (rotationTimeBase == PER_SECOND) frameTime = (time - lastTime) / 1e9 ; // Compute speed based on acceleration interval. transTime = (time - buttonDownTime) / 1e9 ; if (transTime <= accelerationTime) { currSpeed = (transTime / accelerationTime) * speedScaled ; } else { currSpeed = speedScaled ; } // Set the rotation axis. if (reverse) axis.set(0.0, -1.0, 0.0) ; else axis.set(0.0, 1.0, 0.0) ; // To avoid echo frame lag, compute sensorToVworld based on // computed trackerToVworld. getSensorToVworld() isn't current // for this frame. Sensor s = e.getSensor() ; s.getRead(sensorToTracker) ; sensorToVworld.mul(trackerToVworld, sensorToTracker) ; // Transform rotation axis into target coordinate system. if (rotationCoords == SENSOR) { if (nominalSensorRotation != null) nominalSensorRotation.transform(axis) ; sensorToVworld.transform(axis) ; } else if (rotationCoords == HEAD) { view.getUserHeadToVworld(headToVworld) ; headToVworld.transform(axis) ; } else { viewPlatformToVworld.transform(axis) ; } // Get the rotation center. if (transformCenterSource == HOTSPOT) { s.getHotspot(center) ; sensorToVworld.transform(center) ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -