I want to have an expansive world composed of multiple maps. I want to add features to objects, or tag objects, within these maps, eg. marking certain meshes as portals, or other objects that can be clicked on / interacted with within my game.
What’s the typical way that maps with such features would be implemented? I can think of two ways (please bear with me, I’m really inexperienced with 3D modelling/games!)
do everything with 3D modelling software eg. Blender. some problems/questions I have with this approach are:
is there a way to tag meshes with additional data? ie. marking objects as a certain type, so the game knows to handle them accordingly eg. portals
how would we prevent many copies of the same object from resulting in duplicated data and a bloated asset size when exporting the scene? is there a way to mark multiple objects as “instances” of the same base object?
rely on a special map file format that will describe how all the individual 3D models are placed and oriented within the map, and this would also handle tagging, de-duplicating/instancing multiple copies of the same model, etc. is there existing software out there for this use case? or will I likely need to create my own file format for this (and therefore a custom map editor too, probably)?
@sairens : If you are exporting from Blender using @JCPalmer 's “babylon” exporter then you can create “tags” with multipe key words (separated by spaces) in the tag box shown below in the image. It produces this in the exported .babylon file:
@sairens, the solution @gryff mentioned above is a simple and elegant solution an likely will fit your needs. There is one part of your question that stuck out to me and that is your mentioning of instances. If you truly have multiple instances of the same object, i.e. a waypoint marker, it would be better to create instances of that mesh in the scene in code. The reason is that the instances are batched into one draw call and you only have to take the hit on load for a small mesh since it is only a single copy of the mesh.
For example, this scene has 20,000 meshes and only one draw call since they are all instances of a single mesh. This is extremely fast to render. So if you had 10s, 100s, or 1000s of the same mesh to distribute around your scene, it could be best to instance them in code. So then how to you distribute them in your scene? One way is to use a locator (Maya)/empty (Blender)/null transform. This is just a transform that holds translation, rotation, and scale information. You can name them to be the type of object you want with a naming scheme like objectType_1 with the objectType being a descriptor of the mesh you want to position there, and the _1 allowing you to number each one so they have a unique name. Then you can iterate through mesh names on load exploding them on _ and comparing the string index[0] to your map of what objects to instance in which locations. You can then take the translation, rotation, and scale of the null to apply to the instance.
This method does take a little more planning to execute, but you do gain in performance with smaller asset loads and fewer draw calls. An added benefit is the ability to swap out meshes at any of your null locations in your level if conditions change. Hope this helps.
InstancedMesh’s are represented in .babylon / JSON files. They also have a Duplicate equivalent respresentation in Blender. The Blender exporter fills the instances field of a mesh with all blender duplicates.
Doing your duplicates in Blender allows you to place everything in the place you want without doing that in code. All export properties, as shown by @gryff 's screen shot, are shared. If things do not move, think about checking the Freeze World Matrix for scalability in addition to the tags field.
The only caveat is which duplicate gets to become the mesh, and the others its instances. The first one encountered is the mesh.
@PatrickRyan this exporter is very full featured. Maybe other exporters don’t have instances. This even has PBR properties which Blender has no equivalent for like Parallax. Cannot let a limitation of other exporters “color” this one.
Edit: The Freeze world Matrix is relatent for the original InstancedMesh, but have not implemented a switch to thin instances as well. I added that to my list for 3.03.0 exporter as an enhancement, which I just push up to server for backup purposes
I apologize, @JCPalmer, that I was not more clear in my post. I was specifically talking about the process for those who are using glTF as their preferred file format or are not using Blender in their art pipeline. But yes, your exporter is a wonderful tool for exporting from Blender to .babylon files.
Thanks everyone for your replies, they’ve been really helpful.
Just to clarify @JCPalmer - you mentioned in your reply:
If things do not move, think about checking the Freeze World Matrix for scalability in addition to the tags field.
Just confirming that by “scalability” here you’re referring to scaling the model size along the axes? And you’re not referring to performance (ie. scalability of performance)?
I am too lazy to look at your other thread on a Saturday. Your question about Freezing World Matrix is about CPU performance. This not only applies to to instances, but any mesh that does not move / rotate / scale dynamically once loaded.
Part of what makes BJS “easy” is everything is turned on by default. This means that once things are running you probably want to go through and turn off the stuff you are using, before you publish. For mesh level stuff (world matrix, picking) I have custom properties so that if you do not need that on a particular mesh, you can get that recorded on the export file & not have to code it.
The packaging of Blender duplicates into a mesh with instances in the export file does save writing the geometry more than once for reduced file size. Each instance is just 9 - 10 numbers in the file (3 for position, 3 for scaling, & 3 or 4 for rotation)