From 69365f2a0bfffdfcf304ccd0bbe1ed50fbf51538 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Thu, 2 Aug 2012 10:52:21 +0000 Subject: [PATCH] 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 --- polymer/eduke32/Makefile | 3 +- polymer/eduke32/source/lunatic/defs.ilua | 6 ++ polymer/eduke32/source/lunatic/dynsymlist | 1 + polymer/eduke32/source/lunatic/geom.lua | 94 +++++++++++++++++++ polymer/eduke32/source/lunatic/test.elua | 2 + .../eduke32/source/lunatic/test/test_geom.lua | 41 ++++++++ 6 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 polymer/eduke32/source/lunatic/geom.lua create mode 100755 polymer/eduke32/source/lunatic/test/test_geom.lua diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile index 4c3f3a4cf..1448f7f2a 100644 --- a/polymer/eduke32/Makefile +++ b/polymer/eduke32/Makefile @@ -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 diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 6efe7f825..515565b43 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -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 = {} diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 0825a7140..27d4ce937 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -40,6 +40,7 @@ g_player; luaJIT_BC_lunacon; luaJIT_BC_con_lang; +luaJIT_BC_geom; gethitickms; }; diff --git a/polymer/eduke32/source/lunatic/geom.lua b/polymer/eduke32/source/lunatic/geom.lua new file mode 100644 index 000000000..92a605804 --- /dev/null +++ b/polymer/eduke32/source/lunatic/geom.lua @@ -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(), 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 , nil +-- if retpoint_p evaluates to a non-true value, coefficients cv and cw such that +-- 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 diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index cfa2823a2..730d3db6b 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -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, diff --git a/polymer/eduke32/source/lunatic/test/test_geom.lua b/polymer/eduke32/source/lunatic/test/test_geom.lua new file mode 100755 index 000000000..9d577ab2b --- /dev/null +++ b/polymer/eduke32/source/lunatic/test/test_geom.lua @@ -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