[sort of solved] Model falls through some geometry

Tried to make that title as descriptive as possible :stuck_out_tongue:

I’ve generated 2 CollisionRay solids, and each one is one a separate model node. They’re processed in the same loop, actually-- there’s really nothing different about them.

Each Ray is added to its own collision node, and then the CollisionRay nodepaths and the CollisionHandlerFloor are passed to the colllision traverser.

The first model with its accompanying CollisionRay drops out of the sky and lands on the ground–All is well.

The second model with its accompanying CollisionRay drops out of the sky and actually passes through the ground, and then instead collides with a different plane beneath the ground. (The plane itself is the water in the world.) I haven’t the foggiest idea why the second one doesn’t act more like the first. As stated above, both collision solids are created, passed to the handler, and then passed to the traverser all in the same for loop.

This isn’t a question of dropping out of the sky too quickly and passing through the geometry in a single frame-- This happens when I place the model 50 feet over the ground or 1 foot. It doesn’t matter.

It’s hard to get more specific than that without giving you all of the code (it’s getting rather lengthy), and I’m sure nobody wants to wade through all of that just to find a tiny weird part.

I’ve looked at the render.ls() printout of the Scene Graph layout, and both model nodes with their CollisionNodes are identical… Is there anybody who might know right off the bat what the problem could be? I can supply more details if needed, but I really have no idea what else could possibly influence this.

Thanks!

oooo, actually, this might be a polygon-collision problem, where my thing is slipping through for some reason.

When I position model2 exactly where model1 is, model2 stays up on the ground just fine. However, when I move model2 around in realtime, I can watch him slip through the geometry…

Hmm… Well, if that’s the case, then it’s a pity that the CollisionTube doesn’t work well (if at all?) as a From object. Without that, you could perhaps use more than one ray - perhaps a triangle of three around your current ray position. If you use the position of the current ray’s collision to set the object to the the appropriate height, then you should, I think, be able to get away with averaging the results of the set of rays and using that for most situations, at least.

Of course, this has its problems. First of all, it doesn’t guarantee that you won’t encounter problematic situations; it does however, I think, reduce the probability of such occurring by a fair bit. The more rays that you use, the less likely the object is to fall through the floor, I believe (the degree depending on your placement of the rays, I imagine). Second, it is doubtless more expensive than a single ray. Finally, there are circumstances (such as having the object placed on a peak) in which the averaged height could be visibly incorrect. IF such situations are an issue, then you might look into other means of getting the appropriate height - directly from a height field, if you’re using one, or perhaps moving the rays further inwards, towards each other.

huh… this is a little goofy…

Thaumaturge, I thank you muchly for your response. It’s actually given me an idea for how I want to do character movement later on.

For now, I was playing with where the origin of the Rays were, and it seems that if I put the array ANYWHERE higher than at z-coordinate 0, I don’t slip through.

Can I petition that this sort of behavior gets put into the Manual/Reference? If the CollisionRay is left at the origin, the Object influenced by the HandlerFloor will slip through a geometry mesh that isn’t a Plane.

As for your suggestion, Thaumaturge, I think I may be implamenting it for some of my more complex character-environment movement ideas. I’m not settling for just any game here :slight_smile:

Fair enough - I’m glad that you seem to have a solution to your problems, and to have prompted your idea. :slight_smile:

Right, if the ray begins at (0, 0, 0), then when its object lands on the floor, the ray will begin exactly at the floor and continue downward from there. This means that, if the numeric calculation were perfect, it would always detect the floor collision every frame thereafter (because the ray intersects the floor at exactly one point, its beginning point).

In practice, numeric calculation on a computer is far from perfect. Floating-point numbers hold at best a loose approximation of their true value. Most of the time, it’s close enough–but if your code relies on the detection of just one point of an infinitely thin plane, you’re walking on thin ice, so to speak.

Raising the ray at least a little bit makes it much more likely that the intersection will be detected, for obvious reasons.

There still remains the possibility that the intersection will be overlooked, for instance in the gap between polygons. You will have to write your code so that it does not ruin the game if the floor is occasionally missed. This is a rule of thumb when working with any collisions system: you have to design for the occasional failure.

David

I more or less had the same problem with collision rays (and I think Roaming Ralph has it too). e.g. when you have 2 polygons that connect exactly at one point (exactly the same vertex) and the ray is going exactly through this edge then there may be no collision (i have tested the same code on two different computer and got different results).
IMO you always have to consider a second approach e.g. lookup your heightmap or use a collision primitive with a volume.

Fancy thing is that even mega budget games like Crysis have problems with collision detection (the bug happened to me too).

The issue I’ve had with collision solids is that there aren’t many good choices for “from” obejcts. I’d kill for a cube. I don’t care how expensive it is to calculate, but sometimes I just want a cube. Not 6 planes, because those extend infinitely toward the “back” side of the plane. Not 6 square polygons, because polygons don’t support “from” collision. Not spheres, because those don’t have a nice shape. Not the Tube because there aren’t many collision detection routines written for it.

[color=darkred]
the Sphere would work decently if I could scale it so that it was taller than it was wide, but that doesn’t work so hot for the collision routines yet…

All in all, I feel rather stuck with a Ray, but I’d kill for a cube.

I even considered making a polygon cube around my character as an “into” object, and then compose my walls/etc of “into” objects, but then I have no good choices for “into” solids for use with the walls…

My only thought, to keep this relatively simple, and to keep it within the bounds of collision detection, I’d stick 2 rays under the character, and then check to see if there’s a big difference between the collision’s Z coord. If one is smaller than the other, then just keep the bigger one.

for realistic movement and balance (which I plan to eventually tackle) I’m considering parenting the Rays to the moving feet of the character, to really be able to detect what you’re weight should be on.

… but a height map comparison would be nice. I want to avoid having multiple forms of detection, though, because it means that I’ve got 2 things to change if my terrain ever needs adjustment…

Thaumaturge has already written it. With more than one ray you only minimize the probability. If both rays are exactly on a edge you may get two wrong z coordinates. Maybe you have bridge with a river beneath. In this case you don’t fall through the whole scene but onto the river, where your character maybe never has any chance to get out.
What about stacking two spheres with a small radius? A sphere may also have the advantage that you can ascend a stair.

Well, I’d expect that this dual-Ray system would need more technical work than simply giving it 2 Ray solids, but yes, I agree.

As for the “never getting out” thing, that shouldn’t be much of an issue, since the world is designed to allow you to go to any place that you can see, virtually. The issue to me seems to be stopping your character for accidentally going someplace where you can’t see :smiley:

The dual-sphere idea may be workable, but I really wish that I could just use a box. The spheres will still get in the way at times… the character’s collidable area will be big around the shoulders and knees, yet small everywhere else.

My other reason for wanting a box is to be able to “push” other things around on the world, simply by collision. With spheres, it’s impossible to maintain a pushing motion for any longer than a few frames at best, before the object slides to one side.

It’s getting more and more complicated (but rock solid CD is not an easy task IMHO). What if you distinguish this two situations? CD against bottom = method 1 and CD against characters = method 2? I think you can even benefit from a small sphere at the characters feet. If you distinguish situations it may even get faster because your Collision Traverser doesn’t need to check anything.

that’s true-- the CollisionHandlerEvent (and Pusher, and Physics) all send events to Panda, so you could catch them and pass them onto the right method depending on what you’ve collided with.

One complication with having multiple spheres is that it’ll be hard to make them touch or overlap because they’ll be colliding with each other inside of your character.

However-- Imagine this: Use the BitMasks for collision to your advantage. Reserve bits 1 through 10 (for example) for character collision spheres/rays/whatever. A sphere on the head of a character would have a “from” BitMask of 1, the spheres over hands would have a “from” Bitmask of 2, legs 3, torso 4, etc, etc. Each of their “into” masks would be 0 or something, to prevent them from recieving collisions from random objects. More importantly, because they’re all on different Masks, they won’t collide with each other.

Secondly, Bits 11 through 32 could be for environment objects… ground, buildings, walls, enemies, etc etc. All of their “from” masks would be 0, but their “into” Masks would be all of the Bits from 1 to 10, in order to allow them to recieve collision from each of the body parts of the character.

Events are fired off upon collision, and then you could extract which body part it was that was responsible for the collision, as well as allowing only certain body parts to collide with certain other objects.

There’s more that would have to be worked out, but what do you think? :stuck_out_tongue:

It’s true that doing what you described would/could work, but you don’t need all the collision masks, because if you set the “into” bits on the rays/spheres to allOff and their from bits to, say, 1, they would not collide with each other. Then the environment only needs one bit to collide with the players and the others can be used for other graphical effects…

yes, what you’ve said is true, but I’m also trying to achieve the effect of making certain parts of the body only capable of making important desired collisions.

For instance, if I have an environment where I can move the character’s hand, I only want collision to be detected if I wack a paricular object with the hand, and not with the head or torso or leg.

For me, solving the slip-through (when the collision point is exactly at triangle edge) by using multiple rays is ridiculous. I’d like to expand the triangle edge a little instead, to build some kind of skirt around it. From my test, 1.0e-6 is enough.
CollisionPolygon::is_right (in collisionPolygon.I) :

  return (v1[0] * v2[1] - v1[1] * v2[0]) > 1.0e-6;

Using 0 threshold is a great recipe for a weird behavior, especially when it’s used for decision making like this.

Egad. Why didn’t we do that in the first place? I’ll make the change.

David