mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +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)/luaJIT_BC_con_lang.$o \
|
||||
$(OBJ)/luaJIT_BC_lunacon.$o \
|
||||
$(OBJ)/luaJIT_BC_geom.$o \
|
||||
$(OBJ)/luaJIT_BC_randgen.$o \
|
||||
$(OBJ)/luaJIT_BC_stat.$o \
|
||||
$(OBJ)/luaJIT_BC_bitar.$o \
|
||||
|
|
|
@ -13,7 +13,6 @@ local io = require("io")
|
|||
local math = require("math")
|
||||
local table = require("table")
|
||||
|
||||
local geom = require("geom")
|
||||
local bcheck = require("bcheck")
|
||||
local con_lang = require("con_lang")
|
||||
|
||||
|
@ -447,6 +446,8 @@ end
|
|||
local xmath = require("xmath")
|
||||
local abs = math.abs
|
||||
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 distvec = ps.pos - spr^(28*256)
|
||||
|
@ -473,15 +474,15 @@ end
|
|||
|
||||
local FN_DISTFUNC = {
|
||||
d2 = function(s1, s2, d)
|
||||
return (xmath.ldist(s1, s2) < d)
|
||||
return (ldist(s1, s2) < d)
|
||||
end,
|
||||
|
||||
d3 = function(s1, s2, d)
|
||||
return (xmath.dist(s1, s2) < d)
|
||||
return (dist(s1, s2) < d)
|
||||
end,
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
|
@ -790,10 +791,10 @@ end
|
|||
|
||||
|
||||
-- switch statement support
|
||||
function _switch(swtab, testval, aci,pli,dist)
|
||||
function _switch(swtab, testval, aci,pli,dst)
|
||||
local func = swtab[testval] or swtab.default
|
||||
if (func) then
|
||||
func(aci, pli, dist)
|
||||
func(aci, pli, dst)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -931,7 +932,7 @@ function _A_DoGuts(i, gutstile, n)
|
|||
end
|
||||
|
||||
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,
|
||||
ang=krandand(2047), xvel=48+krandand(31), zvel=-512-krandand(2047) }
|
||||
local newspr = sprite[j]
|
||||
|
@ -954,7 +955,7 @@ function _debris(i, dtile, n)
|
|||
for j=n-1,0, -1 do
|
||||
local isblimpscrap = (ispic(spr.picnum, "BLIMP") and ispic(dtile, "SCRAP1"))
|
||||
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,
|
||||
shade=spr.shade, xrepeat=32+krandand(15), yrepeat=32+krandand(15),
|
||||
ang=krandand(2047), xvel=32+krandand(127), zvel=-krandand(2047) }
|
||||
|
@ -1270,7 +1271,7 @@ end
|
|||
|
||||
-- d is a distance
|
||||
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) }
|
||||
for i=1,4 do
|
||||
if (not inside(vecs[i]+spr, spr.sectnum)) then
|
||||
|
@ -1372,14 +1373,14 @@ end
|
|||
|
||||
-- CON "hitscan" command
|
||||
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)
|
||||
return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z
|
||||
end
|
||||
|
||||
-- CON "neartag" command
|
||||
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)
|
||||
return near.sector, near.wall, near.sprite, near.dist
|
||||
end
|
||||
|
@ -1387,7 +1388,7 @@ end
|
|||
-- CON "getzrange" command
|
||||
function _getzrange(x, y, z, sectnum, walldist, clipmask)
|
||||
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)
|
||||
-- return: ceilz, ceilhit, florz, florhit
|
||||
return hit.c.z, hit.c.num + (hit.c.spritep and 49152 or 16384),
|
||||
|
@ -1397,16 +1398,16 @@ end
|
|||
-- CON "clipmove" and "clipmovenoslide" commands
|
||||
function _clipmovex(x, y, z, sectnum, xv, yv, wd, cd, fd, clipmask, noslidep)
|
||||
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 ret = ffiC.clipmovex(ipos, sect, xv, yv, wd, cd, fd, clipmask, noslidep)
|
||||
-- Return: clipmovex() return value; updated x, y, sectnum
|
||||
return ret, ipos.x, ipos.y, sect[0]
|
||||
end
|
||||
|
||||
function _sleepcheck(aci, dist)
|
||||
function _sleepcheck(aci, dst)
|
||||
local acs = actor[aci]
|
||||
if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then
|
||||
if (dst > MAXSLEEPDIST and acs.timetosleep == 0) then
|
||||
acs.timetosleep = SLEEPTIME
|
||||
end
|
||||
end
|
||||
|
@ -1419,7 +1420,7 @@ end
|
|||
|
||||
function _movesprite(spritenum, x, y, z, cliptype)
|
||||
check_sprite_idx(spritenum)
|
||||
local vel = geom.ivec3(x, y, z)
|
||||
local vel = ivec3(x, y, z)
|
||||
return ffiC.A_MoveSprite(spritenum, vel, cliptype)
|
||||
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
|
||||
end
|
||||
|
||||
function _canshoottarget(dist, aci)
|
||||
if (dist > 1024) then
|
||||
function _canshoottarget(dst, aci)
|
||||
if (dst > 1024) then
|
||||
local spr = sprite[aci]
|
||||
|
||||
local hitspr, hitdist = A_CheckHitSprite(spr, 0)
|
||||
|
@ -1513,9 +1514,9 @@ function _hypot(a, b)
|
|||
end
|
||||
|
||||
function _rotatepoint(pivotx, pivoty, posx, posy, ang)
|
||||
local pos = geom.ivec3(posx, posy)
|
||||
local pivot = geom.ivec3(pivotx, pivoty)
|
||||
pos = xmath.rotate(pos, pivot, ang):toivec3()
|
||||
local pos = ivec3(posx, posy)
|
||||
local pivot = ivec3(pivotx, pivoty)
|
||||
pos = rotate(pos, pivot, ang):toivec3()
|
||||
return pos.x, pos.y
|
||||
end
|
||||
|
||||
|
|
|
@ -326,7 +326,6 @@ struct {
|
|||
local WEAPONDATA_STRUCT = "struct {"..table.concat(con_lang.wdata_members, ';').."; }"
|
||||
|
||||
local randgen = require("randgen")
|
||||
local geom = require("geom")
|
||||
|
||||
local ma_rand = randgen.new(true) -- initialize to "random" (time-based) seed
|
||||
local ma_count = nil
|
||||
|
@ -1427,7 +1426,6 @@ local allowed_modules = {
|
|||
},
|
||||
|
||||
randgen = randgen,
|
||||
geom = geom,
|
||||
stat = require("stat"),
|
||||
bitar = require("bitar"),
|
||||
xmath = require("xmath"),
|
||||
|
|
|
@ -246,10 +246,10 @@ if (not _LUNATIC_AUX) then
|
|||
assert(ffi.alignof("palette_t")==1)
|
||||
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
|
||||
require("geom")
|
||||
require("xmath")
|
||||
end
|
||||
|
||||
local hitdata_ct = ffi.typeof("hitdata_t")
|
||||
|
|
|
@ -165,7 +165,6 @@ g_logoFlags;
|
|||
|
||||
luaJIT_BC_lunacon;
|
||||
luaJIT_BC_con_lang;
|
||||
luaJIT_BC_geom;
|
||||
luaJIT_BC_randgen;
|
||||
luaJIT_BC_stat;
|
||||
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.
|
||||
"local require=require",
|
||||
"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.
|
||||
"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",
|
||||
|
||||
-- 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 v=_IVEC[num]; v.x=x; v.y=y; v.z=z; return v;",
|
||||
"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
|
||||
-- Too many hex digits, but they're all Fs.
|
||||
pwarnprintf(pos, "number %s truncated to 32 bits", numstr)
|
||||
num = bit.band(num, 0xffffffff)
|
||||
num = bit.tobit(num)
|
||||
else
|
||||
perrprintf(pos, "number %s out of the range of a 32-bit integer", numstr)
|
||||
-- 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
|
||||
pwarnprintf(pos, "number %s converted to a negative one", numstr)
|
||||
end
|
||||
num = bit.band(num, 0xffffffff)
|
||||
num = bit.tobit(num)
|
||||
end
|
||||
|
||||
-- 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]
|
||||
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,
|
||||
-- in which case we may only warn and get the global gamevar
|
||||
-- (TODO_MP) instead.
|
||||
-- in which case we may only warn and access that instead. Note
|
||||
-- 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 xprintf = warnp and warnprintf or errprintf
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ local sector = sector
|
|||
local inside = inside
|
||||
|
||||
local math = require("math")
|
||||
local geom = require("geom")
|
||||
local xmath = require("xmath")
|
||||
local stat = require("stat")
|
||||
|
||||
local function resetseed()
|
||||
|
@ -39,7 +39,7 @@ local function getpoints(n, min, max)
|
|||
for i=1,n do
|
||||
local x = math.random(min.x, max.x)
|
||||
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)
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
local ffi = require "ffi"
|
||||
local ffiC = ffi.C
|
||||
|
||||
local geom = require "geom"
|
||||
local xmath = require "xmath"
|
||||
local stat = require "stat"
|
||||
|
||||
|
||||
|
@ -33,7 +33,7 @@ function randwalk(N, spritenum, minlen, maxlen, randofs, funci, logfn)
|
|||
local times = {}
|
||||
local successp = {}
|
||||
|
||||
local pos = geom.vec3(sprite[spritenum])
|
||||
local pos = xmath.vec3(sprite[spritenum])
|
||||
local sectnum = sprite[spritenum].sectnum
|
||||
|
||||
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 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 newsect = updatesectorfunc(newpos, sectnum)
|
||||
|
|
|
@ -256,7 +256,7 @@ gameevent
|
|||
end
|
||||
}
|
||||
|
||||
local geom = require "geom"
|
||||
local xmath = require "xmath"
|
||||
|
||||
gameevent
|
||||
{
|
||||
|
@ -351,12 +351,12 @@ gameevent
|
|||
"must be called from top level")
|
||||
|
||||
-- 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
|
||||
mpos = mpos + wall[i]
|
||||
end
|
||||
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)
|
||||
printf("Map center point: (%d,%f)", mpos.x, impos.y)
|
||||
end
|
||||
|
@ -381,11 +381,11 @@ gameactor
|
|||
local r = math.random
|
||||
local d = 20
|
||||
-- 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)
|
||||
|
||||
-- Test vec3 constructor with cdata.
|
||||
local tempvec = geom.vec3(player[0].pos)
|
||||
local tempvec = xmath.vec3(player[0].pos)
|
||||
end
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ local ffi = require "ffi"
|
|||
local math = require "math"
|
||||
local os = require "os"
|
||||
|
||||
local geom = require "geom"
|
||||
local xmath = require "xmath"
|
||||
|
||||
local ldist = xmath.ldist
|
||||
|
@ -64,8 +63,8 @@ t = os.clock()
|
|||
|
||||
-- from control.lua (the CON version of rotatepoint)
|
||||
local function _rotatepoint(pivotx, pivoty, posx, posy, ang)
|
||||
local pos = geom.ivec3(posx, posy)
|
||||
local pivot = geom.ivec3(pivotx, pivoty)
|
||||
local pos = xmath.ivec3(posx, posy)
|
||||
local pivot = xmath.ivec3(pivotx, pivoty)
|
||||
pos = xmath.rotate(pos, pivot, ang):toivec3()
|
||||
return pos.x, pos.y
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
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
|
||||
|
@ -19,7 +19,7 @@ if (os.exit) then
|
|||
local math = require("math")
|
||||
|
||||
randvec = function()
|
||||
return geom.vec2(math.random(), math.random())
|
||||
return xmath.vec2(math.random(), math.random())
|
||||
end
|
||||
|
||||
print("Running stand-alone. ourname: "..tostring(ourname))
|
||||
|
@ -30,7 +30,7 @@ else
|
|||
-- NOTE: factoring out the inner s:getdbl() into a separate function
|
||||
-- reduces performance seriously (about an order of magnitude!)
|
||||
randvec = function()
|
||||
return geom.vec2(s:getdbl(), s:getdbl())
|
||||
return xmath.vec2(s:getdbl(), s:getdbl())
|
||||
end
|
||||
|
||||
-- Test optional arguments from our_require().
|
||||
|
@ -62,9 +62,9 @@ end
|
|||
|
||||
local t3 = os.clock()
|
||||
|
||||
local v = geom.vec2(0, 0)
|
||||
local v = xmath.vec2(0, 0)
|
||||
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
|
||||
v = v + intersp
|
||||
end
|
||||
|
|
|
@ -5,14 +5,19 @@ local ffi = require("ffi")
|
|||
local bit = require("bit")
|
||||
local math = require("math")
|
||||
|
||||
local geom = require("geom")
|
||||
local arshift = bit.arshift
|
||||
local abs, sqrt = math.abs, math.sqrt
|
||||
|
||||
local assert = assert
|
||||
local error = error
|
||||
local type = type
|
||||
|
||||
|
||||
module(...)
|
||||
|
||||
|
||||
---=== TRIGONOMETRY ===---
|
||||
|
||||
local BANG2RAD = math.pi/1024
|
||||
local isintab = ffi.new("int16_t [?]", 2048)
|
||||
local dsintab = ffi.new("double [?]", 2048)
|
||||
|
@ -67,9 +72,8 @@ function cosb(ang)
|
|||
end
|
||||
|
||||
|
||||
-- Approximations to 2D and 3D Euclidean distances (also see common.c)
|
||||
local abs = math.abs
|
||||
local arshift = bit.arshift
|
||||
---=== Approximations to 2D and 3D Euclidean distances ===---
|
||||
-- (also see common.c)
|
||||
|
||||
local function dist_common(pos1, pos2)
|
||||
local x = abs(pos1.x - pos2.x)
|
||||
|
@ -100,14 +104,213 @@ function dist(pos1, pos2)
|
|||
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.
|
||||
-- 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)
|
||||
function rotate(pos, pivot, ang)
|
||||
local p = geom.vec3(pos)-pivot
|
||||
local p = vec3(pos)-pivot
|
||||
local c, s = cosb(ang), sinb(ang)
|
||||
local x, y = p.x, p.y
|
||||
p.x = pivot.x + (c*x - s*y)
|
||||
p.y = pivot.y + (c*y + s*x)
|
||||
return p
|
||||
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