[SOLVED] Need some tips on optimizing collisions

Community Forums/General Help/[SOLVED] Need some tips on optimizing collisions

RustyKristi(Posted 2015) [#1]
Hey guys, so I just needed some tips or samples from doing straight main loop code to using multi-threading to speed up and increase performance.

I'm planning either to stick with B3D using Fast Pointer or moving it to BMX. I'm sure the FOR NEXT loops needs to be threaded but still need more info to set this up properly.


Matty(Posted 2015) [#2]
My thoughts on multi threading -

it is far more than simply 'for next loops'....and at the same time that is not what it is about either.

Mostly with games you want things singlethreaded - especially the games at the level blitz produces....it is mainly of use when you have a call you wish to make to a routine that could potentially come back quickly or slowly (such as a network call) and you don't want it to hang/stall the main thread and where the time it returns with a result is not critical.

There are lots of things to be careful of with multi threading (such as touching the same variable in separate threads).

Re b3d....the most I'd use multi threading for if it were possible with blitz3d is offloading network calls (especially tcp) to a separate thread.


EDIT - some nice image compression speed ups can be had though by splitting an image into 4 or more channels (argb) and handling them each in a separate thread on a separate core - much, much faster than single threaded.


RustyKristi(Posted 2015) [#3]
ok thanks for the input Matty. As I saw from the old examples the bemchmarks were done using those loops or doing some heavy task or some kind.

i would really like to improve performance regardless of any methods. i hope its not my 3k poly models coz i can trim those down too.


Matty(Posted 2015) [#4]
Without knowing what you are making or what hardware you are aiming at it is difficult to know what to suggest re performance.

However......


typically in b3d:

Boned animations (b3d animations) will impact performance when you have more than about a dozen entities animating at once.

Loops within loops every frame, where the total calculations (such as square roots) are in the order of thousands every frame are a likely culprit.

Filling the screen with multiple overlapping full screen (or large) alphaed quads can have performance issues due to overdraw and sorting of the drawing operations.

Reading/Writing from/to disk during gameplay is a definite no no.....this will impact performance and should never be done.

Allocating large arrays or banks during gameplay will do this to a lesser extent (by large I mean tens or hundreds of megabytes of RAM at a time)

Using draw operations, writepixels,readpixels will affect performance.

Using text drawing operations will affect performance - the more text displayed the worse it becomes.

These are some general guidelines however....worrying about whether a for loop is faster than a while/wend is pointless - it is the big things to worry about when doing any optimisation at all/designing for speed.

For the most part blitz is fast enough that unless you are making big errors in your coding design you can get away with doing things in lots of different ways and there will be no appreciable speed difference because the inefficiencies will be elsewhere in things you have no control over (at least with blitz).


RustyKristi(Posted 2015) [#5]
Thanks. For the requirement, I guess you can say modern hardware down to a core/core2 duo and as for the graphics card any decent card that can max handle dx7 capabilities since its b3d.

I don't have loops within loops but I do have multiple loops within the main loop. Text is not that heavy but if I have a chatbox window will it affect performance?

It looks like I passed the general guidelines so do you think it's the 3k per models coz I have waves of them in the max of 60 - 80 meshes. :/

I have not implemented LODs and Occlusion Culling so I guess that's another major issue.


Matty(Posted 2015) [#6]
3000 triangles x 75 = 225,000 polygons - if they are animated it will struggle. If they are static then with blitz3d I cannot say...the actual raw numbers mean very little to me these days (been out of the PC game dev scene for a number of years)

Re: mesh detail.....

think of it like this - if the area taken up by your triangles is less than a few pixels ... do you really need that much detail?

I've been working in the mobile world for a while now instead and I try and keep my meshes to under 1000 triangles if I'm going to have lots of them (over 20 on screen at once)....

The easiest way to check if the chatbox window affects performance is to observe with and without...my guess is that if it is full of standard text then yes it will affect performance.

These 60-80 meshes - are they all visible on screen at once....if so then I doubt very much you need 3k triangles on each of them.

In the old days texture size would also be an issue but with the amount of memory on modern video cards I doubt it very much...


RustyKristi(Posted 2015) [#7]

think of it like this - if the area taken up by your triangles is less than a few pixels ... do you really need that much detail?

These 60-80 meshes - are they all visible on screen at once....if so then I doubt very much you need 3k triangles on each of them.



Yes, it is a pc game and I'm aiming for decent graphics and I could maybe trim it down to 2k to 1.5k and use normal maps. Sadly, that is another problem in blitz3d :/

No, the entities are not all at once on screen but maybe half of it. it's also arcade so a few hits and most of them are dead or gone.

In the old days texture size would also be an issue but with the amount of memory on modern video cards I doubt it very much...


I agree and I'm keeping it to 512x512 (probably a couple of 1024s) and just around 10 - 15 loaded textures that is around 200kb each.. :)


Hey Matty, do you have any experience or resources with occlusion culling or lods for blitz3d? :) seems to me this needs to be managed now.

thanks again.


Matty(Posted 2015) [#8]
Not a lot of experience with those other than to say that occlusion culling won't benefit you much with blitz3d since the effort required to work out if an object can be seen or not is often more than simply throwing it at the video card.

Hard to say with LOD - depends a lot on if the meshes are animated or static.

Still with half, 30 or so as you say on screen at once - I find it hard to believe that the detail of each of the 3000 polygon meshes will really be visible to the end user. Think of the size of the triangles when rendered on the screen - will some of them be less than a few pixels across...that is when LOD will come in handy.

What are these entities? Monsters, space ships, other objects?

If they are animated you would benefit hugely from using md2s instead of b3ds - finding a tool that still outputs md2s might be difficult in this day and age though....(milkshape does it but doesn't import b3d - only exports).

LOD does work well but it depends a lot on how quickly objects move in and out of the LOD stages - do they travel quickly from a position out of range to a position in range. Note - you can recycle meshes sometimes if you know that the same qty of objects will be in range most of the time.

Note LOD doesn't have to simply be the distance from the camera but it can also be based on the position on the screen - if an object is right in the player's focus (centre) you will want more detail than if it is on the edge or moving quickly.


RustyKristi(Posted 2015) [#9]
yes mostly vehicles and characters and other objects, typical 3d games. Right now I'm using static meshes for a demo. I guess LOD distance for starters to make it simple.


Yasha(Posted 2015) [#10]
Matty's advice on other areas is important, but I should also point out: threading in Blitz3D with FastPointer is not safe. Blitz3D's entire runtime is designed with the assumption that it will only run in a single thread. There is plenty of global and object state being manipulated behind the scenes without any locks or integrity checks or anything you need to implement a threading system. You cannot do anything interesting in a B3D thread (basically anything other than manipulate ints and floats in a bank) without risking data corruption.

Even if you tested some code and it didn't crash or leak, that doesn't prove it's safe, as multithreaded code has non-deterministic bugs that might-or-might-not show up depending on how the OS schedules it and how the CPU implements it.

Do not use B3D for threading. There are many, many other options that will serve your goals better, pretty much regardless of what your actual goals are (threading is actually not that easy to use for performance anyway, nor is it all that effective; a naive approach can actually slow your program down by a huge margin).


RemiD(Posted 2015) [#11]
The other thing which can cause slowdowns is too many different surfaces rendered...
For static meshes (trees, rocks, bushes, buildings, containers, machines, furnitures) which are in the same area, you can combine them in one suface with one texture.


About skinned animated meshes, i have never noticed a major slowdown because of that...
But my skinned animated meshes have always 1 or 2 influences maximum of a joint/bone over a vertex, so if your meshes have more than 2 influences it will take more mstime.
Also, for far away meshes it is pointless to use high detailed meshes and a skeleton with all joints/bones, just use a simplified version of the mesh and of the skeleton with less joints/bones so that it appears to be the same shape/colors/animation but it takes less mstime to update/render.



occlusion culling won't benefit you much with blitz3d since the effort required to work out if an object can be seen or not is often more than simply throwing it at the video card.


Not true in my experience, but it depends on what kind of game we are talking about... For indoor or closed areas, it will certainly decrease the mstime it takes to create a new frame. For outdoor or open areas, it is more complicated but compared to letting Blitz3d manages which meshes to render, it is worth it.


RustyKristi(Posted 2015) [#12]
Thanks guys for all your tips. So upon doing further testing, it got down to and might have to do with my collision system.

- Doing EntityAlpha entity,0 on all objects doesn't seem to make a difference, so I guess it's not the rendering part..

- when I used HideEntity entity while running the game, fps shoots back up obviously while AI still running. So the AI decision and other loops are out of the equation and it left me with collisions.

as per doc..

An EntityAlpha value of 0 is especially useful as Blitz3D will not render entities with such a value, but will still involve the entities in collision tests. This is unlike HideEntity, which doesn't involve entities in collisions.


So how do I do better collisions with many objects? of course, I'm using standard blitz3d collisions with simple setup. Do I have to deal with some physics dll library now or is there a way to not use it and keep it simple, blitz style? I hear coldet is another option and faster for doing basic collisions. http://telias.free.fr/3d_blitz3d.html

I also got a chance to read this old topic posted a decade ago and so far I think I'm doing alright, basically.
http://www.blitzbasic.com/Community/posts.php?topic=45945


I should probably change the title to collisions now since obviously multithreading is out of the question. ;-)


RemiD(Posted 2015) [#13]
If you use Blitz3d collision system, it only allows to detect and manage ellipsoid -> ellipsoid collision or ellipsoid -> mesh collision (ellipsoid ->box is useless imo)
So i suggest to use high details meshes for your "renderers" and low details meshes for your "collidables" (and hide them with entityalpha 0).

Note that you can set several ellipsoids as childs of a pivot and turn move the pivot to turn move all ellipsoids. This way you can have a kind of hull made of several ellipsoids, this can be useful if your character/vehicle has a non spherical shape. (for example, in the case of a humanoid character, (0.5x1.75x0.5) i use 6 ellipsoids with a radius of 0.5 positioned at 0.25,0.5,0.75,1.0,1.25,1.5, and set as child of a pivot. This allows to have a kind of collider capsule...)

Then if it is still slow, you can create ellipsoids colliders only when a turningmoving ellipsoid is near enough an obstacle. This means that you check if distance(turningmoving,obstacle) < turningmovingxzradius+obstaclexzradius+turningmovingmaxspeed and if yes you create an ellipsoid, if not no need to (an ellipsoid is usually associated to a pivot, and creating/destroying a pivot takes almost no time)

About coldet, i have done some tests with it and there were some weird results that made no sense to me. (when trying to do capsule collision vs random shape)

Personally i use linepicks and low tris pickables in my custom collision system because i have found that the Blitz3d collision system is unpredictable if i create/destroy ellipsoids on the fly. (the ellipsoids sometimes go through a collidable when they should stop)

Do some tests you will see.


Yasha(Posted 2015) [#14]
Coldet is crazy-fast, it's far superior to Blitz3D's native collisions performance-wise. B3D's built-in collisions are fairly basic and are definitely on the slow side, especially for anything->polygon. (This goes for picks as well.) Coldet is one of the fastest options out there for pure collision detection - to beat it, you need to get into the realm of dedicated high-end physics engines (in fairness I think this is largely because people don't write standalone collision libraries any more, but anyway).

NB that Coldet offers detection, but not response. You need to manually check for collisions and reposition objects accordingly in game code. This is not the part that causes B3D collisions to be slow - so reasonable code here ought to still be faster - but it is a tedious thing to have to do for yourself. Still, it gives you a chance to tailor the responses to your specific game's movement style (e.g. you can implement "pushers" quite easily by simply choosing to move Object B instead of Object A).


RemiD(Posted 2015) [#15]
Coldet could be good if the results were predictable and stable, but i have seen some weird results... (collision point position and triangle normal)

@Yasha>>What have you used coldet for ? Have you found some weird results when debugging or not ?


Yasha(Posted 2015) [#16]
I have used Coldet in the past for raypicking and poly-poly colliding (didn't check position, only that it happened) with a small number (< 12 or so) of very detailed trimeshes. I never noticed any problems with it at the time. Haven't done that sort of thing in years, though.


Kryzon(Posted 2015) [#17]
Ideally, as a game designer, you don't want to handle threading at all. You want the game engine to do that for you.

So you have to think if you want to dive into multi-threaded programming, or you want to make a game.


RustyKristi(Posted 2015) [#18]
Thanks guys, I'll check out coldet and see if it can fix my collision problem.

So i suggest to use high details meshes for your "renderers" and low details meshes for your "collidables" (and hide them with entityalpha 0).


Ok I'll try that one too. So I just create an EntityCollision on a separate low poly version then assign that to the entity?

NB that Coldet offers detection, but not response. You need to manually check for collisions and reposition objects accordingly in game code.


Wow, I thought it was a complete solution. I'll check out the examples if there are some..

Ideally, as a game designer, you don't want to handle threading at all. You want the game engine to do that for you.


That's true Kryzon and that's why where on the topic here before that I'm finding out how and if Blitz3D can handle that for me with all these options. ;-)

changed topic now to collisions


RustyKristi(Posted 2015) [#19]
@Yasha

Hey, I found your modified coldet wrapper here from a couple of years ago:

http://www.blitzbasic.com/Community/post.php?topic=100759&post=1192519

with added functions that copied blitz3d, that is cool! Can I use this and you have a basic example how will this work. thanks :)


RemiD(Posted 2015) [#20]

So I just create an EntityCollision on a separate low poly version then assign that to the entity?


You just position rotate the "collidable" and the "renderer" at the same position with the same orientation.

The collidables are never rendered (thanks to entityalpha 0), they are just used to detect collisions and reoriente reposition a turning moving entity (characters, vehicles, bullets) so that it does no go through the obstacles.
The renderers are never used for collisions, they are just used to display the final scene on the screen.
Same thing for linepicks and pickables. Depending on the complexity of your renderers it can be good to have low tris pickables (which you hide with entityalpha 0). Collidables and pickables can be the same low tris meshes, depending on what you are trying to do.


Matty(Posted 2015) [#21]
What used to be very fast in blitz for detecting collisions between point sources is to simply have a bank or array lookup in 3d space...divide your world into large chunks and only loop through objects in the same or adjacent chunks. Ive used it in a game with thousands of bullets being fired by large numbers of units in the past and it was very quick...tricky to setup originally though as you want to design it such that no looping is necessary at all to find an object. Everything is lookups...memory inefficient but great for speed.


Yue(Posted 2015) [#22]
All I've been able to successfully use FastPointer, is in charge of resources in the background and show an animation of a loading progress bar.




RustyKristi(Posted 2015) [#23]
Yes Yue, that multithreading will come in handy for preloading objects. thanks for sharing :)

@Matty

Do you have a basic example on how I can do this lookup thing?


Yue(Posted 2015) [#24]
Hi, Here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=3228


RustyKristi(Posted 2015) [#25]
hey, I already saw that earlier Yue. good tip :-)


Matty(Posted 2015) [#26]
A very simple example in theory (not at a pc right now) is to have a 3d array of say 10x10x10 or larger and each element holds a handle to a bank or zero if the chunk is empty. When an object is created, moves or is destroyed you update its position in the array's banks. When you are checking for a collision simply loop through each offset in the relevant bank which contains the object handles for that chunk. Do a simple distance check against these objects and if within range then they count as collided.

Eg. You have 1000 entities in your 3d space scattered across a grid 20x20x20. Some cells have a lot of entities...some have none. Rather than checking for collisions between each entity (1, 000, 000 calculations) the entity checks if there are other entities in its chunk. If not exit check. If so then iterate through those in the chunk. Hence number of calculations reduced massively. The larger the array the more efficient in terms of speed but also more wasteful of memory.

Thats the basic idea.....you will have to code your own implementation of it....
Im typing this on my phone.


Matty(Posted 2015) [#27]
Edit positions are scaled to fit the array of course. Be careful on boundaries.


RemiD(Posted 2015) [#28]

Rather than checking for collisions between each entity (1, 000, 000 calculations) the entity checks if there are other entities in its chunk. If not exit check. If so then iterate through those in the chunk. Hence number of calculations reduced massively.


Another approach similar to what Matty suggests is what i have explained with areas connected with passages :
Each area can have any shape (not necessarily square)
Each area is connected to one or several others areas with passages.
In each area there are staticobstacles childs of the area
Each staticobstacle has a precalculated xzradius (which represents the distance between the origine of the mesh and the farest (i don't like farthest) vertex on xz)
In the map there are turningmovings (characters, vehicles, projectiles)
Each turningmoving has a precalculated xzradius
Each turningmoving is positionned in one area.

Each loop :
For each turningmoving,
determine in which area it is, (with linepick to down on a low tris floor mesh or with point in triangle in a low tris floor mesh)
depending on in which area it is, calculate if this turningmoving will be near enough an obstacle (staticobstacle or other turningmoving in this area or areas connected to this area) (with if distancexz(turningmoving,obstacle) <= turningmovingxzradius + obstaclexzradius + turningmovingspeed + 1), if yes, with the turningmoving orientation position try to detect a collision by considering only the obstacles which are near enough (with several linepicks and pickables or with several ellipsoids and collidables) then reoriente reposition the turningmoving appropriatly, if no, do nothing.

This is fast.


RustyKristi(Posted 2015) [#29]
Thanks guys. One thing I noticed is the performance drop when the entities are closer together with the normal blitz3d collision. I think this is the part where I need some boost.


RustyKristi(Posted 2015) [#30]
Finally, I tried RemiD's quick solution to use low poly meshes for colliders with standard b3d collision and it does make a huge difference.

Come to think of it, this is really a no brainer and went over my head. Now 60-80 entities in close and vicinity and an increase in 40-50fps performance! :D

Thank you guys for all your contributions! :-D


RemiD(Posted 2015) [#31]
Good :) (this is not really my solution, it has been suggested many times before)

I will post a code example later to demonstrate how to identify the near enough collidables/pickables depending on the distance between the turningmoving and the collidable/pickable and how to create/destroy ellipsoids only when necessary and consequently decrease the mstime it takes to calculate collisions/linepicks.


RustyKristi(Posted 2015) [#32]

Good :) (this is not really my solution, it has been suggested many times before)

I will post a code example later to demonstrate how to identify the near enough collidables/pickables depending on the distance between the turningmoving and the collidable/pickable and how to create/destroy ellipsoids only when necessary and consequently decrease the mstime it takes to calculate collisions/linepicks.


Yep, thanks. I mean on this topic and I did read this many times but it's kinda hard to catch up and think clearly when you're in the middle of something, at least for me.

That would be great and looking forward to that example :D


Guy Fawkes(Posted 2016) [#33]
Yea, @RustiKrusti or anyone else, please release a working example of recreating blitz3d collisions polygon-to-polygon, sliding collisions, etc...

I've been looking for a good collision lib & this is it. I just need an example for it. These examples are no good for collision->collision objects.

Thanks alot! =)

~GF


RemiD(Posted 2016) [#34]
I am trying to create my own collision system with for each turningmoving entity a low tris mesh and for each static entity a low tris mesh, with the use of precalculated radius for each entity in order to do a distance3d calculation before a triangles intersect others triangles calculation, with the possibility to get the collided entity reference, the collided entity name (which can contain the list and index/handle of the entity), the collided point position, the collided triangle normal, but don't wait for me, i am not sure that it will work well or that it will be fast enough...

An alternative, that i have already mentioned, it to use the Blitz3d collision system and for each turningmoving entity use a root pivot and several child ellipsoids (to create a kind of hull) and for each static entity use a low tris mesh, then turnmove the root pivot by small steps (and this will also turnmove the child ellipsoids), and if a collision is detected reoriente reposition the entity to its previous orientation position (for example with a small step of 10.0 for turns and with a small step of 0.01 for movement)..
Some notes :
If you use this method, turnmove only one entity at a time, then detect collision only for this entity, then reoriente reposition only this entity, so that it prevents a turningmoving entity to go through another turningmoving entity...
When you want to turnmove, detectcollisions, reorientereposition, a turningmoving entity, only this entity must have ellipsoids, the static entities or the others turningmoving entities (which are static during this step) must have collidables low tris meshes.


Guy Fawkes(Posted 2016) [#35]
I could have SWORN a few years ago I found a coldet example that included a sphere as a player, and slides + cubes "holding up" those "slides" using Coldet. I can't find it ANYWHERE! T_T

~GF


Guy Fawkes(Posted 2016) [#36]
I could have SWORN a few years ago I found a coldet example that included a sphere as a player, and slides + cubes "holding up" those "slides" using Coldet. I can't find it ANYWHERE! T_T

~GF


RustyKristi(Posted 2016) [#37]
I did use RemiD's solution, just create a lowpoly version of that mesh and hook it in your mesh.

Example:

Type Player
  Field Name
  Field Health
  Field CollisionMesh
  Field Mesh
End Type


I'm sure RemiD is always thinking of new ideas but this one works for me. It has some quirks but that is on blitz3d side afaik when the mesh count increases.


Guy Fawkes(Posted 2016) [#38]
See I just want that old demo that someone made a long time ago on these boards that had like the slides attached to stacked cubes and you could run up and down them all day with coldet collision.

I miss that demo :/

~GF


RemiD(Posted 2016) [#39]
From my past tests, coldet is not reliable... Sometimes it returns a wrong collided point position and/or a wrong collided triangle normal... (to confirm)
(and i don't think it is as fast as some say, i have several ideas to make a faster collision system (with a first check using 3dradiuses (or 2dradiuses) and distance3d (or distance2d) and also with precalculated prestored datas about the triangles (and their vertices) of the colliders/collidables)
We will see how it goes...


Guy Fawkes(Posted 2016) [#40]
Well that's just LOVELY.... ><

~GF


Guy Fawkes(Posted 2016) [#41]
I'm a bit hostile today... I hurt my back...