import myou_engine import std/sequtils # Create engine, scene, camera let engine = newMyouEngine(1024, 768) let scene = engine.newScene() let cam = scene.newCamera() # Move the camera upwards (the default rotation looks down) cam.position.z = 10 let armature = engine.newArmature(scene=scene) let b0 = armature.add_bone("Bone", vec3(), quat(), 0, "", 0.5) let b1 = armature.add_bone("Bone1", vec3(0,0.5,0), quat(), 1, "Bone", 0.5) let b2 = armature.add_bone("Bone2", vec3(0,0.5,0), quat(), 2, "Bone1", 0.5) let b3 = armature.add_bone("Bone3", vec3(0,0.5,0), quat(), 3, "Bone2", 0.5) armature.update_rest_matrices armature.position.y = -1 var layout: AttributeList layout.add Attribute(name: "vertex", dtype: Float, count: 3) layout.add Attribute(name: "weights", dtype: UByte, count: 4) layout.add Attribute(name: "b_indices", dtype: UByte, count: 4) var vertices: seq[(Vec3, array[4, uint8], array[4, uint8])] var indices: seq[uint16] const faces_x = 2 const faces_y = 16 for y in 0 .. faces_y: for x in 0 .. faces_x: let pos = vec3(0.5 * (x/faces_x - 0.5), 2f * (y/faces_y), -0.1) let p = vec3(0, pos.y, 0) var weights = [ clamp(0.5-(b0.dist_to_sphere(p) * 3), 0, 1), clamp(0.5-(b1.dist_to_sphere(p) * 3), 0, 1), clamp(0.5-(b2.dist_to_sphere(p) * 3), 0, 1), clamp(0.5-(b3.dist_to_sphere(p) * 3), 0, 1), ] let sum = weights.foldl a+b let w_u8 = weights.mapIt uint8(255 * it/sum) let w_u8a = [w_u8[0], w_u8[1], w_u8[2], w_u8[3]] vertices.add (pos, w_u8a, [0'u8,1,2,3]) for y in 0'u16 ..< faces_y.uint16: let p = y * (faces_x.uint16 + 1) for x in p ..< p + faces_x.uint16: let x2 = x + faces_x.uint16 + 1 indices.add @[ x, x+1, x2, x2, x+1, x2+1, ] let grid = scene.newMesh("grid", layout = layout, vertex_array = vertices, index_array = indices, ) grid.parent_to armature, keep_transform=false grid.armature = armature grid.add_modifier engine.newArmatureModifier(4) grid.materials.add engine.newSolidMaterial("blue", vec4(0.1,0.3,1,1)) # TODO: Move visualization of armature wireframe to the engine let wireframe = scene.newMesh("wireframe", draw_method=Lines, vertex_count=8) wireframe.parent_to armature, keep_transform=false wireframe.materials.add engine.newSolidMaterial("white", vec4(1)) const OCTAEDRON = @[ vec3(0), vec3(-0.1, 0.1, -0.1), vec3(0), vec3(-0.1, 0.1, 0.1), vec3(0), vec3(0.1, 0.1, -0.1), vec3(0), vec3(0.1, 0.1, 0.1), vec3(0.1, 0.1, 0.1), vec3(-0.1, 0.1, -0.1), vec3(-0.1, 0.1, -0.1), vec3(-0.1, 0.1, 0.1), vec3(-0.1, 0.1, 0.1), vec3(0.1, 0.1, -0.1), vec3(0.1, 0.1, -0.1), vec3(0.1, 0.1, 0.1), vec3(-0.1, 0.1, -0.1), vec3(0,1,0), vec3(-0.1, 0.1, 0.1), vec3(0,1,0), vec3(0.1, 0.1, -0.1), vec3(0,1,0), vec3(0.1, 0.1, 0.1), vec3(0,1,0), ] proc update_wireframe() = armature.recalculate_bone_matrices() # only needed here for visualization wireframe.clear_vertices() wireframe.ensure_capacity(OCTAEDRON.len * armature.bone_list.len) for bone in armature.bone_list: let m = bone.matrix for point in OCTAEDRON: wireframe.add_vertex(m * (bone.blength * point)) wireframe.data.update_varray() update_wireframe() var time = -1.0 scene.pre_draw_callbacks.add proc(scene: Scene, dt: float) = time += dt if time < 0: return let f = time * 2f const w = 1.0 armature.bones["Bone"].rotation = quat().rotateZ(-sin(f) * w) armature.bones["Bone1"].rotation = quat().rotateZ(-sin(f*1.1) * w) armature.bones["Bone2"].rotation = quat().rotateZ(-sin(f*1.2) * w) armature.bones["Bone3"].rotation = quat().rotateZ(-sin(f*1.4) * w) update_wireframe() scene.enable_render() engine.run()