Package org.jdesktop.wonderland.modules.orb.client.cell

Source Code of org.jdesktop.wonderland.modules.orb.client.cell.FollowMe

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.orb.client.cell;

import org.jdesktop.wonderland.common.cell.CellTransform;
import org.jdesktop.wonderland.client.cell.MovableComponent;

import com.jme.math.Quaternion;
import com.jme.math.Vector3f;

import java.util.logging.Level;
import java.util.logging.Logger;

public class FollowMe extends Thread {

    private static final Logger logger =
            Logger.getLogger(FollowMe.class.getName());

    private static final float MASS = 1.0f;
    private static final float MAX_SPEED = 0.5f;
    private static final float DAMPING = 9.0f;
    private static final float SPRING = 5.0f;
    private static final float EPSILON = 0.01f;
    private static final float LONG_DISTANCE = 10f;
       
    private Vector3f currentPosition;
    private Vector3f targetPosition;
   
    private long oldTime;
    private Vector3f oldVelocity;
    private Vector3f oldAcceleration;
   
    private Quaternion rotation;

    private  MovableComponent movableComp;

    private FollowMeListener listener;

    private boolean animate = true;

    public FollowMe(MovableComponent movableComp, Vector3f initialPosition,
      FollowMeListener listener) {

  this.movableComp = movableComp;
  this.listener = listener;

        currentPosition = new Vector3f(initialPosition);
        targetPosition = new Vector3f(initialPosition);
       
        oldVelocity = new Vector3f();
        oldAcceleration = new Vector3f();

  start();
    }
   
    public void setAnimate(boolean animate) {
  this.animate = animate;
    }

    public void jumpToTargetPosition(Vector3f newTarget) {
        //Add a little hop
        oldVelocity.addLocal(new Vector3f(0.0f, 3.0f, 0.0f));
        setTargetPosition(newTarget);
    }
   
    public void setTargetPosition(Vector3f targetPosition) {
        setTargetPosition(targetPosition, null);
    }

    public void setTargetPosition(Vector3f targetPosition,
      Quaternion rotation) {

  this.targetPosition = targetPosition;
  this.rotation = rotation;

        oldTime = System.currentTimeMillis();

  logger.finer("Set targetPosition " + targetPosition
      + " rotation " + rotation);

        Vector3f positionError  = new Vector3f(targetPosition);
            positionError.subtractLocal(currentPosition);
 
  float length = positionError.length();

  logger.fine("current " + currentPosition + "target "
      + targetPosition + " error " + length);

  if (length >= LONG_DISTANCE) {
      // Get to LONG_DISTANCE away, then animate from there

      Vector3f moveTo = new Vector3f(positionError);

            moveTo.multLocal((length - LONG_DISTANCE) / length);
      move(moveTo);
      logger.fine("JUMP TO: " + currentPosition);
  } else {
      if (animate == false) {
          move(positionError);
      }
  }

  synchronized (this) {
      notifyAll();
  }
    }
   
    private boolean done;

    public void done() {
  done = true;
    }

    private void sleep(int ms) {
  try {
      Thread.sleep(ms);
  } catch (InterruptedException e) {
  }
    }

    public void run() {
  while (!done) {
            long newTime = System.currentTimeMillis();
            float timeScale = 0.001f;
            float deltaTime = (newTime - oldTime) * timeScale;

      logger.finest("oldTime " + oldTime + " newTime " + newTime
        + " deltaTime " + deltaTime);

            oldTime = newTime;
       
            if (deltaTime <= 0.0) {
        sleep(40);
        continue;
            }
       
            //Difference between where we are and where we want to be.
            Vector3f positionError = new Vector3f(targetPosition);
            positionError.subtractLocal(currentPosition);
   
            if (positionError.length() < EPSILON) {
    logger.fine("Orb reached target position.");

    if (listener != null) {
        listener.targetReached(currentPosition);
    }

    synchronized (this) {
        try {
      wait();
        } catch (InterruptedException e) {
        }
    }
        continue;
            }

            Vector3f springForce = new Vector3f(positionError);
            springForce.multLocal(SPRING);

            Vector3f dampingForce = new Vector3f(oldVelocity);
            dampingForce.multLocal(DAMPING * -1.0f);

            Vector3f netAcceleration = new Vector3f(springForce);
            netAcceleration.addLocal(springForce);
            netAcceleration.addLocal(dampingForce);
            netAcceleration.multLocal(1.0f / MASS);
     
            Vector3f aIntegration = new Vector3f(netAcceleration);
            aIntegration.multLocal(0.5f * deltaTime * deltaTime);
    
            Vector3f vIntegration = new Vector3f(oldVelocity);
            vIntegration.multLocal(deltaTime);
    
            Vector3f jump = new Vector3f();
            jump.addLocal(aIntegration);
            jump.addLocal(vIntegration);
     
            //Speed limiter
            float newVelocity = jump.length() / deltaTime;

            if (newVelocity > MAX_SPEED) {
                jump.normalizeLocal();
                jump.multLocal(MAX_SPEED * deltaTime);
            }
    
            jump.multLocal(1.0f/deltaTime);
            oldVelocity = jump;
   
      move(jump);
      sleep(40);
  }
    }

    long time;

    private void move(Vector3f position) {
  currentPosition.addLocal(position);

  if (logger.isLoggable(Level.FINEST)) {
      long now = System.currentTimeMillis();

      logger.finest("current " + currentPosition + " time delta "
          + (now - time));

      time = now;
  }

        movableComp.localMoveRequest(
            new CellTransform(rotation, currentPosition));

  if (listener != null) {
      listener.positionChanged(currentPosition);
  }
    }
   
    public void targetSwap(Vector3f oldVector, Vector3f newVector) {
        oldVector.subtractLocal(newVector);
        currentPosition.addLocal(oldVector);
        setTargetPosition(new Vector3f());
    }

}
TOP

Related Classes of org.jdesktop.wonderland.modules.orb.client.cell.FollowMe

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.