I feel you, i had ran into the same issue. What i ended up with was to generate a abitrary downforce value given the triangles at spawn. So imagine you shoot a beam at the center of a triangle and then look by how much it deflects up. Multiply that by the m2 of the triangle and add in the lift coef somehow.
Imma give you the code, altough you have to replicate it as im using my own vec3 library to make my code free of garbage for the gc.
Also added comments for you
VARBUF.evalTriangle = {Vec3(), Vec3(), Vec3(), Vec3(), Vec3(), Vec3(), Vec3()}
local function evalTriangle(n1, n2, n3)
local m_pos, v_dir, e_pos, e1, e2, normal, reflect = unpack(VARBUF.evalTriangle)
v_dir:set(obj:getDirectionVectorXYZ()):unm() -- unm is (x * -1)
-- middle of the triangle
m_pos:set(
n1.x + n2.x + n3.x,
n1.y + n2.y + n3.y,
n1.z + n2.z + n3.z
):div(3) -- (n1 + n2 + n3) / 3
e_pos:setV(m_pos):sub(v_dir) -- m_pos - v_dir
-- edges
e1:set(
n2.x - n1.x,
n2.y - n1.y,
n2.z - n1.z
) -- n2 - n1
e2:set(
n3.x - n1.x,
n3.y - n1.y,
n3.z - n1.z
) -- n3 - n1
-- create normalized normal of the edges
normal:setV(e1):cross(e2) -- e1 cross e2
local area = normal:length() * 0.5 -- grab area before normalizing
normal:normalize()
-- create exit dir
local dot = v_dir:dot(normal)
reflect:set(
v_dir.x - 2 * dot * normal.x,
v_dir.y - 2 * dot * normal.y,
v_dir.z - 2 * dot * normal.z
)
if reflect.z < 0 then return 0 end
local angle = v_dir:acosAngle(reflect)
return angle, area
end
VARBUF.evalDownforce = {Vec3(), Vec3(), Vec3(), Vec3()}
local function evalDownforce()
local c_pos, n1, n2, n3 = unpack(VARBUF.evalDownforce)
local total = 0
c_pos:set(obj:getPositionXYZ()) -- global veh pos
for _, triangle in pairs(v.data.triangles) do
if triangle.liftCoef then
n1:setV(obj:getNodePosition(triangle.id1)):add(c_pos) -- local node pos + global veh pos = global node pos
n2:setV(obj:getNodePosition(triangle.id2)):add(c_pos) -- ..
n3:setV(obj:getNodePosition(triangle.id3)):add(c_pos) -- ..
local angle, area = evalTriangle(n1, n2, n3)
-- ...
end
end
return total
end