From 9c1eeae751a8cdca708e1ecdeff8342358aad9d2 Mon Sep 17 00:00:00 2001
From: helixhorned <helixhorned@1a8010ca-5511-0410-912e-c29ae57300e0>
Date: Wed, 12 Jun 2013 17:49:56 +0000
Subject: [PATCH] Lunatic: clean up 'geom' module, make walls readable with
 pseudo-member 'z'.

git-svn-id: https://svn.eduke32.com/eduke32@3875 1a8010ca-5511-0410-912e-c29ae57300e0
---
 .../eduke32/source/lunatic/defs_common.lua    |  4 +++
 polymer/eduke32/source/lunatic/geom.lua       | 36 +++++++++----------
 polymer/eduke32/source/lunatic/test.elua      | 12 +++++--
 3 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua
index 33e451b94..b9016d0e8 100644
--- a/polymer/eduke32/source/lunatic/defs_common.lua
+++ b/polymer/eduke32/source/lunatic/defs_common.lua
@@ -579,6 +579,10 @@ local walltype_mt = {
         ishittable = function(w)
             return (band(w.cstat, 64)~=0)
         end,
+
+        -- Indexing a wall with 'z' gets 0, so that you can e.g. use a wall as
+        -- RHS to vec3_t addition.
+        z = 0,
     }
 }
 ffi.metatype("walltype", walltype_mt)
diff --git a/polymer/eduke32/source/lunatic/geom.lua b/polymer/eduke32/source/lunatic/geom.lua
index caae5a508..03c6b1a09 100644
--- a/polymer/eduke32/source/lunatic/geom.lua
+++ b/polymer/eduke32/source/lunatic/geom.lua
@@ -4,6 +4,9 @@ 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
 
@@ -23,7 +26,6 @@ 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,
@@ -47,14 +49,12 @@ local vec2_mt = {
         return dvec2_t(a.x/b, a.y/b)
     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,
 
-        mhlen = function(a) return math.abs(a.x)+math.abs(a.y) end,
+        mhlen = function(a) return abs(a.x)+abs(a.y) end,
     },
 }
 
@@ -91,44 +91,40 @@ local vec3_mt = {
         return v(v.x, v.y, v.z-zofs)
     end,
 
-    -- The # operator returns the Euclidean length.
-    -- TODO: REMOVE.
-    __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y + a.z*a.z) end,
-
-    -- INTERNAL: Calling a vector calls the constructor of its type.
-    __call = function(v, ...)
-        return v:_isi() and ivec3_t(...) or dvec3_t(...)
-    end,
-
-    -- INTERNAL
+    -- 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 math.sqrt(a.x*a.x + a.y*a.y + a.z*a.z) end,
+        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 math.sqrt(a.x*a.x + a.y*a.y) end,
+        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 math.abs(a.x)+math.abs(a.y)+math.abs(a.z) end,
+        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,
 
+        -- Get the type constructor for this vector.
+        _getctor = function(v)
+            return v:_isi() and ivec3_t or dvec3_t
+        end,
+
         -- BUILD-coordinate (z scaled by 16) <-> uniform conversions.
         touniform = function(v)
             return v:_isi()
-                and v(v.x, v.y, arshift(v.z, 4))
-                or v(v.x, v.y, v.z/4)
+                and v:_getctor(v.x, v.y, arshift(v.z, 4))
+                or v:_getctor(v.x, v.y, v.z/4)
         end,
 
-        tobuild = function(v) return v(v.x, v.y, 16*v.z) end,
+        tobuild = function(v) return v:_getctor(v.x, v.y, 16*v.z) end,
 
         -- Is <v> integer vec3? INTERNAL.
         _isi = function(v)
diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua
index cdef1421a..ba71deed8 100644
--- a/polymer/eduke32/source/lunatic/test.elua
+++ b/polymer/eduke32/source/lunatic/test.elua
@@ -247,6 +247,8 @@ gameevent
     end
 }
 
+local geom = require "geom"
+
 gameevent
 {
     gv.EVENT_ENTERLEVEL,
@@ -337,11 +339,17 @@ gameevent
 
         checkfail("gameevent('GAME', function() print('qwe') end)",
                   "must be called from top level")
+
+        -- Test vec3 + wall. Pseudo wall member 'z' will be accessed.
+        local mpos = geom.vec3()
+        for i=0,gv.numwalls-1 do
+            mpos = mpos + wall[i]
+        end
+        mpos = mpos/gv.numwalls
+        printf("Map center point: (%d,%d)", mpos.x, mpos.y)
     end
 }
 
-local geom = require "geom"
-
 gameevent{"LOADACTOR", function(i)
     local spr = sprite[i]
     if (i==614 and spr.picnum==930) then