Hi,
I’m attaching an array of cone-shaped GhostControls to a spatial (a robot) to simulate a short range sonar sensor, i.e when the GhostControl facing a given direction reports a collision with a physics object, the robot reports a sonar hit in that quadrant. I’m trying to debug the implementation I have so far, and it would really help if there was some analog to
bulletAppState.getPhysicsSpace().enableDebug(assetManager);
for GhostControls, is there? Or should GhostControls should up with that command enabled and I’m not seeing mine for some other reason?
Thanks!
Uh, they should appear for ghost controls too… It does for me in the tests… Maybe you wanted to enable debug mode because you don’t have a collision shape? Its not auto-generated for characters.
Hey normen, awesome response time as usual… This was my code:
forward = new GhostControl(new SphereCollisionShape(1f));
forward.setSpatial(robot.Robot);
world.getStateManager().getState(BulletAppState.class).getPhysicsSpace().add(forward);
I built the GhostControl with a CollisionShape but from looking at the test code it needs to control a spatial (node) as well, which I haven’t done. Is that right?
You have to set the control to the spatial. Check the tutorials or at least the javadoc of the methods you try to use
Sweet! thanks normen
Btw you can create a sonar by making only one GhostControl with a SphereCollisionShape of your desired maximum sonar radius.
However, this i have only tested it for 2D → the height component is neglected
You can determine 2 things, direction relative to sonar direction and distance from sonar to object.
+++Set a fixed sonar direction vector+++
like: [java]Vector3f sonarDir = new Vector3f(0,0,-1);[/java]
OR implement a direction vector yourself (something like [java]CharacterControl.getViewDirection();[/java] or [java]VehicleControl.getForwardVector(null); [/java]). The important thing is the y Component must be zero.
+++Compute the direction from the sonar to the object+++
[java]
if (collisionObject instanceof PhysicsRigidBody) {
PhysicsRigidBody rigidBody = (PhysicsRigidBody) collisionObject;
Vector3f rigidLoc = rigidBody.getPhysicsLocation();
Vector3f dirToRigid = rigidLoc.subtract(sonarLoc).setY(0f);
}
[/java]
+++The distance from the sonar to the object is computed as follows+++
[java]float distanceToRigid = dirToRigid.length();[/java]
+++The directions relative to the sonar direction+++
-
North to South Direction (North = 1, West&East = 0, South = -1)
- 1 ... the direction to the object points to the same direction as the sonars fixed direction
- 0.5 ... the direction to the object is 45 degrees to the left or right of the fixed sonar direction vector
- 0 ... the direction to the object is 90 degrees to the left or right of the fixed sonar direction vector
- -0.5 ... the direction to the object is 135 degrees to the left or right of the fixed sonar direction vector
- -1 ... the direction to the object points to the opposite direction of the sonars fixed direction
[java]float northSouthDirectionOffset = sonarDir.dot(dirToRigid.normalize());[/java]
-
West to East Direction (West = 1, North&South= 0, East = -1)
- 1 ... the direction to the object points to the same direction as the perpendicular direction vector
- 0.5 ... the direction to the object is 45 degrees to the left or right of the perpendicular direction vector
- 0 ... the direction to the object is 90 degrees to the left or right of the perpendicular direction vector
- -0.5 ... the direction to the object is 135 degrees to the left or right of the perpendicular direction vector
- -1 ... the direction to the object points to the opposite direction of the perpendicular direction vector
let the perpendicular direction vector of the sonar direction vector be defined as the direction vector from right to left (east to west)
[java]float westEastDirectionOffset = sonarDir.cross(dirToRigid.normalize()).getY();[/java]
__
Combining the distance, the North to South Direction Offset and the West to East Direction Offset you should be able to pinpoint the position of the collision object!
wow, thats amazing nego, thanks!
You are lucky i just implemented it for myself an hour ago
Hey nego, i can’t understand your direction offsets, what about
float angleInXZPlane = dirToRigid.angleBetween(robot.ViewDirection.normalize());
?
That would be 100 times better yeah
hey one more question (probably for normen),
is it possible to get the ghostcontrol to return the point of collision rather than just the object which collides? I can’t find a method that can do that, and if I collide with a long object (say a wall) then knowing where it’s centre is isn’t nearly as useful as knowing where i collide with it…
thanks!
Hm, not so easily, no. The character uses a GhostControl and tracks each object and the penetration etc. separately.
I thought about trying to retrieve the spatials that are involved in the collision, and then using the collideWith() method, what do you think?
You’re basically mixing two types of collision detection by this… You can do anything you can do with the BIH collision in bullet too. (except mesh-accurate picking where you don’t have meshes but hulls ofc)
Yes, it’s definately unwieldy, but I can’t think of a better way of carrying a ghost shape around and detecting the impact point… maybe that functionality could be added to GhostControl?
Sure, go ahead
probably out of my ability range. But I think I could solve the problem if i come up with a method to calculate the shortest distance from one geometry to another… Do you know of such a method?
BoundingVolume.distanceToEdge?