1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.jme3.scene.control; 33 34 import com.jme3.export.JmeExporter; 35 import com.jme3.export.JmeImporter; 36 import com.jme3.math.Quaternion; 37 import com.jme3.math.Vector3f; 38 import com.jme3.renderer.Camera; 39 import com.jme3.renderer.RenderManager; 40 import com.jme3.renderer.ViewPort; 41 import com.jme3.scene.Spatial; 42 import com.jme3.util.TempVars; 43 import java.io.IOException; 44 45 /** 46 * This Control maintains a reference to a Camera, 47 * which will be synched with the position (worldTranslation) 48 * of the current spatial. 49 * @author tim 50 */ 51 public class CameraControl extends AbstractControl { 52 53 public static enum ControlDirection { 54 55 /** 56 * Means, that the Camera's transform is "copied" 57 * to the Transform of the Spatial. 58 */ 59 CameraToSpatial, 60 /** 61 * Means, that the Spatial's transform is "copied" 62 * to the Transform of the Camera. 63 */ 64 SpatialToCamera; 65 } 66 private Camera camera; 67 private ControlDirection controlDir = ControlDirection.CameraToSpatial; 68 69 /** 70 * Constructor used for Serialization. 71 */ 72 public CameraControl() { 73 } 74 75 /** 76 * @param camera The Camera to be synced. 77 */ 78 public CameraControl(Camera camera) { 79 this.camera = camera; 80 } 81 82 /** 83 * @param camera The Camera to be synced. 84 */ 85 public CameraControl(Camera camera, ControlDirection controlDir) { 86 this.camera = camera; 87 this.controlDir = controlDir; 88 } 89 90 public Camera getCamera() { 91 return camera; 92 } 93 94 public void setCamera(Camera camera) { 95 this.camera = camera; 96 } 97 98 public ControlDirection getControlDir() { 99 return controlDir; 100 } 101 102 public void setControlDir(ControlDirection controlDir) { 103 this.controlDir = controlDir; 104 } 105 106 // fields used, when inversing ControlDirection: 107 @Override 108 protected void controlUpdate(float tpf) { 109 if (spatial != null && camera != null) { 110 switch (controlDir) { 111 case SpatialToCamera: 112 camera.setLocation(spatial.getWorldTranslation()); 113 camera.setRotation(spatial.getWorldRotation()); 114 break; 115 case CameraToSpatial: 116 // set the localtransform, so that the worldtransform would be equal to the camera's transform. 117 // Location: 118 TempVars vars = TempVars.get(); 119 120 Vector3f vecDiff = vars.vect1.set(camera.getLocation()).subtractLocal(spatial.getWorldTranslation()); 121 spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation())); 122 123 // Rotation: 124 Quaternion worldDiff = vars.quat1.set(camera.getRotation()).subtractLocal(spatial.getWorldRotation()); 125 spatial.setLocalRotation(worldDiff.addLocal(spatial.getLocalRotation())); 126 vars.release(); 127 break; 128 } 129 } 130 } 131 132 @Override 133 protected void controlRender(RenderManager rm, ViewPort vp) { 134 // nothing to do 135 } 136 137 @Override 138 public Control cloneForSpatial(Spatial newSpatial) { 139 CameraControl control = new CameraControl(camera, controlDir); 140 control.setSpatial(newSpatial); 141 control.setEnabled(isEnabled()); 142 return control; 143 } 144 private static final String CONTROL_DIR_NAME = "controlDir"; 145 146 @Override 147 public void read(JmeImporter im) throws IOException { 148 super.read(im); 149 im.getCapsule(this).readEnum(CONTROL_DIR_NAME, 150 ControlDirection.class, ControlDirection.SpatialToCamera); 151 } 152 153 @Override 154 public void write(JmeExporter ex) throws IOException { 155 super.write(ex); 156 ex.getCapsule(this).write(controlDir, CONTROL_DIR_NAME, 157 ControlDirection.SpatialToCamera); 158 } 159 }