I have a bunch of TGLFreeForms that are being loaded in my app. The models are being loaded in a timely manner but since the octree build process can be somewhat lengthy I run the build process in a separate thread. (The model is displayed to the user, the octree is built "behind the scenes").
While this process works 99% of the time, we incurred in a scenario, where the octree was only "partially" built. Some parts of the model were "unreachable" by OctreeRayCastIntersect. After some research I found out the issue was two-fold:
1) The model deems the octree as complete as soon as the private field FOctree is assigned. In BuildOctree method, the reference is set at the very beginning. This means that the FOctree is assigned before the octree is actually built
2) The "GetExtents(emin, emax);" method used in BuildOctree might use cached values. This means that the octree in this case might not cover the whole model. (This was basically the issue we incurred onto)
Below is my suggested implementation of the TGLFreeForm.BuildOctree method which covers both bases:
1) Assigns the FOctree field only if the octree build was successful
2) Uses the "tl.GetExtents(emin, emax);" method to calculate extents, this ensures that the up-to-date model is taken into account
I understand that the modifications above might have some Consequences I do not see at the moment, this is why I am sending this snippet here instead of a pull request :)
Let me know your thoughts.
Thanks,
Vasja
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks Vasja,
First, use the demo from the examples folder with octrees as an example (e.g. OctreeRender QuadTreeCulling, ClothActor or OdeRagdo). Second, make a copy and add your code. Third, compare the fps of both versions and report the difference.
Then we'll see if we can somehow integrate your findings into the appropriate engine module so as not to disrupt other demos and existing applications.
Good luck in your work!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I checked the various demos and they mostly relate to Octrees themselves rather than TGLFreeForm. The modification above has no performance impact to those demos at all.
Since the call to a TGLFreeForm.BuildOctree is usually done in an "intialization" or "preparation" phase, the performance while "running" is not impacted. The performance penalty might come from constant loading and building of octree on the fly.
I did actually do a few tests based on the model in the demo "collisions/octreedemo".
I ran the BuildOctree 101 times in a row with the existing version and my modification and the difference is within any normal timing error:
11835.725ms vs 11860.392ms
Regards,
Vasja
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I believe my findings (at least on my system) pointed to my code being safely used in TGLFreeForm class. There seems to be very little (if any) performance impact and the Octree building process in TGLFreeForm and it becomes multithread safer (I have not tested this enough to claim it is 100% multithread safe but I am quite confident).
Thank you for your time. I leave the usage of the code to your judgement. :)
Regards,
Vasja
Last edit: Vasja Stanta 2026-08-24
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I have a bunch of TGLFreeForms that are being loaded in my app. The models are being loaded in a timely manner but since the octree build process can be somewhat lengthy I run the build process in a separate thread. (The model is displayed to the user, the octree is built "behind the scenes").
While this process works 99% of the time, we incurred in a scenario, where the octree was only "partially" built. Some parts of the model were "unreachable" by OctreeRayCastIntersect. After some research I found out the issue was two-fold:
1) The model deems the octree as complete as soon as the private field FOctree is assigned. In BuildOctree method, the reference is set at the very beginning. This means that the FOctree is assigned before the octree is actually built
2) The "GetExtents(emin, emax);" method used in BuildOctree might use cached values. This means that the octree in this case might not cover the whole model. (This was basically the issue we incurred onto)
Below is my suggested implementation of the TGLFreeForm.BuildOctree method which covers both bases:
1) Assigns the FOctree field only if the octree build was successful
2) Uses the "tl.GetExtents(emin, emax);" method to calculate extents, this ensures that the up-to-date model is taken into account
I understand that the modifications above might have some Consequences I do not see at the moment, this is why I am sending this snippet here instead of a pull request :)
Let me know your thoughts.
Thanks,
Vasja
Thanks Vasja,
First, use the demo from the examples folder with octrees as an example (e.g. OctreeRender QuadTreeCulling, ClothActor or OdeRagdo). Second, make a copy and add your code. Third, compare the fps of both versions and report the difference.
Then we'll see if we can somehow integrate your findings into the appropriate engine module so as not to disrupt other demos and existing applications.
Good luck in your work!
Hi Pavel,
I checked the various demos and they mostly relate to Octrees themselves rather than TGLFreeForm. The modification above has no performance impact to those demos at all.
Since the call to a TGLFreeForm.BuildOctree is usually done in an "intialization" or "preparation" phase, the performance while "running" is not impacted. The performance penalty might come from constant loading and building of octree on the fly.
I did actually do a few tests based on the model in the demo "collisions/octreedemo".
I ran the BuildOctree 101 times in a row with the existing version and my modification and the difference is within any normal timing error:
11835.725ms vs 11860.392ms
Regards,
Vasja
Well Vasja,
So it seems that we don't need to update the TGLFreeForm object, may be only could use your code in applications. Thanks.
Hi Pavel,
I believe my findings (at least on my system) pointed to my code being safely used in TGLFreeForm class. There seems to be very little (if any) performance impact and the Octree building process in TGLFreeForm and it becomes multithread safer (I have not tested this enough to claim it is 100% multithread safe but I am quite confident).
Thank you for your time. I leave the usage of the code to your judgement. :)
Regards,
Vasja
Last edit: Vasja Stanta 2026-08-24