[solved] Window Dragging and Collision

I’m having this problem, say, whenever I click and hold on the window’s title bar, the rendering freezes, sure, but at the same time, the collision testing also freezes and as a result of this, my avatar can move through walls, bypassing the collision test…

If this is a coding problem, how can I fix or prevent this?

yes its a coding problem. maybe you have to loop over it twice. i dont think its a big deal to fix this.

if you use a collision primitiv do a bigger offset.

or do a second ray. maybe for each feet one.

new entry:
sorry, i was missunderstanding your problem.

One easy thing is to enable the respectPrevTransform() flag as described in the manual under “rapidly-moving objects”.

David

Actually, I do have respectPrevTransform set to True.

But I think it has to do with the large delta time for the movements that’s causing the instantaneous warping from point A to B so instead of taking steps and checking for collision, the avatar warped over that amount of distance…

Does anyone have a clue how I can get around this?

That’s what respectPrevTransform means: that anytime the avatar (or any object) moves from A to B within one frame, no matter how far apart A and B are, the collision system should consider that the avatar actually moved through the straight line connecting A and B, and it should compute the collisions accordingly. So in theory, this should completely solve the problem.

In practice, it doesn’t do 100%. For instance, it’s possible that the straight line from A to B still somehow avoids your collision solids (but it shouldn’t allow your avatar to escape a closed room). It’s also true that respectPrevTransform really only works on the sphere-polygon test, so it only works if your space is modeled with polygons–but it doesn’t work on the sphere-sphere or sphere-tube test, so if there is a wall of spheres or tubes, your avatar can still pop through. Finally, even given all that, it’s still an approximation (as is any collision test), and it’s always possible for the approximation to fail.

Still, it should work pretty well. If your space is modeled with polygons, and fully enclosed; and your avatar is a sphere, he shouldn’t easily escape when you have respectPrevTransform enabled, even when you have frozen the frame for a very long time. If he does, something else may be wrong, for instance in the way you are moving the avatar (ensure you use setFluidPos() and not just setPos(), for instance).

David

Thanks for the explanation and I am fully aware that what you said is how respectPrevTransform should work and that it must be used in conjunction with setFluidPos, which I have also been using.

The method that I’m using to move the avatar is as follows:

self.avatar.setFluidPos((position + direction) * speed * globalClock.getDt())

I have a sphere attached to the body of the avatar that relies on CollisionPusher for wall detection and a CollisionRay for its feet to detect the ground. I’m also using the Ralph’s map for testing, which contains hills.

Let say the situation is that I’m standing in front of the hill, which is point A and destination B is exactly behind the hill. Normally, whenever the frames are smooth, it should and does advance towards the top of the hill then down. But because the frame is frozen due to dragging, then released after a few seconds, globalClock.getDT() grows too much that, as a result, the calculated position is exactly in the hill or already at B within one frame because the game loop was frozen.

If it ends up in the hill, it can’t detect collision because there’s nothing that can be collided inside the hill since it’s empty space.

Or if it’s already at B within this one frame, doesn’t that mean the avatar has simply just warped, without the possibility of collision testing?

I think this is the best I can put it and if I’m wrong conceptually, correct me as I’m just a beginner.

Ah, right. That’s a special case. In that case, the CollisionRay cannot detect the sloping ground, because you have moved completely below the ground in the space of one frame, and there’s no way for the ray to notice the intervening motion.

So, in that case, there’s not a lot to be done. One thing you can do is limit the size of any one frame, and assume anything larger than that is an error, for instance:

dt = min(globalClock.getDt(), maxDt)

and then use this new dt for your computation. Then you only need to choose a maxDt value that is large enough to allow your normal motion, for any frame rate you expect to achieve, but small enough that your avatar cannot move completely through the slope of the terrain within one frame.

In fact, there is a maxDt value already built into Panda, for just this purpose. You can enable it with:

max-dt 0.2

(or whatever value) in your Config.prc file. This will limit the value returned by globalClock.getDt().

David

Perfect!