![]() |
![]() |
![]() |
![]() |
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:
- First of all, the display of reference (
TCastleTransformReference
) is no longer affected by the transformation (translation, rotation, scale) of the target (inTCastleTransformReference.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, whilertDoNotIgnore
restores the old behavior. And sometimes thertIgnoreTranslation
is useful, to ignore only translation but still apply rotation and scale from the target. -
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:
- The created
TCastleTransformReference
has nice name,Reference
+ target name (with target numeric suffix removed, and new numeric suffix added for uniqueness of the reference). -
Doing it when
TCastleTransformReference
is selected creates anotherTCastleTransformReference
to the same target, not aTCastleTransformReference
toTCastleTransformReference
(which is technically possible but often not what you need in this case). -
New
TCastleTransformReference
starts with copied transformation (translation, rotation, scale) but it is independent from the target (using new defaultTCastleTransformReference.ReferenceTransformation
=rtIgnoreTransform
). So it starts in good place and you can move everything in an obvious way. -
Overall, the idea is that “hitting Ctrl+Shift+D multiple times does what you expect” (creating multiple references to the same target).
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 sourceTCastleTransform
, which can be any composition of transformations, scenes, behaviors. Still, we think that despite these differences — the basic use-case is similar. - The created
-
Our manual has been updated to mention the new option: TCastleTransformReference, 3D tutorial with car.
-
Examples using
TCastleTransformReference
have been adjusted too: - 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 basicTCastleTransform
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. -
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. -
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. -
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 theTCastleScene.TransformOptimization
andTTransformOptimization
API documentation. -
We fixed
TCastleStickToSurface
coordinate system (not really connected toTCastleTransformReference
, although often used together, bothTCastleStickToSurface
andTCastleTransformReference
make sense for planting trees on a terrain). Now moving theTCastleStickToSurface.Target
(like a terrain) makes a proper effect, moving also trees. -
Making the LOD work no longer requires
TCastleSceneCore.ProcessEvents
. The displayed LOD level is updated regardless ofTCastleSceneCore.ProcessEvents
. -
LODs in scenes references by
TCastleTransformReference
work now perfectly. Each reference displays the correct LOD level. It’s not a problem that multipleTCastleTransformReference
instances point to the sameTCastleScene
while displaying a different LOD level of this scene. -
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