Home | History | Annotate | Download | only in control
      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 }