//(c) Copyright 2008, Scott Vorthmann. All rights reserved. package com.vzome.desktop.controller; import javax.vecmath.Matrix4d; import javax.vecmath.Quat4d; import javax.vecmath.Vector3d; import javax.vecmath.Vector3f; import com.vzome.core.math.RealVector; import com.vzome.core.math.symmetry.Axis; import com.vzome.core.math.symmetry.OrbitSet; /** * Transducer: turns trackball roll events into zone (Axis) change events. * * @author Scott Vorthmann * */ public abstract class ZoneVectorBall { private final CameraController mViewPlatform; private OrbitSet orbits; private Vector3d zoneVector3d; private Axis zone = null; public ZoneVectorBall( CameraController viewModel ) { mViewPlatform = viewModel; } public Axis setOrbits( OrbitSet orbits ) { this .orbits = orbits; return resetToZ(); } public Axis getZone() { return zone; } public Axis resetToZ() { Vector3f Z = new Vector3f( 0f, 0f, 1f ); mViewPlatform .mapViewToWorld( Z ); zoneVector3d = new Vector3d( Z.x, Z.y, Z.z ); mapVectorToAxis(); return zone; } public void trackballRolled( Quat4d roll ) { mViewPlatform .getWorldRotation( roll ); Matrix4d rollM = new Matrix4d(); rollM.set( roll ); // roll is now a rotation in world coordinates rollM.transform( zoneVector3d ); mapVectorToAxis(); } /** * This is used when we're doing some non-trackball drag * to define a new vector, as for the working plane. * @param vector */ public void setVector( Vector3d vector ) { zoneVector3d = vector; mapVectorToAxis(); } private void mapVectorToAxis() { RealVector vector = new RealVector( zoneVector3d.x, zoneVector3d.y, zoneVector3d.z ); Axis oldAxis = zone; zone = orbits .getAxis( vector ); if ( zone == null && oldAxis == null ) return; if ( zone != null && zone .equals( oldAxis ) ) return; zoneChanged( oldAxis, zone ); } protected abstract void zoneChanged( Axis oldZone, Axis newZone ); }