Skip to content

Commit

Permalink
demo - ik to push a button
Browse files Browse the repository at this point in the history
  • Loading branch information
nem0 committed Nov 10, 2024
1 parent a4fc59d commit 593e358
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 69 deletions.
73 changes: 63 additions & 10 deletions data/maps/demo/button.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
local math = require "scripts/math"
local lumix_math = require "scripts/math"
local interactive = false

label = {}
player = {}
sound = -1
local ik_target_input = -1
local ik_alpha_input = -1
local ik_co = nil

Editor.setPropertyType(this, "label", Editor.ENTITY_PROPERTY)
Editor.setPropertyType(this, "player", Editor.ENTITY_PROPERTY)
Expand All @@ -16,23 +19,73 @@ end

function update(time_delta)
-- check if player is close
local dist_squared = math.distXZSquared(this.position, player.position)
local dist_squared = lumix_math.distXZSquared(this.position, player.position)
interactive = dist_squared < 2
-- animate the label if player is close
label.property_animator.enabled = interactive

if ik_co then
local status, res = coroutine.resume(ik_co, time_delta)
if not status then
LumixAPI.logError("coroutine error: " .. res)
ik_co = nil
end
if not res then
ik_co = nil
end
end
end

function easeOutBack(x: number): number
local c1 = 1.70158;
local c3 = c1 + 1;

return 1 + c3 * math.pow(x - 1, 3) + c1 * math.pow(x - 1, 2);
end

function calcIKTarget()
local button_pos = this.position
local player_pos = player.position
button_pos = lumix_math.subVec3(button_pos, player_pos) -- relative to player_pos
local player_rot = player.rotation
player_rot[4] = -player_rot[4] --invert rotation
button_pos = lumix_math.transformVec3(player_rot, button_pos) --transform to player space
return button_pos
end

function onInputEvent(event : InputEvent)
-- check if player pressed "F" and is close
-- check if player pressed "F" and is close
if interactive and event.type == "button" and event.device.type == "keyboard" then
if event.key_id == string.byte("F") then
if event.down then
-- play the sound
playSound(sound)
-- press (move) the button
this.property_animator.enabled = false
this.property_animator.enabled = true
end
if event.down then
-- start by moving the hand to button
ik_target_input = player.animator:getInputIndex("left_hand_ik_target")
ik_alpha_input = player.animator:getInputIndex("left_hand_ik_alpha")
local ik_time = 0

ik_co = coroutine.create(function()
local td = 0
while ik_time < 1 do
player.animator:setVec3Input(ik_target_input, calcIKTarget())
if ik_time < 0.2 then
if ik_time + td >= 0.2 then
-- play the sound
playSound(sound)
-- press (move) the button
this.property_animator.enabled = false
this.property_animator.enabled = true
end
player.animator:setFloatInput(ik_alpha_input, easeOutBack(ik_time / 0.2))
else
player.animator:setFloatInput(ik_alpha_input, 1 - easeOutBack((ik_time - 0.2) / 0.8))
end
td = coroutine.yield(true)
ik_time = ik_time + td
end
return false
end)

end
end
end
end
Binary file modified data/maps/demo/demo.unv
Binary file not shown.
Binary file modified data/models/ybot/ybot.act
Binary file not shown.
134 changes: 75 additions & 59 deletions data/scripts/math.lua
Original file line number Diff line number Diff line change
@@ -1,61 +1,77 @@
return {
dot = function(a, b)
return a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
end,

mulQuat = function(a, b)
return {
a[4] * b[1] + b[4] * a[1] + a[2] * b[3] - b[2] * a[3],
a[4] * b[2] + b[4] * a[2] + a[3] * b[1] - b[3] * a[1],
a[4] * b[3] + b[4] * a[3] + a[1] * b[2] - b[1] * a[2],
a[4] * b[4] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3]
}
end,

makeQuatFromYaw = function(yaw)
local syaw = math.sin(yaw * 0.5)
local cyaw = math.cos(yaw * 0.5)
return {0, syaw, 0, cyaw }
end,

makeQuatFromPitch = function(pitch)
local spitch = math.sin(pitch * 0.5)
local cpitch = math.cos(pitch * 0.5)
return {-spitch, 0, 0, cpitch}
end,

yawToDir = function(yaw)
return {math.sin(yaw), 0, math.cos(yaw)}
end,

mulVec3Num = function(v, f)
return {v[1] * f, v[2] * f, v[3] * f}
end,

addVec3 = function(a, b)
return {a[1] + b[1], a[2] + b[2], a[3] + b[3]}
end,
local m = {}

