Apply subobj hierarchy to model

This commit is contained in:
Jarrod Doyle 2024-12-23 11:44:13 +00:00
parent 202edd424b
commit 1177474fd6
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
3 changed files with 58 additions and 31 deletions

View File

@ -265,14 +265,12 @@ public partial class Mission : Node3D
var meshDetails = Timing.TimeStage("Get Models", () => Context.Instance.ModelLoader.Load(modelName));
if (meshDetails.Length != 0)
{
var model = new Node3D();
var joints = jointPosProp != null ? jointPosProp.Positions : [0, 0, 0, 0, 0, 0];
var model = ModelLoader.TransformMeshes(joints, meshDetails);
model.Position = pos;
model.RotationDegrees = rot;
model.Scale = scale;
var joints = jointPosProp != null ? jointPosProp.Positions : [0, 0, 0, 0, 0, 0];
var meshes = ModelLoader.TransformMeshes(joints, meshDetails);
bool GetTextReplPath(PropString prop, out string path)
{
path = "";
@ -301,26 +299,29 @@ public partial class Mission : Node3D
}
var repls = new PropString[] { txtRepl0, txtRepl1, txtRepl2, txtRepl3 };
foreach (var meshInstance in meshes)
foreach (var child in model.FindChildren("*", "MeshInstance3D", true, false))
{
var meshInstance = child as MeshInstance3D;
for (var i = 0; i < 4; i++)
{
if (GetTextReplPath(repls[i], out var path))
if (!GetTextReplPath(repls[i], out var path))
{
var overrideMat = new StandardMaterial3D
{
AlbedoTexture = TextureLoader.LoadTexture(path),
Transparency = BaseMaterial3D.TransparencyEnum.AlphaDepthPrePass,
};
continue;
}
var overrideMat = new StandardMaterial3D
{
AlbedoTexture = TextureLoader.LoadTexture(path),
Transparency = BaseMaterial3D.TransparencyEnum.AlphaDepthPrePass,
};
var surfaceCount = meshInstance.Mesh.GetSurfaceCount();
for (var idx = 0; idx < surfaceCount; idx++)
var surfaceCount = meshInstance.Mesh.GetSurfaceCount();
for (var idx = 0; idx < surfaceCount; idx++)
{
var surfaceMat = meshInstance.Mesh.SurfaceGetMaterial(idx);
if (surfaceMat.HasMeta($"TxtRepl{i}"))
{
var surfaceMat = meshInstance.Mesh.SurfaceGetMaterial(idx);
if (surfaceMat.HasMeta($"TxtRepl{i}"))
{
meshInstance.SetSurfaceOverrideMaterial(idx, overrideMat);
}
meshInstance.SetSurfaceOverrideMaterial(idx, overrideMat);
}
}
}
@ -329,8 +330,6 @@ public partial class Mission : Node3D
{
meshInstance.Transparency = 1.0f - renderAlpha.value;
}
model.AddChild(meshInstance);
}
model.AddToGroup(OBJECT_MODELS_GROUP);

View File

@ -19,13 +19,8 @@ public partial class Model : Node3D
}
Context.Instance.SetCampaign(campaignName);
var model = new Node3D();
var meshDetails = Context.Instance.ModelLoader.Load(modelPath);
var meshes = ModelLoader.TransformMeshes([0, 0, 0, 0, 0, 0], meshDetails);
foreach (var meshInstance in meshes)
{
model.AddChild(meshInstance);
}
var model = ModelLoader.TransformMeshes([0, 0, 0, 0, 0, 0], meshDetails);
AddChild(model);
}
}

View File

@ -8,11 +8,12 @@ namespace KeepersCompound.TMV;
// TODO: Work out a way to share base game models again in the cache
public class ModelLoader
{
public struct MeshDetails(int jointIdx, Transform3D transform, MeshInstance3D mesh)
public struct MeshDetails(int jointIdx, Transform3D transform, MeshInstance3D mesh, int parentIdx)
{
public readonly int JointIdx = jointIdx;
public readonly Transform3D Transform = transform;
public readonly MeshInstance3D Mesh = mesh;
public int ParentIdx = parentIdx;
}
private readonly Dictionary<(string, string), MeshDetails[]> _cache = new();
@ -40,15 +41,20 @@ public class ModelLoader
return details;
}
public static MeshInstance3D[] TransformMeshes(float[] joints, MeshDetails[] meshDetails)
public static Node3D TransformMeshes(float[] joints, MeshDetails[] meshDetails)
{
for (var i = 0; i < joints.Length; i++)
{
joints[i] = float.DegreesToRadians(joints[i]);
}
var meshes = new List<MeshInstance3D>();
foreach (var details in meshDetails)
{
var mesh = details.Mesh.Duplicate() as MeshInstance3D;
if (details.JointIdx != -1)
{
var ang = float.DegreesToRadians(joints[details.JointIdx]);
var ang = joints[details.JointIdx];
var r1 = new Quaternion(new Vector3(0, 0, 1), ang);
var r2 = details.Transform.Basis.GetRotationQuaternion();
var basis = new Basis(r2 * r1);
@ -61,8 +67,23 @@ public class ModelLoader
meshes.Add(mesh);
}
var root = new Node3D();
for (var i = 0; i < meshes.Count; i++)
{
var details = meshDetails[i];
var parentId = details.ParentIdx;
if (parentId == -1)
{
root.AddChild(meshes[i]);
}
else
{
meshes[parentId].AddChild(meshes[i]);
}
}
return [..meshes];
return root;
}
public static MeshDetails[] LoadModel(string modelName)
@ -186,7 +207,19 @@ public class ModelLoader
var pos = -modelFile.Header.Center.ToGodotVec3();
var meshInstance = new MeshInstance3D { Mesh = mesh, Position = pos };
meshDetails[i] = new MeshDetails(jointIdx, transform, meshInstance);
meshDetails[i] = new MeshDetails(jointIdx, transform, meshInstance, -1);
}
// Build parentage
for (var i = 0; i < objCount; i++)
{
var subObj = modelFile.Objects[i];
var childIdx = subObj.Child;
while (childIdx != -1)
{
meshDetails[childIdx].ParentIdx = i;
childIdx = modelFile.Objects[childIdx].Next;
}
}
return meshDetails;