August 25, 2019, 12:24:06 AM

Author Topic: Can't test for collisions when using multiple types?  (Read 208 times)

Offline Kippykip

  • Jr. Member
  • **
  • Posts: 90
    • Kippykip Forums!
Can't test for collisions when using multiple types?
« on: August 07, 2019, 02:24:42 PM »
It seems a collision issue has re-surged but in a different way.  :(
It's kinda hard to explain, but I demoed it on YouTube with my project: (after 0:40)



It seems now, if there's multiple entities using the same type, which tests for 2 or more other collision types. If one of the entities is not hitting anything, the EntityCollidedand CountCollisions functions break for the rest of the entities spawned afterwards using the same type.
I have made a small example demonstrating this bug specifically:
Code: [Select]
'Init scenery
Import openb3dmax.b3dglgraphics
Graphics3D(800, 600, 32, 0)
Global Camera:TCamera = CreateCamera()
Global Map:TEntity = CreateCube()
Global NPC:TEntity = CreateCube()
PositionEntity(NPC, 0, -6, 0)

Global Light:TLight = CreateLight(1, Camera)
PositionEntity(Camera, 0, 2, -5)

EntityType(Map, 1) 'Give the Cube a collision type of 1
EntityType(NPC, 3) 'Give the "NPC" a collision type of 3 - DISABLING THIS LINE FIXES THE DETECTION ISSUE FOR THE MAP! But of course, breaking collisions with the NPC type.
EntityColor(Map, 0, 255, 255) 'Give the cube a colour
Collisions(2, 1, 2, 1) 'Make type 2 (Bullets) collide with type 1 (the cube/map), with "ellipsoid-to-polygon" collisions with a stop response.
Collisions(2, 3, 2, 1) 'Make type 2 (Bullets) collide with type 3 (the NPC), with "ellipsoid-to-polygon" collisions with a stop response.

Type RedBullet
Global List:TList = CreateList()
Field BulletEntity:TEntity
Field DespawnTimer:Int

Function CreateEnt(TMP_X:Float, TMP_Y:Float, TMP_Z:Float)
Local TMP_RedBullet:RedBullet = New RedBullet 'Create the type
TMP_RedBullet.BulletEntity = CreateSphere() 'Create a sphere
EntityColor(TMP_RedBullet.BulletEntity, 255, 0, 0) 'Make it red for visual
EntityType(TMP_RedBullet.BulletEntity, 2) 'Give the Bullet a collision type of 2
PositionEntity(TMP_RedBullet.BulletEntity, TMP_X, TMP_Y, TMP_Z) 'Position the bullet to the specified arguments
RotateEntity(TMP_RedBullet.BulletEntity, EntityPitch(Camera), EntityYaw(Camera), 0) 'Rotate the bullet to whatever the camera currently is
'Scale it down, it's huge
ScaleEntity(TMP_RedBullet.BulletEntity, 0.1, 0.1, 0.1)
EntityRadius(TMP_RedBullet.BulletEntity, 0.1, 0.1)
TMP_RedBullet.DespawnTimer = MilliSecs() 'Keep track of what time it was spawned
ListAddLast(RedBullet.List, TMP_RedBullet) 'Add to update list
End Function

Method Destroy()
FreeEntity(BulletEntity)
ListRemove(List, Self)
End Method

Function Update()
For Local TMP_RedBullet:RedBullet = EachIn RedBullet.List:TList
MoveEntity(TMP_RedBullet.BulletEntity, 0, 0, 0.5)
'Destroy on impact
If(EntityCollided(TMP_RedBullet.BulletEntity, 1))
TMP_RedBullet.Destroy()
Print "HIT!"
Else
'Destroy if it hasn't hit anything after 5 seconds (5000ms)
If(MilliSecs() >= TMP_RedBullet.DespawnTimer + 5000)
TMP_RedBullet.Destroy()
Print "Bullet despawned"
EndIf
EndIf

Next
End Function
EndType

While Not(AppTerminate())
MoveEntity(Camera, 0.1, 0, 0) 'Pan the camera around
PointEntity(Camera, Map) 'Face the cube
RedBullet.Update() 'Update the bullets
If(KeyHit(KEY_Z)) Then RedBullet.CreateEnt(EntityX(Camera), EntityY(Camera), EntityZ(Camera))
If(KeyHit(KEY_X)) Then RedBullet.CreateEnt(EntityX(Camera) + 5, EntityY(Camera), EntityZ(Camera))
UpdateWorld()
RenderWorld()
Text(0, 0, "Press Z to hit the blue target, press X to completely miss target.")
Text(0, 10, "If you miss a target with X, actual collisions will break on the Z key until missed bullets despawn.")
Flip()
Wend
WaitKey
End

I really hope this can be fixed! :)
(Also markcwm, do you have a patreon account of any kind? I'd love to support the OpenB3D wrapper in anyway I can!)

Offline markcwm

  • Sr. Member
  • ****
  • Posts: 397
Re: Can't test for collisions when using multiple types?
« Reply #1 on: August 08, 2019, 03:00:39 AM »
Hi Kippy,

yes you've exposed a bug which I had introduced in the previous collisions fix, using your example code it didn't take me long to find the problem, so thanks for that! It should be fixed now, it basically just needed a change to one line in collision2.cpp.

Thanks for your offer of support, I don't have a Patreon page and don't really need the money anyway but if you want to help you're already doing enough with these uber bug reports, I have so few beta testers so that's worth more than money to me. You could also contribute directly to the wrapper in some way, add your own module, like a Kippy FPS framework, or more examples, whatever you have and I'll credit you for it but it must be stable, have examples and/or docs explanation.

Offline Kippykip

  • Jr. Member
  • **
  • Posts: 90
    • Kippykip Forums!
Re: Can't test for collisions when using multiple types?
« Reply #2 on: August 08, 2019, 04:28:12 AM »
Hi Kippy,

yes you've exposed a bug which I had introduced in the previous collisions fix, using your example code it didn't take me long to find the problem, so thanks for that! It should be fixed now, it basically just needed a change to one line in collision2.cpp.

Thanks for your offer of support, I don't have a Patreon page and don't really need the money anyway but if you want to help you're already doing enough with these uber bug reports, I have so few beta testers so that's worth more than money to me. You could also contribute directly to the wrapper in some way, add your own module, like a Kippy FPS framework, or more examples, whatever you have and I'll credit you for it but it must be stable, have examples and/or docs explanation.
Thanks man, as I've said before OpenB3D is probably my favourite hobby!
As for this FPS project made with it, when it's more feature complete I'm planning on releasing the entire BMX source code to the whole thing.

This project currently supports the following:
*A special FMV format (although using jpegs for frames, so low resolution only)
*Ingame console (Which runs data\autoexec.txt on startup, making every level setup from console commands)
*FMOD 3D Sound
*Low resolution rendering effect with scanlines (Using RenderToTex, such a useful command! :) )
*Dynamic Music (Using FMOD Streaming, supports playlists under the same filename)
*Weapon Scripts (.WPN files, with a weird instruction set, still needs work atm)
*Full Deltatime support, plus a second variable for slow motion effects ingame
*Decals
*Everything extends a "BaseEntity", making everything easily manageable and unloadable (and in debug mode, delete/undo stuff with Z)
*Supports a \Mods folder, anything in there with the same filename will get loaded instead
*Player stamina, death, health, jumping physics, crouching, DUSK like flipping, view bobbing.

