vengi-voxel / vengi

free and open source voxel art tools - editor, thumbnailer and format converter
http://vengi-voxel.github.io/vengi/
Other
1.05k stars 87 forks source link

VOXELGENERATOR: add animation creation support to lua #436

Closed mgerhardy closed 2 months ago

mgerhardy commented 3 months ago

511226787cbfcb92fd7c279116573c937c47e838 added the initial animation system - which was extended later on to support lua animations, too

this was all removed once I decided to remove the game parts from the code base - but it's all still available in the history

this was e.g. the swimming animation for the old system.

local c_halfPi = math.pi/ 2.0
local toolOrientation = boneutil.rotateYZ(math.rad(-90.0), math.rad(110.0))

function swim(animTime, velocity, skeleton, skeletonAttr)
    local timeFactor = skeletonAttr.runTimeFactor
    local sin = math.sin
    local cos = math.cos
    local scaledTime = animTime * timeFactor;
    local sine = sin(scaledTime)
    local cosine = cos(scaledTime)
    local cosineSlow = cos(0.25 * scaledTime)
    local movement = 0.15 * sine
    local animTimeCos = cos(animTime)
    local headLookX = math.rad(-30.0) + 0.1 * animTimeCos
    local headLookY = 0.1 * sine
    local pantsY = skeletonAttr.pantsY
    local beltY = skeletonAttr.beltY

    local head = skeleton:headBone()
    head:setScale(skeletonAttr.headScale)
    head:setTranslation(0.0, 0.5 + skeletonAttr.neckHeight + skeletonAttr.headY + 1.3 * cosine, -1.0 + skeletonAttr.neckForward)
    head:setOrientation(boneutil.rotateXY(headLookX, headLookY))

    local rotateYMovement = boneutil.rotateY(movement)
    local bodyMoveY = 0.5 * cosine
    local chest = skeleton:chestBone()
    chest:setScale(1.0)
    chest:setTranslation(0.0, skeletonAttr.chestY + bodyMoveY, 0.0)
    chest:setOrientation(rotateYMovement)

    local belt = skeleton:beltBone()
    belt:setScale(1.0)
    belt:setTranslation(0.0, beltY + bodyMoveY, 0.0)
    belt:setOrientation(rotateYMovement)

    local pants = skeleton:pantsBone()
    pants:setScale(1.0)
    pants:setTranslation(0.0, pantsY + bodyMoveY, 0.0)
    pants:setOrientation(rotateYMovement)

    local handAngle = 0.05 * sine
    local handMoveY = 3.0 * cosineSlow
    local handMoveX = math.abs(4.0 * cosineSlow)
    local righthand = skeleton:righthandBone()
    righthand:setTranslation(0.1 + skeletonAttr.handRight + handMoveX, handMoveY, skeletonAttr.handForward)
    righthand:setOrientation(boneutil.rotateX(handAngle))

    local lefthand = skeleton:lefthandBone()
    lefthand:mirrorXZ(righthand)
    lefthand:setOrientation(boneutil.rotateX(-handAngle))

    local footAngle = 0.8 * cosine
    local footMoveY = 0.001 * cosine
    local rightfoot = skeleton:rightfootBone()
    rightfoot:setTranslation(skeletonAttr.footRight, skeletonAttr.hipOffset - footMoveY, 0.0)
    rightfoot:setOrientation(boneutil.rotateX(footAngle))

    skeleton:leftfootBone():mirrorX(rightfoot)

    local tool = skeleton:toolBone()
    tool:setScale(0.8 * skeletonAttr.toolScale)
    tool:setTranslation(skeletonAttr.toolRight, pantsY, skeletonAttr.toolForward)
    tool:setOrientation(toolOrientation)

    local rightshoulder = skeleton:rightshoulderBone()
    rightshoulder:setScale(skeletonAttr.shoulderScale)
    rightshoulder:setTranslation(skeletonAttr.shoulderRight, skeletonAttr.chestHeight, skeletonAttr.shoulderForward)
    rightshoulder:setOrientation(boneutil.rotateX(movement))

    local torsoScale = skeletonAttr.scaler
    local torso = skeleton:torsoBone(torsoScale)
    torso:setTranslation(0.0, 0.5 + 0.04 * sine, -beltY * torsoScale)
    torso:setOrientation(boneutil.rotateXZ(-0.2 + c_halfPi + 0.15 * cosine, 0.1 * cosine))

    skeleton:hideGliderBone()

    skeleton:leftshoulderBone():mirrorX(rightshoulder)
