Intersection check between a CharacterControl and a Spatial?

Hi,

I’ve been pulling my hair out for 2 hours now and tried various things, but I can’t quite figure out the proper way to do an intersection check between a CharacterControl and a Spatial.

inb4 make a collision listener. I already have one that I use but what I need for this case is to check when the 2 objects STOP colliding, therefore the collision event listener seems to be useless in this case since it’s only there to detect collisions and not the countrary.

I have tried to play with bounding volumes, but even tough I create a Spatial and set a model bounding volume on it, when I getWorldBounding() on it it’s always null.

Anybody has suggestions for this case?

Thx

@.Ben. said: inb4 make a collision listener. I already have one that I use but what I need for this case is to check when the 2 objects STOP colliding, therefore the collision event listener seems to be useless in this case since it's only there to detect collisions and not the countrary.

Some pseudo code:

boolean areColliding;

simpleUpdate() {
areColliding = false;
}

collisionListener {
colliding() {
areColliding = true;
}
}

Not pretty and slightly trickier then that but it can work.

Hi Paul,

Yes, I already tried this, but it does not work or when it does it’s 50% of the time wrong, because the collision event listener runs in parrallel and therefore updates are asynchroneous it seems. Sometimes it’s off unfortunately.

@.Ben. said: Hi Paul,

Yes, I already tried this, but it does not work or when it does it’s 50% of the time wrong, because the collision event listener runs in parrallel and therefore updates are asynchroneous it seems. Sometimes it’s off unfortunately.

There is a way to run code at the end (or beginning?) of a physics tick. You’d have to put the flag clearing and checking there, I guess.

Oh really, now that’s very interesting, can you elaborate on how to inject code before/after the physics tick? That really seems like a solution to this case.

@.Ben. said: Oh really, now that's very interesting, can you elaborate on how to inject code before/after the physics tick? That really seems like a solution to this case.

I’ve never used the built in physics before… but looking in the javadoc:
http://hub.jmonkeyengine.org/javadoc/com/jme3/bullet/PhysicsTickListener.html

OK, I implemented what you showed me, which looks very simple, but for some reason, it never calls those functions. I put a println() in them and it never goes there, whether collisions happen or not. It does go in my collisions event handler tough, just not the PhysicsTickListener implemented functions. Weird. Maybe it’s broken in nightly builds? (would doubt so, since it looks so simple)

That sucks, because it would look actually look like a very good solution candidate for this case.

Here’s how I implemented it, maybe you guys can see if I did something wrong that makes the functions never be called at runtime:

[java]
//
public class Main extends SimpleApplication implements ActionListener, PhysicsCollisionListener, PhysicsTickListener, ScreenController {

@Override
public void prePhysicsTick(PhysicsSpace space, float tpf) {
System.out.println(“Falling…?”); // Never gets called
is_falling = true;
}

@Override
public void physicsTick(PhysicsSpace space, float tpf) {
System.out.println(“Falling2…?”); // Never gets called
is_falling = true;
}

@Override
public void collision(PhysicsCollisionEvent event) {
// This does get called a lot…
}

}

[/java]

Do you invoke addTickListener() somewhere?

1 Like

… stupid me haha! GOOD catch. +1’ed for this. Now it calls the handlers indeed :smiley:

OK but it does about the same thing as what’s described in Paul’s first method, which is most of the time it’s off, meaning that often, between the time it takes to go from prePhysicsTick() to collision() there is a simpleUpdate() pass and thus, it thinks it has not collided (or vice versa)…

I fear this is too dirty of a trick for this to work in this case.

OK, so… what I did for now is that I have declared a variable like so: int is_falling_ticks_counter = 0;

…and on every physicsTick() I increment it: is_falling_ticks_counter++;

…and in collision() handler:

[java]
if(collided_node.getName().contains(“TerrainQuad”)){
is_falling = false;
is_falling_ticks_counter = 0;
}
[/java]

…and in simpleUpdate() loop:

[java]
if(is_falling_ticks_counter > 30){
is_falling = true;
is_falling_ticks_counter = 0;
}
[/java]

So… I imagine this will break easily on lower end CPU’s or if there is lag for some reason on runtime, 30 ticks might not be enough or might be too much on faster CPU’s I guess. It’s pretty dirty.

Anybody knows the proper way to detect the lack of collision between a CharacterControl and a Spatial? It’s basically the countrary of the collision event handler. I also read that it’s possible to get a list of colliding spatials using a GhostControl but I’ve never used it and I’m really unsure how to bind a GhostControl to… or… in place (?!) of the CharacterControl.

Thx for reading.

@.Ben. said: ... stupid me haha! GOOD catch. +1'ed for this. Now it calls the handlers indeed :D

OK but it does about the same thing as what’s described in Paul’s first method, which is most of the time it’s off, meaning that often, between the time it takes to go from prePhysicsTick() to collision() there is a simpleUpdate() pass and thus, it thinks it has not collided (or vice versa)…

I fear this is too dirty of a trick for this to work in this case.

The idea would have been that you’d do ALL that logic in the physics tick and collision listener. No more simpleUpdate(). It’s running out of control, obviously.

Clear the flag on start tick, set it in the collision listener, check it on end tick… call appropriate code.

1 Like

uhmmm… I see. But I mean, I see so many things that will end up depending on if the CharacterControl is falling or not, it even extends to other handlers like onAction() for key presses… by this, are you implying I should put all code that checks on if the player is falling inside the physicsTick() handler so that it is synchronized with the collision check?

EDIT: Isn’t there a way to compute if the CharacterControl intersects with the TerrainQuad instead? I’d just do that check every simpleUpdate() pass… not depending on implementing the physicsTick interface and stuff /only/ for this check :stuck_out_tongue:

