mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-17 22:30:59 +00:00
Lunatic: add 'geom' module, sporting a vec2 type and a general 'intersect' func.
git-svn-id: https://svn.eduke32.com/eduke32@2855 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
defe79216d
commit
69365f2a0b
6 changed files with 146 additions and 1 deletions
|
@ -165,7 +165,8 @@ ifneq (0,$(LUNATIC))
|
|||
|
||||
GAMEOBJS+= $(OBJ)/../lpeg.$o # TEMP
|
||||
GAMEOBJS+= $(OBJ)/luaJIT_BC_con_lang.$o \
|
||||
$(OBJ)/luaJIT_BC_lunacon.$o
|
||||
$(OBJ)/luaJIT_BC_lunacon.$o \
|
||||
$(OBJ)/luaJIT_BC_geom.$o
|
||||
|
||||
# now, take care of having the necessary symbols (sector, wall, etc.) in the
|
||||
# executable no matter what the debugging level
|
||||
|
|
|
@ -525,6 +525,12 @@ string.dump = nil
|
|||
|
||||
local allowed_modules = {
|
||||
coroutine=coroutine, bit=bit, table=table, math=math, string=string,
|
||||
|
||||
os = {
|
||||
clock = function() return gv_.gethitickms()/1000 end,
|
||||
},
|
||||
|
||||
geom = require("geom"),
|
||||
}
|
||||
|
||||
local package_loaded = {}
|
||||
|
|
|
@ -40,6 +40,7 @@ g_player;
|
|||
|
||||
luaJIT_BC_lunacon;
|
||||
luaJIT_BC_con_lang;
|
||||
luaJIT_BC_geom;
|
||||
|
||||
gethitickms;
|
||||
};
|
||||
|
|
94
polymer/eduke32/source/lunatic/geom.lua
Normal file
94
polymer/eduke32/source/lunatic/geom.lua
Normal file
|
@ -0,0 +1,94 @@
|
|||
-- Geometry module for Lunatic.
|
||||
|
||||
local ffi = require("ffi")
|
||||
local math = require("math")
|
||||
|
||||
local type = type
|
||||
local assert = assert
|
||||
|
||||
|
||||
module(...)
|
||||
|
||||
|
||||
ffi.cdef[[
|
||||
typedef struct { double x, y; } dvec2_t;
|
||||
]]
|
||||
|
||||
local vec2_
|
||||
local mt = {
|
||||
__add = function(a, b) return vec2_(a.x+b.x, a.y+b.y) end,
|
||||
__sub = function(a, b) return vec2_(a.x-b.x, a.y-b.y) end,
|
||||
__unm = function(a) return vec2_(-a.x, -b.x) end,
|
||||
|
||||
__mul = function(a,b)
|
||||
if (type(a)=="number") then
|
||||
return vec2_(a*b.x, a*b.y)
|
||||
end
|
||||
|
||||
assert(type(b)=="number")
|
||||
return vec2_(a.x*b, a.y*b)
|
||||
end,
|
||||
|
||||
__div = function(a,b)
|
||||
assert(type(b)=="number")
|
||||
return vec2_(a.x/b, a.y/b)
|
||||
end,
|
||||
|
||||
__eq = function(a,b)
|
||||
return (a.x==b.x and a.y==b.y)
|
||||
end,
|
||||
|
||||
__len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) 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,
|
||||
},
|
||||
}
|
||||
|
||||
-- VEC2 user data constructor.
|
||||
-- * vec2(<table or ctype>), the arg should be indexable with "x" and "y"
|
||||
-- * vec2(x, y), assuming that x and y are numbers
|
||||
vec2_ = ffi.metatype("dvec2_t", mt)
|
||||
vec2 = vec2_
|
||||
|
||||
-- Returns a vec2 from anything indexable with "x" and "y"
|
||||
-- (vec2(t) works if t is such a table, but not if it's a vec2)
|
||||
function tovec2(t)
|
||||
return vec2(t.x, t.y)
|
||||
end
|
||||
|
||||
-- Two-element vector cross product.
|
||||
-- Anti-commutative, distributive.
|
||||
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 = tovec2(a)-tovec2(b)
|
||||
local cv, cw = cross2(w, btoa)/vxw, cross2(v, btoa)/vxw
|
||||
|
||||
if (retpoint_p) then
|
||||
return tovec2(a)+cv*tovec2(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
|
|
@ -249,6 +249,8 @@ printf("EVENT_INIT = %d", gv.EVENT_INIT) -- tests default defines
|
|||
local bittest = require "bittest"
|
||||
bittest.sieve()
|
||||
|
||||
require("test/test_geom")
|
||||
|
||||
print('---=== END TEST SCRIPT ===---')
|
||||
|
||||
-- This will complain about wrong usage of 'error'. In particular,
|
||||
|
|
41
polymer/eduke32/source/lunatic/test/test_geom.lua
Executable file
41
polymer/eduke32/source/lunatic/test/test_geom.lua
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env luajit
|
||||
|
||||
local math = require("math")
|
||||
local os = require("os")
|
||||
|
||||
local geom = require("geom")
|
||||
|
||||
|
||||
local N = os.exit and tostring(arg[1]) or 1e6
|
||||
|
||||
local A,B = {}, {}
|
||||
local V,W = {}, {}
|
||||
|
||||
local function randvec()
|
||||
return geom.vec2(math.random(), math.random())
|
||||
end
|
||||
|
||||
local t1 = os.clock()
|
||||
|
||||
-- init random points and vectors
|
||||
for i=1,N do
|
||||
A[i] = randvec()
|
||||
B[i] = randvec()
|
||||
V[i] = randvec()
|
||||
W[i] = randvec()
|
||||
end
|
||||
|
||||
local t2 = os.clock()
|
||||
|
||||
local v = geom.vec2(0, 0)
|
||||
for i=1,N do
|
||||
v = v + geom.intersect(A[i],V[i], B[i],W[i], true)
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
|
||||
print(1000*(t2-t1))
|
||||
print(1000*(t3-t2))
|
||||
print(v)
|
||||
|
||||
return {} -- appease Lunatic's require
|
Loading…
Reference in a new issue