Can't test for collisions when using "Collisions" function multiple times

Started by Kippykip, February 05, 2018, 15:21:53

Previous topic - Next topic

Kippykip

I was programming bullets for my little project, and I noticed I can't actually test for multiple collisions in OpenB3D.

Here's what I mean, if I was to use the "Collisions" command, other commands will only work for the last type I used "Collisions" on:
Collisions DEFS.Collision_Bullet, DEFS.Collision_Map, 2, 1 'Make it stop with map
Collisions DEFS.Collision_Bullet, DEFS.Collision_NPC, 2, 1 'Make it hit npcs too

I would set the bullet to have collisions for the NPC and another one for the map itself.

However here's where the problem starts, it only detects the collision from last entity type I used "Collisions" on.
So if I was to use something like CountCollisions(), it would always stay at 0 unless it hit the DEFS.Collision_NPC type.
This also affects EntityCollided aswell, if I test for example:
if(EntityCollided(BulletEnt,DEFS.Collision_Map) 'Will always = 0 even when it hits that type
if(EntityCollided(BulletEnt,DEFS.Collision_NPC) 'Will equal something once it collides with the NPC type


Not to sure what's causing this, but I was wondering whether anyone knows a workaround. I don't actually recall this happening with Blitz3D or MiniB3D but I could be wrong.

Kippykip

I made an example of the bug

Import openb3d.B3dglgraphics
Graphics3D(640, 360, 32, 2, 60)

'Create a light, don't need a var for it.
CreateLight(1)
'Create the camera
Global Camera:TCamera = CreateCamera()

'Create a basic Map
Global Map:TEntity = CreateCube()
PositionEntity(Map:TEntity, - 3, 0, 10)
EntityColor(Map:TEntity, 128, 255, 128)

'Create a basic enemy
Global Enemy:TEntity = CreateCube()
PositionEntity(Enemy:TEntity, 3, 0, 10)
EntityColor(Enemy:TEntity, 255, 128, 128)

'Types
Const Type_Map:Int = 1
Const Type_Enemy:Int = 2
Const Type_Bullet:Int = 3

'Apply the types
EntityType(Map:TEntity, Type_Map:Int)
EntityType(Enemy:TEntity, Type_Enemy:Int)

'Define collsions, you can swap these in a different order for a different effect
Collisions(Type_Bullet:Int, Type_Map:Int, 1, 1)
Collisions(Type_Bullet:Int, Type_Enemy:Int, 1, 1)

'Bullet Function
Global Bullet:TEntity
Function CreateBullet(X_Pos:Float)
'If one already exists
If(Bullet:TEntity)
'Delete it
FreeEntity Bullet:TEntity
EndIf
'Create it
Bullet:TEntity = CreateSphere()
EntityColor(Bullet:TEntity, 255, 255, 0)     'Color it
ScaleEntity(Bullet:TEntity, 0.5, 0.5, 0.5)   'Scale it
EntityRadius(Bullet:TEntity, 0.5, 0.5)    'Set the Radius
PositionEntity(Bullet:TEntity, X_Pos, 0, 0)  'Reposition it
EntityType(Bullet:TEntity, Type_Bullet:Int)  'Set the type
End Function

'Main loop
While Not AppTerminate()
'Create the bullet depending on the key
If(KeyHit(KEY_Z)) Then CreateBullet(- 3)
If(KeyHit(KEY_X)) Then CreateBullet(3)

'If the bullet exists, move it forward
If(Bullet:TEntity) Then MoveEntity(Bullet:TEntity, 0, 0, 0.5)

UpdateWorld()
RenderWorld()
BeginMax2D()
DrawText("Press Z to spawn bullet on the left.", 0, 0)
DrawText("Press X to spawn bullet on the right.", 0, 12)
'If the bullet exists
If(Bullet:TEntity)
'If it hits the map?
If(EntityCollided(Bullet:TEntity, Type_Map:Int))
EntityColor(Bullet:TEntity, 128, 255, 128)   'Change the color
DrawText("Bullet's colliding with the map!", GraphicsWidth() / 4, GraphicsHeight() / 4)       'Inform you
'If it hits the Enemy?
ElseIf(EntityCollided(Bullet:TEntity, Type_Enemy:Int))
EntityColor(Bullet:TEntity, 255, 128, 128)   'Change the color also
DrawText("Bullet's colliding with the enemy!", GraphicsWidth() / 4, GraphicsHeight() / 3)           'Inform you
EndIf
EndIf
'Obviously the same glitch happens outside of the BeginMax2D/EndMax2D too.
EndMax2D()
Flip True 'Flip + Vsync
Wend


Edit: Just tested with Import sidesign.minib3d, the bug is only present in OpenB3D

markcwm


Kippykip

Quote from: markcwm on February 06, 2018, 13:19:15
Bummer, I'll have a look later. Thanks for the example.
Thanks Mark, and good luck!
It would be awesome to have this fixed, as me, my brother and a few friends are hoping to make a full entire retro FPS game out of OpenB3D + BlitzMax-NG. (Kind of like the recently released Dusk)
So far it's been a very very fun project, and you've been a hero quite a few times whenever something goes wrong in the project haha :D.


Derron

Just a minor thing - to improve readability:


PositionEntity(Enemy:TEntity, 3, 0, 10)
EntityColor(Enemy:TEntity, 255, 128, 128)


would run fine without the ":type" appendix.


PositionEntity(Enemy, 3, 0, 10)
EntityColor(Enemy, 255, 128, 128)

Excuse if you are aware of this.

OpenB3D provides a collision-sample too - and sets the collision mask each update loop. I tried that in your sample too - without a change (glancing at the cpp-source, this makes sense :-)).

bye
Ron

Kippykip

Quote from: Derron on February 06, 2018, 16:55:33
Just a minor thing - to improve readability:


PositionEntity(Enemy:TEntity, 3, 0, 10)
EntityColor(Enemy:TEntity, 255, 128, 128)


would run fine without the ":type" appendix.


PositionEntity(Enemy, 3, 0, 10)
EntityColor(Enemy, 255, 128, 128)

Excuse if you are aware of this.

OpenB3D provides a collision-sample too - and sets the collision mask each update loop. I tried that in your sample too - without a change (glancing at the cpp-source, this makes sense :-)).

