-- $LastChangedDate: 2010-04-16 09:27:50 -0500 (Fri, 16 Apr 2010) $
-- Math and graphics code.
-- See module.txt for documentation and pitfalls.
-- Notes: Use Vec3() instead of tables (XX=0).

-- *************************************************************
-- IMPORTANT: Indexs used with C++/Lua bindings MUST BE ZERO-BASED.
-- This is why special Lua classes such as RGBA and Vec3 are defined
-- instead of passing array-like one-based Lua tables.
-- *************************************************************

---------------
-- constants --
---------------

-- Axis:
XX = 0
YY = 1
ZZ = 2
WW = 3

AXIS_INVALID = sim.Math.AXIS_INVALID()  -- defined as ~0 in C++ which varies by CPU
AXIS_X = 0
AXIS_Y = 1
AXIS_Z = 2

AXIS_PITCH = 0
AXIS_YAW   = 1
AXIS_ROLL  = 2

-- Matrix:
Xx =  0; Xy =  1; Xz =  2; Xw =  3
Yx =  4; Yy =  5; Yz =  6; Yw =  7
Zx =  8; Zy =  9; Zz = 10; Zw = 11
Ox = 12; Oy = 13; Oz = 14; Ow = 15

-- Spherical coordinates:
LAT = 0  -- degree 0..180
LON = 1  -- degree 0..360
ALT = 2  -- meter

----------------------------
-- vector and gfx classes --
----------------------------

-- 2D vector class (index starts as zero).
local Vec2Class = {}

function Vec2( x, y )  -- this is a ctor
    local t = { [XX] = x, [YY] = y }
    setmetatable( t, Vec2Class )
    return t
end

function Vec2Class:__tostring()
    return "Vec2: "
        .. tostring(self[XX]) .. ","
        .. tostring(self[YY])
end

-- 3D vector class (index starts as zero).
local Vec3Class = { }

function Vec3( x, y, z )  -- this is a ctor
    local t = { [XX] = x, [YY] = y, [ZZ] = z }
    setmetatable( t, Vec3Class )
    return t
end

function Vec3Class:__tostring()
    return "Vec3: "
        .. tostring(self[XX]) .. ","
        .. tostring(self[YY]) .. ","
        .. tostring(self[ZZ])
end

-- RGBA class (index starts as zero).
RR = 0
GG = 1
BB = 2
AA = 3

local RGBAClass = {}

function RGBA( r, g, b, a )  -- this is a ctor
    local t = { [RR] = r, [GG] = g, [BB] = b, [AA] = a }
    RGBAClass.__index = RGBAClass
    return t
end

function RGBAClass:__tostring()
    return "RGBA: "
        .. tostring(self[RR]) .. ","
        .. tostring(self[GG]) .. ","
        .. tostring(self[BB]) .. ","
        .. tostring(self[AA])
end

---------------------
-- radians/degrees --
---------------------

PI         = 3.14159265358979323846
PI_DOUBLE  = 6.28318530717958647692
PI_HALF    = 1.57079632679489661926  -- pi/2 equivalent to 90'
RADIAN_90  = PI_HALF    -- 90'  in radians (quarter circle)
RADIAN_180 = PI         -- 180' in radians (half circle)
RADIAN_360 = PI_DOUBLE  -- 360' in radians (full circle)

--------------------
-- math functions --
--------------------

Deg2Rad = math.rad  -- function
Rad2Deg = math.deg  -- function

-- Distance between two vertexs (or origin if second vertex omitted).
function Distance2( v0, v1 )
    if ( v1 ) then
        local dx = v1[XX] - v0[XX]
        local dy = v1[YY] - v0[YY]
        return math.sqrt( dx*dx
                        + dy*dy )
    else
        return math.sqrt( v0[XX] * v0[XX]
                        + v0[YY] * v0[YY] )
    end
end

function Distance3( v0, v1 )
    if ( v1 ) then
        local dx = v1[XX] - v0[XX]
        local dy = v1[YY] - v0[YY]
        local dz = v1[ZZ] - v0[ZZ]
        return math.sqrt( dx*dx
                        + dy*dy
                        + dz*dz )
    else
        return math.sqrt( v0[XX] * v0[XX]
                        + v0[YY] * v0[YY]
                        + v0[ZZ] * v0[ZZ] )
    end
end
