system
April 23, 2011, 5:46pm
1
I am trying to extend the Hello Collision tutorial for a small game.
I want to add 3 Oto objects and be able to shoot them.
I started with the tutorial code and added
[java] private Node createOto(float x, float y, float z)
{
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
CharacterControl oto_character = new CharacterControl(capsuleShape, 0.01f);
//load model
Node oto = (Node) assetManager.loadModel(“Models/Oto/Oto.mesh.xml”);
//set position
oto.setLocalTranslation(x, y, z);
//set size
oto.setLocalScale(0.5f);
//enable shadows
oto.setShadowMode(ShadowMode.CastAndReceive);
oto.addControl(oto_character);
bulletAppState.getPhysicsSpace().add(oto_character);
return oto;
}[/java]
This places the Oto’s on the scene but know I have 2 problems
The objects and not on the ground but rather float a bit above the ground.
I can run trough the objects without colliding
system
April 24, 2011, 12:16pm
3
normen thanks for the fast response.
For the first I checked with bulletAppState.getPhysicsSpace().enableDebug(assetManager); to finetune the capsule.
For the second I created a special Node (otoNode) and added a GhostControl for every oto.
During the simpleUpdate I looped trough all the nodes in otoNode to see if there was anything overlapping.
One other Issue I am having now (don’t know if I should start a new thread), is that when I add animation to my oto I get a error.
[java]
AnimControl control = oto.getControl(AnimControl.class);
control.addListener(this);
AnimChannel channel = control.createChannel();
channel.setAnim(“stand”);
[/java]
The given listener is already registed at this AnimControl
when I do control.clearListeners(); before the addListener it doesn't give the error and runs as expected
normen
April 24, 2011, 12:58pm
4
Well, so you add the listener some time before already.
system
April 24, 2011, 3:40pm
5
which seems odd since I don’t do that explicitely
[java]private Node createOto(float x, float y, float z, String name) {
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 2f, 1);
//CharacterControl oto_character = new CharacterControl(capsuleShape, 0.01f);
GhostControl oto_ghost = new GhostControl(capsuleShape);
//load model
Node oto = (Node) assetManager.loadModel(“Models/Oto/Oto.mesh.xml”);
//set position
oto.setLocalTranslation(x, y, z);
//set size
oto.setLocalScale(0.5f);
//enable shadows
oto.setShadowMode(ShadowMode.CastAndReceive);
//oto.addControl (oto_character);
oto.addControl(oto_ghost);
bulletAppState.getPhysicsSpace().add(oto_ghost);
otoNode.attachChild(oto);
oto.setName(name);
AnimControl control = oto.getControl(AnimControl.class);
// control.clearListeners();
control.addListener(this);
AnimChannel channel = control.createChannel();
channel.setAnim(“stand”);
return oto;
}[/java]
cealex
April 26, 2011, 4:35pm
6
Hi!
for example if you use a class like that:
public class HelloCollision extends SimpleApplication
implements ActionListener, AnimEventListener {
when you call the first
createOto(10, 4, 0, “test”);
you register this class “HelloCollision” as an event listener.
AnimControl control = oto.getControl(AnimControl.class);
control.addListener(this); //note the this statment
so, in the second call, you will try to register, again, the same listen class, and the code throws
an exception: “The given listener is already registed at this AnimControl”, because the class HelloCollision as already registered
as listener.
createOto(15, 4, 0, “test_1”);
system
April 26, 2011, 5:32pm
7
that’s what I thought and tested
In the simpleUpdate method I added a call to checkCollision
[java]
private void checkCollision()
{
List<Spatial> otos = otoNode.getChildren();
for (Spatial oto : otos)
{
GhostControl otoGhost = oto.getControl(GhostControl.class);
if (otoGhost.getOverlappingCount() > 1) {
System.out.println(“Collision”);
List<PhysicsCollisionObject> objects = otoGhost.getOverlappingObjects();
System.out.println(oto.getName());
AnimControl control = oto.getControl(AnimControl.class);
control.getChannel(0).setAnim(“push”);
}
}
}[/java]
and I added
[java]public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
System.out.println(“AnimCycleDone”);
if (animName.equals(“push”)) {
channel.setAnim(“stand”, 0.50f);
channel.setLoopMode(LoopMode.DontLoop);
channel.setSpeed(1f);
}
}[/java]
This would mean the push anim is triggered during a collision with the GhostControl (CapsuleCollisionShape) and after the first anim it would return to ‘stand’. However it does not trigger the “AnimCycleDone” and keeps on repeating the push anim.
When I explicitly perform control.clearListeners(); and control.addListener(this); It works as I expected it.
cealex
April 26, 2011, 6:45pm
8
instead of using checkCollision use the PhysicsCollisionListener to detect collision’s
public class HelloCollision extends SimpleApplication
implements ActionListener, AnimEventListener, PhysicsCollisionListener {
…
@Override
public void collision(PhysicsCollisionEvent event) {
if (event.getObjectA() instanceof GhostControl) {
//System.out.println (“A-Object- collision detected”);
System.out.println(“A ->” + event.getNodeA().getName());
}
if (event.getObjectB() instanceof GhostControl) {
//System.out.println (“B-Object- collision detected”);
System.out.println(“B ->” + event.getNodeB().getName());
}
}
1 Like
system
April 26, 2011, 7:01pm
9
thanks. I also added bulletAppState.getPhysicsSpace().addCollisionListener(this);
Still strange that animcycledone is not triggered in my custom checkCollision method but is triggered in the collision method.
cealex
April 26, 2011, 8:20pm
10
drice said:
... I also added bulletAppState.getPhysicsSpace().addCollisionListener(this);
yes, I forgot in example code to put the call addCollisionListener ...
I think it is the following, but I'm not sure ...
when a collision happens an event is triggered, and that can be processed in
the event handler or not (if we don't set up the trigger), after that, the "colision
state" is cleared, so only by chance will be detected in the simple update ...
imo
system
April 27, 2011, 6:19am
11
hmmz but in the simpleUpdate we don’t check for the event. We check to see if there is an overlappingcount higher than 1. So I think this succesfully detects an overlap (in hindsight wrongfully for a collision since you already have an overlap).
I will do some more testing to see why the after the animation is done the animcycledone is not triggered. This has nothing to do with the collision since this only triggers the animation
cealex
April 27, 2011, 7:37am
12