109 lines
3.7 KiB
Nim
109 lines
3.7 KiB
Nim
|
|
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()
|