m.dot = function(a, b)
return a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
end

m.mulQuat = function(a, b)
return {
a[4] * b[1] + b[4] * a[1] + a[2] * b[3] - b[2] * a[3],
a[4] * b[2] + b[4] * a[2] + a[3] * b[1] - b[3] * a[1],
a[4] * b[3] + b[4] * a[3] + a[1] * b[2] - b[1] * a[2],
a[4] * b[4] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3]
}
end

m.makeQuatFromYaw = function(yaw)
local syaw = math.sin(yaw * 0.5)
local cyaw = math.cos(yaw * 0.5)
return {0, syaw, 0, cyaw }
end

m.makeQuatFromPitch = function(pitch)
local spitch = math.sin(pitch * 0.5)
local cpitch = math.cos(pitch * 0.5)
return {-spitch, 0, 0, cpitch}
end

m.yawToDir = function(yaw)
return {math.sin(yaw), 0, math.cos(yaw)}
end

m.mulVec3Num = function(v, f)
return {v[1] * f, v[2] * f, v[3] * f}
end

m.addVec3 = function(a, b)
return {a[1] + b[1], a[2] + b[2], a[3] + b[3]}
end

m.subVec3 = function(a, b)
return {a[1] - b[1], a[2] - b[2], a[3] - b[3]}
end

m.mulVec3 = function(a, f)
return {a[1] * f, a[2] * f, a[3] * f}
end

m.distSquared = function(a, b)
local xd = a[1] - b[1]
local yd = a[2] - b[2]
local zd = a[3] - b[3]

subVec3 = function(a, b)
return {a[1] - b[1], a[2] - b[2], a[3] - b[3]}
end,
return xd * xd + yd * yd + zd * zd
end

m.distXZSquared = function(a, b)
local xd = a[1] - b[1]
local zd = a[3] - b[3]

mulVec3 = function(a, f)
return {a[1] * f, a[2] * f, a[3] * f}
end,

distSquared = function(a, b)
local xd = a[1] - b[1]
local yd = a[2] - b[2]
local zd = a[3] - b[3]

return xd * xd + yd * yd + zd * zd
end,

distXZSquared = function(a, b)
local xd = a[1] - b[1]
local zd = a[3] - b[3]

return xd * xd + zd * zd
end,
}
return xd * xd + zd * zd
end

m.cross = function(a, b)
return {a[2] * b[3] - a[3] * b[2], a[3] * b[1] - a[1] * b[3], a[1] * b[2] - a[2] * b[1]}
end

m.transformVec3 = function(rot_quat, pos)
local qvec = {rot_quat[1], rot_quat[2], rot_quat[3] }
local uv = m.cross(qvec, pos)
local uuv = m.cross(qvec, uv)
uv = m.mulVec3(uv, 2.0 * rot_quat[4])
uuv = m.mulVec3Num(uuv, 2.0)

return m.addVec3(pos, m.addVec3(uv, uuv));
end

return m
1 change: 1 addition & 0 deletions src/animation/animation_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ void AnimationModule::reflect(Engine& engine) {
.LUMIX_CMP(Animator, "animator", "Animation / Animator")
.function<(void (AnimationModule::*)(EntityRef, u32, float))&AnimationModule::setAnimatorInput>("setFloatInput", "AnimationModule::setAnimatorInput")
.function<(void (AnimationModule::*)(EntityRef, u32, bool))&AnimationModule::setAnimatorInput>("setBoolInput", "AnimationModule::setAnimatorInput")
.function<(void (AnimationModule::*)(EntityRef, u32, Vec3))&AnimationModule::setAnimatorInput>("setVec3Input", "AnimationModule::setAnimatorInput")
.LUMIX_FUNC_EX(AnimationModule::getAnimatorInputIndex, "getInputIndex")
.LUMIX_PROP(AnimatorSource, "Source").resourceAttribute(anim::Controller::TYPE)
.LUMIX_PROP(AnimatorDefaultSet, "Default set")
Expand Down
2 changes: 2 additions & 0 deletions src/editor/asset_browser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,10 @@ struct AssetBrowserImpl : AssetBrowser {
{
FileInfo& tile = m_file_infos[j];
bool b = m_selected_resources.find([&](const Path& p){ return p == tile.filepath; }) >= 0;
ImGui::PushID(&tile);
ImGui::Selectable(tile.clamped_filename, b);
callbacks(tile, j, b);
ImGui::PopID();
}
}
}
Expand Down

0 comments on commit 593e358

Please sign in to comment.