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.light.DirectionalLight; 37 import com.jme3.light.Light; 38 import com.jme3.light.PointLight; 39 import com.jme3.math.Vector3f; 40 import com.jme3.renderer.RenderManager; 41 import com.jme3.renderer.ViewPort; 42 import com.jme3.scene.Spatial; 43 import com.jme3.util.TempVars; 44 import java.io.IOException; 45 46 /** 47 * This Control maintains a reference to a Camera, 48 * which will be synched with the position (worldTranslation) 49 * of the current spatial. 50 * @author tim 51 */ 52 public class LightControl extends AbstractControl { 53 54 public static enum ControlDirection { 55 56 /** 57 * Means, that the Light's transform is "copied" 58 * to the Transform of the Spatial. 59 */ 60 LightToSpatial, 61 /** 62 * Means, that the Spatial's transform is "copied" 63 * to the Transform of the light. 64 */ 65 SpatialToLight; 66 } 67 private Light light; 68 private ControlDirection controlDir = ControlDirection.SpatialToLight; 69 70 /** 71 * Constructor used for Serialization. 72 */ 73 public LightControl() { 74 } 75 76 /** 77 * @param light The light to be synced. 78 */ 79 public LightControl(Light light) { 80 this.light = light; 81 } 82 83 /** 84 * @param light The light to be synced. 85 */ 86 public LightControl(Light light, ControlDirection controlDir) { 87 this.light = light; 88 this.controlDir = controlDir; 89 } 90 91 public Light getLight() { 92 return light; 93 } 94 95 public void setLight(Light light) { 96 this.light = light; 97 } 98 99 public ControlDirection getControlDir() { 100 return controlDir; 101 } 102 103 public void setControlDir(ControlDirection controlDir) { 104 this.controlDir = controlDir; 105 } 106 107 // fields used, when inversing ControlDirection: 108 @Override 109 protected void controlUpdate(float tpf) { 110 if (spatial != null && light != null) { 111 switch (controlDir) { 112 case SpatialToLight: 113 spatialTolight(light); 114 break; 115 case LightToSpatial: 116 lightToSpatial(light); 117 break; 118 } 119 } 120 } 121 122 private void spatialTolight(Light light) { 123 if (light instanceof PointLight) { 124 ((PointLight) light).setPosition(spatial.getWorldTranslation()); 125 } 126 TempVars vars = TempVars.get(); 127 128 if (light instanceof DirectionalLight) { 129 ((DirectionalLight) light).setDirection(vars.vect1.set(spatial.getWorldTranslation()).multLocal(-1.0f)); 130 } 131 vars.release(); 132 //TODO add code for Spot light here when it's done 133 // if( light instanceof SpotLight){ 134 // ((SpotLight)light).setPosition(spatial.getWorldTranslation()); 135 // ((SpotLight)light).setRotation(spatial.getWorldRotation()); 136 // } 137 138 } 139 140 private void lightToSpatial(Light light) { 141 TempVars vars = TempVars.get(); 142 if (light instanceof PointLight) { 143 144 PointLight pLight = (PointLight) light; 145 146 Vector3f vecDiff = vars.vect1.set(pLight.getPosition()).subtractLocal(spatial.getWorldTranslation()); 147 spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation())); 148 } 149 150 if (light instanceof DirectionalLight) { 151 DirectionalLight dLight = (DirectionalLight) light; 152 vars.vect1.set(dLight.getDirection()).multLocal(-1.0f); 153 Vector3f vecDiff = vars.vect1.subtractLocal(spatial.getWorldTranslation()); 154 spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation())); 155 } 156 vars.release(); 157 //TODO add code for Spot light here when it's done 158 159 160 } 161 162 @Override 163 protected void controlRender(RenderManager rm, ViewPort vp) { 164 // nothing to do 165 } 166 167 @Override 168 public Control cloneForSpatial(Spatial newSpatial) { 169 LightControl control = new LightControl(light, controlDir); 170 control.setSpatial(newSpatial); 171 control.setEnabled(isEnabled()); 172 return control; 173 } 174 private static final String CONTROL_DIR_NAME = "controlDir"; 175 176 @Override 177 public void read(JmeImporter im) throws IOException { 178 super.read(im); 179 im.getCapsule(this).readEnum(CONTROL_DIR_NAME, 180 ControlDirection.class, ControlDirection.SpatialToLight); 181 } 182 183 @Override 184 public void write(JmeExporter ex) throws IOException { 185 super.write(ex); 186 ex.getCapsule(this).write(controlDir, CONTROL_DIR_NAME, 187 ControlDirection.SpatialToLight); 188 } 189 }