end

the new system should allow to iterate for x seconds and create keyframes with their transforms.

46d87482df414ab999ab43eff666c5238e66e707 extended or added the node, keyframe and transforms bindings

f0bef016eaa8a246c192d40c15785677667f4c96 extended the quaternion bindings

mgerhardy commented 3 months ago

It was all removed in 3ecc5e35c8803f5c8358e5e48ac44e9c28b357a5 - find the latest version in https://github.com/vengi-voxel/vengi/tree/12affef7e7ec06d33ab7a0211f28a596587d2fe8/src/modules/animation

mgerhardy commented 3 months ago

this would be a run implementation for the old code

local c_halfPi = math.pi / 2.0

function run(animTime, velocity, skeleton, skeletonAttr)
    local timeFactor = skeletonAttr.runTimeFactor
    local sin = math.sin
    local cos = math.cos
    local scaledTime = animTime * timeFactor
    local sine = sin(scaledTime)
    local cosine = cos(scaledTime)
    local cosineDouble = cos(scaledTime * 2.0)
    local movement = 0.35 * sine
    local animTimeCos = cos(animTime)
    local headLookX = math.rad(10.0) + 0.05 * animTimeCos
    local headLookY = 0.1 * sine
    local pantsY = skeletonAttr.pantsY
    local beltY = skeletonAttr.beltY

    local head = skeleton:headBone()
    head:setScale(skeletonAttr.headScale)
    head:setTranslation(0.0, 0.5 + skeletonAttr.neckHeight + skeletonAttr.headY + 1.3 * cosine, -1.0 + skeletonAttr.neckForward)
    head:setOrientation(boneutil.rotateXY(headLookX, headLookY))

    local rotateYMovement = boneutil.rotateY(movement)
    local bodyMoveY = 1.1 * cosine
    local chest = skeleton:chestBone()
    chest:setScale(1.0)
    chest:setTranslation(0.0, skeletonAttr.chestY + bodyMoveY, 0.0)
    chest:setOrientation(rotateYMovement)

    local belt = skeleton:beltBone()
    belt:setScale(1.0)
    belt:setTranslation(0.0, beltY + bodyMoveY, 0.0)
    belt:setOrientation(rotateYMovement)

    local pants = skeleton:pantsBone()
    pants:setScale(1.0)
    pants:setTranslation(0.0, pantsY + bodyMoveY, 0.0)
    pants:setOrientation(rotateYMovement)

    local handAngle = 0.2 * sine
    local handMoveY = cosine
    local handMoveZ = 4.0 * cosine
    local righthand = skeleton:righthandBone()
    righthand:setTranslation(skeletonAttr.handRight + cosineDouble, handMoveY, skeletonAttr.handForward + handMoveZ)
    righthand:setOrientation(boneutil.rotateX(handAngle))

    skeleton:lefthandBone():mirrorX(righthand)

    local footAngle = 1.5 * cosine
    local footMoveY = 0.5 * cosineDouble
    local rightfoot = skeleton:rightfootBone()
    rightfoot:setTranslation(skeletonAttr.footRight, skeletonAttr.hipOffset - footMoveY, 0.0)
    rightfoot:setOrientation(boneutil.rotateX(footAngle))

    skeleton:leftfootBone():mirrorX(rightfoot)

    skeleton:toolBone(skeletonAttr, cosine * 0.25)

    local rightshoulder = skeleton:rightshoulderBone()
    rightshoulder:setScale(skeletonAttr.shoulderScale)
    rightshoulder:setTranslation(skeletonAttr.shoulderRight, skeletonAttr.chestHeight, skeletonAttr.shoulderForward)
    rightshoulder:setOrientation(boneutil.rotateX(sine * 0.15))

    local torsoScale = skeletonAttr.scaler
    local torso = skeleton:torsoBone(torsoScale)
    torso:setTranslation(0.0, 0.0, 0.04 * sine)
    torso:setOrientation(boneutil.rotateX(cosine * 0.1))

    skeleton:hideGliderBone()

    skeleton:leftshoulderBone():mirrorX(rightshoulder)
end
mgerhardy commented 2 months ago

I think everything should be in place to do animations with lua code now.