We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TrackballControls works fine but I think Orbit is better so I've made a simple port of Orbit.js, you are free to use it
// bartolomiew package thothbot.parallax.core.client.controls; import thothbot.parallax.core.shared.core.Object3D; import thothbot.parallax.core.shared.math.Vector2; import thothbot.parallax.core.shared.math.Vector3; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.ContextMenuEvent; import com.google.gwt.event.dom.client.ContextMenuHandler; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.dom.client.MouseWheelEvent; import com.google.gwt.event.dom.client.MouseWheelHandler; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; public class OrbitControls extends Controls implements MouseMoveHandler, MouseDownHandler, MouseUpHandler, KeyDownHandler, KeyUpHandler, ContextMenuHandler, MouseWheelHandler { private enum STATE { NONE, ROTATE, ZOOM, PAN }; private boolean enabled = true; private Vector3 center = new Vector3(); private boolean isZoom = true; private double userZoomSpeed = 1.0; private boolean isRotate = true; private double userRotateSpeed = 1.0; private boolean isPan = true; private double userPanSpeed = 2.0; private boolean autoRotate = false; private double autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 private double minPolarAngle = 0; // radians private double maxPolarAngle = Math.PI; // radians private double minDistance = 0; private double maxDistance = Double.MAX_VALUE; // 65 /*A*/, 83 /*S*/, 68 /*D*/ // this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40, ROTATE: 65, ZOOM: 83, PAN: 68 }; private int keyRotate = 65; // A private int keyZoom = 83; // S private int keyPan = 68; // D private Vector2 rotateStart; private Vector2 rotateEnd; private Vector2 rotateDelta; private Vector2 zoomStart; private Vector2 zoomEnd; private Vector2 zoomDelta; private Vector3 lastPosition; private double phiDelta; private double thetaDelta; private double scale; private boolean isKeyPressed = false; private STATE state = STATE.NONE; private static final double EPS = 0.000001; private static final double PIXELS_PER_ROUND = 1800; public OrbitControls(Object3D object, Widget widget) { super(object, widget); if(getWidget().getClass() != RootPanel.class) getWidget().getElement().setAttribute( "tabindex", "-1" ); rotateStart = new Vector2(); rotateEnd = new Vector2(); rotateDelta = new Vector2(); zoomStart = new Vector2(); zoomEnd = new Vector2(); zoomDelta = new Vector2(); phiDelta = 0; thetaDelta = 0; scale = 1; lastPosition = new Vector3(); getWidget().addDomHandler(this, ContextMenuEvent.getType()); getWidget().addDomHandler(this, MouseMoveEvent.getType()); getWidget().addDomHandler(this, MouseDownEvent.getType()); getWidget().addDomHandler(this, MouseUpEvent.getType()); getWidget().addDomHandler(this, MouseWheelEvent.getType()); RootPanel.get().addDomHandler(this, KeyDownEvent.getType()); RootPanel.get().addDomHandler(this, KeyUpEvent.getType()); } @Override public void onContextMenu(ContextMenuEvent event) { event.preventDefault(); } @Override public void onKeyUp(KeyUpEvent event) { if ( !enabled ) return; state = STATE.NONE; } @Override public void onKeyDown(KeyDownEvent event) { if ( !enabled ) return; if ( !isPan ) return; if ( state != STATE.NONE ) { return; } else if ( event.getNativeEvent().getKeyCode() == this.keyRotate && this.isRotate ) { state = STATE.ROTATE; } else if ( event.getNativeEvent().getKeyCode() == this.keyZoom && this.isZoom ) { state = STATE.ZOOM; } else if ( event.getNativeEvent().getKeyCode() == this.keyPan && this.isPan ) { state = STATE.PAN; } if ( state != STATE.NONE ) this.isKeyPressed = true; } @Override public void onMouseUp(MouseUpEvent event) { if ( !enabled ) return; if ( !isRotate ) return; event.preventDefault(); event.stopPropagation(); this.state = STATE.NONE; } @Override public void onMouseDown(MouseDownEvent event) { if ( !enabled ) return; if ( !isRotate ) return; event.preventDefault(); event.stopPropagation(); if ( state == STATE.NONE ) { if ( event.getNativeButton() == NativeEvent.BUTTON_LEFT && this.isRotate ) { state = STATE.ROTATE; } else if ( event.getNativeButton() == NativeEvent.BUTTON_MIDDLE && this.isZoom ) { state = STATE.ZOOM; } else if ( event.getNativeButton() == NativeEvent.BUTTON_RIGHT && this.isPan ) { state = STATE.PAN; } } if ( state == STATE.ROTATE ) { rotateStart.set( event.getClientX(), event.getClientY() ); } else if ( state == STATE.ZOOM ) { zoomStart.set( event.getClientX(), event.getClientY() ); } else if ( state == STATE.PAN ) { } } private int previousX; private int previousY; @Override public void onMouseMove(MouseMoveEvent event) { if ( !enabled ) return; event.preventDefault(); previousX = event.getClientX(); previousY = event.getClientY(); if ( state == STATE.ROTATE ) { rotateEnd.set( event.getClientX(), event.getClientY() ); rotateDelta.sub( rotateEnd, rotateStart ); rotateLeft( 2 * Math.PI * rotateDelta.getX() / PIXELS_PER_ROUND * userRotateSpeed ); rotateUp( 2 * Math.PI * rotateDelta.getY() / PIXELS_PER_ROUND * userRotateSpeed ); rotateStart.copy( rotateEnd ); } else if ( state == STATE.ZOOM ) { zoomEnd.set( event.getClientX(), event.getClientY() ); zoomDelta.sub( zoomEnd, zoomStart ); if ( zoomDelta.getY() > 0 ) { zoomIn(getZoomScale()); } else { zoomOut(getZoomScale()); } zoomStart.copy( zoomEnd ); } else if ( state == STATE.PAN ) { int movementX = previousX - event.getClientX(); int movementY = previousY - event.getClientY(); pan( new Vector3( - movementX, movementY, 0 ) ); } } @Override public void onMouseWheel(MouseWheelEvent event) { if ( !enabled ) return; if ( !isZoom ) return; int delta = event.getDeltaY(); if ( delta > 0 ) { zoomOut(getZoomScale()); } else { zoomIn(getZoomScale()); } } public void rotateLeft( double angle ) { thetaDelta -= angle; } public void rotateRight( double angle ) { thetaDelta += angle; } public void rotateUp( double angle ) { phiDelta -= angle; } public void rotateDown( double angle ) { phiDelta += angle; } public void zoomIn( double zoomScale ) { scale /= zoomScale; } public void zoomOut( double zoomScale ) { scale *= zoomScale; } public void pan( Vector3 distance ) { distance.transformDirection( getObject().getMatrix() ); distance.multiply( userPanSpeed ); getObject().getPosition().add( distance ); center.add( distance ); } public void update() { Vector3 position = getObject().getPosition(); Vector3 offset = position.clone().sub( this.center ); // angle from z-axis around y-axis double theta = Math.atan2( offset.getX(), offset.getZ() ); // angle from y-axis double phi = Math.atan2( Math.sqrt( offset.getX() * offset.getX() + offset.getZ() * offset.getZ() ), offset.getY() ); if ( this.autoRotate ) { rotateLeft( getAutoRotationAngle() ); } theta += thetaDelta; phi += phiDelta; // restrict phi to be between desired limits phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) ); // restrict phi to be between EPS and PI-EPS phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) ); double radius = offset.length() * scale; // restrict radius to be between desired limits radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) ); offset.setX(radius * Math.sin( phi ) * Math.sin( theta )); offset.setY(radius * Math.cos( phi )); offset.setZ(radius * Math.sin( phi ) * Math.cos( theta )); position.copy( this.center ).add( offset ); getObject().lookAt( this.center ); thetaDelta = 0; phiDelta = 0; scale = 1; if ( lastPosition.distanceTo( getObject().getPosition() ) > 0 ) { lastPosition.copy( getObject().getPosition() ); } } public double getAutoRotationAngle() { return 2 * Math.PI / 60 / 60 * autoRotateSpeed; } public double getZoomScale() { return Math.pow( 0.95, userZoomSpeed ); } }
The text was updated successfully, but these errors were encountered:
Some setters are missing but it enough for the demo I'm working on
Sorry, something went wrong.
Thank you. You can make a pull request to include your code to Parallax. I think it will be in v1.6 or early if we have critical issues.
No branches or pull requests
TrackballControls works fine but I think Orbit is better so I've made a simple port of Orbit.js, you are free to use it
The text was updated successfully, but these errors were encountered: