Code to collide with a moving object and move with it.

Blitz3D Forums/Blitz3D Programming/Code to collide with a moving object and move with it.

sswift(Posted 2003) [#1]
http://www.balpoint.com/~squishy/dcol.zip

This is a modified version of Simon harrison's dynamic collison code. Someone asked me how to make the code allow you to walk onto a moving platform and move with it, and I coded a new function for the collision system which handles that in a basic way. I leave it to you to figure out how to apply fristion and stuff if you so desire. This basically will tell you where a specific point on the moving platform is one frame, and where it has moved to in the next. I just make the model move in the same realtive manner as that collision point for one frame after the collision if that collision point appears to be on a floor. If the models continue to collide, then it continues to stick. This works with rotating platforms as well. And you can of course move about on the platform normally as you continue to move with it.

The only thing this code needs now is the ability to scale the dynamic collision objects without breaking the collision, and the ability to collide with more than one such object at the same time. (I think that would involve translating all the copies of the colliding object at once, and determining when the first collision occured and then moving all the colliding objects to that location.)

Don't email me for support. If you have a question use the forums. :-)


Binary_Moon(Posted 2003) [#2]
:)

Have you managed to get the character to rotate with the object, or is it just the position that changes?


Rob(Posted 2003) [#3]
Excellent work swift ;)


sswift(Posted 2003) [#4]
Just position.

To do rotation, one method you could use is to create a second point offset from the collision point by one unit in the direction of the object's Z axis, and then transform that point in the same manner from one frame to the next. Then each frame, use aligntovector to align the object's Z axis to the vector formed by the two points.


Binary_Moon(Posted 2003) [#5]
ok - I got rotation working... kinda.

Occassionally the collision goes wonky, which I don't want (obviously).

Play it and you will see what I mean.

http://www.binarymoon.co.uk/preview/dccol03.zip

edit : just noticed you need to change the include name to get this to work.


sswift(Posted 2003) [#6]
I'm sorry but I can't fix that. You broke something. And you didn't do what I said to do. :-) I don't see an aligntovector or a point being transformed anywhere. :-)


sswift(Posted 2003) [#7]
I notice you put some new code in DCO_Update. You should not do that. Any code for handling friction should go in that seperate function dofriction. People may not want this sort of fake-friction cheat in the physics, and so it needs to be seperate. And it makes things simpler to understand.


sswift(Posted 2003) [#8]
Why in the world did you remove the # symbol from all the floating point numbers in the dofriction function? It may make the code a little easier to read but it will inevitably lead to bugs where you have failed to typecast a variable as float without realising it.


sswift(Posted 2003) [#9]
I tried using your example code without the friction stuff I added, and when you turn the enetity weird things happen. And I tried the old example code without turning with the new system and weird things did not happen. Therefore, the turning of the colliding entity... the sphere and cube, is revealing a bug in the original collision code with dealing with such a thing. Or it could be the person who sent me their version of the collision code to repair to make this collision code work caused the bug, because the version of the collision code I got from them had all new collision normal getting functions, since the old ones seemed to be broken when working with multiple entities. But I know he changed more than that.

So for now I guess the system is broken. I'll see if the original version of the system has this issue.


sswift(Posted 2003) [#10]
Yup, the original code has the same problem. Nobody tested with collider entity which can rotate, and doing so causes glitches. I don't know how to fix this issue, and I don't have time to go over the code with a fine toothed comb to figure out why it occurs.

So I guess you didn't break anyhting. Well, you DID, but not by doing something wrong. :-)


Rob(Posted 2003) [#11]
Then UNBREAK it perminantly :)


Bot Builder(Posted 2003) [#12]
Aye. I'm 'anxiously waiting" for this routine to be "finalized". okay, not really. but still... I don't understand how it works and can't really help in making it better. I probably *could* get it if I put effort into it, but eh.


sswift(Posted 2003) [#13]
Each time you create a new pair of objects, it creates two new invisible entities at some far off location in the world. I will refer to these as the collider, and the collidee.

Imagine the original collidee is a rotating block. And imagine the original collider is a ball that is unmoving.

In this case, the invisible objects would be doing the opposite. The copy of the colidee never actually moves. The invisible ball would be rotating around the colidee to simulate how and where it would hit the colidee if the collidee were actually rotating and the ball were sitting still, as the real copies are.

This is how the system fools Blitz's collision system which can't handle tweo moving objects colliding.

It should also be notedm that in addition to rotating around the copy of the collidee if the collidee is rotating, the collider will also move relative to the copy of the collidee in the same relative manner that it moves relative to the real collidee.

If it sounds complicated, it is. I understand it well enough, but still was having problems getting scaling to also work, and I'm pretty sure you can get that to work as long as you scale uniformly on all axes.


Binary_Moon(Posted 2003) [#14]
I'm sorry but I can't fix that.


I CAN - I worked out what was wrong

You broke something. And you didn't do what I said to do. :-)


I broke nothing, and what I did is based on a method you suggested in the original dynamic collision thread.

I notice you put some new code in DCO_Update.


I did, but the code I added was not specific to the friction command, all it does is store the amount of rotation of the dco. It affects nothing else and saves adding another for next loop in the friction function.

So does anyone want to know how I fixed it... lol ?

If it sounds complicated, it is


Not really. All I did was change a single line of code.

What got me stumped was why the rotation mattered, the src entity is a sphere regardless of its rotation so why should its angle mess things up.

At first I thought it was the collision normals that were being read wrong because of the different angles... but nope, that doesn't matter. The normal is the normal of the mesh to the sphere which won't change. Below that, though, is the command

moveentity c\src_ent... blah de blah


Of course, rotate the entity and its going to move in the direction the entity is facing rather than move in world coords (as required). Change the command to 'TranslateEntity' and everything works fine.


sswift(Posted 2003) [#15]
Ah I think I foufn that bug before, and I fixed it in the version fo the library I was cleaning up, but then people sent me all these modified versiond of the original code so I said screw it and went back to using the regular library and forgot about what I fixed. :-)


poopla(Posted 2003) [#16]
May I ask for a breif overview of how this is being done?


Marcelo(Posted 2003) [#17]
That's what I've done in my game, I don't know if it's the same approach as this lib:

In your GameUpdate() function:
- Move the player, thus applying gravity;
- UpdateWorld(0);
- Check if the player collided with the "ground" (CollisionNY()), if yes, add the player as a child at the collided entity;
- Move the entities (platforms, trains, elevators), if the player is standing on these entities he will be moved together;
- Restore old player parent (EntityParent()) and scale (ScaleEntity()), scale get messed up if you collide with a scaled entity;
- UpdateWorld(animspeed);

This worked perfectly in my games, and the player also is rotated;

Some details of this approach:
- You need to use some "verlet-like" integration for player physics (derivating the speed from the old position), this way, if the player is in the top of a moving train for example, it will behave correctly if you jump; it also allows to make an catapult to throw the player away, hehe;

- It only works if the player collides with the object, but you can assign an ellipse to the object so it can push the player also. But it's very hard to assign an elipse to an odd shaped thing like a platform or a train;

- Two UpdateWorld()'s per frame doesn't seems to slow down anything, because I think blitz only check collision for moving things.


sswift(Posted 2003) [#18]
Marcelo:
The method in this library allows the object to push the player. So if the player collides with a moving, rotating box, they will be pushed back. The method you describe does not allow that.

But the verlet-like physics trickery sounds useful.


poopla(Posted 2003) [#19]
sswift, would you care to explain what it is doing?

[edit] Just saw your explanation above.