358 lines
9.4 KiB
Lua
358 lines
9.4 KiB
Lua
-------------------------------------------------------------------------------
|
|
-- Mob Framework Mod by Sapier
|
|
--
|
|
-- You may copy, use, modify or do nearly anything except removing this
|
|
-- copyright notice.
|
|
-- And of course you are NOT allow to pretend you have written it.
|
|
--
|
|
--! @file geometry.lua
|
|
--! @brief generic functions used in many different places
|
|
--! @copyright Sapier
|
|
--! @author Sapier
|
|
--! @date 2013-02-04
|
|
--!
|
|
-- Contact sapier a t gmx net
|
|
-------------------------------------------------------------------------------
|
|
|
|
--! @defgroup gen_func Generic functions
|
|
--! @brief functions for various tasks
|
|
--! @ingroup framework_int
|
|
--! @{
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_distance(pos1,pos2)
|
|
--
|
|
--! @brief calculate 3d distance between to points
|
|
--
|
|
--! @param pos1 first position
|
|
--! @param pos2 second position
|
|
--! @retval scalar value, distance
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_distance(pos1,pos2)
|
|
mobf_assert_backtrace(pos1 ~= nil)
|
|
mobf_assert_backtrace(pos2 ~= nil)
|
|
|
|
return math.sqrt( math.pow(pos1.x-pos2.x,2) +
|
|
math.pow(pos1.y-pos2.y,2) +
|
|
math.pow(pos1.z-pos2.z,2))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_distance_2d(pos1,pos2)
|
|
--
|
|
--! @brief calculate 2d distance between to points
|
|
--
|
|
--! @param pos1 target position
|
|
--! @param pos2 start position
|
|
--! @return scalar value, distance
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_distance_2d(pos1,pos2)
|
|
return math.sqrt( math.pow(pos1.x-pos2.x,2) +
|
|
math.pow(pos1.z-pos2.z,2))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_direction(pos1,pos2)
|
|
--
|
|
--! @brief calculate direction angles from pos2 to pos1
|
|
--
|
|
--! @param start starting position
|
|
--! @param destination end position
|
|
--! @return anglexz,anglexy
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_direction(start,destination)
|
|
mobf_assert_backtrace(start ~= nil)
|
|
mobf_assert_backtrace(destination ~= nil)
|
|
|
|
local xdelta = destination.x - start.x
|
|
local ydelta = destination.y - start.y
|
|
local zdelta = destination.z - start.z
|
|
|
|
local distance = math.sqrt(
|
|
math.pow(xdelta,2) +
|
|
math.pow(ydelta,2) +
|
|
math.pow(zdelta,2)
|
|
)
|
|
|
|
local anglexz = math.atan2(zdelta,xdelta)
|
|
local anglexy = math.acos(ydelta/distance)
|
|
return anglexz,anglexy
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_scalar_speed(speedx,speedz)
|
|
--
|
|
--! @brief calculate scalar speed
|
|
--
|
|
--! @param speedx speed in direction x
|
|
--! @param speedz speed in direction z
|
|
--
|
|
--! @return scalar speed value
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_scalar_speed(speedx,speedz)
|
|
return math.sqrt(math.pow(speedx,2)+
|
|
math.pow(speedz,2))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_vector_components(dir_radians,absolute_speed)
|
|
--
|
|
--! @brief calculate calculate x and z components of a directed speed
|
|
--
|
|
--! @param dir_radians direction of movement radians
|
|
--! @param absolute_speed speed in direction
|
|
--
|
|
--! @return {x,z}
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_vector_components(dir_radians,absolute_speed)
|
|
|
|
local retval = {x=0,z=0}
|
|
|
|
retval.x = absolute_speed * math.cos(dir_radians)
|
|
retval.z = absolute_speed * math.sin(dir_radians)
|
|
|
|
return retval
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_vector_components_3d(xzplane_radians,xy_plane_radians,absolute_speed)
|
|
--
|
|
--! @brief calculate calculate x and z components of a directed speed
|
|
--
|
|
--! @param xz_plane_radians direction of movement within x-z plane radians
|
|
--! @param xy_plane_radians direction of movement within x-y plane radians
|
|
--! @param absolute_speed speed in direction
|
|
--
|
|
--! @return {x,z}
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_vector_components_3d(xz_plane_radians,xy_plane_radians,absolute_speed)
|
|
|
|
local retval = {x=0,z=0,y=0}
|
|
|
|
retval.x= absolute_speed * math.sin(xy_plane_radians) * math.cos(xz_plane_radians)
|
|
retval.z= absolute_speed * math.sin(xy_plane_radians) * math.sin(xz_plane_radians)
|
|
retval.y= absolute_speed * math.cos(xy_plane_radians)
|
|
|
|
return retval
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_get_direction(pos1,pos2)
|
|
--
|
|
--! @brief get normalized direction from pos1 to pos2
|
|
--
|
|
--! @param pos1 source point
|
|
--! @param pos2 destination point
|
|
--! @return xyz direction
|
|
-------------------------------------------------------------------------------
|
|
function mobf_get_direction(pos1,pos2)
|
|
|
|
local x_raw = pos2.x -pos1.x
|
|
local y_raw = pos2.y -pos1.y
|
|
local z_raw = pos2.z -pos1.z
|
|
|
|
|
|
local x_abs = math.abs(x_raw)
|
|
local y_abs = math.abs(y_raw)
|
|
local z_abs = math.abs(z_raw)
|
|
|
|
if x_abs >= y_abs and
|
|
x_abs >= z_abs then
|
|
|
|
y_raw = y_raw * (1/x_abs)
|
|
z_raw = z_raw * (1/x_abs)
|
|
|
|
x_raw = x_raw/x_abs
|
|
|
|
end
|
|
|
|
if y_abs >= x_abs and
|
|
y_abs >= z_abs then
|
|
|
|
|
|
x_raw = x_raw * (1/y_abs)
|
|
z_raw = z_raw * (1/y_abs)
|
|
|
|
y_raw = y_raw/y_abs
|
|
|
|
end
|
|
|
|
if z_abs >= y_abs and
|
|
z_abs >= x_abs then
|
|
|
|
x_raw = x_raw * (1/z_abs)
|
|
y_raw = y_raw * (1/z_abs)
|
|
|
|
z_raw = z_raw/z_abs
|
|
|
|
end
|
|
|
|
return {x=x_raw,y=y_raw,z=z_raw}
|
|
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_yaw(x,z)
|
|
--
|
|
--! @brief calculate radians value of a 2 dimendional vector
|
|
--
|
|
--! @param x vector component 1
|
|
--! @param z vector component 2
|
|
--
|
|
--! @return radians value
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_yaw(x,z)
|
|
local direction = math.atan2(z,x)
|
|
|
|
while direction < 0 do
|
|
direction = direction + (2* math.pi)
|
|
end
|
|
|
|
while direction > (2*math.pi) do
|
|
direction = direction - (2* math.pi)
|
|
end
|
|
|
|
return direction
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_assert_backtrace(value)
|
|
--
|
|
--! @brief assert in case value is false
|
|
--
|
|
--! @param heightdiff height difference between shooter and target
|
|
--! @param time time to reach target
|
|
--! @param acceleration acceleration set for object
|
|
--
|
|
--! @return y-velocity at start
|
|
-------------------------------------------------------------------------------
|
|
function mobf_balistic_start_speed(heightdiff,time,acceleration)
|
|
mobf_assert_backtrace(heightdiff ~= nil)
|
|
mobf_assert_backtrace(time ~= nil)
|
|
mobf_assert_backtrace(acceleration ~= nil)
|
|
|
|
return (heightdiff - (acceleration/2) * (time*time)) / time
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_calc_travel_time(distance,velocity,acceleration)
|
|
--
|
|
--! @brief assert in case value is false
|
|
--
|
|
--! @param distance distance to target
|
|
--! @param velocity to start with
|
|
--! @param acceleration acceleratio to use
|
|
--
|
|
--! @return time to target
|
|
-------------------------------------------------------------------------------
|
|
function mobf_calc_travel_time(distance,velocity,acceleration)
|
|
mobf_assert_backtrace(distance ~= nil)
|
|
mobf_assert_backtrace(velocity ~= nil)
|
|
mobf_assert_backtrace(acceleration ~= nil)
|
|
|
|
if acceleration == 0 then
|
|
--print("no accel shortcut time calculation")
|
|
return distance/velocity
|
|
end
|
|
|
|
local a = acceleration/2
|
|
local b = velocity
|
|
local c = -distance
|
|
|
|
--print("a=" .. a .. " b=" .. b .. " c=" .. c)
|
|
|
|
local det = b*b - 4*a*c
|
|
|
|
--print("det=" .. det)
|
|
|
|
if det < 0 then
|
|
return nil
|
|
end
|
|
|
|
local ret1 = (-b + math.sqrt(det))/(2*a)
|
|
local ret2 = (-b - math.sqrt(det))/(2*a)
|
|
|
|
--print("x1=" .. ret1 .. " x2=" .. ret2)
|
|
|
|
if ret1 > 0 then
|
|
return ret1
|
|
end
|
|
|
|
return ret2
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_same_quadrant(x1,z1,x2,z2)
|
|
--
|
|
--! @brief check if two points are in same quadrant
|
|
--
|
|
--! @param x1 x of point1
|
|
--! @param z1 z of point1
|
|
--! @param x2 x of point2
|
|
--! @param z2 z of point2
|
|
--
|
|
--! @return true/false
|
|
-------------------------------------------------------------------------------
|
|
function mobf_same_quadrant(x1,z1,x2,z2)
|
|
|
|
if x1 > 0 and x2 < 0 or
|
|
x1 < 0 and x2 >0 then
|
|
return false
|
|
end
|
|
|
|
if z1 > 0 and z2 < 0 or
|
|
z1 < 0 and z2 >0 then
|
|
return false
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_gauss(center)
|
|
--
|
|
--! @brief calc random value based uppon gauss distribution around a value
|
|
--
|
|
--! @param center center value for distribution
|
|
--! @param max_deviation maximum deviation from center
|
|
--
|
|
--! @return gauss randomized value
|
|
-------------------------------------------------------------------------------
|
|
function mobf_gauss(center,max_deviation)
|
|
|
|
local u1 = 2 * math.random() -1
|
|
local u2 = 2 * math.random() -1
|
|
|
|
local q = u1*u1 + u2*u2
|
|
|
|
local maxtries = 0
|
|
|
|
while (q == 0 or q >= 1) and maxtries < 10 do
|
|
u1 = math.random()
|
|
u2 = math.random() * -1
|
|
q = u1*u1 + u2*u2
|
|
|
|
maxtries = maxtries +1
|
|
end
|
|
|
|
--abort random generation
|
|
if maxtries >= 10 then
|
|
return center
|
|
end
|
|
|
|
local p = math.sqrt( (-2*math.log(q))/q )
|
|
|
|
local retval = nil
|
|
|
|
--calculate normalized value of max deviation
|
|
if math.random() < 0.5 then
|
|
retval = center + ( u1*p * (center*max_deviation))
|
|
else
|
|
retval = center + ( u2*p * (center*max_deviation))
|
|
end
|
|
|
|
return retval
|
|
end
|
|
--!@} |