Home | History | Annotate | Download | only in control
      1 /*
      2  * To change this template, choose Tools | Templates
      3  * and open the template in the editor.
      4  */
      5 package com.jme3.bullet.control;
      6 
      7 import com.jme3.bullet.PhysicsSpace;
      8 import com.jme3.bullet.collision.shapes.CollisionShape;
      9 import com.jme3.bullet.objects.PhysicsGhostObject;
     10 import com.jme3.export.InputCapsule;
     11 import com.jme3.export.JmeExporter;
     12 import com.jme3.export.JmeImporter;
     13 import com.jme3.export.OutputCapsule;
     14 import com.jme3.math.Quaternion;
     15 import com.jme3.math.Vector3f;
     16 import com.jme3.renderer.RenderManager;
     17 import com.jme3.renderer.ViewPort;
     18 import com.jme3.scene.Spatial;
     19 import com.jme3.scene.control.Control;
     20 import java.io.IOException;
     21 
     22 /**
     23  * A GhostControl moves with the spatial it is attached to and can be used to check
     24  * overlaps with other physics objects (e.g. aggro radius).
     25  * @author normenhansen
     26  */
     27 public class GhostControl extends PhysicsGhostObject implements PhysicsControl {
     28 
     29     protected Spatial spatial;
     30     protected boolean enabled = true;
     31     protected boolean added = false;
     32     protected PhysicsSpace space = null;
     33     protected boolean applyLocal = false;
     34 
     35     public GhostControl() {
     36     }
     37 
     38     public GhostControl(CollisionShape shape) {
     39         super(shape);
     40     }
     41 
     42     public boolean isApplyPhysicsLocal() {
     43         return applyLocal;
     44     }
     45 
     46     /**
     47      * When set to true, the physics coordinates will be applied to the local
     48      * translation of the Spatial
     49      * @param applyPhysicsLocal
     50      */
     51     public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
     52         applyLocal = applyPhysicsLocal;
     53     }
     54 
     55     private Vector3f getSpatialTranslation() {
     56         if (applyLocal) {
     57             return spatial.getLocalTranslation();
     58         }
     59         return spatial.getWorldTranslation();
     60     }
     61 
     62     private Quaternion getSpatialRotation() {
     63         if (applyLocal) {
     64             return spatial.getLocalRotation();
     65         }
     66         return spatial.getWorldRotation();
     67     }
     68 
     69     public Control cloneForSpatial(Spatial spatial) {
     70         GhostControl control = new GhostControl(collisionShape);
     71         control.setCcdMotionThreshold(getCcdMotionThreshold());
     72         control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
     73         control.setCollideWithGroups(getCollideWithGroups());
     74         control.setCollisionGroup(getCollisionGroup());
     75         control.setPhysicsLocation(getPhysicsLocation());
     76         control.setPhysicsRotation(getPhysicsRotationMatrix());
     77         control.setApplyPhysicsLocal(isApplyPhysicsLocal());
     78 
     79         control.setSpatial(spatial);
     80         return control;
     81     }
     82 
     83     public void setSpatial(Spatial spatial) {
     84         if (getUserObject() == null || getUserObject() == this.spatial) {
     85             setUserObject(spatial);
     86         }
     87         this.spatial = spatial;
     88         if (spatial == null) {
     89             if (getUserObject() == spatial) {
     90                 setUserObject(null);
     91             }
     92             return;
     93         }
     94         setPhysicsLocation(getSpatialTranslation());
     95         setPhysicsRotation(getSpatialRotation());
     96     }
     97 
     98     public void setEnabled(boolean enabled) {
     99         this.enabled = enabled;
    100         if (space != null) {
    101             if (enabled && !added) {
    102                 if (spatial != null) {
    103                     setPhysicsLocation(getSpatialTranslation());
    104                     setPhysicsRotation(getSpatialRotation());
    105                 }
    106                 space.addCollisionObject(this);
    107                 added = true;
    108             } else if (!enabled && added) {
    109                 space.removeCollisionObject(this);
    110                 added = false;
    111             }
    112         }
    113     }
    114 
    115     public boolean isEnabled() {
    116         return enabled;
    117     }
    118 
    119     public void update(float tpf) {
    120         if (!enabled) {
    121             return;
    122         }
    123         setPhysicsLocation(getSpatialTranslation());
    124         setPhysicsRotation(getSpatialRotation());
    125     }
    126 
    127     public void render(RenderManager rm, ViewPort vp) {
    128         if (enabled && space != null && space.getDebugManager() != null) {
    129             if (debugShape == null) {
    130                 attachDebugShape(space.getDebugManager());
    131             }
    132             debugShape.setLocalTranslation(spatial.getWorldTranslation());
    133             debugShape.setLocalRotation(spatial.getWorldRotation());
    134             debugShape.updateLogicalState(0);
    135             debugShape.updateGeometricState();
    136             rm.renderScene(debugShape, vp);
    137         }
    138     }
    139 
    140     public void setPhysicsSpace(PhysicsSpace space) {
    141         if (space == null) {
    142             if (this.space != null) {
    143                 this.space.removeCollisionObject(this);
    144                 added = false;
    145             }
    146         } else {
    147             if (this.space == space) {
    148                 return;
    149             }
    150             space.addCollisionObject(this);
    151             added = true;
    152         }
    153         this.space = space;
    154     }
    155 
    156     public PhysicsSpace getPhysicsSpace() {
    157         return space;
    158     }
    159 
    160     @Override
    161     public void write(JmeExporter ex) throws IOException {
    162         super.write(ex);
    163         OutputCapsule oc = ex.getCapsule(this);
    164         oc.write(enabled, "enabled", true);
    165         oc.write(applyLocal, "applyLocalPhysics", false);
    166         oc.write(spatial, "spatial", null);
    167     }
    168 
    169     @Override
    170     public void read(JmeImporter im) throws IOException {
    171         super.read(im);
    172         InputCapsule ic = im.getCapsule(this);
    173         enabled = ic.readBoolean("enabled", true);
    174         spatial = (Spatial) ic.readSavable("spatial", null);
    175         applyLocal = ic.readBoolean("applyLocalPhysics", false);
    176         setUserObject(spatial);
    177     }
    178 }
    179