bye
Ron
Thanks, I'm aware though but I was never sure myself whether it was standard to do so or not. Does anyone else do it or is it just me?
Anyhow, I just looked into the collisions example myself, that's very interesting.
If you open "mod\openb3d.mod\examples\blitz3d\collisions.bmx", you'll see that it actually ignores the ground. Putting the "Import sidesign.minib3d" on the top instead shows it actually does detect the ground.
Guess the bug was overlooked haha :P

Kippykip

EDIT: Double post sorry

Kippykip

I found a interesting fix! ;D
When I was tinkering around in mod\openb3d.mod\openb3dlib.mod\openb3d\src\collision2.cpp
In the UpdateStaticCollisions function I found that by disabling the line:
// clear collisions
ent.no_collisions=0;


It would fix the issue of not being able to test for multiple collisions, however it resulted in the CountCollisions function increasing every frame.
So that's not a great fix, HOWEVER when exploring the file, I found at line 525 there was a disabled version of the same UpdateStaticCollisions function!!

And when uncommenting the code on the bottom of the file, and commenting out the function that's on the top. IT FIXED THE BUG ENTIRELY!
No idea why this function is commented out when this one works better!




NEVERMIND, DON'T DO THAT. The function is extremely buggy and gets type numbers mismatched with other type values causing stop collisions when it should be slide etc.

markcwm

Hi Kip,

well I am working on this if you're wondering, I did find a fix which is a smallfixes fix from topic=87446. That makes your example work but doesn't work (for the ground) in the blitz3d/collisions example, I am debugging it now and it is detected in updatestaticcollisions but then it seems to disappear from the collision list.

I never wrapped the collision objects as it was a bit complicated and messy looking and there are lots of commands to get access to everything anyway.

markcwm

Okay, I have a fix! See the repo.

It was due to the way Minib3d and Openb3d loop through collision pairs, Angros changed it but didn't notice that he was deleting the entities collision list every loop so only the last collision would still be there.

I also added a "smallfixes" collision functions lag fix from here: http://mojolabs.nz/posts.php?topic=87446

I updated the blitz3d/Collisions example as it seems the collision list is in reverse in Openb3d so using CollisionEntity may need index set to CountCollisions() instead of 1. I haven't investigated this but it seems to work fine.

Kippykip

Quote from: markcwm on February 13, 2018, 02:31:21
Okay, I have a fix! See the repo.

It was due to the way Minib3d and Openb3d loop through collision pairs, Angros changed it but didn't notice that he was deleting the entities collision list every loop so only the last collision would still be there.

I also added a "smallfixes" collision functions lag fix from here: http://mojolabs.nz/posts.php?topic=87446

I updated the blitz3d/Collisions example as it seems the collision list is in reverse in Openb3d so using CollisionEntity may need index set to CountCollisions() instead of 1. I haven't investigated this but it seems to work fine.
https://www.youtube.com/watch?v=P3ALwKeSEYs
I suspected it was something to do with it clearing the collisions being reset early, but I'm not good at C code at all. Glad that it's fixed! :D
OpenB3D just got a bit more stable!

markcwm

LOL! Yes, bug fixing can feel pretty good!

I just uploaded a fix that inverts the index order of the entity collision vector functions because this was reversed in Openb3d. I tried a reverse loop through the collision pairs but collisions didn't work well so I inverted CollisionXYZetc(index) by no_collisions-index. CollisionEntity works fine but the others are untested.

Also I've updated blitz3d/collisions.bmx again, I tested this in Minib3d (and B3d) and the ball disappeared sometimes when hitting the pyramid, so I added a D to drop the sphere, it doesn't seem to happen in Openb3d so I won't investigate more.

markcwm

Another update (I think that's the final one now). Instead of inverting the index in the collision functions I just changed push_back(obj) to insert(begin,obj) in collision2.cpp. Seems to work fine.

markcwm

Just reviving this topic to say the multiple collisions fix broke standard collisions in the ball_collisions demo. Getting both to work was tricky, I think I had to use my sixth sense but I seem to have fixed it now! ;D

RemiD

@markcwm>>not sure how the collisisions detection / repositionning system that you have coded work, but i have coded a collisions detection / repositionning system in the past and it worked in "steps" (each step, only one turning moving collider turns moves and all others colliders are static.) and this allowed to have collisions between turning moving entity <-> static entities entity but also between turning moving entity <-> turning moving entity

The system used linepicks and pickables (low details shapes) and it was rather fast !

You can see a code example (Blitz3d) here :
https://www.syntaxbomb.com/index.php/topic,2011.msg15313.html (reply#1)
( the code is unecessarily bloaty, but it was coded 3 years ago, so hey ;D )