And plans for the future
*NPC mouth lipsyncing
*NPC A* Pathfinding
*Oblivion like inventory
*Dropped inventory items
*NPC hit detection (for hands, legs, headshots etc)
*GMOD spawn menu (for debugging/creating levels)
*Particles
*Maybe Ingame Cutscene Scripts?

I'll likely release on GitHub in the future, but I'd like to make an actual game using this as a Base first, as everything is a placeholder right now.
This would not at all be possible without your module, and I absolutely thank you for that! :D
While this project isn't a module extending functions of OpenB3D, I could probably provide some small examples .BMX for things I used for OpenB3D in general if that would help the project?

Offline markcwm

  • Sr. Member
  • ****
  • Posts: 397
Re: Can't test for collisions when using multiple types?
« Reply #3 on: August 09, 2019, 01:16:15 AM »
Hi Kippy,

okay, well open-sourcing your project on Github would be great for Openb3dmax, especially if it can be used as a base for other FPS projects.

That's a pretty big list, I am interested in a delta time example as I never really got my head around how it works, added to the core module, or just point me to somewhere I can learn how.

When it comes to particles I recommend you use batch sprites instead of the library particles as they're really fast and easier to work with.

Also, what gfx card/s do you have? It seems alpha blending breaks on some old cards. Thanks.

Offline Kippykip

  • Jr. Member
  • **
  • Posts: 90
    • Kippykip Forums!
Re: Can't test for collisions when using multiple types?
« Reply #4 on: August 09, 2019, 04:27:14 AM »
Hi Kippy,

okay, well open-sourcing your project on Github would be great for Openb3dmax, especially if it can be used as a base for other FPS projects.

