mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +00:00
Lunatic: retire 'geom' module, putting vector types into xmath.
git-svn-id: https://svn.eduke32.com/eduke32@3909 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
7cb94070e1
commit
885036a6a3
13 changed files with 257 additions and 265 deletions
|
@ -151,7 +151,6 @@ ifneq (0,$(LUNATIC))
|
||||||
GAMEOBJS+= $(OBJ)/../lpeg.a # TEMP
|
GAMEOBJS+= $(OBJ)/../lpeg.a # TEMP
|
||||||
GAMEOBJS+= $(OBJ)/luaJIT_BC_con_lang.$o \
|
GAMEOBJS+= $(OBJ)/luaJIT_BC_con_lang.$o \
|
||||||
$(OBJ)/luaJIT_BC_lunacon.$o \
|
$(OBJ)/luaJIT_BC_lunacon.$o \
|
||||||
$(OBJ)/luaJIT_BC_geom.$o \
|
|
||||||
$(OBJ)/luaJIT_BC_randgen.$o \
|
$(OBJ)/luaJIT_BC_randgen.$o \
|
||||||
$(OBJ)/luaJIT_BC_stat.$o \
|
$(OBJ)/luaJIT_BC_stat.$o \
|
||||||
$(OBJ)/luaJIT_BC_bitar.$o \
|
$(OBJ)/luaJIT_BC_bitar.$o \
|
||||||
|
|
|
@ -13,7 +13,6 @@ local io = require("io")
|
||||||
local math = require("math")
|
local math = require("math")
|
||||||
local table = require("table")
|
local table = require("table")
|
||||||
|
|
||||||
local geom = require("geom")
|
|
||||||
local bcheck = require("bcheck")
|
local bcheck = require("bcheck")
|
||||||
local con_lang = require("con_lang")
|
local con_lang = require("con_lang")
|
||||||
|
|
||||||
|
@ -447,6 +446,8 @@ end
|
||||||
local xmath = require("xmath")
|
local xmath = require("xmath")
|
||||||
local abs = math.abs
|
local abs = math.abs
|
||||||
local dist, ldist = xmath.dist, xmath.ldist
|
local dist, ldist = xmath.dist, xmath.ldist
|
||||||
|
local vec3, ivec3 = xmath.vec3, xmath.ivec3
|
||||||
|
local rotate = xmath.rotate
|
||||||
|
|
||||||
local function A_FP_ManhattanDist(ps, spr)
|
local function A_FP_ManhattanDist(ps, spr)
|
||||||
local distvec = ps.pos - spr^(28*256)
|
local distvec = ps.pos - spr^(28*256)
|
||||||
|
@ -473,15 +474,15 @@ end
|
||||||
|
|
||||||
local FN_DISTFUNC = {
|
local FN_DISTFUNC = {
|
||||||
d2 = function(s1, s2, d)
|
d2 = function(s1, s2, d)
|
||||||
return (xmath.ldist(s1, s2) < d)
|
return (ldist(s1, s2) < d)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
d3 = function(s1, s2, d)
|
d3 = function(s1, s2, d)
|
||||||
return (xmath.dist(s1, s2) < d)
|
return (dist(s1, s2) < d)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
z = function(s1, s2, d, zd)
|
z = function(s1, s2, d, zd)
|
||||||
return (xmath.ldist(s1, s2) < d and abs(s1.z-s2.z) < zd)
|
return (ldist(s1, s2) < d and abs(s1.z-s2.z) < zd)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,10 +791,10 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- switch statement support
|
-- switch statement support
|
||||||
function _switch(swtab, testval, aci,pli,dist)
|
function _switch(swtab, testval, aci,pli,dst)
|
||||||
local func = swtab[testval] or swtab.default
|
local func = swtab[testval] or swtab.default
|
||||||
if (func) then
|
if (func) then
|
||||||
func(aci, pli, dist)
|
func(aci, pli, dst)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -931,7 +932,7 @@ function _A_DoGuts(i, gutstile, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i=n,1, -1 do
|
for i=n,1, -1 do
|
||||||
local pos = geom.vec3(spr.x+krandand(255)-128, spr.y+krandand(255)-128, z-krandand(8191))
|
local pos = vec3(spr.x+krandand(255)-128, spr.y+krandand(255)-128, z-krandand(8191))
|
||||||
local j = insertsprite{ gutstile, pos, spr.sectnum, i, 5, shade=-32, xrepeat=xsz, yrepeat=ysz,
|
local j = insertsprite{ gutstile, pos, spr.sectnum, i, 5, shade=-32, xrepeat=xsz, yrepeat=ysz,
|
||||||
ang=krandand(2047), xvel=48+krandand(31), zvel=-512-krandand(2047) }
|
ang=krandand(2047), xvel=48+krandand(31), zvel=-512-krandand(2047) }
|
||||||
local newspr = sprite[j]
|
local newspr = sprite[j]
|
||||||
|
@ -954,7 +955,7 @@ function _debris(i, dtile, n)
|
||||||
for j=n-1,0, -1 do
|
for j=n-1,0, -1 do
|
||||||
local isblimpscrap = (ispic(spr.picnum, "BLIMP") and ispic(dtile, "SCRAP1"))
|
local isblimpscrap = (ispic(spr.picnum, "BLIMP") and ispic(dtile, "SCRAP1"))
|
||||||
local picofs = isblimpscrap and 0 or krandand(3)
|
local picofs = isblimpscrap and 0 or krandand(3)
|
||||||
local pos = spr + geom.vec3(krandand(255)-128, krandand(255)-128, -(8*256)-krandand(8191))
|
local pos = spr + vec3(krandand(255)-128, krandand(255)-128, -(8*256)-krandand(8191))
|
||||||
local jj = insertsprite{ dtile+picofs, pos, spr.sectnum, i, 5,
|
local jj = insertsprite{ dtile+picofs, pos, spr.sectnum, i, 5,
|
||||||
shade=spr.shade, xrepeat=32+krandand(15), yrepeat=32+krandand(15),
|
shade=spr.shade, xrepeat=32+krandand(15), yrepeat=32+krandand(15),
|
||||||
ang=krandand(2047), xvel=32+krandand(127), zvel=-krandand(2047) }
|
ang=krandand(2047), xvel=32+krandand(127), zvel=-krandand(2047) }
|
||||||
|
@ -1270,7 +1271,7 @@ end
|
||||||
|
|
||||||
-- d is a distance
|
-- d is a distance
|
||||||
function _awayfromwall(spr, d)
|
function _awayfromwall(spr, d)
|
||||||
local vec2 = geom.vec2
|
local vec2 = xmath.vec2
|
||||||
local vecs = { vec2(d,d), vec2(-d,-d), vec2(d,-d), vec2(-d,d) }
|
local vecs = { vec2(d,d), vec2(-d,-d), vec2(d,-d), vec2(-d,d) }
|
||||||
for i=1,4 do
|
for i=1,4 do
|
||||||
if (not inside(vecs[i]+spr, spr.sectnum)) then
|
if (not inside(vecs[i]+spr, spr.sectnum)) then
|
||||||
|
@ -1372,14 +1373,14 @@ end
|
||||||
|
|
||||||
-- CON "hitscan" command
|
-- CON "hitscan" command
|
||||||
function _hitscan(x, y, z, sectnum, vx, vy, vz, cliptype)
|
function _hitscan(x, y, z, sectnum, vx, vy, vz, cliptype)
|
||||||
local srcv = geom.ivec3(x, y, z)
|
local srcv = ivec3(x, y, z)
|
||||||
local hit = hitscan(srcv, sectnum, vx, vy, vz, cliptype)
|
local hit = hitscan(srcv, sectnum, vx, vy, vz, cliptype)
|
||||||
return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z
|
return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z
|
||||||
end
|
end
|
||||||
|
|
||||||
-- CON "neartag" command
|
-- CON "neartag" command
|
||||||
function _neartag(x, y, z, sectnum, ang, range, tagsearch)
|
function _neartag(x, y, z, sectnum, ang, range, tagsearch)
|
||||||
local pos = geom.ivec3(x, y, z)
|
local pos = ivec3(x, y, z)
|
||||||
local near = neartag(pos, sectnum, ang, range, tagsearch)
|
local near = neartag(pos, sectnum, ang, range, tagsearch)
|
||||||
return near.sector, near.wall, near.sprite, near.dist
|
return near.sector, near.wall, near.sprite, near.dist
|
||||||
end
|
end
|
||||||
|
@ -1387,7 +1388,7 @@ end
|
||||||
-- CON "getzrange" command
|
-- CON "getzrange" command
|
||||||
function _getzrange(x, y, z, sectnum, walldist, clipmask)
|
function _getzrange(x, y, z, sectnum, walldist, clipmask)
|
||||||
check_sector_idx(sectnum)
|
check_sector_idx(sectnum)
|
||||||
local ipos = geom.ivec3(x, y, z)
|
local ipos = ivec3(x, y, z)
|
||||||
local hit = sector[sectnum]:zrangeat(ipos, walldist, clipmask)
|
local hit = sector[sectnum]:zrangeat(ipos, walldist, clipmask)
|
||||||
-- return: ceilz, ceilhit, florz, florhit
|
-- return: ceilz, ceilhit, florz, florhit
|
||||||
return hit.c.z, hit.c.num + (hit.c.spritep and 49152 or 16384),
|
return hit.c.z, hit.c.num + (hit.c.spritep and 49152 or 16384),
|
||||||
|
@ -1397,16 +1398,16 @@ end
|
||||||
-- CON "clipmove" and "clipmovenoslide" commands
|
-- CON "clipmove" and "clipmovenoslide" commands
|
||||||
function _clipmovex(x, y, z, sectnum, xv, yv, wd, cd, fd, clipmask, noslidep)
|
function _clipmovex(x, y, z, sectnum, xv, yv, wd, cd, fd, clipmask, noslidep)
|
||||||
check_sector_idx(sectnum)
|
check_sector_idx(sectnum)
|
||||||
local ipos = geom.ivec3(x, y, z)
|
local ipos = ivec3(x, y, z)
|
||||||
local sect = ffi.new("int16_t [1]")
|
local sect = ffi.new("int16_t [1]")
|
||||||
local ret = ffiC.clipmovex(ipos, sect, xv, yv, wd, cd, fd, clipmask, noslidep)
|
local ret = ffiC.clipmovex(ipos, sect, xv, yv, wd, cd, fd, clipmask, noslidep)
|
||||||
-- Return: clipmovex() return value; updated x, y, sectnum
|
-- Return: clipmovex() return value; updated x, y, sectnum
|
||||||
return ret, ipos.x, ipos.y, sect[0]
|
return ret, ipos.x, ipos.y, sect[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
function _sleepcheck(aci, dist)
|
function _sleepcheck(aci, dst)
|
||||||
local acs = actor[aci]
|
local acs = actor[aci]
|
||||||
if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then
|
if (dst > MAXSLEEPDIST and acs.timetosleep == 0) then
|
||||||
acs.timetosleep = SLEEPTIME
|
acs.timetosleep = SLEEPTIME
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1419,7 +1420,7 @@ end
|
||||||
|
|
||||||
function _movesprite(spritenum, x, y, z, cliptype)
|
function _movesprite(spritenum, x, y, z, cliptype)
|
||||||
check_sprite_idx(spritenum)
|
check_sprite_idx(spritenum)
|
||||||
local vel = geom.ivec3(x, y, z)
|
local vel = ivec3(x, y, z)
|
||||||
return ffiC.A_MoveSprite(spritenum, vel, cliptype)
|
return ffiC.A_MoveSprite(spritenum, vel, cliptype)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1438,8 +1439,8 @@ local function A_CheckHitSprite(spr, angadd)
|
||||||
return hit.sprite, math.sqrt(dx*dx+dy*dy) -- TODO: use "ldist" approximation for authenticity
|
return hit.sprite, math.sqrt(dx*dx+dy*dy) -- TODO: use "ldist" approximation for authenticity
|
||||||
end
|
end
|
||||||
|
|
||||||
function _canshoottarget(dist, aci)
|
function _canshoottarget(dst, aci)
|
||||||
if (dist > 1024) then
|
if (dst > 1024) then
|
||||||
local spr = sprite[aci]
|
local spr = sprite[aci]
|
||||||
|
|
||||||
local hitspr, hitdist = A_CheckHitSprite(spr, 0)
|
local hitspr, hitdist = A_CheckHitSprite(spr, 0)
|
||||||
|
@ -1513,9 +1514,9 @@ function _hypot(a, b)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _rotatepoint(pivotx, pivoty, posx, posy, ang)
|
function _rotatepoint(pivotx, pivoty, posx, posy, ang)
|
||||||
local pos = geom.ivec3(posx, posy)
|
local pos = ivec3(posx, posy)
|
||||||
local pivot = geom.ivec3(pivotx, pivoty)
|
local pivot = ivec3(pivotx, pivoty)
|
||||||
pos = xmath.rotate(pos, pivot, ang):toivec3()
|
pos = rotate(pos, pivot, ang):toivec3()
|
||||||
return pos.x, pos.y
|
return pos.x, pos.y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -326,7 +326,6 @@ struct {
|
||||||
local WEAPONDATA_STRUCT = "struct {"..table.concat(con_lang.wdata_members, ';').."; }"
|
local WEAPONDATA_STRUCT = "struct {"..table.concat(con_lang.wdata_members, ';').."; }"
|
||||||
|
|
||||||
local randgen = require("randgen")
|
local randgen = require("randgen")
|
||||||
local geom = require("geom")
|
|
||||||
|
|
||||||
local ma_rand = randgen.new(true) -- initialize to "random" (time-based) seed
|
local ma_rand = randgen.new(true) -- initialize to "random" (time-based) seed
|
||||||
local ma_count = nil
|
local ma_count = nil
|
||||||
|
@ -1427,7 +1426,6 @@ local allowed_modules = {
|
||||||
},
|
},
|
||||||
|
|
||||||
randgen = randgen,
|
randgen = randgen,
|
||||||
geom = geom,
|
|
||||||
stat = require("stat"),
|
stat = require("stat"),
|
||||||
bitar = require("bitar"),
|
bitar = require("bitar"),
|
||||||
xmath = require("xmath"),
|
xmath = require("xmath"),
|
||||||
|
|
|
@ -246,10 +246,10 @@ if (not _LUNATIC_AUX) then
|
||||||
assert(ffi.alignof("palette_t")==1)
|
assert(ffi.alignof("palette_t")==1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local vec3_ct = ffi.typeof("vec3_t") -- will be metatype'd in geom.lua:
|
local vec3_ct = ffi.typeof("vec3_t") -- will be metatype'd in xmath.lua:
|
||||||
|
|
||||||
if (not _LUNATIC_AUX) then
|
if (not _LUNATIC_AUX) then
|
||||||
require("geom")
|
require("xmath")
|
||||||
end
|
end
|
||||||
|
|
||||||
local hitdata_ct = ffi.typeof("hitdata_t")
|
local hitdata_ct = ffi.typeof("hitdata_t")
|
||||||
|
|
|
@ -165,7 +165,6 @@ g_logoFlags;
|
||||||
|
|
||||||
luaJIT_BC_lunacon;
|
luaJIT_BC_lunacon;
|
||||||
luaJIT_BC_con_lang;
|
luaJIT_BC_con_lang;
|
||||||
luaJIT_BC_geom;
|
|
||||||
luaJIT_BC_randgen;
|
luaJIT_BC_randgen;
|
||||||
luaJIT_BC_stat;
|
luaJIT_BC_stat;
|
||||||
luaJIT_BC_bitar;
|
luaJIT_BC_bitar;
|
||||||
|
|
|
@ -1,208 +0,0 @@
|
||||||
-- Geometry module for Lunatic.
|
|
||||||
|
|
||||||
local require = require
|
|
||||||
local ffi = require("ffi")
|
|
||||||
local math = require("math")
|
|
||||||
|
|
||||||
local abs = math.abs
|
|
||||||
local sqrt = math.sqrt
|
|
||||||
|
|
||||||
local type = type
|
|
||||||
local error = error
|
|
||||||
|
|
||||||
|
|
||||||
module(...)
|
|
||||||
|
|
||||||
|
|
||||||
-- The integer 3-vector can be useful for calculations expecting integer
|
|
||||||
-- values, e.g. geom.ivec3(x, y, z) is a reasonable way to round a vec3. It can
|
|
||||||
-- also be used as the RHS to the vec2/vec3 arithmetic methods.
|
|
||||||
-- NOTE: We must have a typedef with that exact name, because for Lunatic
|
|
||||||
-- (i.e. not stand-alone), the type was already declared in defs_common.lua.
|
|
||||||
ffi.cdef "typedef struct { int32_t x, y, z; } vec3_t;"
|
|
||||||
local ivec3_t = ffi.typeof("vec3_t")
|
|
||||||
|
|
||||||
|
|
||||||
local dvec2_t = ffi.typeof("struct { double x, y; }")
|
|
||||||
local dvec3_t = ffi.typeof("struct { double x, y, z; }")
|
|
||||||
|
|
||||||
local vec2_mt = {
|
|
||||||
__add = function(a, b) return dvec2_t(a.x+b.x, a.y+b.y) end,
|
|
||||||
__sub = function(a, b) return dvec2_t(a.x-b.x, a.y-b.y) end,
|
|
||||||
__unm = function(a) return dvec2_t(-a.x, -a.y) end,
|
|
||||||
|
|
||||||
__mul = function(a,b)
|
|
||||||
if (type(a)=="number") then
|
|
||||||
return dvec2_t(a*b.x, a*b.y)
|
|
||||||
end
|
|
||||||
|
|
||||||
if (type(b)~="number") then
|
|
||||||
error("number expected in vec2 multiplication", 2)
|
|
||||||
end
|
|
||||||
return dvec2_t(a.x*b, a.y*b)
|
|
||||||
end,
|
|
||||||
|
|
||||||
__div = function(a,b)
|
|
||||||
if (type(b)~="number") then
|
|
||||||
error("number expected in vec2 division", 2)
|
|
||||||
end
|
|
||||||
return dvec2_t(a.x/b, a.y/b)
|
|
||||||
end,
|
|
||||||
|
|
||||||
__tostring = function(a) return "vec2("..a.x..", "..a.y..")" end,
|
|
||||||
|
|
||||||
__index = {
|
|
||||||
lensq = function(a) return a.x*a.x + a.y*a.y end,
|
|
||||||
|
|
||||||
mhlen = function(a) return abs(a.x)+abs(a.y) end,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
local arshift = require("bit").arshift
|
|
||||||
|
|
||||||
-- The vec3 metatable is shared between the integer- and double-based 3-vector
|
|
||||||
-- types. However, some operations are slightly different.
|
|
||||||
local vec3_mt = {
|
|
||||||
-- Arithmetic operations. Note that they always return a dvec3.
|
|
||||||
__add = function(a, b) return dvec3_t(a.x+b.x, a.y+b.y, a.z+b.z) end,
|
|
||||||
__sub = function(a, b) return dvec3_t(a.x-b.x, a.y-b.y, a.z-b.z) end,
|
|
||||||
__unm = function(a) return dvec3_t(-a.x, -a.y, -a.z) end,
|
|
||||||
|
|
||||||
__mul = function(a,b)
|
|
||||||
if (type(a)=="number") then
|
|
||||||
return dvec3_t(a*b.x, a*b.y, a*b.z)
|
|
||||||
end
|
|
||||||
|
|
||||||
if (type(b)~="number") then
|
|
||||||
error("number expected in vec3 multiplication", 2)
|
|
||||||
end
|
|
||||||
return dvec3_t(a.x*b, a.y*b, a.z*b)
|
|
||||||
end,
|
|
||||||
|
|
||||||
__div = function(a,b)
|
|
||||||
if (type(b)~="number") then
|
|
||||||
error("number expected in vec3 division", 2)
|
|
||||||
end
|
|
||||||
return dvec3_t(a.x/b, a.y/b, a.z/b)
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- '^' is the "translate upwards" operator, returns same-typed vector.
|
|
||||||
__pow = function(v, zofs)
|
|
||||||
return v:_ctor(v.x, v.y, v.z-zofs)
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- XXX: Rewrite using _serialize internal API instead.
|
|
||||||
__tostring = function(a)
|
|
||||||
return (a:_isi() and "i" or "").."vec3("..a.x..", "..a.y..", "..a.z..")"
|
|
||||||
end,
|
|
||||||
|
|
||||||
__index = {
|
|
||||||
-- Euclidean 3D length.
|
|
||||||
len = function(a) return sqrt(a.x*a.x + a.y*a.y + a.z*a.z) end,
|
|
||||||
-- Euclidean 3D squared length.
|
|
||||||
lensq = function(a) return a.x*a.x + a.y*a.y + a.z*a.z end,
|
|
||||||
|
|
||||||
-- Euclidean 2D length.
|
|
||||||
len2 = function(a) return sqrt(a.x*a.x + a.y*a.y) end,
|
|
||||||
-- Euclidean 2D squared length.
|
|
||||||
len2sq = function(a) return a.x*a.x + a.y*a.y end,
|
|
||||||
|
|
||||||
-- Manhattan-distance 3D length:
|
|
||||||
mhlen = function(a) return abs(a.x)+abs(a.y)+abs(a.z) end,
|
|
||||||
|
|
||||||
toivec3 = function(v) return ivec3_t(v.x, v.y, v.z) end,
|
|
||||||
|
|
||||||
-- BUILD-coordinate (z scaled by 16) <-> uniform conversions.
|
|
||||||
touniform = function(v)
|
|
||||||
return v:_isi()
|
|
||||||
and v:_ctor(v.x, v.y, arshift(v.z, 4))
|
|
||||||
or v:_ctor(v.x, v.y, v.z/16)
|
|
||||||
end,
|
|
||||||
|
|
||||||
tobuild = function(v) return v:_ctor(v.x, v.y, 16*v.z) end,
|
|
||||||
|
|
||||||
-- PRIVATE methods --
|
|
||||||
|
|
||||||
-- Get the type constructor for this vector.
|
|
||||||
_ctor = function(v, ...)
|
|
||||||
return v:_isi() and ivec3_t(...) or dvec3_t(...)
|
|
||||||
end,
|
|
||||||
-- Is <v> integer vec3? INTERNAL.
|
|
||||||
_isi = function(v)
|
|
||||||
return ffi.istype(ivec3_t, v)
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ffi.metatype(dvec2_t, vec2_mt)
|
|
||||||
ffi.metatype(dvec3_t, vec3_mt)
|
|
||||||
ffi.metatype(ivec3_t, vec3_mt)
|
|
||||||
|
|
||||||
-- VEC2 user data constructor.
|
|
||||||
-- * vec2([x [, y]]), assuming that x and y are numbers. Vacant positions are
|
|
||||||
-- assumed to be 0.
|
|
||||||
-- * vec2(<compound>), <compound> can be anything indexable with "x" and "y"
|
|
||||||
function vec2(...)
|
|
||||||
local x, y = ...
|
|
||||||
if (type(x)=="number" or x==nil) then
|
|
||||||
return dvec2_t(...)
|
|
||||||
else
|
|
||||||
return dvec2_t(x.x, x.y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- VEC3 user data constructor.
|
|
||||||
-- Analogous to VEC2.
|
|
||||||
function vec3(...)
|
|
||||||
local x, y, z = ...
|
|
||||||
if (type(x)=="number" or x==nil) then
|
|
||||||
return dvec3_t(...)
|
|
||||||
else
|
|
||||||
return dvec3_t(x.x, x.y, x.z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- IVEC3 user data constructor.
|
|
||||||
function ivec3(...)
|
|
||||||
local x, y, z = ...
|
|
||||||
if (type(x)=="number" or x==nil) then
|
|
||||||
return ivec3_t(...)
|
|
||||||
else
|
|
||||||
return ivec3_t(x.x, x.y, x.z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Two-element vector cross product.
|
|
||||||
-- Anti-commutative, distributive.
|
|
||||||
local function cross2(v, w)
|
|
||||||
return v.y*w.x - v.x*w.y
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Finds the intersection point of two lines given by
|
|
||||||
-- point a and vector v
|
|
||||||
-- and
|
|
||||||
-- point b and vector w
|
|
||||||
--
|
|
||||||
-- Returns:
|
|
||||||
-- if <TODO>, nil
|
|
||||||
-- if retpoint_p evaluates to a non-true value, coefficients cv and cw such that <TODO>
|
|
||||||
-- else, the intersection point
|
|
||||||
function intersect(a,v, b,w, retpoint_p)
|
|
||||||
local vxw = cross2(v,w)
|
|
||||||
|
|
||||||
if (vxw ~= 0) then
|
|
||||||
local btoa = vec2(a) - vec2(b)
|
|
||||||
local cv, cw = cross2(w, btoa)/vxw, cross2(v, btoa)/vxw
|
|
||||||
|
|
||||||
if (retpoint_p) then
|
|
||||||
return vec2(a) + cv*vec2(v)
|
|
||||||
else
|
|
||||||
return cv, cw
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- return nil if v and w parallel (or either of them is a point), or if
|
|
||||||
-- they contain NaNs
|
|
||||||
end
|
|
|
@ -179,7 +179,7 @@ local function new_initial_codetab()
|
||||||
-- Requires.
|
-- Requires.
|
||||||
"local require=require",
|
"local require=require",
|
||||||
"local _con, _bit, _math = require'con', require'bit', require'math'",
|
"local _con, _bit, _math = require'con', require'bit', require'math'",
|
||||||
"local _xmath, _geom = require'xmath', require'geom'",
|
"local _xmath = require'xmath'",
|
||||||
|
|
||||||
-- Cache globals into locals.
|
-- Cache globals into locals.
|
||||||
"local sector, sprite, wall, spriteext, atsprite = sector, sprite, wall, spriteext, atsprite",
|
"local sector, sprite, wall, spriteext, atsprite = sector, sprite, wall, spriteext, atsprite",
|
||||||
|
@ -205,7 +205,7 @@ local function new_initial_codetab()
|
||||||
"local _V,_A=_V,_A",
|
"local _V,_A=_V,_A",
|
||||||
|
|
||||||
-- Static ivec3s so that no allocations need to be made.
|
-- Static ivec3s so that no allocations need to be made.
|
||||||
"local _IVEC = { _geom.ivec3(), _geom.ivec3() }",
|
"local _IVEC = { _xmath.ivec3(), _xmath.ivec3() }",
|
||||||
"local function _IV(num, x, y, z)",
|
"local function _IV(num, x, y, z)",
|
||||||
" local v=_IVEC[num]; v.x=x; v.y=y; v.z=z; return v;",
|
" local v=_IVEC[num]; v.x=x; v.y=y; v.z=z; return v;",
|
||||||
"end",
|
"end",
|
||||||
|
@ -561,7 +561,7 @@ local function parse_number(pos, numstr)
|
||||||
if (hex and #hex>8 and hex:sub(1,#hex-8):match("^[fF]$")) then
|
if (hex and #hex>8 and hex:sub(1,#hex-8):match("^[fF]$")) then
|
||||||
-- Too many hex digits, but they're all Fs.
|
-- Too many hex digits, but they're all Fs.
|
||||||
pwarnprintf(pos, "number %s truncated to 32 bits", numstr)
|
pwarnprintf(pos, "number %s truncated to 32 bits", numstr)
|
||||||
num = bit.band(num, 0xffffffff)
|
num = bit.tobit(num)
|
||||||
else
|
else
|
||||||
perrprintf(pos, "number %s out of the range of a 32-bit integer", numstr)
|
perrprintf(pos, "number %s out of the range of a 32-bit integer", numstr)
|
||||||
-- Be careful not to write bound checks like
|
-- Be careful not to write bound checks like
|
||||||
|
@ -572,7 +572,7 @@ local function parse_number(pos, numstr)
|
||||||
if (not hex and g_warn["number-conversion"]) then
|
if (not hex and g_warn["number-conversion"]) then
|
||||||
pwarnprintf(pos, "number %s converted to a negative one", numstr)
|
pwarnprintf(pos, "number %s converted to a negative one", numstr)
|
||||||
end
|
end
|
||||||
num = bit.band(num, 0xffffffff)
|
num = bit.tobit(num)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- printf("numstr:%s, num=%d (0x%s) '%s', resnum=%d (0x%s)",
|
-- printf("numstr:%s, num=%d (0x%s) '%s', resnum=%d (0x%s)",
|
||||||
|
@ -1807,8 +1807,9 @@ local function GetOrSetPerxvarCmd(Setp, Actorp)
|
||||||
local gv = g_gamevar[perxvarname]
|
local gv = g_gamevar[perxvarname]
|
||||||
if (gv and bit.band(gv.flags, GVFLAG.PERX_MASK)~=EXPECTED_PERX_BIT) then
|
if (gv and bit.band(gv.flags, GVFLAG.PERX_MASK)~=EXPECTED_PERX_BIT) then
|
||||||
-- [gs]set*var for wrong gamevar type. See if it's a getactorvar,
|
-- [gs]set*var for wrong gamevar type. See if it's a getactorvar,
|
||||||
-- in which case we may only warn and get the global gamevar
|
-- in which case we may only warn and access that instead. Note
|
||||||
-- (TODO_MP) instead.
|
-- that accesses of player gamevars with actor indices are usually
|
||||||
|
-- meaningless.
|
||||||
local warnp = not Setp and Actorp and not g_warn["error-bad-getactorvar"]
|
local warnp = not Setp and Actorp and not g_warn["error-bad-getactorvar"]
|
||||||
local xprintf = warnp and warnprintf or errprintf
|
local xprintf = warnp and warnprintf or errprintf
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ local sector = sector
|
||||||
local inside = inside
|
local inside = inside
|
||||||
|
|
||||||
local math = require("math")
|
local math = require("math")
|
||||||
local geom = require("geom")
|
local xmath = require("xmath")
|
||||||
local stat = require("stat")
|
local stat = require("stat")
|
||||||
|
|
||||||
local function resetseed()
|
local function resetseed()
|
||||||
|
@ -39,7 +39,7 @@ local function getpoints(n, min, max)
|
||||||
for i=1,n do
|
for i=1,n do
|
||||||
local x = math.random(min.x, max.x)
|
local x = math.random(min.x, max.x)
|
||||||
local y= math.random(min.y, max.y)
|
local y= math.random(min.y, max.y)
|
||||||
posns[i] = geom.vec2(x, y)
|
posns[i] = xmath.vec2(x, y)
|
||||||
sects[i] = math.random(0, ffiC.numsectors-1)
|
sects[i] = math.random(0, ffiC.numsectors-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
local ffi = require "ffi"
|
local ffi = require "ffi"
|
||||||
local ffiC = ffi.C
|
local ffiC = ffi.C
|
||||||
|
|
||||||
local geom = require "geom"
|
local xmath = require "xmath"
|
||||||
local stat = require "stat"
|
local stat = require "stat"
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ function randwalk(N, spritenum, minlen, maxlen, randofs, funci, logfn)
|
||||||
local times = {}
|
local times = {}
|
||||||
local successp = {}
|
local successp = {}
|
||||||
|
|
||||||
local pos = geom.vec3(sprite[spritenum])
|
local pos = xmath.vec3(sprite[spritenum])
|
||||||
local sectnum = sprite[spritenum].sectnum
|
local sectnum = sprite[spritenum].sectnum
|
||||||
|
|
||||||
for i=1,N do
|
for i=1,N do
|
||||||
|
@ -51,7 +51,7 @@ function randwalk(N, spritenum, minlen, maxlen, randofs, funci, logfn)
|
||||||
local len = math.random(minlen, maxlen)
|
local len = math.random(minlen, maxlen)
|
||||||
local ax, ay, az = len*math.cos(ang), len*math.sin(ang), 0
|
local ax, ay, az = len*math.cos(ang), len*math.sin(ang), 0
|
||||||
--]]
|
--]]
|
||||||
local newpos = pos + geom.ivec3(ax,ay,az)
|
local newpos = pos + xmath.ivec3(ax,ay,az)
|
||||||
|
|
||||||
local t = ffiC.gethitickms()
|
local t = ffiC.gethitickms()
|
||||||
local newsect = updatesectorfunc(newpos, sectnum)
|
local newsect = updatesectorfunc(newpos, sectnum)
|
||||||
|
|
|
@ -256,7 +256,7 @@ gameevent
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
local geom = require "geom"
|
local xmath = require "xmath"
|
||||||
|
|
||||||
gameevent
|
gameevent
|
||||||
{
|
{
|
||||||
|
@ -351,12 +351,12 @@ gameevent
|
||||||
"must be called from top level")
|
"must be called from top level")
|
||||||
|
|
||||||
-- Test vec3 + wall. Pseudo wall member 'z' will be accessed.
|
-- Test vec3 + wall. Pseudo wall member 'z' will be accessed.
|
||||||
local mpos = geom.vec3()
|
local mpos = xmath.vec3()
|
||||||
for i=0,gv.numwalls-1 do
|
for i=0,gv.numwalls-1 do
|
||||||
mpos = mpos + wall[i]
|
mpos = mpos + wall[i]
|
||||||
end
|
end
|
||||||
mpos = mpos/gv.numwalls
|
mpos = mpos/gv.numwalls
|
||||||
local impos = geom.ivec3(mpos)^20 -- test ivec3 with dvec3 arg, test '^' op
|
local impos = xmath.ivec3(mpos)^20 -- test ivec3 with dvec3 arg, test '^' op
|
||||||
assert(impos.z == -20)
|
assert(impos.z == -20)
|
||||||
printf("Map center point: (%d,%f)", mpos.x, impos.y)
|
printf("Map center point: (%d,%f)", mpos.x, impos.y)
|
||||||
end
|
end
|
||||||
|
@ -381,11 +381,11 @@ gameactor
|
||||||
local r = math.random
|
local r = math.random
|
||||||
local d = 20
|
local d = 20
|
||||||
-- NOTE: __add metamethod is called because of the RHS:
|
-- NOTE: __add metamethod is called because of the RHS:
|
||||||
local v = spr + geom.vec3(r(-d,d), r(-d,d))
|
local v = spr + xmath.vec3(r(-d,d), r(-d,d))
|
||||||
spr:setpos(v)
|
spr:setpos(v)
|
||||||
|
|
||||||
-- Test vec3 constructor with cdata.
|
-- Test vec3 constructor with cdata.
|
||||||
local tempvec = geom.vec3(player[0].pos)
|
local tempvec = xmath.vec3(player[0].pos)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ local ffi = require "ffi"
|
||||||
local math = require "math"
|
local math = require "math"
|
||||||
local os = require "os"
|
local os = require "os"
|
||||||
|
|
||||||
local geom = require "geom"
|
|
||||||
local xmath = require "xmath"
|
local xmath = require "xmath"
|
||||||
|
|
||||||
local ldist = xmath.ldist
|
local ldist = xmath.ldist
|
||||||
|
@ -64,8 +63,8 @@ t = os.clock()
|
||||||
|
|
||||||
-- from control.lua (the CON version of rotatepoint)
|
-- from control.lua (the CON version of rotatepoint)
|
||||||
local function _rotatepoint(pivotx, pivoty, posx, posy, ang)
|
local function _rotatepoint(pivotx, pivoty, posx, posy, ang)
|
||||||
local pos = geom.ivec3(posx, posy)
|
local pos = xmath.ivec3(posx, posy)
|
||||||
local pivot = geom.ivec3(pivotx, pivoty)
|
local pivot = xmath.ivec3(pivotx, pivoty)
|
||||||
pos = xmath.rotate(pos, pivot, ang):toivec3()
|
pos = xmath.rotate(pos, pivot, ang):toivec3()
|
||||||
return pos.x, pos.y
|
return pos.x, pos.y
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
local os = require("os")
|
local os = require("os")
|
||||||
|
|
||||||
local geom = require("geom")
|
local xmath = require("xmath")
|
||||||
|
|
||||||
|
|
||||||
local N = os.exit and (arg[1] and tostring(arg[1])) or 1e6
|
local N = os.exit and (arg[1] and tostring(arg[1])) or 1e6
|
||||||
|
@ -19,7 +19,7 @@ if (os.exit) then
|
||||||
local math = require("math")
|
local math = require("math")
|
||||||
|
|
||||||
randvec = function()
|
randvec = function()
|
||||||
return geom.vec2(math.random(), math.random())
|
return xmath.vec2(math.random(), math.random())
|
||||||
end
|
end
|
||||||
|
|
||||||
print("Running stand-alone. ourname: "..tostring(ourname))
|
print("Running stand-alone. ourname: "..tostring(ourname))
|
||||||
|
@ -30,7 +30,7 @@ else
|
||||||
-- NOTE: factoring out the inner s:getdbl() into a separate function
|
-- NOTE: factoring out the inner s:getdbl() into a separate function
|
||||||
-- reduces performance seriously (about an order of magnitude!)
|
-- reduces performance seriously (about an order of magnitude!)
|
||||||
randvec = function()
|
randvec = function()
|
||||||
return geom.vec2(s:getdbl(), s:getdbl())
|
return xmath.vec2(s:getdbl(), s:getdbl())
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Test optional arguments from our_require().
|
-- Test optional arguments from our_require().
|
||||||
|
@ -62,9 +62,9 @@ end
|
||||||
|
|
||||||
local t3 = os.clock()
|
local t3 = os.clock()
|
||||||
|
|
||||||
local v = geom.vec2(0, 0)
|
local v = xmath.vec2(0, 0)
|
||||||
for i=1,N do
|
for i=1,N do
|
||||||
local intersp = geom.intersect(A[i],V[i], B[i],W[i], true)
|
local intersp = xmath.intersect(A[i],V[i], B[i],W[i], true)
|
||||||
if (intersp ~= nil) then
|
if (intersp ~= nil) then
|
||||||
v = v + intersp
|
v = v + intersp
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,14 +5,19 @@ local ffi = require("ffi")
|
||||||
local bit = require("bit")
|
local bit = require("bit")
|
||||||
local math = require("math")
|
local math = require("math")
|
||||||
|
|
||||||
local geom = require("geom")
|
local arshift = bit.arshift
|
||||||
|
local abs, sqrt = math.abs, math.sqrt
|
||||||
|
|
||||||
local assert = assert
|
local assert = assert
|
||||||
|
local error = error
|
||||||
|
local type = type
|
||||||
|
|
||||||
|
|
||||||
module(...)
|
module(...)
|
||||||
|
|
||||||
|
|
||||||
|
---=== TRIGONOMETRY ===---
|
||||||
|
|
||||||
local BANG2RAD = math.pi/1024
|
local BANG2RAD = math.pi/1024
|
||||||
local isintab = ffi.new("int16_t [?]", 2048)
|
local isintab = ffi.new("int16_t [?]", 2048)
|
||||||
local dsintab = ffi.new("double [?]", 2048)
|
local dsintab = ffi.new("double [?]", 2048)
|
||||||
|
@ -67,9 +72,8 @@ function cosb(ang)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Approximations to 2D and 3D Euclidean distances (also see common.c)
|
---=== Approximations to 2D and 3D Euclidean distances ===---
|
||||||
local abs = math.abs
|
-- (also see common.c)
|
||||||
local arshift = bit.arshift
|
|
||||||
|
|
||||||
local function dist_common(pos1, pos2)
|
local function dist_common(pos1, pos2)
|
||||||
local x = abs(pos1.x - pos2.x)
|
local x = abs(pos1.x - pos2.x)
|
||||||
|
@ -100,14 +104,213 @@ function dist(pos1, pos2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---=== VECTOR TYPES ===---
|
||||||
|
|
||||||
|
|
||||||
|
-- The integer 3-vector can be useful for calculations expecting integer
|
||||||
|
-- values, e.g. ivec3(x, y, z) is a reasonable way to round a vec3. It can also
|
||||||
|
-- be used as the RHS to the vec2/vec3 arithmetic methods.
|
||||||
|
-- NOTE: We must have a typedef with that exact name, because for Lunatic
|
||||||
|
-- (i.e. not stand-alone), the type was already declared in defs_common.lua.
|
||||||
|
ffi.cdef "typedef struct { int32_t x, y, z; } vec3_t;"
|
||||||
|
local ivec3_t = ffi.typeof("vec3_t")
|
||||||
|
|
||||||
|
|
||||||
|
local dvec2_t = ffi.typeof("struct { double x, y; }")
|
||||||
|
local dvec3_t = ffi.typeof("struct { double x, y, z; }")
|
||||||
|
|
||||||
|
local vec2_mt = {
|
||||||
|
__add = function(a, b) return dvec2_t(a.x+b.x, a.y+b.y) end,
|
||||||
|
__sub = function(a, b) return dvec2_t(a.x-b.x, a.y-b.y) end,
|
||||||
|
__unm = function(a) return dvec2_t(-a.x, -a.y) end,
|
||||||
|
|
||||||
|
__mul = function(a,b)
|
||||||
|
if (type(a)=="number") then
|
||||||
|
return dvec2_t(a*b.x, a*b.y)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(b)~="number") then
|
||||||
|
error("number expected in vec2 multiplication", 2)
|
||||||
|
end
|
||||||
|
return dvec2_t(a.x*b, a.y*b)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__div = function(a,b)
|
||||||
|
if (type(b)~="number") then
|
||||||
|
error("number expected in vec2 division", 2)
|
||||||
|
end
|
||||||
|
return dvec2_t(a.x/b, a.y/b)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__tostring = function(a) return "vec2("..a.x..", "..a.y..")" end,
|
||||||
|
|
||||||
|
__index = {
|
||||||
|
lensq = function(a) return a.x*a.x + a.y*a.y end,
|
||||||
|
|
||||||
|
mhlen = function(a) return abs(a.x)+abs(a.y) end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- The vec3 metatable is shared between the integer- and double-based 3-vector
|
||||||
|
-- types. However, some operations are slightly different.
|
||||||
|
local vec3_mt = {
|
||||||
|
-- Arithmetic operations. Note that they always return a dvec3.
|
||||||
|
__add = function(a, b) return dvec3_t(a.x+b.x, a.y+b.y, a.z+b.z) end,
|
||||||
|
__sub = function(a, b) return dvec3_t(a.x-b.x, a.y-b.y, a.z-b.z) end,
|
||||||
|
__unm = function(a) return dvec3_t(-a.x, -a.y, -a.z) end,
|
||||||
|
|
||||||
|
__mul = function(a,b)
|
||||||
|
if (type(a)=="number") then
|
||||||
|
return dvec3_t(a*b.x, a*b.y, a*b.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(b)~="number") then
|
||||||
|
error("number expected in vec3 multiplication", 2)
|
||||||
|
end
|
||||||
|
return dvec3_t(a.x*b, a.y*b, a.z*b)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__div = function(a,b)
|
||||||
|
if (type(b)~="number") then
|
||||||
|
error("number expected in vec3 division", 2)
|
||||||
|
end
|
||||||
|
return dvec3_t(a.x/b, a.y/b, a.z/b)
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- '^' is the "translate upwards" operator, returns same-typed vector.
|
||||||
|
__pow = function(v, zofs)
|
||||||
|
return v:_ctor(v.x, v.y, v.z-zofs)
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- XXX: Rewrite using _serialize internal API instead.
|
||||||
|
__tostring = function(a)
|
||||||
|
return (a:_isi() and "i" or "").."vec3("..a.x..", "..a.y..", "..a.z..")"
|
||||||
|
end,
|
||||||
|
|
||||||
|
__index = {
|
||||||
|
-- Euclidean 3D length.
|
||||||
|
len = function(a) return sqrt(a.x*a.x + a.y*a.y + a.z*a.z) end,
|
||||||
|
-- Euclidean 3D squared length.
|
||||||
|
lensq = function(a) return a.x*a.x + a.y*a.y + a.z*a.z end,
|
||||||
|
|
||||||
|
-- Euclidean 2D length.
|
||||||
|
len2 = function(a) return sqrt(a.x*a.x + a.y*a.y) end,
|
||||||
|
-- Euclidean 2D squared length.
|
||||||
|
len2sq = function(a) return a.x*a.x + a.y*a.y end,
|
||||||
|
|
||||||
|
-- Manhattan-distance 3D length:
|
||||||
|
mhlen = function(a) return abs(a.x)+abs(a.y)+abs(a.z) end,
|
||||||
|
|
||||||
|
toivec3 = function(v) return ivec3_t(v.x, v.y, v.z) end,
|
||||||
|
|
||||||
|
-- BUILD-coordinate (z scaled by 16) <-> uniform conversions.
|
||||||
|
touniform = function(v)
|
||||||
|
return v:_isi()
|
||||||
|
and v:_ctor(v.x, v.y, arshift(v.z, 4))
|
||||||
|
or v:_ctor(v.x, v.y, v.z/16)
|
||||||
|
end,
|
||||||
|
|
||||||
|
tobuild = function(v) return v:_ctor(v.x, v.y, 16*v.z) end,
|
||||||
|
|
||||||
|
-- TODO: v:rotate()?
|
||||||
|
|
||||||
|
-- PRIVATE methods --
|
||||||
|
|
||||||
|
-- Get the type constructor for this vector.
|
||||||
|
_ctor = function(v, ...)
|
||||||
|
return v:_isi() and ivec3_t(...) or dvec3_t(...)
|
||||||
|
end,
|
||||||
|
-- Is <v> integer vec3? INTERNAL.
|
||||||
|
_isi = function(v)
|
||||||
|
return ffi.istype(ivec3_t, v)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ffi.metatype(dvec2_t, vec2_mt)
|
||||||
|
ffi.metatype(dvec3_t, vec3_mt)
|
||||||
|
ffi.metatype(ivec3_t, vec3_mt)
|
||||||
|
|
||||||
|
-- VEC2 user data constructor.
|
||||||
|
-- * vec2([x [, y]]), assuming that x and y are numbers. Vacant positions are
|
||||||
|
-- assumed to be 0.
|
||||||
|
-- * vec2(<compound>), <compound> can be anything indexable with "x" and "y"
|
||||||
|
function vec2(...)
|
||||||
|
local x, y = ...
|
||||||
|
if (type(x)=="number" or x==nil) then
|
||||||
|
return dvec2_t(...)
|
||||||
|
else
|
||||||
|
return dvec2_t(x.x, x.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- VEC3 user data constructor.
|
||||||
|
-- Analogous to VEC2.
|
||||||
|
function vec3(...)
|
||||||
|
local x, y, z = ...
|
||||||
|
if (type(x)=="number" or x==nil) then
|
||||||
|
return dvec3_t(...)
|
||||||
|
else
|
||||||
|
return dvec3_t(x.x, x.y, x.z)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- IVEC3 user data constructor.
|
||||||
|
function ivec3(...)
|
||||||
|
local x, y, z = ...
|
||||||
|
if (type(x)=="number" or x==nil) then
|
||||||
|
return ivec3_t(...)
|
||||||
|
else
|
||||||
|
return ivec3_t(x.x, x.y, x.z)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---=== MISCELLANEOUS MATH ===---
|
||||||
|
|
||||||
-- Point rotation. Note the different order of arguments from engine function.
|
-- Point rotation. Note the different order of arguments from engine function.
|
||||||
-- XXX: passing mixed vec2/vec3 is problematic. Get rid of geom.vec2?
|
-- XXX: passing mixed vec2/vec3 is problematic. Get rid of vec2?
|
||||||
-- <ang>: BUILD angle (0-2047 based)
|
-- <ang>: BUILD angle (0-2047 based)
|
||||||
function rotate(pos, pivot, ang)
|
function rotate(pos, pivot, ang)
|
||||||
local p = geom.vec3(pos)-pivot
|
local p = vec3(pos)-pivot
|
||||||
local c, s = cosb(ang), sinb(ang)
|
local c, s = cosb(ang), sinb(ang)
|
||||||
local x, y = p.x, p.y
|
local x, y = p.x, p.y
|
||||||
p.x = pivot.x + (c*x - s*y)
|
p.x = pivot.x + (c*x - s*y)
|
||||||
p.y = pivot.y + (c*y + s*x)
|
p.y = pivot.y + (c*y + s*x)
|
||||||
return p
|
return p
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Two-element vector cross product.
|
||||||
|
-- Anti-commutative, distributive.
|
||||||
|
local function cross2(v, w)
|
||||||
|
return v.y*w.x - v.x*w.y
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Finds the intersection point of two lines given by
|
||||||
|
-- point a and vector v
|
||||||
|
-- and
|
||||||
|
-- point b and vector w
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- if <TODO>, nil
|
||||||
|
-- if retpoint_p evaluates to a non-true value, coefficients cv and cw such that <TODO>
|
||||||
|
-- else, the intersection point
|
||||||
|
function intersect(a,v, b,w, retpoint_p)
|
||||||
|
local vxw = cross2(v,w)
|
||||||
|
|
||||||
|
if (vxw ~= 0) then
|
||||||
|
local btoa = vec2(a) - vec2(b)
|
||||||
|
local cv, cw = cross2(w, btoa)/vxw, cross2(v, btoa)/vxw
|
||||||
|
|
||||||
|
if (retpoint_p) then
|
||||||
|
return vec2(a) + cv*vec2(v)
|
||||||
|
else
|
||||||
|
return cv, cw
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- return nil if v and w parallel (or either of them is a point), or if
|
||||||
|
-- they contain NaNs
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in a new issue