Package org.pollux3d.cam

Source Code of org.pollux3d.cam.PolluxCam

package org.pollux3d.cam;


import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* A camera that follows a spatial and can turn around it by dragging the mouse
* @author nehon
*/
public class PolluxCam implements Control, Cam{

    private Spatial target = null;
    private float distance = 180;
    private float minHeight = -(FastMath.PI / 2 - 0.0001f);
    private float maxHeight = (FastMath.PI / 2 - 0.0001f);
    private float minDistance = 10.0f;
    private float maxDistance = 10000.0f;
    private float zoomSpeed = 0.1f;
    private boolean canZoom = true;
    private float rotationSpeed = 0.01f;
    private Quaternion rotaionOffset = new Quaternion();
    /**
     * the camera.
     */
    private Camera cam = null;
    private Vector3f initialUpVec;
    private boolean canRotate = true;
    private float hRotation = FastMath.PI / 2;
    private float vRotation = 0;
    private boolean enabled = true;
   
  private List<CamLocationListener> camDirectionListeners = new ArrayList<CamLocationListener>();

    /**
     * Constructs the chase camera
     * @param cam the application camera
     * @param target the spatial to follow
     */
    public PolluxCam(Camera cam, final Spatial target) {
        this.target = target;
        target.addControl(this);
        this.cam = cam;
        cam.setFrustumFar(10000000f);
        initialUpVec = cam.getUp().clone();
        //this.setHorizontalOffset(-0.2f);
    }
   
    public Vector3f getDirection() {
      return cam.getDirection();
    }
   
    public float getZoomDistance() {
      return distance;
    }
   
    public void setZoomDistance(float distance) {
      this.distance = distance;
    }
   
    public void setCanZoom(boolean canZoom) {
      this.canZoom = canZoom;
    }
   
  public Ray getClickRay(Vector2f point) {
    Vector3f camLocation = cam.getLocation();
    Vector3f clickPoint = cam.getWorldCoordinates(point, 0.9f);
    Vector3f dir = clickPoint.subtract(camLocation).normalize();
    return new Ray(camLocation, dir);
    //return new Ray(camLocation, cam.getDirection());
  }

    //rotate the camera around the target on the horizontal plane
    public void hRotateCamera(float value) {
        if (!canRotate || !enabled) {
            return;
        }
        hRotation += value * rotationSpeed;
        //updateCamera();
    }

    //move the camera toward or away the target
    public void zoomCamera(float value) {
        if (!enabled || !canZoom) {
            return;
        }

        distance += value * zoomSpeed;
        if (distance > maxDistance) {
            distance = maxDistance;
        }
        if (distance < minDistance) {
            distance = minDistance;
        }
        if ((vRotation < minHeight) && (distance > (minDistance + 1.0f))) {
            vRotation = minHeight;
        }

        //updateCamera();
    }

    //rotate the camera around the target on the vertical plane
    public void vRotateCamera(float value) {
        if (!canRotate || !enabled) {
            return;
        }
        vRotation += value * rotationSpeed;
        if (vRotation > maxHeight) {
            vRotation = maxHeight;
        }
        if ((vRotation < minHeight) && (distance > (minDistance + 1.0f))) {
            vRotation = minHeight;
        }
        //updateCamera();
    }

    /**
     * Update the camera, should only be called internally
     */
    public void updateCamera() {
        float hDistance = distance * FastMath.sin((FastMath.PI / 2) - vRotation);
        Vector3f pos = new Vector3f(hDistance * FastMath.cos(hRotation), distance * FastMath.sin(vRotation), hDistance * FastMath.sin(hRotation));
        pos = pos.add(target.getLocalTranslation());
        cam.setLocation(pos);
        cam.lookAt(target.getLocalTranslation(), initialUpVec);
        cam.setRotation(cam.getRotation().mult(rotaionOffset));
        cam.updateViewProjection();
    }
   
  public void updateListeners() {
    for (CamLocationListener listener : camDirectionListeners) {
      listener.onCamLocationChange(cam.getLocation());
    }
  }
   
    public void setRotationOffset(float vertical, float horizontal) {
      rotaionOffset = new Quaternion().fromAngles(vertical, horizontal, 0);;
    }

    /**
     * Return the enabled/disabled state of the camera
     * @return true if the camera is enabled
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * Enable or disable the camera
     * @param enabled true to enable
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
        if (!enabled) {
            canRotate = false; // reset this flag in-case it was on before
        }
    }

    /**
     * Returns the max zoom distance of the camera (default is 40)
     * @return maxDistance
     */
    public float getMaxDistance() {
        return maxDistance;
    }

    /**
     * Sets the max zoom distance of the camera (default is 40)
     * @param maxDistance
     */
    public void setMaxDistance(float maxDistance) {
        this.maxDistance = maxDistance;
    }

    /**
     * Returns the min zoom distance of the camera (default is 1)
     * @return minDistance
     */
    public float getMinDistance() {
        return minDistance;
    }

    /**
     * Sets the min zoom distance of the camera (default is 1)
     * @return minDistance
     */
    public void setMinDistance(float minDistance) {
        this.minDistance = minDistance;
    }

    /**
     * clone this camera for a spatial
     * @param spatial
     * @return
     */
    public Control cloneForSpatial(Spatial spatial) {
        PolluxCam pc = new PolluxCam(cam, spatial);
        pc.setMaxDistance(getMaxDistance());
        pc.setMinDistance(getMinDistance());
        return pc;
    }
   

    /**
     * Sets the spacial for the camera control, should only be used internally
     * @param spatial
     */
    public void setSpatial(Spatial spatial) {
        target = spatial;
    }

    /**
     * update the camera control, should on ly be used internally
     * @param tpf
     */
    public void update(float tpf) {
        updateCamera();
    }

    /**
     * renders the camera control, should on ly be used internally
     * @param rm
     * @param vp
     */
    public void render(RenderManager rm, ViewPort vp) {
        //nothing to render (in Control interface but we use only update)
    }

    /**
     * Write the camera
     * @param ex the exporter
     * @throws IOException
     */
    public void write(JmeExporter ex) throws IOException {
        OutputCapsule capsule = ex.getCapsule(this);
        capsule.write(maxDistance, "maxDistance", 40);
        capsule.write(minDistance, "minDistance", 1);
    }

    /**
     * Read the camera
     * @param im
     * @throws IOException
     */
    public void read(JmeImporter im) throws IOException {
        InputCapsule ic = im.getCapsule(this);
        maxDistance = ic.readFloat("maxDistance", 40);
        minDistance = ic.readFloat("minDistance", 1);
    }

  public void addCamDirectionListener(CamLocationListener listener) {
    if (listener == null) throw new NullPointerException();
    camDirectionListeners.add(listener);
  }

  public void removeAllCamDirectionListener() {
    camDirectionListeners.clear();
  }

  public void removeCamDirectionListener(CamLocationListener listener) {
    if (listener == null) throw new NullPointerException();
    camDirectionListeners.remove(listener);
  }
}
TOP

Related Classes of org.pollux3d.cam.PolluxCam

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.