I foresee another problem too: the CharacterControl is a capsule shape right, so it’s possible that NOT ALL frames will collide with the TerrainQuad right? That means that it will cause problems even if I synchronize collision checks with simpleUpdate(). In fact, it may already be happening, that’s why it’s not “perfect” and it’s off most of the time I guess. Then I’d have to “smooth out” the on/off variations so that even if it’s “off” for a couple frames, it remains “on” until a certain threshold of “off” states are met.

Wow this is a lot more complicated than I first imagined! :stuck_out_tongue: But at the time I’m writing this, it’s already quite well working even tough it’s quite a dirty fix. I’m just unsure of how well/bad this will work on older computers… or maybe faster ones too. Not sure. I’ll +1 you Paul for the effort, but I fear there is no perfect way of doing it if it’s not by computing the intersection of the CharacterControl on the TerrainQuad each simpleUpdate() pass.

@.Ben. said: uhmmm... I see. But I mean, I see so many things that will end up depending on if the CharacterControl is falling or not, it even extends to other handlers like onAction() for key presses... by this, are you implying I should put all code that checks on if the player is falling inside the physicsTick() handler so that it is synchronized with the collision check?

I didn’t actually know you were checking for falling… but either way. Yes, but I don’t think it’s that much code.

“Am I colliding with something under me? No? Then I might be falling if that’s been true for x frames.”

BetterCharacterControl is the one that’s an actual physics object, right? Is there a reason you aren’t using that one?

I saw CharacterControl was deprecated and wanted at some point to do the switch. I checked a couple weeks ago quickly and found out all the lines of code to set the player up were broken after changing the declaration from CharacterControl to BetterCharacterControl, like setGravity(), setJumpSpeed() and all those setup functions are not longer supported, so I feared it was going to be problematic and decided that until now, CharacterControl was offering EXACTLY what I wanted… ok well… except for the fact that I can’t check intersection on its shape and also maybe… that I can rotate completely upside down (which I fixed myself the first week I used JME3 by limiting the angle) ahah! >.<

Are you saying BetterCharacterControl would enable me to do a collideWith() on a Spatial? BECAUSE… that would be awesome!! :smiley:

No, I’m saying it would handle falling.

I have no idea why you are doing what you’re doing so I can’t offer any better advice. Sometimes when you work in the microproblem then you miss the macro-solution.

Well, I suppose that using the BetterCharacterControl is exactly what I need then. But I’ve been trying to migrate from CharacterControl for over an hour now and it doesn’t go well. I followed the example and I even have it open side by side and I can’t for the life of me figure out why the player is INDEED MOVING but as soon as I release the keyboard key, it reverts back to the start location. Like if I do:

[java]
// Player
start_position = new Vector3f(0, 600, 0);
player_physics = new BetterCharacterControl(1.2f, 2f, 0);
player = new Node(“Player”);
player.setLocalTranslation(start_position);
player.addControl(player_physics);
bulletAppState.getPhysicsSpace().add(player_physics);
rootNode.attachChild(player);
[/java]

Then if I press W and maintain it pressed, I see that the coordinates of the player node are 0,600,3 which is weird because it means that it’s sticking to 3 units forward… isn’t it supposed to add 3 on each frame? The worst thing is that if I release the W key, it goes immediately back to the starting location which is 0,600,0 so it means that there is some place that reverts any movement or sets it back to the starting location.

I have never had any issues like this with the old CharacterControl. I’ll have to dig some more… man, I never thought I’d be wasting over an hour just to migrate from CharacterControl to BetterCharacterControl… I must really have missed a tiny but so important detail… but what is it… that’s the question! O.O

Dumb question: but are you really 100% sure you aren’t resetting the position somewhere?

I have no experience with any of this but I’ve also never read a thread with this problem before.

Edit: alternately are you still doing movement yourself on input?

1 Like

100% positive about reseting the position anywhere in the code. I tried to reuse the walking code I had, but obviously it didn’t move at all, so then I took the example code and it moved the player node, but I need the camera to follow so I began tweaking it and I think I have found the culprit. I’m sorry for the noobness, but I figured that if I do not put a mass in the BetterCharacterControl instanciation, it would not move at all. I think it’s because the BetterCharacterControl applies gravity forces instead of translating the player (like it was before with CharacterControl). That’s one big change that really breaks the compatibility, but I figured out the biggest problem and now it moves freely and bounces all over the place because it has like advanced physics that bounces when it collides on objects… it’s… I mean, it’s fun, but it’s not what I want to do, so now I’m gonna spend another hour trying to figure out how to remove all those fancy physics addons haha… but at least it’s… mostly… working right now with the BetterCharacterControl except for annoyances, like I have to subtractLocal() on Y because else the player is like a rocket and it flies all over the place in air LOL >.<

BUT BACK TO THE MAIN ISSUE, it is SOLVED by using this BetterCharacterControl because this control already implements the PhysicsTick() handler you guys pointed yesterday and also, since it’s a physics control it already has the collideWith() functions available, which is A LOT easier and faster to poll collisions than use the old way. As a matter of fact, I think I do not need the old collision() handler anymore because now I can poll the collisions list whenever I want anywhere in the code and it’s already synchronized with the simpleUpdate() loop if you will, so it’s constantly returning correct values.

Thank you Paul and Stephen.

+1’ed you Paul.

Case closed! (almost, I just need to stop the rocket physics madness here, JUST F*** walk will ya!)

Translated though you don’t realize it yet:
“BetterCharacterControl does what I want because of advanced physics… now I just need to remove all of the advanced physics.”

See you back at step 1. :slight_smile: