Blender GLM Export: Parenting, Hierarchy, and Tag Management
A technical discussion regarding the automation of object parenting in Blender for Jedi Academy model exporting. It covers the constraints of the GLM format, including hierarchy requirements for dismemberment, LOD handling, and the implementation of tags.
Channel: #models-skinsSource window: 2024-03-25 09:14 - 2024-03-26 18:215 posts4 views0 votes
Tags: JKAGLMBlenderGLA
Contributors: maui.94 (32), mrwonko (13), .mjt (2), archangel35757 (1), ashuradx (1), +1 more
Comms log
[2024-03-25 09:14] <maui.94> Hey guys, I have a question concerning parenting in blender
[2024-03-25 09:14] <maui.94> Do the objects have to be parented to each other? Or can they be parented to bones? / I want to adjust my addon to something that everybody can use to parent their mesh without having to do it manually and having to follow some name convention / People tend to give object names like tbxarmleft_0 for example / That makes no sense to my addon so it will cause an error to occur and no parenting happening / But if I could adjust my code so it parents the objects to the nearest bone on the armature instead, it wouldn't matter what name one would use for their mesh (edited)
[2024-03-25 09:18] <maui.94> So what I want the parent function to do for example: / Find object which is weighted on the hand bone, parent it to the object that is weighted onto the arm bone(s)
[2024-03-25 09:19] <maui.94> And then works it way up until the parenting is done completely like: / hand -> arm -> torso / head -> torso / torso -> hips / legs -> hips / misc objects like armor -> respective bodypart it's supposed to be parented to
[2024-03-25 09:20] <maui.94> Then do the tags ofcourse
[2024-03-25 09:21] <maui.94> But, all this work would be different if the objects can be parented to the respective bones instead
[2024-03-25 09:21] <mrwonko> I've never heard of parenting objects to individual bones, only to the armature itself. Does Blender support that?
[2024-03-25 09:21] <maui.94> Apprently, I googled it and somebody made a Parent to Nearest Bone addon
[2024-03-25 09:23] <mrwonko> The glm exporter requires a properly set up object hierarchy, because it will use it 1:1 in the exported file. If objects can be parented to bones, this could in theory be modified to deduce the hierarchy from the bone hierarchy instead, but the exporter would need to be adjusted.
[2024-03-25 09:24] <mrwonko> A correct hierarchy containing certain correctly-named surfaces in the exported glm is important for proper dismemberment support.
[2024-03-25 09:24] <maui.94> Exactly what I thought
[2024-03-25 09:24] <maui.94> So would you suggest I would keep my addon as it is?
[2024-03-25 09:24] <maui.94> And just make sure people understand they would have to name their objects properly?
[2024-03-25 09:25] <mrwonko> one could add additional automatic checks to notify users if their objects are not named properly (edited)
[2024-03-25 09:25] <maui.94> I didn't think of that
[2024-03-25 09:27] <mrwonko> If parenting to bones is practical, and does not mess with weights, it may offer a simpler alternative and could be worth adding support for. How would you handle LODs, though? Currently, the exporter relies on each LOD having one distinct common scene_root model_root ancestor. (edited)
[2024-03-25 09:27] <mrwonko> Maybe collections (formerly layers) would be a better way to separate LODs...
[2024-03-25 09:27] <maui.94> Those are distinguished using a name splitter and see what LOD level it is currently working on
[2024-03-25 09:27] <maui.94> I have that support already in there
[2024-03-25 09:28] <maui.94> It makes sure that it parents the objects to _0, _1, _2, ...
[2024-03-25 09:30] <maui.94> https://codeshare.io/g86178
[2024-03-25 09:30] <maui.94> That's how I did it
[2024-03-25 09:33] <maui.94> class OBJECT_OT_Parent(bpy.types.Operator): / """Parent all objects""" / bl_idname = "object.parent" / bl_label = "Parent Objects/Tags" / / def execute(self, context): / / for obj in bpy.data.objects: / / lod = LastIndex(obj) / / if "scene_root" in obj.name: / continue / / if "skeleton_root" in obj.name or "model_root_" + lod in obj.name: / obj.parent = bpy.data.objects["scene_root"] / continue / / obj.parent = GetParent(obj) / / return {'FINISHED'}
[2024-03-25 09:33] <maui.94> And that is the class that does the rest
[2024-03-25 09:42] <mrwonko> So you're working off Blender object names? That works for _humanoid, but in general, surface names in glm can be up to 64 characters long, while Blender names are limited to 63 characters (and you still need the _N suffix)
[2024-03-25 20:43] <.mjt> ^^
[2024-03-25 21:07] <.mjt> https://en.wikipedia.org/wiki/Polygon_mesh
[2024-03-25 21:39] <ashuradx> 👍
[2024-03-26 09:33] <maui.94> if "*" in object.name:
[2024-03-26 09:33] <maui.94> It's a simpler way to tell if it's a tag
[2024-03-26 09:33] <maui.94> Or let it check the Ghoul2 modifiers
[2024-03-26 09:34] <mrwonko> There's a bitflag in glm files that marks surfaces as tags, the name is irrelevant for that
[2024-03-26 09:34] <maui.94> if "g2_prop_tag" in obj:
[2024-03-26 09:35] <mrwonko> In JA, all tags happen to start with *, presumably because their export pipeline worked that way, but the file format does not require it
[2024-03-26 09:35] <maui.94> Oh?
[2024-03-26 09:35] <maui.94> I wonder, are we able to create tags ourselves without having to take them from other models?
[2024-03-26 09:35] <maui.94> Because I came to a temporary solution. I saved a blender file with a skeleton and all LOD tags in it
[2024-03-26 09:36] <maui.94> So if someone would need it, all they have to do is open up that file and copy paste all
[2024-03-26 09:41] <mrwonko> yeah, but you need to enable vertex index display in Blender to get it right. I should add an operator for creating correct tags some time.
[2024-03-26 09:42] <mrwonko> I've already fixed it https://github.com/mrwonko/Blender-Jedi-Academy-Tools/commit/c3d2813700aa6867066b0cdd4ebcac3a22542ea8
[2024-03-26 10:01] <maui.94> Thanks
[2024-03-26 11:28] <maui.94> So what's happening now is that the tag does not have to be a *nameoftag ?
[2024-03-26 11:28] <maui.94> @mrwonko
[2024-03-26 11:30] <maui.94> Also, you changed that piece of code now. Does this mean that we can create the tags ourselves now instead of using a jka model to take them over? (edited)
[2024-03-26 12:11] <mrwonko> Correct, though if you're building a standard player model, it still does because that's what the game expects
[2024-03-26 12:13] <mrwonko> [attachment: https://cdn.discordapp.com/attachments/1103343134160728144/1222156586542432358/ZAAAAAElFTkSuQmCC.png?ex=6a0270c4&is=6a011f44&hm=6918c82321f9228837ab4049ea9ad7d69699e1418dbb6621f29eea57f073aa76&]
[2024-03-26 14:01] <maui.94> lol
[2024-03-26 14:02] <maui.94> I tried to create that a long time ago, but the exporter or the game did not accept it
[2024-03-26 17:43] <cir.ca> https://www.deviantart.com/entar0178/art/Jedi-Academy-Kel-Dor-Jedi-Commission-832134071
[2024-03-26 18:21] <archangel35757> In 3ds Max "bolt_" is expected for an Assimilate/Carcass workflow (Carcass replaces it with an asterisk) ... using Scooper's GLM plugins (that I've updated) the workflow replaces the "*" with "bolt_" on import and exports it out as "*" (edited)
maui.94
I have a question concerning parenting in Blender for JKA models. Do the objects have to be parented to each other, or can they be parented to bones? I want to adjust my addon so users can parent their mesh without having to follow strict naming conventions manually.
People often use names like tbxarmleft_0, which can cause errors in my current code if the naming isn't exact. If I could adjust the code to parent objects to the nearest bone on the armature instead, the mesh name wouldn't matter. The goal is to have the function find an object weighted to a specific bone (like the hand) and parent it up the chain: hand -> arm -> torso -> hips, etc., including armor and tags.
mrwonko
I've never heard of parenting objects to individual bones in this context, only to the armature itself. Does Blender even support that for this workflow?
The GLM exporter requires a properly set up object hierarchy because it uses it 1:1 in the exported file. If objects were parented to bones, the exporter would need to be modified to deduce the hierarchy from the bone hierarchy instead. A correct hierarchy with correctly-named surfaces is essential for proper dismemberment support.
Also, keep in mind that while GLM surface names can be 64 characters, Blender names are limited to 63. Once you add the _N LOD suffix, you're even more restricted. How would you handle LODs if you changed the parenting method? Currently, the exporter relies on each LOD having a distinct scene_root or model_root ancestor.
maui.94
For LODs, I'm using a name splitter to see which level is being worked on and ensuring objects are parented to _0, _1, _2, etc.
Here is the logic I'm using for the parent function:
python
class OBJECT_OT_Parent(bpy.types.Operator):
"""Parent all objects"""
bl_idname = "object.parent"
bl_label = "Parent Objects/Tags"
def execute(self, context):
for obj in bpy.data.objects:
lod = LastIndex(obj)
if "scene_root" in obj.name:
continue
if "skeleton_root" in obj.name or "model_root_" + lod in obj.name:
obj.parent = bpy.data.objects["scene_root"]
continue
obj.parent = GetParent(obj)
return {'FINISHED'}
I'm also looking for a simpler way to identify tags, maybe checking for the * prefix or looking at Ghoul2 modifiers.
mrwonko
archangel35757
Just for context on other workflows: In 3ds Max, bolt_ is expected for the Assimilate/Carcass workflow. Carcass then replaces that prefix with an asterisk * during processing. Using the updated version of Scooper's GLM plugins, the workflow replaces * with bolt_ on import and exports it back out as *.