TCastleTransformReference improvements – intuitive transformation, menu items to “Duplicate Linked”, “Edit (Make Independent Copy)”, cooperates with LOD, fixed TCastleStickToSurface

Posted on

Terrain with multiple trees and houses
LOD demo screenshot
LOD demo screenshot
LOD demo screenshot

We implemented multiple improvements around TCastleTransformReference, making it easier to use, have more options, be more optimal and correct in certain cases. Overall, we think that after these improvements, you will use TCastleTransformReference much more often 🙂

The TCastleTransformReference is a component that allows to use the same TCastleTransform multiple times in the viewport. This can imply using the same TCastleScene many times or using a whole hierarchy of TCastleTransform multiple times in one viewport. The technique implies we point to the same TCastleTransform from multiple parents, so the same pointer is present multiple times in the TCastleTransform graph. This is sometimes a very powerful optimization: having a million TCastleTransformReference means you display a million trees, but we still have only one tree in the memory, with one set of GPU resources (VBO etc.). Rendering it will be fast and memory-efficient. On the other hand, this technique also imposes some limits: as all instances are really one object, it must have the same state, e.g. play the same moment of the same animation.

Our engine has other features to cache things between models (even when not using TCastleTransformReference, we cache textures, shaders, we make an effort to cache VBOs too). But using TCastleTransformReference triumphs (in terms of efficiency) everything: everything has to be shared across all references, because they are really just one object underneath.

What we effectively want to achieve by improvements below: encourage you to use TCastleTransformReference more often!

  • It’s available with an easy menu item (“Duplicate Linked”) and key shortcut (Ctrl + Shift + D),

  • it behaves in a more intuitive way (thanks to ignoring target transformation by default),

  • and if you change your mind — you can always “escape” from sharing by using “Edit (Make Independent Copy) Referenced Transform”.

The choice between “Duplicate” and “Duplicate Linked” comes down to answering “will I want to modify this clone”, and if the answer is “probably not” -> then “Duplicate Linked (TCastleTransformReference)” is an excellent choice. So you can use TCastleTransformReference and reap the benefits (i.e. enjoy smaller resource usage) when it makes sense.

Thanks go to DiggiDoggi for providing a lot of useful feedback, testcases and analysis that ultimately resulted in these improvements!

The changes are:

  1. First of all, the display of reference (TCastleTransformReference) is no longer affected by the transformation (translation, rotation, scale) of the target (in TCastleTransformReference.Reference). This makes the relation between reference and target more intuitive. You can move target independently of the reference.

    You can adjust this behavior using TCastleTransformReference.ReferenceTransformation: rtIgnoreTransform is now the default, while rtDoNotIgnore restores the old behavior. And sometimes the rtIgnoreTranslation is useful, to ignore only translation but still apply rotation and scale from the target.

  2. New menu item “Duplicate Linked (TCastleTransformReference)” is available in both the main menu (in “Edit”) and in the context menu (right-click on source transformation in the hierarchy).

    It creates a TCastleTransformReference that points to the selected transformation object.

    The shortcut is Ctrl+Shift+D, similar to Ctrl+D for the regular “Duplicate”.

    The behavior tries to be natural and nice for duplicating multiple times:

    Moreover, this is deliberately similar to Blenders’s command “Duplicate Linked” (Alt+D). The use-case in Blender is similar: create another instance, but sharing all the properties with the original.

    NOTE: The underlying implementation and capabilities differ between Blender and our engine for this functionality. Blender does “Duplicate Linked” by utilizing it’s separation between “Blender Object” and “Blender Mesh”. “Duplicate Linked” in Blender makes new “Blender Object” that links to the same “Blender Mesh”. Our “Duplicate Linked”, doing TCastleTransformReference, is a more powerful beast: we link to the whole source TCastleTransform, which can be any composition of transformations, scenes, behaviors. Still, we think that despite these differences — the basic use-case is similar.

  3. Our manual has been updated to mention the new option: TCastleTransformReference, 3D tutorial with car.

  4. Examples using TCastleTransformReference have been adjusted too:

  5. We have additional options in the editor context menu, when you right-click on TCastleTransformReference instance in the hierarchy.
    • “Edit (Make Independent Copy) Referenced Transform”
    • “Revert To Referenced Transform”

    In effect, you can easily “make real copy” (making the TCastleTransformReference act like a basic TCastleTransform container for that copy, and nothing more) or remove that copy. They work in a consistent way with analogous commands for TCastleTransformDesign, which is good.

  6. We fixed a bug (crash in debug mode, missing texture in release mode) when you use TCastleTransformReference in certain conditions. Namely, when some references are within a given light radius, the others are not, then the shaders were not setup correctly. This is now fixed. See issue 664 for details and 3 testcases, one testcase is also part of our automatic tests now.

  7. We improved optimzation around the TCastleTransformReference, to better account that when you have multiple references, some of them may be affected by different lights than others. See also the same issue 664.

  8. We exposed a new option to configure optimization: TCastleScene.TransformOptimization. It may be beneficial to use this for scenes where you change the translation often, and by a large amount: it will prevent recreating shaders needlessly. Much more details are in the TCastleScene.TransformOptimization and TTransformOptimization API documentation.

  9. We fixed TCastleStickToSurface coordinate system (not really connected to TCastleTransformReference, although often used together, both TCastleStickToSurface and TCastleTransformReference make sense for planting trees on a terrain). Now moving the TCastleStickToSurface.Target (like a terrain) makes a proper effect, moving also trees.

  10. Making the LOD work no longer requires TCastleSceneCore.ProcessEvents. The displayed LOD level is updated regardless of TCastleSceneCore.ProcessEvents.

  11. LODs in scenes references by TCastleTransformReference work now perfectly. Each reference displays the correct LOD level. It’s not a problem that multiple TCastleTransformReference instances point to the same TCastleScene while displaying a different LOD level of this scene.

  12. The example examples/viewport_and_scenes/level_of_detail_demo/ has been expanded with a demo of it, the README.md there was also updated.

Enjoy! And if you like what we do, please remember to support us on Patreon or in other ways. Have fun making games!

Start the discussion at Castle Game Engine Forum