Two Entity collision response?

Blitz3D Forums/Blitz3D Beginners Area/Two Entity collision response?

funkmaster5000(Posted 2016) [#1]
Dear community,

I have been trying to wrap my head around this several times, as the problem is haunting me since my first (few) steps in 3D programming, but maybe I am missunderstanding/missusing the collision detection functions of B3D.

I have two cars and one track. I assign the constants
const col_world = 1
and the constant
const col_car = 2
. After that I give my track the
EntityType track,col_world
and the car the
EntityType car,col_car
. After that I set
Collisions car_col,world_col,2,2
. Works like a charm.

Now I have two cars, both collide. When I assign Car1 the
EntityType col_car
and Car2 the
EntityType col_car
and set
Collisions col_car,col_car,2,2
it works, but only one entity responds (Car1)...which is correct I guess? But how can I get the second entity to response? Do I have to use another technique? Think about a LAN Game. Do I have to do


Thanks in advance and kind regards.


RemiD(Posted 2016) [#2]
You may want to take a look at this code example ( http://www.blitzbasic.com/codearcs/codearcs.php?code=3141 ) which demonstrates how to detect collisions with different turning moving ellipsoid colliders.

If this does not work, i remember that i have done tests about collisions of different turning moving ellipsoid colliders and the idea was to have one constant to store the start id of the collision group and use one different id for each turning moving entity of the collision group. And define collisions between each collision group (each entity).

For example :



That's the idea...


Guy Fawkes(Posted 2016) [#3]
My masterpiece is finally done! :D Idc if any of you hate it. I'm PROUD of it!

Here's a special type of Collision demo I made!

Collision_Demo_3D.bb ::



Hope this helps!

Enjoy!

~GF


Bobysait(Posted 2016) [#4]
when you updatecollisions, then you can access to the collisions encountered
-> you can use EntityCollided to get the second entity of the current collisions (according to entitytype specified)
-> or you can CollisionEntity to get the second entity involved in the collisions at specified index ( Index is the collision index of the entity when you loop the collisions encountered on the last UpdateWorld, in the range 1 to CountCollisions(entity) )

Notice that when 2 entity collide while both moving, they will generate a collision, but then will pass one through the other
The blitz3d collisions are nice for some stuff, but not very accurate for "great physic" stuff.


funkmaster5000(Posted 2016) [#5]
Hey guys,

thanks for helping me out on this.

@RemiD
Your first example features exactly what I want to achieve. Is it limited to spheres only? If so, should I
- declare the car as a sphere collider (how do I determine the radius then)? Except for guessing, because that doesn't help me understand the fundamentals at all.
- use a sphere the same radius as the collider, make it the car's parent, make the sphere invisible (alpha = 0)?

A sphere doesn't come into my mind at first, when checking for collisions of boxy cars. But my several tries showed, that it generates great smoothing at corners etc.

@Guy Fawkes
Thanks for sharing this mate. It gave me a good understanding, how to access the entities, which are affected by the collision. Maybe I ditch the internal Blitz collision response and code the responses myself. Since it's an arcadish racer, I might be able to use both movement vectors and apply them in the oppisite direction on collision (I'm a noob, that idea may be ridiculous).

@Bobysait
Thanks for the further info on working out the entities that collide. It helped me to understand Guy Fawke's code. Your hint is very much appreciated, because that was exactly what I was experiencing. Both cars, all set up, both moving, sliding through each other. But it's an arcade racer (and I'm new to 3D), so I couldn't understand, why all cars stopped reacting.


funkmaster5000(Posted 2016) [#6]
Hey guys,

thanks for helping me out on this.

@RemiD
Your first example features exactly what I want to achieve. Is it limited to spheres only? If so, should I
- declare the car as a sphere collider (how do I determine the radius then)? Except for guessing, because that doesn't help me understand the fundamentals at all.
- use a sphere the same radius as the collider, make it the car's parent, make the sphere invisible (alpha = 0)?

A sphere doesn't come into my mind at first, when checking for collisions of boxy cars. But my several tries showed, that it generates great smoothing at corners etc.

@Guy Fawkes
Thanks for sharing this mate. It gave me a good understanding, how to access the entities, which are affected by the collision. Maybe I ditch the internal Blitz collision response and code the responses myself. Since it's an arcadish racer, I might be able to use both movement vectors and apply them in the oppisite direction on collision (I'm a noob, that idea may be ridiculous).

@Bobysait
Thanks for the further info on working out the entities that collide. It helped me to understand Guy Fawke's code. Your hint is very much appreciated, because that was exactly what I was experiencing. Both cars, all set up, both moving, sliding through each other. But it's an arcade racer (and I'm new to 3D), so I couldn't understand, why all cars stopped reacting.


Bobysait(Posted 2016) [#7]
Most of the time, 3D perception is just a 2D with some different elevation.
If you can "transform" the 3D logic to a 2D system, then you 'll be able to use 2D collisions library (that works much better)

For example, cars on a track mostly involve only 2D reactions (except if you need some jumps and gravity)
Box2D or any kind of verlet collision system will be great for this. Those are 2D physic library that should be better than the blitz3d collisions.

And yes, Blitz3D collisions can acheive different kind of response for collisions (sliding/stop etc ... with different kind of interactions elipsoid/box/polygons) but it only works for the "receiver". The emitter will always use an elipsoid for collisions, and that's what makes it fast ... and hard to use accurately in most cases.


RemiD(Posted 2016) [#8]
Guy Fawkes's code has several errors, (as always) so don't take this as a reliable example...


There is another way which i have used in the past to detect collisions between turningmoving non sphere shapes. (for example cars or spaceships)

The idea is to have a pivot for the root of your turningmoving entity, that you will use to turn move (or rotate translate) the entity.
And a hull made of several ellipsoid colliders set as child of the root pivot.
And have one collision group per turningmoving entity so that one turningmoving entity can detect a collision against another turningmoving entity (as explained in my previous example). (the ellipsoid colliders of the same turningmoving entity can be in the same collision group).

Also to prevent inaccuracies, you can calculate collision in steps, in each step you turn move (or rotate translate) only one turningmoving entity (and consequently its hull made of several ellipsoids colliders), then calculate the collisions between this turningmoving entity and the others entities (statics collidables and the others turningmoving collidables (which are static in this step)). With this approach, you have a hull made of several ellipsoids colliders for each turningmoving entity and a low tris mesh collidable for each static and for each turningmoving entity (when it is static).

With the same logic, you can forget about the collision system and use several linepicks cast from a position related to the root pivot and in a specific direction and with a specific length depending on the orientation and speed of the entity. And have a low tris mesh pickable for each static and for each turningmoving entity (when it is static).

Alternatively, take a look at the car physics example of BlitzBullet : http://www.blitzbasic.com/Community/posts.php?topic=95713


Guy Fawkes(Posted 2016) [#9]
Remi... Go screw yourself. At least I tried. D***...


funkmaster5000(Posted 2016) [#10]
@RemiD
The collisions are for a LAN game, I have converted (or should I say: wanted to convert) from 2D to 3D. At the beginning I had all clients simulate the physics themselves = horrible to keep synced. Then I broke down the physics to: two cars collide, reverse their vx and vy, so they don't collide anymore. Your basic arcadish 2D collision.

Then I jumped to 3D collisions, which I have been trying literally the whole day. Your example worked, yes. But if I assign the car the radius it needs to detect the collision with other cars, it overdetects collisions with the world and slows you down everytime you try to go on a ramp or sth. Then I've tried the 2D approach. On MeshIntersect(car1,car2), set collision to true, give both cars an impact in their opposite direction, so they don't collide anymore. Worked at first, but then a car got stuck in a corner due to level collision and the collision paramter never went false = both cars were stuck. Ugh. Then I tried an example from the codearcs (something with vehicle movement on terrain) and it provided beautiful movement worldwise. But went crazy when car to car collisions came into play. I really worked hard on this game and have gained a basic grasp of 3D programming in the process, but right now I feel stupid and frustrated. Should I seperate the collisions car->world and car->car? Maybe use the actual car mesh for the collision detection with the world (radius 0.25,0.25 work fine) and then a sphere for car to car (how do I translate the effects of the slide then?). Phew.


RemiD(Posted 2016) [#11]

Should I seperate the collisions car->world and car->car?


No, car->world is ok but to detect collisions between turningmoving cars you want to have one collision group for each car (the colliders of the same car can be in the same collision group) and if you want it to be more accurate, only turnmove detectcollisions reorientereposition one entity at a time (so all others turningmoving entities are static during this step)

About meshesintersect, you can indeed use this, it will be fast enough if you use a distance check before, to see which entities are near enough and must be considered for the meshesintersect check, but you won't be able to get the collision point or the collision normal...

An alternative to meshesintersect is the coldet lib to calculate collisions between meshes. Search the forum about that.

To decrease the mstime it takes to calculate collisions, you want to use low details meshes for collidables (the obstacles shapes) and medium/high details meshes for the renderers (the shape you want to display).
You want to position the collidables at the same position with the same orientation than the renderers and set their alpha to 0.
Then when you need to calculate collisions, only consider the collidables meshes (low details), not the renderers meshes (high details).

If you use the blitz3d collisions system with ellipsoids colliders and low details meshes collidables, it should be fast enough, unless your map has really complex shapes or is too big...


funkmaster5000(Posted 2016) [#12]
Thanks again for the reply. I will try to use MeshIntersect. Could you tell me, why I would need collisions points/normals?


RemiD(Posted 2016) [#13]
Also for meshesintersect, use low details meshes to decrease the time it takes to calculate.

About the possibility to get hat is the collided surface, the collision point, the collision normal, this is to be able to know which part of the car was collided, to be able to emit particles from the collision point, in the direction of the collision normal.
The normal is a vector (an arrow...) which starts from the triangle (a surface is made of vertices and triangles...) and which points to the direction the triangle faces/is oriented towards/looks at.


funkmaster5000(Posted 2016) [#14]
Oh snap. I have achieved some nice effects with MeshesIntersect (been working and trying for couple of hours now). This is it, stripped down basically, but I still have some trouble with it. If you would be so kind and look at my function below. The other car doesn't respond to the collision, but if I didn't get the loop wrong, it should check: this.car = car 1 against other.car = car 2 and after that this.car = car 2 against other.car = car 1. Then I basically retrieve the speed in all directions of car 2 and store it to the variables ix to iz (impact x to impact z). In the next step I apply the impacts to them untill there is no collision happening. As I've said, car 1 does respond, car 2 doesn't. And I need a way to retrieve the direction, in which the cars to push (I'm afraid, that's why ppl want to know the collision normals :P). Any chance of calculating it with...say...DeltaYaw? Thanks in advance.




RemiD(Posted 2016) [#15]

And I need a way to retrieve the direction, in which the cars to push (I'm afraid, that's why ppl want to know the collision normals :P). Any chance of calculating it with...say...DeltaYaw?


If you use vectors to translate your cars, when one car collides with another car you could indeed invert the vector but it will look inaccurate and ugly compared to being able to get the collided surface, the collision point, the collision normal, and calculate the direction in which the car must be redirected...

To go further, you could also use linearvelocity (moving speed) and angularvelocity (turning speed) to turn move your cars, for this take a look at a physics engine like Bullet (BlitzBullet)


Bobysait(Posted 2016) [#16]
@Guy Fawkes :
Proud or not, your code actually contains errors

Collisions type_car, type_scene, 2, 3
-> type_scene not defined

grav# = grav# * 1.0
-> grav is always "0" in your code.
0.0 * 1.0 is still 0.0.

your sky (which sould seriously be replaced with a CameraClsColor instead of a monochrome fliped cube) should be positioned with the camera position, not the player, and BTW, you have a loop for "all players" which assume you can load more than 1 player, the "sky" will be positioned on the last one. It's definitely not what you want.

Regarding the collisions :

You update the player collisions before the UpdateWorld ...
So, you react each frame on the collisions from the previous frame rendered.
Call UpdateWorld "Before" your "For each" loop on player type

You update object collisions after updateworld ... which seems to be good, but ... it's still not !
You call the renderworld after updateworld, so the "obj" Types are not updated before the next frame too.

What you should have done :
1 - move/rotate entities
2 - UpdateWorld to update collisions
3 - Intercept collision states (replace entities if required)
4 - update things that relates on position of "physical" entities
5 - Renderworld when everything is ok



Then your collisions will be updated correctly.

But ... there still remain 2 things :

1 / checking collisions against another collision_type is not very usefull, it doesn't return the position or the normal of the impact so there is nothing to do with but random entitycolor ...
-> for more robust collisions, you need to traverse all collisions with a "for c = 1 to countcollisions(entity)" and retreive the collisions informations using CollisionX(entity, c)/CollisionNx(entity,c) etc ...
You'll then be able to react on effective collisions.

2 / it still does not resolve the problem of two entities moving. they will generate a collision event and a small sliding on a single frame, but on the next loop, they will both traverse the other entity.
So, your code doesn't solve anything, but show a sample that is actually harder to read, sorry for that, but I can't approve your sample as a good example for understanding the problem of this topic.

ps : and there is no need to comment on every lines.
If the guy that read your code doesn't know what a "Else" or a "Endif" or a "Next" is, there is no way he will understand the purpose of the collisions. "First things First" he need to read some doc on blitz3d syntax, don't you think ?


funkmaster5000(Posted 2016) [#17]
If you use vectors to translate your cars, when one car collides with another car you could indeed invert the vector but it will look inaccurate and ugly compared to being able to get the collided surface, the collision point, the collision normal, and calculate the direction in which the car must be redirected...


I know you want to introduce a physics engine to me, but I need to grasp the basics before moving on to advanced examples (including a "whole" engine).

I have managed to use reverse vectors on collision. What happens is, that car 1 bounces back, when it hits car 2, car 2 stays still. So basically I have managed to move them out of the collision zone, so that they don't get stuck or accelerate forever. It doesn't look that smooth, like you've said, but I'm proud on it for my first 3D project! Still I don't get, why only 1 car is affected and the other isn't. What I want to happen is (Pseudo):

-On collision car 1 to car 2(3,4,5)
-Apply the velocity(x,y,z) of car 1 to the impact(x,y,z) of car 2(3,4,5)
-Apply the velocity(x,y,z) of car 2(3,4,5) to the impact(x,y,z) of car 1

-On collision car 2 to car 1(3,4,5)
-Apply the velocity(x,y,z) of car 2 to the impact(x,y,z) of car 1(3,4,5)
-Apply the velocity(x,y,z) of car 1(3,4,5) to the impact(x,y,z) of car 2

(Loop through all...)

-Apply the impact to all cars

What might work too, since it's an arcade game, compare the speed of the cars and if one is faster, apply an impact to the slower car and reduce the faster car's speed to a slower value (harcoded).




RemiD(Posted 2016) [#18]

I know you want to introduce a physics engine to me


Not really, i just suggested the available possibilities with Blitz3d...


You can get the collided surface, the collision point, the collision normal, with the Blitz3d collision system, and it is easy to use.

You may like this code example : http://www.blitzbasic.com/codearcs/codearcs.php?code=415