Core-Dump said:
can you make a simple runnable test case to reproduce the problem ?
Could be difficult because my whole code is a mess.^^ But I'll give it a try.
evilangelist said:
I think core-dump is along the right track and your problem is related to how you are translating your unit node. How do you create the box node? And how do you initially position it?
Until then, I could post some code snippets which describe how I position my nodes and stuff.
Lets start.
This codesnippet is executed int the initGame Method. The UnitManager contains a Hashmap which stores all Units. Unit is a self written class which extends Node.
Box box = new Box("Player1", new Vector3f(0, 0, 0), new Vector3f(10, 10, 10));
box.setModelBound(new BoundingBox());
box.updateModelBound();
UnitManager.getUnitMap().put("Player1", new Unit(50, 10, 10, box));
Because I create two units at the startup, I've written this "for" segment. We're still in InitGame. It gets all units, stored in the Hashmap and places them onto the terrain. This code seems to work to me.
int distance = 0;
Node model = null;
for (String i : UnitManager.getUnitMap().keySet())
{
model = UnitManager.getUnitMap().get(i);
rootNode.attachChild(model);
model.setLocalTranslation(new Vector3f(100, 0, distance));
distance += 20;
float characterMinHeight = terrain.getHeight(model.getLocalTranslation())
+ ((BoundingBox) model.getChild(0).getWorldBound()).yExtent;
model.getLocalTranslation().y = characterMinHeight;
}
Here the unit is demermined which was clicked and the selectionshape is set. Executed in the update Method.
if (MouseInput.get().isButtonDown(0))
{
Ray mouseRay = getRay();
pr.clear();
rootNode.findPick(mouseRay, pr);
for (int i = 0; i < pr.getNumber(); i++)
{
PickData pd = pr.getPickData(i);
if (pd.getTargetMesh().getName().startsWith("Play"))
{
activeToMove = pd.getTargetMesh().getParent();
float radius = 0;
Vector3f extent = new Vector3f();
((BoundingBox) activeToMove.getWorldBound()).getExtent(extent);
if (extent.x >= extent.z)
{
radius = extent.x;
}
else
{
radius = extent.z;
}
float delta = FastMath.PI / 12;
Vector3f vec = null;
Vector3f[] points = new Vector3f[24];
ColorRGBA[] colors = new ColorRGBA[24];
for (int j = 0; j < 24; j++) {
vec =
new Vector3f(activeToMove.getWorldTranslation().x + radius * FastMath.cos(delta * j),
terrain.getHeight(activeToMove.getWorldTranslation().x + radius * FastMath.cos(delta * j), activeToMove.getWorldTranslation().z + radius * FastMath.sin(delta * j))+ terrain.getWorldTranslation().y,
activeToMove.getWorldTranslation().z + radius * FastMath.sin(delta * j));
points[j] = vec.add(0, 0.05f, 0);
colors[j] = new ColorRGBA(0,1,0,1);
}
selectionShape = new Line("selection " + activeToMove.getName(), points, null, colors, null);
selectionShape.setMode(Line.Mode.Loop);
selectionShape.setLineWidth(3);
selectionShape.updateRenderState();
activeToMove.attachChild(selectionShape);
}
[...]
If a unit is selected and the right mousebutton is pressed it'll be moved. MovementManger contains a Hashmap also. This Hashmap is used to store the unit and its desired location. Yes i know this could be solved a bit better, but this was the first thing which came to my mind :)
Picker is an instance of BresenhamTerrainPicker. The if part which includes"needsToMove = MovementManager.moveUnits(tpf);" issues the unit movement.
This code is executed in the updateMethod.
if (MouseInput.get().isButtonDown(1))
{
Ray mouseRay = getRay();
pr.clear();
rootNode.findPick(mouseRay, pr);
Vector3f loc = new Vector3f();
for (int i = 0; i < pr.getNumber(); i++)
{
if (activeToMove.getName().startsWith("Play"))
{
picker.getTerrainIntersection(mouseRay, loc);
MovementManager.getMoveUnitMap().put(activeToMove.getName(), new UnitToMove((Unit) activeToMove, loc));
needsToMove = true;
}
}
if (needsToMove)
{
needsToMove = MovementManager.moveUnits(tpf);
}
This is the code from the MovementManager class, which handles the unit movement. Evertime a unit needs to be moved. the unit and its desired loaction will be putted into the hashmap. If the unit reaches its location, the approprate entry in the hasmap will be deleted.
public static boolean moveUnits(float tpf)
{
Collection keys = new ArrayList(MoveUnitMap.keySet());
if (MoveUnitMap.size() > 0)
{
for (Iterator iterator = keys.iterator(); iterator.hasNext();)
{
String key = (String) iterator.next();
UnitToMove UTM = MoveUnitMap.get(key);
UTM.getUnit().setMoving(true);
Vector3f loc = UTM.getLoc();
Vector3f unit2Destination = new Vector3f();
unit2Destination = loc.subtract(UTM.getUnit().getLocalTranslation());
logger.info("Moving " + UTM.getUnit().getName() + " to " + loc + ". now: "
+ UTM.getUnit().getLocalTranslation());
UTM.getUnit().setLocalTranslation(UTM.getUnit().getLocalTranslation().add(unit2Destination.mult(tpf)));
checkReached(loc, key, UTM.getUnit());
}
return true;
}
else
{
return false;
}
}
private static void checkReached(Vector3f loc, String Field, Unit unit)
{
float eps = 3f;
float x = loc.x - unit.getWorldTranslation().x;
float y = loc.y - unit.getWorldTranslation().y;
float z = loc.z - unit.getWorldTranslation().z;
if (x < eps && y < eps && z < eps)
{
unit.setMoving(false);
MoveUnitMap.remove(Field);
}
}
The whole code i've posted here is working to me, but maybe there is some logical fault in it.
I hope someone understands what i've done there. :)
Thanks
Edregol