Menu

TGLFreeForm.BuildOctree enhancements

2026-08-20
2026-08-24
  • Vasja Stanta

    Vasja Stanta - 2026-08-20

    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

    procedure TGLFreeForm.BuildOctree(TreeDepth: Integer = 3);
    var
      emin, emax: TAffineVector;
      tl: TAffineVectorList;
      tmp: TGLOctree;
    begin
      tmp := TGLOctree.Create;
      try
        tl := MeshObjects.ExtractTriangles;
        try
          tl.GetExtents(emin, emax);
          tmp.InitializeTree(emin, emax, tl, TreeDepth);
    
          FreeAndNil(FOctree);
          FOctree := tmp;
          tmp := nil;
        finally
          tl.Free;
        end;
      finally
        tmp.free;
      end;
    end;
    

    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

     
  • Pavel Vassiliev

    Pavel Vassiliev - 2026-08-21

    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!

     
  • Vasja Stanta

    Vasja Stanta - 2026-08-21

    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

     
  • Pavel Vassiliev

    Pavel Vassiliev - 2026-08-21

    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.

     
  • Vasja Stanta

    Vasja Stanta - 2026-08-24

    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

Log in to post a comment.