Allow Linked Groups to Reuse Mesh Resources #114
Replies: 2 comments
-
Just to add something - It would be amazing if we could decide somehow when linked groups use multimesh. There's some cases when using multimesh will cause performance problems if you are trying to render stuff that is far away from each other. It really makes sense to use multimesh for small repeatable detailing like the posts in fences, bars in a jail cell, a bunch of window frames, lots of neighbouring columns - the entire linked group set being all of 1 multimesh instance. But there may be lots of other uses for this, even for large meshes (thinking of distant modelled skyscrapers at the boundary similar to a cs2 map). Having the choice to use multimesh would be better than making it a default behaviour for all linked groups |
Beta Was this translation helpful? Give feedback.
-
Another thing to add that might slightly complicate things is that I plan on adding the ability to split the CollisionBodies generated as a part of the map building process by the material that is assigned to them (ie, the arraymesh surfaces) so whatever kind of resource sharing that goes on will need to be capable of handling that too. (this is important so that developers can detect which kind of surface they hit) I think an initial first step that doesnt even take into account the concept of linked groups is to do this automagically behind the scenes where we take all the non worldspawn brush entities and hash the arrays of the mesh and if it matches one we already have then make them share that resource but as you say that is rather incomplete. |
Beta Was this translation helpful? Give feedback.
-
I've been looking into how Linked Groups are treated in the Map File, along with Groups, and I'm thinking we should think of them as separate features even though they're intrinsically... linked.
I've come up with some ideas after studying map files generated by Trenchbroom. One of my observations is that it's important to differentiate between Groups and Linked Groups, despite Linked Groups' requirement of being in a Group.
I made a basic map file that uses 2 different Groups, with one of the groups being duplicated as a Linked Group. The Group contains a structural brush and a
func_detail
brush entity with a single brush. One of the Linked Groups has been rotated 45 degrees on the Z axis.This is the generated map file:
As you can see, even though the
func_detail
is grouped with the structural brush, they get split into two separate entities:func_group
andfunc_detail
. However, the func_group has a_tb_id
property, and the func_detail has a_tb_group
property with a matching value.The linked func_groups are interesting in that they have both a
__tb_linked_group_id
and_tb_transformation
, while the unlinked func_group omits these. Despite having the_tb_transformation
property, the brush coordinates are still different, which makes sense as a BSP compiler is not going to have any idea what those things are and only wants the brush plane values.That said, we can use these key values to find links between the groups. Qodot builds meshes and collision on the request of the entity being generated, meaning we should be able to request key value pairs of that entity prior to mesh generation. An array or dictionary could be used to keep track of the Groups as they come. Each brush entity could then check if it has a matching
_tb_group
value with the Groups Array, and if that Group entry has a_tb_linked_group_id
then try to reuse the saved mesh resource.This would probably work fine for structural / worldspawn brushes, but I'm not sure how to identify which sub entities match with a previous group.
Say you have 1 func_group with its own mesh and 2 func_details with their own meshes. Since the func_details have no other identifiable information and you can't guarantee entity order in a generated map file, how do you identify which func_detail mesh resource gets applied to which func_detail in another Linked Group? Only thing I can think of is matching brush count and brush attributes, which means we'd still need to generate the meshes, but we'd still be able to replace them after the fact and unused unsaved resources are freed / deleted.
That's really the biggest hurdle in all of this I think. The transformation matrix is more a matter of coordinate conversion like we already do between origin and angles, but it handles us modifying our MeshInstance3D's local transform (that way we don't lose the transform in the parent entity). Everything else is doable, just a lot of work.
Unfortunately, we can't simply duplicate the collision Shape resources. While position and rotation aren't problems, CollisionShape scaling isn't really supported in Godot (causes problems) so we shouldn't use it with Qodot.
A simpler solution I suppose would be to "just reuse func_group mesh resources", but it feels rather incomplete to leave it at that.
Anyway, those are probably most of my current thoughts on the subject.
Beta Was this translation helpful? Give feedback.
All reactions