Hi
Godot Version
Godot 4.3-stable-mono
Question
I am using the SurfaceTool to generate a 3D Mesh at runtime. I am also trying to generate a Skeleton that follows the edges of each face.
As first step, I created a square out of two triangles and added a skeleton & bones to it in order to get a feel for this feature. Unfortunately, I don’t see any bones in the editor at runtime and the mesh no longer appears as soon as I set the Skeleton to a Skeleton3D Node. I’m guessing I don’t understand Skeleton’s fully, so any help would be appreciated.
Here’s my scene layout:
Here’s my code attached to “Mesh”:
extends MeshInstance3D
func createBaseMesh(origin: Vector3, end: Vector3, st: SurfaceTool):
var x = origin.x
var y = origin.y
var z = origin.z
var lowerLeft = origin
var upperLeft = Vector3(end.x, y, z)
var lowerRight = Vector3(x, y, end.z)
var upperRight = Vector3(end.x, y, end.z)
st.begin(Mesh.PRIMITIVE_TRIANGLES)
## Playing with bones
var skel = get_node(skeleton)
var bone_middle = skel.add_bone("middle")
var bone_left = skel.add_bone("left")
var bone_right = skel.add_bone("right")
var bone_up = skel.add_bone("up")
var bone_down = skel.add_bone("down")
skel.set_bone_parent(bone_left, bone_middle)
skel.set_bone_parent(bone_down, bone_middle)
skel.set_bone_parent(bone_up, bone_middle)
skel.set_bone_parent(bone_right, bone_middle)
skel.set_bone_pose_position(bone_left, origin)
skel.set_bone_pose_position(bone_middle, origin)
skel.set_bone_pose_position(bone_down, origin)
skel.set_bone_pose_position(bone_up, end)
skel.set_bone_pose_position(bone_right, end)
skel.set_bone_pose_rotation(bone_left, Quaternion(Vector3.RIGHT, 0))
# rotate middle, so it's along the shared axis of both faces
skel.set_bone_pose_rotation(bone_middle, Quaternion(Vector3.UP, TAU / 8))
skel.set_bone_pose_rotation(bone_down, Quaternion(Vector3.FORWARD, 0))
skel.set_bone_pose_rotation(bone_up, Quaternion(Vector3.FORWARD, 0))
skel.set_bone_pose_rotation(bone_right, Quaternion(Vector3.RIGHT, 0))
skel.set_bone_rest(bone_left, Transform3D.IDENTITY)
skel.set_bone_rest(bone_middle, Transform3D.IDENTITY)
skel.set_bone_rest(bone_down, Transform3D.IDENTITY)
skel.set_bone_rest(bone_up, Transform3D.IDENTITY)
skel.set_bone_rest(bone_right, Transform3D.IDENTITY)
skel.set_bone_global_pose(bone_left, Transform3D.IDENTITY)
skel.set_bone_global_pose(bone_middle, Transform3D.IDENTITY)
skel.set_bone_global_pose(bone_down, Transform3D.IDENTITY)
skel.set_bone_global_pose(bone_up, Transform3D.IDENTITY)
skel.set_bone_global_pose(bone_right, Transform3D.IDENTITY)
# Define nodes and skeletons
st.set_weights([0.3, 0.3, 0.3, 0])
st.set_bones([bone_left, bone_middle, bone_down, bone_right])
st.add_vertex(lowerLeft)
st.set_weights([0.5, 0.5, 0, 0])
st.set_bones([bone_left, bone_up, bone_down, bone_right])
st.add_vertex(upperLeft)
st.set_weights([0.5, 0.5, 0, 0])
st.set_bones([bone_down, bone_right, bone_left, bone_up])
st.add_vertex(lowerRight)
st.set_weights([0.3, 0.3, 0.3, 0])
st.set_bones([bone_right, bone_middle, bone_up, bone_left])
st.add_vertex(upperRight)
# lower left
st.add_index(1)
st.add_index(0)
st.add_index(2)
# upper right
st.add_index(1)
st.add_index(2)
st.add_index(3)
func finishGeometry(st: SurfaceTool):
mesh.clear_surfaces()
st.generate_normals()
mesh = st.commit()
ResourceSaver.save(mesh, "res://mesh.tres", ResourceSaver.FLAG_COMPRESS)
var material: StandardMaterial3D = StandardMaterial3D.new()
material.cull_mode = StandardMaterial3D.CULL_DISABLED
material.albedo_color = Color.ORANGE
set_surface_override_material(0, material)
func createMesh(origin: Vector3, end: Vector3):
var st = SurfaceTool.new()
createBaseMesh(origin, end, st)
finishGeometry(st)
func _ready():
var origin = Vector3(0, 0, 0)
var end = Vector3(1, 0, 1)
createMesh(origin, end)
The final goal of the skeleton is to have players drag one of the edges of the square and have the skeleton determine how the rest of the mesh should rotate/look like in 3D.