1520DLC/res/scripts/vehicleutil.lua

469 lines
17 KiB
Lua

local transf = require "transf"
local vec2 = require "vec2"
local vec3 = require "vec3"
local vehicleutil = { }
local function distToTime(dist)
return 1000 * dist
end
local function calcNumSteps(radius)
-- TODO ?
return 16
end
function vehicleutil.makeCouplingRodAnim(wheelCenter, wheelPos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local keyframes = { }
for i = 0, num do
local f = i / num
--local angle = wheelAngle0 + dist / wheelCenter.y
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
table.insert(keyframes, {
time = duration * f,
transf = transf.transl(vec3.new(wheelPos.x - wheelPos0.x, .0, wheelPos.y - wheelPos0.y))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makePistonAnim(wheelCenter, wheelPos0, pistonPos0)
local length = vec2.distance(wheelPos0, pistonPos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local rodAngle0 = math.atan((wheelPos0.y - pistonPos0.y) / (pistonPos0.x - wheelPos0.x))
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local keyframes = { }
for i = 0, num do
local f = i / num
--local angle = wheelAngle0 + dist / wheelCenter.y
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
local dy = wheelPos.y - pistonPos0.y
local dx = math.sqrt(length * length - dy * dy)
local pistonPos = vec2.new(wheelPos.x + dx, pistonPos0.y)
table.insert(keyframes, {
time = duration * f,
transf = transf.transl(vec3.new(pistonPos.x - pistonPos0.x, .0, .0))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makeConnectingRodAnim(wheelCenter, wheelPos0, pistonPos0)
local length = vec2.distance(wheelPos0, pistonPos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local rodAngle0 = math.atan((wheelPos0.y - pistonPos0.y) / (pistonPos0.x - wheelPos0.x))
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local keyframes = { }
for i = 0, num do
local f = i / num
--local angle = wheelAngle0 + dist / wheelCenter.y
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
local dy = wheelPos.y - pistonPos0.y
local dx = math.sqrt(length * length - dy * dy)
local pistonPos = vec2.new(wheelPos.x + dx, pistonPos0.y)
table.insert(keyframes, {
time = duration * f,
--transf = transf.rotYCntTransl(math.atan(dy / dx) - rodAngle0, vec3.new(pistonPos0.x, .0, pistonPos0.y),
-- vec3.new(pistonPos.x - pistonPos0.x, .0, .0))
transf = transf.rotYCntTransl(math.atan(dy / dx) - rodAngle0, vec3.new(pistonPos0.x - wheelPos0.x, .0, pistonPos0.y - wheelPos0.y),
vec3.new(pistonPos.x - pistonPos0.x, .0, .0))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makegear3Anim(wheelCenter, wheelPos0, gearcenter, gearpos0)
local length = vec2.distance(wheelPos0, gearpos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local rodAngle0 = math.atan((wheelPos0.y - gearpos0.y) / (gearpos0.x - wheelPos0.x))
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local gearradius = math.sqrt((gearcenter.y-gearpos0.y)^2+(gearcenter.x-gearpos0.x)^2)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local angle1 = math.atan((gearcenter.x-gearpos0.x)/(gearcenter.y-gearpos0.y)) - math.pi/2
local angle2 = angle1 - 2*(math.asin((2*radius)/(2*gearradius)))
local angledif = angle1 - angle2
local anglestep = angledif/(num/2)
local keyframes = { }
for i = 0, num/2 do
local f = i / num
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
local gearangle = angle1+anglestep*i
local gearpos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = wheelPos.y - gearpos.y
local dx = math.sqrt(length * length - dy * dy)
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(dy / dx)-rodAngle0, vec3.new(gearpos0.x - wheelPos0.x, .0, gearpos0.y - wheelPos0.y),
vec3.new(gearpos.x - gearpos0.x, .0, gearpos.y -gearpos0.y ))
})
end
for i = (num/2)+1, num do
local f = i / num
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
local gearangle = angle1+angledif-anglestep*(i-num/2)
local gearpos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = wheelPos.y - gearpos.y
local dx = math.sqrt(length * length - dy * dy)
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(dy / dx)-rodAngle0, vec3.new(gearpos0.x - wheelPos0.x, .0, gearpos0.y - wheelPos0.y),
vec3.new(gearpos.x - gearpos0.x, .0, gearpos.y -gearpos0.y ))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makegear2Anim(wheelCenter, wheelPos0, gearcenter, gearpos0)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local radius = vec2.distance(wheelPos0, wheelCenter)
local gearradius = math.sqrt((gearcenter.y-gearpos0.y)^2+(gearcenter.x-gearpos0.x)^2)
local num = calcNumSteps(radius)
local angle1 = math.atan((gearcenter.x-gearpos0.x)/(gearcenter.y-gearpos0.y))
local gearangle0 = math.atan((gearcenter.y - gearpos0.y) / (gearpos0.x - gearcenter.x)) - math.pi/2
local angle2 = angle1 - 2*(math.asin((2*radius)/(2*gearradius)))
local angledif = angle1 - angle2
local anglestep = angledif/(num/2)
local keyframes = { }
for i = 0, num/2 do
local f = i / num
local gearangle = angle1+anglestep*i
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(gearangle - gearangle0, vec3.new(.0,.0, .0), vec3.new(.0,.0, .0) )
})
end
for i = (num/2)+1, num do
local f = i / num
local gearangle = angle1+angledif-anglestep*(i-num/2)
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(gearangle - gearangle0, vec3.new(.0,.0, .0), vec3.new(.0,.0, .0) )
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makegear4Anim(wheelCenter, wheelPos0, gearcenter, gear4pos0, valvepos0, gearpos0)
local length = vec2.distance(valvepos0, gearpos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local rodAngle0 = math.atan((gear4pos0.y-valvepos0.y) / (valvepos0.x-gear4pos0.x ))
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local gearradius = math.sqrt((gearcenter.y-gear4pos0.y)^2+(gearcenter.x-gear4pos0.x)^2)
local gearradius1 = math.sqrt((gearcenter.y-gearpos0.y)^2+(gearcenter.x-gearpos0.x)^2)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local angle1 = math.atan((gearcenter.x-gear4pos0.x)/(gearcenter.y-gear4pos0.y)) - math.pi/2
local angle2 = angle1 - 2*(math.asin((2*radius)/(2*gearradius1)))
local angledif = angle1 - angle2
local anglestep = angledif/(num/2)
local keyframes = { }
for i = 0, num/2 do
local f = i / num
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
local gearangle = angle1+anglestep*i
local gear4pos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = gear4pos.y - valvepos0.y
local dx = math.sqrt(length * length - dy * dy)
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(dy / dx)-rodAngle0, vec3.new(gear4pos0.x - wheelPos0.x, .0, gear4pos0.y - wheelPos0.y),
vec3.new(gear4pos.x - gear4pos0.x, .0, .0))
})
end
for i = (num/2)+1, num do
local f = i / num
local angle = wheelAngle0 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius, vec2.new(-math.cos(angle), math.sin(angle))))
local gearangle = angle1+angledif-anglestep*(i-num/2)
local gear4pos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = gear4pos.y - valvepos0.y
local dx = math.sqrt(length * length - dy * dy)
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(dy / dx)-rodAngle0, vec3.new(gear4pos0.x - wheelPos0.x, .0, gear4pos0.y - wheelPos0.y),
vec3.new(gear4pos.x - gear4pos0.x, .0, .0))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makegear5Anim(wheelCenter,wheelPos1, wheelPos0, pistonPos0, gearcenter, gear4pos0, valvepos0, gearpos0, gear5pos0, gear6pos0)
local length = vec2.distance(wheelPos1, pistonPos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local radius1 = vec2.distance(wheelPos1, wheelCenter)
local c = vec2.distance(valvepos0, gear5pos0)
local b = vec2.distance(gear6pos0, gear5pos0)
local rodAngle0 = math.atan2(-valvepos0.y+gear5pos0.y, -gear5pos0.x+valvepos0.x)
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local wheelAngle1 = math.atan2(wheelPos1.y - wheelCenter.y, wheelCenter.x - wheelPos1.x)
local gearradius = math.sqrt((gearcenter.y-gear4pos0.y)^2+(gearcenter.x-gear4pos0.x)^2)
local gearradius1 = math.sqrt((gearcenter.y-gearpos0.y)^2+(gearcenter.x-gearpos0.x)^2)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local angle1 = math.atan((gearcenter.x-gear4pos0.x)/(gearcenter.y-gear4pos0.y)) - math.pi/2
local angle2 = angle1 - 2*(math.asin((2*radius)/(2*gearradius1)))
local angledif = angle1 - angle2
local anglestep = angledif/(num/2)
local keyframes = { }
for i = 0, num/2 do
local f = i / num
local angle = wheelAngle1 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius1, vec2.new(-math.cos(angle), math.sin(angle))))
local dy = wheelPos.y - pistonPos0.y
local dx = (math.sqrt(length * length - dy * dy))-(pistonPos0.x-gear5pos0.x)
local pistonPos = vec2.new(wheelPos.x + dx - (gear5pos0.x-gear6pos0.x), gear5pos0.y)
local gearangle = angle1+anglestep*i
local gear4pos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = valvepos0.y-gear5pos0.y
local dx = (gear4pos.x+(gear5pos0.x-gear4pos0.x))- (pistonPos.x)
a = math.sqrt(dy^2+dx^2)
A = math.acos((b^2+c^2-a^2)/(2*b*c))
B = math.acos((a^2+c^2-b^2)/(2*a*c))
C = math.acos((b^2+a^2-c^2)/(2*b*a))
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(-dy/dx)-B-rodAngle0, vec3.new(valvepos0.x - gear5pos0.x, .0, valvepos0.y - gear5pos0.y),
vec3.new((gear4pos.x+(gear5pos0.x-gear4pos0.x)) - gear5pos0.x, .0, .0))
})
end
for i = (num/2)+1, num do
local f = i / num
local angle = wheelAngle1 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius1, vec2.new(-math.cos(angle), math.sin(angle))))
local dy = wheelPos.y - pistonPos0.y
local dx = math.sqrt(length * length - dy * dy)-(pistonPos0.x-gear5pos0.x)
local pistonPos = vec2.new(wheelPos.x + dx - (gear5pos0.x-gear6pos0.x), gear5pos0.y)
local gearangle = angle1+angledif-anglestep*(i-num/2)
local gear4pos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = valvepos0.y-gear5pos0.y
local dx = (gear4pos.x+(gear5pos0.x-gear4pos0.x))- (pistonPos.x)
a = math.sqrt(dy^2+dx^2)
A = math.acos((b^2+c^2-a^2)/(2*b*c))
B = math.acos((a^2+c^2-b^2)/(2*a*c))
C = math.acos((b^2+a^2-c^2)/(2*b*a))
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(-dy/dx)-B-rodAngle0, vec3.new(valvepos0.x - gear5pos0.x, .0, valvepos0.y - gear5pos0.y),
vec3.new((gear4pos.x+(gear5pos0.x-gear4pos0.x)) - gear5pos0.x, .0, .0))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
function vehicleutil.makegear6Anim(wheelCenter,wheelPos1, wheelPos0, pistonPos0, gearcenter, gear4pos0, valvepos0, gearpos0, gear5pos0, gear6pos0)
local length = vec2.distance(wheelPos1, pistonPos0)
local radius = vec2.distance(wheelPos0, wheelCenter)
local radius1 = vec2.distance(wheelPos1, wheelCenter)
local c = vec2.distance(valvepos0, gear5pos0)
local b = vec2.distance(gear6pos0, gear5pos0)
local rodAngle0 = math.atan2(gear6pos0.y-gear5pos0.y, gear5pos0.x-gear6pos0.x)
local wheelAngle0 = math.atan2(wheelPos0.y - wheelCenter.y, wheelCenter.x - wheelPos0.x)
local wheelAngle1 = math.atan2(wheelPos1.y - wheelCenter.y, wheelCenter.x - wheelPos1.x)
local gearradius = math.sqrt((gearcenter.y-gear4pos0.y)^2+(gearcenter.x-gear4pos0.x)^2)
local gearradius1 = math.sqrt((gearcenter.y-gearpos0.y)^2+(gearcenter.x-gearpos0.x)^2)
local duration = distToTime(2.0 * math.pi * wheelCenter.y)
local num = calcNumSteps(radius)
local angle1 = math.atan((gearcenter.x-gear4pos0.x)/(gearcenter.y-gear4pos0.y)) - math.pi/2
local angle2 = angle1 - 2*(math.asin((2*radius)/(2*gearradius1)))
local angledif = angle1 - angle2
local anglestep = angledif/(num/2)
local keyframes = { }
for i = 0, num/2 do
local f = i / num
local angle = wheelAngle1 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius1, vec2.new(-math.cos(angle), math.sin(angle))))
local dy = wheelPos.y - pistonPos0.y
local dx = (math.sqrt(length * length - dy * dy))-(pistonPos0.x-gear5pos0.x)
local pistonPos = vec2.new(wheelPos.x + dx - (gear5pos0.x-gear6pos0.x), gear5pos0.y)
local gearangle = angle1+anglestep*i
local gear4pos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = valvepos0.y-gear5pos0.y
local dx = (gear4pos.x+(gear5pos0.x-gear4pos0.x))- (pistonPos.x)
a = math.sqrt(dy^2+dx^2)
A = math.acos((b^2+c^2-a^2)/(2*b*c))
B = math.acos((a^2+c^2-b^2)/(2*a*c))
C = math.acos((b^2+a^2-c^2)/(2*b*a))
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(-dy/dx)+C-rodAngle0, vec3.new(gear6pos0.x - gear5pos0.x, .0, gear6pos0.y - gear5pos0.y),
vec3.new(pistonPos.x - gear6pos0.x , .0, .0))
})
end
for i = (num/2)+1, num do
local f = i / num
local angle = wheelAngle1 + 2.0 * math.pi * f
local wheelPos = vec2.add(wheelCenter, vec2.mul(radius1, vec2.new(-math.cos(angle), math.sin(angle))))
local dy = wheelPos.y - pistonPos0.y
local dx = math.sqrt(length * length - dy * dy)-(pistonPos0.x-gear5pos0.x)
local pistonPos = vec2.new(wheelPos.x + dx - (gear5pos0.x-gear6pos0.x), gear5pos0.y)
local gearangle = angle1+angledif-anglestep*(i-num/2)
local gear4pos = vec2.add(gearcenter,vec2.mul(gearradius ,vec2.new(-math.cos(gearangle),math.sin(gearangle))))
local dy = valvepos0.y-gear5pos0.y
local dx = (gear4pos.x+(gear5pos0.x-gear4pos0.x))- (pistonPos.x)
a = math.sqrt(dy^2+dx^2)
A = math.acos((b^2+c^2-a^2)/(2*b*c))
B = math.acos((a^2+c^2-b^2)/(2*a*c))
C = math.acos((b^2+a^2-c^2)/(2*b*a))
table.insert(keyframes, {
time = duration * f,
transf = transf.rotYCntTransl(math.atan(-dy/dx)+C-rodAngle0, vec3.new(gear6pos0.x - gear5pos0.x, .0, gear6pos0.y - gear5pos0.y),
vec3.new(pistonPos.x - gear6pos0.x , .0, .0))
})
end
return {
type = "KEYFRAME_MATRIX",
params = {
keyframes = keyframes
}
}
end
return vehicleutil