Placing objects on the 'Floor'

I’m trying to ‘automatically’ place objects on the scene ‘floor’ using either a Ray or collideWith(), but nothing is reporting the correct distance between the two Spatials in order to translate my new Geometry correctly.

I believe the correct was is to create either a plane, or a quad, as the floor and then collideWith() the new Geometry to get the Y distance to translate by? (I’ve tried a Ray as well but this doesn’t produce any results).

The added complication is that my entire scene is rotated to align with a localised coordinate system, therefore the floor and simple geometries like Box() are rotated as; Front: (0.79030997, -0.029681953, -0.6119788), Up: (-0.61155105, 0.02296824, -0.79087156)

I would like this method to work for both 2D flat ‘Floors’, but shortly I’m also going to implement a HeightMap terrain as well, therefore the distance between new objects and the ground will vary, hence the need for something ‘automatic’.

Can anyone tell me why neither of these work?

[java]
CollisionResults results = new CollisionResults();
featureRoot.collideWith(floor2D.getWorldBound(), results);
if (results.size() > 0) {
// how to react when a collision was detected
CollisionResult closest = results.getClosestCollision();
System.out.println("What was hit? " + closest.getGeometry().getName() );
System.out.println("Distance? " + closest.getDistance() );
}
floor2D.collideWith(featureRoot, results);
if (results.size() > 0) {
// how to react when a collision was detected
CollisionResult closest = results.getClosestCollision();
System.out.println("What was hit? " + closest.getGeometry().getName() );
System.out.println("Distance? " + closest.getDistance() );
}
[/java]

Floor creation code;

[java]
Vector3f[] vertices = toVector3fArray( geomToProcess.getCoordinates() );

Vector2f[] texCoord = new Vector2f[4];
texCoord[0] = new Vector2f(0,0);
texCoord[1] = new Vector2f(1,0);
texCoord[2] = new Vector2f(0,1);
texCoord[3] = new Vector2f(1,1);

short [] indexes = { 2,0,1, 1,3,2 };

float[] normals = new float[]{
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1};

Mesh mesh = new Mesh();
mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
mesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
mesh.setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(indexes));
mesh. setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normals));
mesh.updateBound();
[/java]

Many thanks…

Object → object collisions don’t work in JME and I’m surprised you didn’t get an exception. Even BoundingShape to object collisions are a bit hit or miss… and anyway the bounding shape may be larger than the object for a variety of reasons.

Ray is what you want to use. We can’t help with why it didn’t work for you because we can’t see that code. Most often causes: direction vector that’s not really a direction vector or: direction vector or ray location that isn’t in world space.

Sorry, the second test in the original code was throwing an error - I uncommented mistakenly.
I’ve been working on this further this afternoon and have got it mostly working. I now have the following code using a Ray;
[java]
public void setOnGround(Spatial floor2D) {
if (parentFeatureNode==null) return;

CollisionResults results = new CollisionResults();
com.jme3.bounding.BoundingBox bbox = (com.jme3.bounding.BoundingBox)parentFeatureNode.getWorldBound();

Vector3f origin = bbox.getCenter();
Vector3f direction = new Vector3f(-1,0,0);

floor2D.collideWith( new Ray(origin, direction), results);

if (results.size() > 0) {
	// how to react when a collision was detected
	CollisionResult farthest  = results.getClosestCollision();
	if (farthest.getGeometry().getName().equals(SceneLoaderAppState.GROUND_NAME)) {

		float move = farthest.getDistance();

		if (geomType.contains("point")) {
			move-=bbox.getXExtent();
		}

		parentFeatureNode.setLocalTranslation(new Vector3f(move * -1f, 0f, 0f));
		System.out.println("Distance? " + farthest.getDistance() );

	}

}

}
[/java]

The parentFeatureNode holds 1 or more geometries. geomType can be line, point or polygon. The point is handled differently as it could be a model, Box mesh or similar, whereas lines (currently) are being added as polylines and therefore have no width and rather random X,Y dimensions.

The polylines are translating nicely with a distance of around 82f. The point (read Box()) is getting a distance but for some reason isn’t translating at all - The only difference is that lines have no local translation as the vertex coordinates are created with respect to the scene axis, whereas points are translated to the correct world position.

I thought that translating a parent node would also translate all children, with the child translation added on top - Is this not the case, or am I missing something else?

Cheers.

@MikeR said: Sorry, the second test in the original code was throwing an error - I uncommented mistakenly. I've been working on this further this afternoon and have got it mostly working. I now have the following code using a Ray; [java] public void setOnGround(Spatial floor2D) { if (parentFeatureNode==null) return;
CollisionResults results = new CollisionResults();
com.jme3.bounding.BoundingBox bbox = (com.jme3.bounding.BoundingBox)parentFeatureNode.getWorldBound();

Vector3f origin = bbox.getCenter();
Vector3f direction = new Vector3f(-1,0,0);

floor2D.collideWith( new Ray(origin, direction), results);

if (results.size() > 0) {
	// how to react when a collision was detected
	CollisionResult farthest  = results.getClosestCollision();
	if (farthest.getGeometry().getName().equals(SceneLoaderAppState.GROUND_NAME)) {

		float move = farthest.getDistance();

		if (geomType.contains("point")) {
			move-=bbox.getXExtent();
		}

		parentFeatureNode.setLocalTranslation(new Vector3f(move * -1f, 0f, 0f));
		System.out.println("Distance? " + farthest.getDistance() );

	}

}

}
[/java]

The parentFeatureNode holds 1 or more geometries. geomType can be line, point or polygon. The point is handled differently as it could be a model, Box mesh or similar, whereas lines (currently) are being added as polylines and therefore have no width and rather random X,Y dimensions.

The polylines are translating nicely with a distance of around 82f. The point (read Box()) is getting a distance but for some reason isn’t translating at all - The only difference is that lines have no local translation as the vertex coordinates are created with respect to the scene axis, whereas points are translated to the correct world position.

I thought that translating a parent node would also translate all children, with the child translation added on top - Is this not the case, or am I missing something else?

Cheers.

Yes, of course translating a parent node translates the children.

It is strange that your floor normals all point in Z as if Z is up but your ray that you want to cast “down” is casting down in the x axis.

Just from a coding conventions standpoint it’s also strange that you set the closest collision to a variable called “farthest” but I assume you keep all of that straight somehow.

Very true, these are both strange! Essentially through test numerous times I haven’t got to renaming variables back correctly.
The coordinate axis are still up for grabs at the moment in that I don’t have a standard way of going from standard to those used in the app.