Godot Version
4.1.1
4.2.1
Question
I’ve been trying to programmatically generate a 3d mesh, with bones attached to the vertices. Everything seems to be working to create the mesh. However once I use set_bones at all the rendered mesh ceases to be visible in the scene. If I then go into the Remote scene tree in the editor, right click and save the existing node as a scene, the mesh and bones are linked up properly in the saved scene and the mesh is visible and deformable. This leads me to think I’m using the APIs something akin to correctly, but I’ve run out of my ability to figure out what might be the cause.
The scene tree consists of the following:
The script is attached below. In the code the issue shows up if the add_bones flag is set to true.
using Godot;
public partial class GenerateMeshTest : Skeleton3D {
[Export]
public Material Mat { get; set; }
[Export]
public MeshInstance3D MeshInstance { get; set; }
[Export]
public Camera3D Camera { get; set; }
private int max_x = 4;
private int max_y = 5;
private bool add_bones = true;
public override void _Ready() {
using SurfaceTool surface_tool = new SurfaceTool();
ArrayMesh mesh;
surface_tool.Begin(Mesh.PrimitiveType.Triangles);
surface_tool.SetMaterial(Mat);
surface_tool.SetColor(Colors.Red);
AddBone($"b0");
AddBone($"b1");
AddBone($"b3");
AddBone($"b4");
SetBoneParent(1, 0);
SetBoneParent(2, 1);
SetBoneParent(3, 2);
SetBoneEnabled(0, true);
SetBoneEnabled(1, true);
SetBoneEnabled(2, true);
SetBoneEnabled(3, true);
SetBoneRest(0, new Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0));
SetBoneRest(1, new Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0));
SetBoneRest(2, new Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0));
SetBoneRest(3, new Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0));
SetBonePosePosition(0, new Vector3(0, 0, 0));
SetBonePosePosition(1, new Vector3(0, 2, 0));
SetBonePosePosition(2, new Vector3(0, 2, 0));
SetBonePosePosition(3, new Vector3(0, 2, 0));
for (int y = 0; y < max_y; y++) {
for (int x = 0; x < max_x; x++) {
AddQuad(surface_tool,
new Vector3(x + 0, y + 0, 0),
new Vector3(x + 0, y + 1, 0),
new Vector3(x + 1, y + 1, 0),
new Vector3(x + 1, y + 0, 0));
}
}
surface_tool.GenerateNormals();
surface_tool.GenerateTangents();
surface_tool.Index();
// mesh = surface_tool.Commit();
mesh = (ArrayMesh)this.MeshInstance.Mesh;
surface_tool.Commit(mesh);
MeshInstance.Mesh = mesh;
//CreateSkinFromRestTransforms();
}
private double time = 0;
public override void _Process(double delta) {
time += delta;
//SetBonePoseRotation(1, Quaternion.FromEuler(new Vector3(0, (float)time, 0)));
Camera.GlobalPosition = MeshInstance.GlobalPosition + new Vector3(0, 0, 10 + (float)time);
Camera.LookAt(MeshInstance.GlobalPosition);
}
private void AddQuad(SurfaceTool surface_tool, Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3) {
// Triangle 1
if (add_bones) {
surface_tool.SetBones(new int[] { (int)(vertex0.Y / 2), 0, 0, 0 });
surface_tool.SetWeights(new float[] { 1, 0, 0, 0 });
}
surface_tool.SetUV(new Vector2(0, 0));
surface_tool.AddVertex(vertex0);
if (add_bones) {
surface_tool.SetBones(new int[] { (int)(vertex1.Y / 2), 0, 0, 0 });
surface_tool.SetWeights(new float[] { 1, 0, 0, 0 });
}
surface_tool.SetUV(new Vector2(1, 0));
surface_tool.AddVertex(vertex1);
if (add_bones) {
surface_tool.SetBones(new int[] { (int)(vertex2.Y / 2), 0, 0, 0 });
surface_tool.SetWeights(new float[] { 1, 0, 0, 0 });
}
surface_tool.SetUV(new Vector2(1, 1));
surface_tool.AddVertex(vertex2);
// Triangle 2
if (add_bones) {
surface_tool.SetBones(new int[] { (int)(vertex0.Y / 2), 0, 0, 0 });
surface_tool.SetWeights(new float[] { 1, 0, 0, 0 });
}
surface_tool.SetUV(new Vector2(0, 0));
surface_tool.AddVertex(vertex0);
if (add_bones) {
surface_tool.SetBones(new int[] { (int)(vertex2.Y / 2), 0, 0, 0 });
surface_tool.SetWeights(new float[] { 1, 0, 0, 0 });
}
surface_tool.SetUV(new Vector2(1, 1));
surface_tool.AddVertex(vertex2);
if (add_bones) {
surface_tool.SetBones(new int[] { (int)(vertex3.Y / 2), 0, 0, 0 });
surface_tool.SetWeights(new float[] { 1, 0, 0, 0 });
}
surface_tool.SetUV(new Vector2(0, 1));
surface_tool.AddVertex(vertex3);
}
}
