Mesh, AbstractMesh, TransformNode hierarchy

Mesh extends AbstractMesh extends TransformNode.

  • What are some purposes of AbstractMesh class?
    • If it’s not much more than a “container” for the logic that’s common between Mesh and InstancedMesh, what do you think about stating that directly in the documentation/jsdoc to make AbstractMesh less of a mystery?
    • On the other hand, I’m pretty sure I saw objects of type AbstractMesh (as well as Mesh) flying around at runtime and that (along with the fact that the class isn’t declared abstract) tells me there’s more to the story…
  • How do we reconcile the fact that all meshes are transform nodes with A TransformNode is an object that is not rendered ... written prominently in documentation?

Please reference any pieces of existing documentation that address these questions, too. I didn’t find any.

Let me add @PatrickRyan the maestro of our documentation

@sevaseva, I would say that the general purpose of AbstractMesh is a single class to hold the common properties of all mesh types but since it holds all of the common properties, it does have uses in a scene. For example, there are plenty of times where I want something that doesn’t render in the scene to perform a function like being an animation target or an emitter for a particle system. A transform node can certainly be used in place of an abstract mesh for that kind of purpose, but what if you want to attach a collider to the node or maybe use a layer mask for rendering the children of the node in a specific camera? You can’t do either of those things with a transform node. Another reason may be just to help with identification in a heirarchy. You can getChildTransformNodes or getChildMeshes for a node. The abstract mesh identifies as a mesh without actually rendering one so maybe you mix transforms and abstract meshes in a hierarchy based on knowing how you need to sort the children.

For how we should reconcile meshes and transforms, I tend to think of it this way. All meshes have a transform on them which stores the TRS (transform, rotation, and scale) data. The mesh component of the node is separate from that TRS data. Each vertex of the triangle list stores a position and a normal, which is needed to render. However, the TRS data affects all vertices at once and does not affect an individual vertex’s data separately from any other vertex. An abstract mesh is just a mesh without a triangle list of vertices to render. It still has a transform which holds the TRS data, but also contains the common properties, accessors, and methods used by all mesh nodes. If you don’t need access to any of these at any given point, falling back to use a transform node is logical.

Typically when I am creating a scene, I think of the elements I need to create the scene hierarchy, and then back out to use as broad a node as possible. For example, if I need a trail mesh, I have one choice, but if I don’t need anything that behaves like a trail mesh, I can back out to a mesh node. If I don’t want to render a triangle list, but need something like layer masking, I back out to an AbstractMesh. And if I just need to hold TRS data and don’t care about anything else, I will back out to a TransformNode.

I’m not sure if this helps clear up all of your questions. I am happy to go expand on the documentation, but I would like to hear if this explanation helps, or if you have more questions or confusion so I can address it all at once in the docs.

4 Likes

I am happy to go expand on the documentation, but I would like to hear if this explanation helps, or if you have more questions or confusion so I can address it all at once in the docs.

Great, thank you. Let me give you some of that feedback. Obviously, the feedback is specific to my unique experience (next-to-none in computer graphics, beginner-ish in babylonjs, advanced in software engineering) and ways to approach stuff.


general purpose of AbstractMesh is a single class to hold the common properties of all mesh types but since it holds all of the common properties, it does have uses in a scene

Yes. Useful to know that instances of abstractmesh are created and used, with some examples of when that is (as a matter of fact) done by babylonjs core and when a user of the framework may want to consider using them.

…attach a collider to the node or maybe use a layer mask for rendering the children of the node in a specific camera…

these examples aren’t helpful and are distracting to me personally. I never messed with either of these things, so cannot easily relate.

Another reason may be just to help with identification in a heirarchy. You can getChildTransformNodes or getChildMeshes for a node.

Useful.

The abstract mesh identifies as a mesh without actually rendering one…

If it’s true that an abstract mesh is never “rendered”, i.e. never has “its own visible state/body” (of whatever you call that) in the scene, then I think this key fact should be mentioned all over documentation/jsdoc/everywhere. (although I think that I had seen AbstractMesh instances that are visible as objects in the scene… well, if I understand what you said correctly, then I must me misremembering; totally possible)

An abstract mesh is just a mesh without a triangle list of vertices to render.

Yes. This is a key insight to also mention all over documentation, I think. Bonus points if you add links to specific members in the subclasses that represent that “triangle list of vertices”.

For how we should reconcile meshes and transforms, I tend to think of it this way. All meshes have a transform on them which stores the TRS (transform, rotation, and scale) data. The mesh component of the node is separate from that TRS data. Each vertex of the triangle list stores a position and a normal, which is needed to render. However, the TRS data affects all vertices at once and does not affect an individual vertex’s data separately from any other vertex. An abstract mesh is just a mesh without a triangle list of vertices to render. It still has a transform which holds the TRS data, but also contains the common properties, accessors, and methods used by all mesh nodes. If you don’t need access to any of these at any given point, falling back to use a transform node is logical.

Sounds like we have a case of misuse of inheritance (i.e. abstractmesh shouldn’t really have become a [subclass of] transform node) where composition could be a better OO design, but I’m not here for that discussion…

Otherwise, the paragraph is overall helpful, except … it’s a bit confusing when you say that

  • all meshes have TRS,
  • TRS affects vertices,
  • AbstractMesh does not have vertices,
  • but still has a transform which holds the TRS…
  • :thinking: … that does not make sense to me as it is. If by saying all that you mean to admit an (object oriented) design issue here, that would be helpful to state directly in jsdoc, etc - for the folks like me to get it and relax.

Typically when I am creating a scene, I think of the elements I need to create the scene hierarchy, and then back out to use as broad a node as possible.

Makes sense, but here’s a side note for you to help you know your target audience :wink:

  • in my limited experience with babylonjs I never so far had to think whether to instantiate an AbstractMesh or a Mesh or what: in all cases so far that decision was made by authors of babylonjs/core; I never directly called those constructors, I just called some methods and got back instances of various classes.

… if I need a trail mesh, I have one choice …

I have no idea what a trail mesh is, so hard to relate to that example. Again, that’s just me.

…something like layer masking…

Ditto. No idea what that is, hard to relate.

Overall that paragraph makes total sense; but again, I never so far had to make a choice what kind of node to instantiate, I just called framework functions/methods.

Thank you very much!