That's a pretty big list, I am interested in a delta time example as I never really got my head around how it works, added to the core module, or just point me to somewhere I can learn how.

When it comes to particles I recommend you use batch sprites instead of the library particles as they're really fast and easier to work with.

Also, what gfx card/s do you have? It seems alpha blending breaks on some old cards. Thanks.

I'm using a GTX 1060 for development, although I have also tested it on an old tablet and Windows 98 PC.
I did notice something odd on my tablet with a black border around the decals I should probably have a look into it as I haven't tested it on there in a while. I think it uses some form of Intel HD Graphics.
The last time I tested it under the Windows 98 was probably last year but I remember it lagged horrendously unless I disabled use of shaders and the RenderToTex command. (Likely due to being an OpenGL 1 card, the Geforce FX 5950 Ultra).

As for DeltaTime, I don't remember where I originally sourced the example code from in the userdocs but I do remember porting it to BlitzMax back in 2015 or so.
At some point I expanded it with a stable FPS counter, added a secondary variable for slow motion effects and turned it into a type. I also added some caps so it didn't go too fast or divide by 0 for example.
Anyhow here's the DeltaTime code straight from my project
Code: [Select]
'Deltatime FPS counter
Type FrameRate
Global TargetFPS:Float = 60
Global SpeedFactor:Float = 1 'The variable that everything physics etc will multiply with, but can be tampered with host_timescale.
Global SpeedFactor2D:Float = 1 'The variable that everything will multiply with.
Global host_timescale:Float = 1 'Used for inventory stuff and cool epic slowmo mechanics :o
Global FPS:Float = 0
Global TicksPerSecond:Int = 1000
Global CurrentTicks:Int
Global FrameDelay:Int
Global FrameDelayStable:Int
Global FPSStable:Int
Global FPSAddStable:Int

Function Init(TMP_TargetFPS:Float)
TargetFPS = TMP_TargetFPS
FrameDelay = MilliSecs()
FrameDelayStable = FrameDelay
End Function

Function Update()
CurrentTicks = MilliSecs()
SpeedFactor2D = (CurrentTicks - FrameDelay) / (TicksPerSecond / TargetFPS)
If(SpeedFactor2D > 8) 'Don't wanna go lightning speeds over a stutter, cap it at 480FPS
SpeedFactor2D = 8
ElseIf(SpeedFactor2D <= 0) 'Eugh this breaks some things when its exactly 0
SpeedFactor2D = 1
EndIf
SpeedFactor = SpeedFactor2D * host_timescale 'host_timescale enables use of cool slow mo features etc

'Ported Blitz3D example code
FPS = TargetFPS / SpeedFactor2D
FrameDelay = CurrentTicks
'I don't exactly recall how this all worked, just that FrameRate.FPSStable is what you use to display a proper FPS counter
FPSAddStable:+1
If(CurrentTicks > FrameDelayStable + TicksPerSecond)
FrameDelayStable = CurrentTicks
FPSStable = FPSAddStable
FPSAddStable = 0
EndIf
End Function
End Type

Everything that you use in OpenB3D has to be tied to the above variables. For example:
Code: [Select]
UpdateWorld(FrameRate.SpeedFactor)
MoveEntity(Entity, 0, 0, 0.1 * FrameRate.SpeedFactor)
And at the beginning of your code, use FrameRate.Init(60)
If you modify FrameRate.host_timescale, everything tied to DeltaTime will move differently, such as setting it to 0.5 will half everythings speed.
If you use FrameRate.SpeedFactor2D in a line of code, FrameRate.host_timescale won't affect it. This is useful once you have utilised slow motion effects for example, but have 2D elements fading in or something that you don't to be affected.

If you've already written a project, porting it to use DeltaTime would definitely require a huge rewrite. Which is why I implemented it straight from the beginning.
Here's a video of me messing around with the variables. (Not to be confused, the set gfx.timescale command I'm typing in the console is actually using FrameRate.Init(). FrameRate.host_timescale is being used for the sepia slow motion effect that I'm planning to turn into an Inventory.)

I also have this older video I forgot I made, which was the original DeltaTime code written for Blitz3D. There's a download in the description.


Enjoy! :)

Offline markcwm

  • Sr. Member
  • ****
  • Posts: 397
Re: Can't test for collisions when using multiple types?
« Reply #5 on: August 14, 2019, 03:25:01 PM »
Hi Kippy,

thanks for the delta time code and the tutorial! I haven't looked at it yet but will soon. Its good to know that Openb3d is working well on a Geforce 10. :)