How to make one model walk on another?

Hi,

i am sure this sounds like (and most probably is) a newbie question.

Suppose i have a model, lets say a dwarf. And i want this dawrf to walk around.

On terrain its simple, i just call getHeight on the terrainblock.

Nice.



Now suppose on the terrain i have a model representing a bridge.

How do i now walk on the bridge ?



I thought one could use the modelbound, but then i would walk "in air" if the bridge has handrails on the right and left.



I also thought that one could define all "walkable areas" somweher but that sounds simply too complicated in order not to have already been solved by a better solution.



The same or lets say a similar problem became appearent when walking INSIDE some building. How do i keep my model on the stairs etc.



Anybody with an idea or a piece of code ?



Any help here would be appreciated … my first "testrelease" only needs this one more feature  :smiley:

Search the forums for older posts and you can find the code for a MeshFollower class! One alternative is to cast a ray down and use the pickdata to follow  the model!

http://www.jmonkeyengine.com/jmeforum/index.php?topic=2627.0

Thanks, didnt know what to search for.



I am trying to implement something now. the terrainfollower is nice but doesnt allow me for multiple values of y for an x.

Will see if i can use that for a start and implement the idea with the rays later.


ok, i had some time for a first hacked test. Didnt work well though.

I used a normal terrain with two boxes on top of that and a character that runs on the terrain.

Now when he reaches the box he should "jump" on that box, when he leaves it he should "fall" onto the terrain.

I have a simple problem. It seems as if in TWO directions the character moves up BEFORE he actually reaches the box while in the other two he actually falls down before he reaches the end. And then there are some (seems very few) sections where he jumps up and down.



Here is the code (messy since i tried a lot of different things to solve the problem first)

  1. determine the distance to the next object i stand on or should stand on
// BOUNDING (not good !)
private float getHeight(float f) {
Vector3f origin = getWorldTranslation(); //should be the MIDDLE of the character !
//testing a ray from the location + 20 in the air down 220
Vector3f origin2 = (Vector3f) origin.clone();

Vector3f destination = new Vector3f(origin2.x, origin2.y - 200, origin2.z);

origin2.y += 20;
results.clear();
Ray r = new Ray(origin2, destination);

results.setCheckDistance(true);
getParent().findPick(r, results);
// rootNode.findPick(r, results);
if (results.getNumber() > 0) {
float distance = 50; //just some value
System.out.println("Found: " + results.getNumber() + "results");
Vector3f loc = null;
for (int i = 0; i < results.getNumber(); i++) {
String str = findNodeName(results.getPickData(i).getTargetMesh()
.getParent());
if (!str.equals(getName()) && !str.equals("state rootNode")
&& !str.equals("DynamicWorld")) {
System.out.println(str);
float distance2 = results.getPickData(i).getDistance();
PickData pd = results.getPickData(i);

System.out.println("stored distance: " + distance);
System.out.println("distance2: " + distance2);
if (distance2 < 800 && distance2 != 0.0f && distance2 > -800) {  //just some values to limit possible results
if (distance2 < distance) {
//pick the closest object
distance = distance2;
System.out.println("new distance: " + distance2);
}
}

}
}
if (distance != 50) {
System.out.println("distance != 50 " + (origin2.y - loc.y));
return distance - 20;// origin2.y-loc.y;
}
return 10f; //just some value to decrease the height smoothely if there is nothing below
}
return 0.0f;
}


that method gets called in my update loop
2)
synchronized (this) {
if (moveStatus == Globals.WALKING || moveStatus == Globals.RUNNING) {
Vector3f tempVa = new Vector3f();
Vector3f loc = getLocalTranslation();
loc.addLocal(getLocalRotation().getRotationColumn(2, tempVa)
.multLocal(movespeed * f));
loc.subtractLocal(0, getHeight(f), 0);
setLocalTranslation(loc);