Move Object with constant speed?

Hi there,

I wonder how to move an Object with a constant speed from a location to another.



Currently I'm moving Objects by clicking them and click again on a location on the terrain.

The movemethod is called in the update Method like this:


Vector3f dest = Unit.getDestination();
Vector3f unit2Destination = new Vector3f();
unit2Destination = dest.subtract(Unit.getLocalTranslation());
Unit.setLocalTranslation(Unit.getLocalTranslation().add(unit2Destination.mult(tpf)));


I got 3 vectors A = orginivector, B= destination vector, C = a vector between A and B and a constant value d. d got a very small value like 0.0001 (tpf)
so the formula would be:

C = A + ((A-B)*d)

But with this, the object moves with a speed, related to the distance between A and B.
So i tried to calculate the distance between A and B:

s = sqrt(((A-B).x^2)+((A-B).y^2)+((A-B).z^2))

and multiplied s by d. But this didnt change anything.

Anybody got an idea, how to solve this?

thanks and regards
Edregol

Perfekt, thanks for the help.



Vector3f nextStep = new Vector3f();
            nextStep.interpolate(unit.getOrigin(),unit.getDestination(), unit.getCounter());
            unit.setLocalTranslation(nextStep);
            unit.setCounter(unit.getCounter() + tpf / (unit.getOrigin().distance(unit.getDestination())/unit.getSpeed()));


This code works fine to me. No matter how long the distance between orign and destionation is, the unit moves with constant speed.

I'm interested in how this could work with the curves.


public void gotToDestination(Vector3f destination)
   {
      Vector3f[] way = new Vector3f[2];
      way[0] = this.getLocalTranslation();
      way[1] = destination;
      float distance = way[0].distance(way[1]);
      curve = new PolylineCurve("path", way);
      curve.setSteps(Math.round(distance));

      cc = new CurveController(curve, this);
      this.addController(cc);
      cc.setRepeatType(Controller.RT_CLAMP);
      cc.setUpVector(Vector3f.UNIT_Y);
      cc.setSpeed(0.5f);
   }


This is a method within my unit class. Its only called once, for each movement order. The Unit moves fine. But the movmentspeed is related to the distance. As you can see, the curve got as many steps as the distance between origin and destination got. So my unit should move with a speed of 0.5f for each step on the line, correct?
If this is correct, i dont see why the unit moves with a speed related to the distance.

regards
Edregol

first of all, take a look at the method A.interpolate(B);



secondly, if you want the interpolation between the two to take three seconds, you have to update with (tpf / 3.0f). So, if you want the interpolation to take one second for one Unit in 3d space you have to calculate the distance between the two vectors


float distance = A.distance(B)



and update it with (tpf / distance);

Cheers

Okay i tried something like that:



Vector3f nextStep = unit.getLocalTranslation();
nextStep.interpolate(unit.getOrigin(),unit.getDestination(), 0.001f);
unit.getLocalTranslation().add(nextStep.mult(tpf/unit.getDistanceToDestination()));



unit.getDistanceToDestination() is the origin destination between the origin vector and the destionation vector.

But the speed still varys. I need to say, im not that good in vector math.

thanks
Edregol

you could move them along a curve, this allows for constant speed. check out jmetest.curve

Eggsworth said:

you could move them along a curve, this allows for constant speed. check out jmetest.curve


CurveController does it quite like i explained above.
Edregol said:


Vector3f nextStep = unit.getLocalTranslation();
nextStep.interpolate(unit.getOrigin(),unit.getDestination(), 0.001f);
unit.getLocalTranslation().add(nextStep.mult(tpf/unit.getDistanceToDestination()));




first of all you have to think about your object references. the first line doesnt set the values of nextStep to those of unit.getLocalTranslation, it just makes nextStep reference the Vector3f instance, which you are changing in line two. That means you are actually moving the origin vector each time you execute that.

next thing is you have to call the interpolate method with a value between 0 and 1, 0 resulting in a vector equal to the origin vector and 1 resulting in a vector equal to the destination vector. so what you shoud do is have a counter variable that you increment each update by

counter += tpf / numSecondsToTake;

then you call interpolate with that value, when counter reaches the same value as numSecondsToTake you can stop the animation. the third line is just bull****, you dont need it.


cc.setSpeed(1f / (curveLength * timeToTakeInSeconds));

Thank you :slight_smile:

I know I"m late to the party but here’s what i have with JME 3.1. I couldn’t find any CurveController.

protected static final Random mRandom = new Random();
protected float mCounter = 1, mSpeed = 0.3f;
protected Vector3f mDestination = Vector3f.ZERO, mDirection, mOrigin;

private void getDestination() {
    mOrigin = this.getWorldBound().getCenter();
    mDestination = new Vector3f(mRandom.nextInt() % 100 - 50, mOrigin.y, mRandom.nextInt() % 100 - 50);
    mDirection = mDestination.subtract(mOrigin);
    mCounter = 0;
}

public void update(float tpf) {
    if (mCounter >= 1) {
        getDestination();
    } else {
        Vector3f nextStep = new Vector3f();
        nextStep.interpolateLocal(mOrigin, mDestination, mCounter);
        setLocalTranslation(nextStep);
        mCounter += tpf / (mOrigin.distance(mDestination) / mSpeed);
    }
}