XYOrthographicCamera.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.android.view.visualization;
00018 
00019 import com.google.common.base.Preconditions;
00020 
00021 import org.ros.math.RosMath;
00022 import org.ros.namespace.GraphName;
00023 import org.ros.rosjava_geometry.FrameTransform;
00024 import org.ros.rosjava_geometry.FrameTransformTree;
00025 import org.ros.rosjava_geometry.Transform;
00026 import org.ros.rosjava_geometry.Vector3;
00027 
00028 import javax.microedition.khronos.opengles.GL10;
00029 
00034 public class XYOrthographicCamera {
00035 
00041   private static final double PIXELS_PER_METER = 100.0;
00042 
00048   private static final Transform ROS_TO_SCREEN_TRANSFORM = Transform.zRotation(Math.PI / 2).scale(
00049       PIXELS_PER_METER);
00050 
00054   private static final float MINIMUM_ZOOM_FACTOR = 0.1f;
00055 
00059   private static final float MAXIMUM_ZOOM_FACTOR = 5.f;
00060 
00061   private final FrameTransformTree frameTransformTree;
00062   private final Object mutex;
00063 
00064   private Viewport viewport;
00065 
00070   private Transform cameraToRosTransform;
00071 
00078   private GraphName frame;
00079 
00080   public XYOrthographicCamera(FrameTransformTree frameTransformTree) {
00081     this.frameTransformTree = frameTransformTree;
00082     mutex = new Object();
00083     resetTransform();
00084   }
00085 
00086   private void resetTransform() {
00087     cameraToRosTransform = Transform.identity();
00088   }
00089 
00090   public void apply(GL10 gl) {
00091     synchronized (mutex) {
00092       OpenGlTransform.apply(gl, ROS_TO_SCREEN_TRANSFORM);
00093       OpenGlTransform.apply(gl, cameraToRosTransform);
00094     }
00095   }
00096 
00097   public boolean applyFrameTransform(GL10 gl, GraphName frame) {
00098     Preconditions.checkNotNull(frame);
00099     if (this.frame != null) {
00100       FrameTransform frameTransform = frameTransformTree.transform(frame, this.frame);
00101       if (frameTransform != null) {
00102         OpenGlTransform.apply(gl, frameTransform.getTransform());
00103         return true;
00104       }
00105     }
00106     return false;
00107   }
00108 
00115   public void translate(double deltaX, double deltaY) {
00116     synchronized (mutex) {
00117       cameraToRosTransform =
00118           ROS_TO_SCREEN_TRANSFORM.invert().multiply(Transform.translation(deltaX, deltaY, 0))
00119               .multiply(getCameraToScreenTransform());
00120     }
00121   }
00122 
00123   private Transform getCameraToScreenTransform() {
00124     return ROS_TO_SCREEN_TRANSFORM.multiply(cameraToRosTransform);
00125   }
00126 
00127   public Transform getScreenTransform(GraphName targetFrame) {
00128     FrameTransform frameTransform = frameTransformTree.transform(frame, targetFrame);
00129     return frameTransform.getTransform().multiply(getCameraToScreenTransform().invert());
00130   }
00131 
00139   public void rotate(double focusX, double focusY, double deltaAngle) {
00140     synchronized (mutex) {
00141       Transform focus = Transform.translation(toCameraFrame((int) focusX, (int) focusY));
00142       cameraToRosTransform =
00143           cameraToRosTransform.multiply(focus).multiply(Transform.zRotation(deltaAngle))
00144               .multiply(focus.invert());
00145     }
00146   }
00147 
00155   public void zoom(double focusX, double focusY, double factor) {
00156     synchronized (mutex) {
00157       Transform focus = Transform.translation(toCameraFrame((int) focusX, (int) focusY));
00158       double scale = cameraToRosTransform.getScale();
00159       double zoom = RosMath.clamp(scale * factor, MINIMUM_ZOOM_FACTOR, MAXIMUM_ZOOM_FACTOR) / scale;
00160       cameraToRosTransform =
00161           cameraToRosTransform.multiply(focus).scale(zoom).multiply(focus.invert());
00162     }
00163   }
00164 
00168   public double getZoom() {
00169     return cameraToRosTransform.getScale() * PIXELS_PER_METER;
00170   }
00171 
00176   public Vector3 toCameraFrame(int pixelX, int pixelY) {
00177     final double centeredX = pixelX - viewport.getWidth() / 2.0d;
00178     final double centeredY = viewport.getHeight() / 2.0d - pixelY;
00179     return getCameraToScreenTransform().invert().apply(new Vector3(centeredX, centeredY, 0));
00180   }
00181 
00188   public Transform toFrame(final int pixelX, final int pixelY, final GraphName frame) {
00189     final Transform translation = Transform.translation(toCameraFrame(pixelX, pixelY));
00190     final FrameTransform cameraToFrame =
00191         frameTransformTree.transform(this.frame, frame);
00192     return cameraToFrame.getTransform().multiply(translation);
00193   }
00194 
00195   public GraphName getFrame() {
00196     return frame;
00197   }
00198 
00206   public void setFrame(GraphName frame) {
00207     Preconditions.checkNotNull(frame);
00208     synchronized (mutex) {
00209       if (this.frame != null && this.frame != frame) {
00210         FrameTransform frameTransform = frameTransformTree.transform(frame, this.frame);
00211         if (frameTransform != null) {
00212           // Best effort to prevent the camera from jumping. If we don't have
00213           // the transform yet, we can't help matters.
00214           cameraToRosTransform = cameraToRosTransform.multiply(frameTransform.getTransform());
00215         }
00216       }
00217       this.frame = frame;
00218     }
00219   }
00220 
00224   public void setFrame(String frame) {
00225     setFrame(GraphName.of(frame));
00226   }
00227 
00234   public void jumpToFrame(GraphName frame) {
00235     synchronized (mutex) {
00236       this.frame = frame;
00237       final double scale = cameraToRosTransform.getScale();
00238       resetTransform();
00239       cameraToRosTransform = cameraToRosTransform.scale(scale / cameraToRosTransform.getScale());
00240     }
00241   }
00242 
00246   public void jumpToFrame(String frame) {
00247     jumpToFrame(GraphName.of(frame));
00248   }
00249 
00250   public void setViewport(Viewport viewport) {
00251     Preconditions.checkNotNull(viewport);
00252     this.viewport = viewport;
00253   }
00254 
00255   public Viewport getViewport() {
00256     Preconditions.checkNotNull(viewport);
00257     return viewport;
00258   }
00259 
00260   public Transform getCameraToRosTransform() {
00261     // Transforms are immutable. No need for a defensive copy.
00262     return cameraToRosTransform;
00263   }
00264 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Jun 6 2019 21:20:07