Author Topic: LaaNaa 5.x advanced vector and matrix math lib.  (Read 1820 times)

DJLinux

  • Guest
LaaNaa 5.x advanced vector and matrix math lib.
« on: May 28, 2013, 02:35:42 AM »
My first try with LaaNaa.
I can't find the math3d.lib how ever here are my own.

DJ
Code: [Select]
import "math.lib"

rem
rem vector 3d math
rem
procedure v3dPrint(v#[])
  wln  str$(v[0])  + "," + str$(v[1]) + "," + str$(v[2])
endproc

function v3dCreate#[](x#,y#,z#)
  return [x,y,z]
endfunc

function v3dCopy#[](v#[])
  return [v[0],v[1],v[2]]
endfunc

rem v = a + b
function v3dAdd#[](a#[], b#[])
  return [a[0]+b[0],a[1]+b[1],a[2]+b[2]]
endfunc

rem v = a - b
function v3dSub#[](a#[], b#[])
  return [a[0]-b[0],a[1]-b[1],a[2]-b[2]]
endfunc

rem v = a * scalar
function v3dMul#[](a#[], s#)
  return [a[0]*s, a[1]*s, a[2]*s]
endfunc

rem v = a * (1.0/scalar)
function v3dDiv#[](a#[], d#)
  if d<>0.0
    d=1.0/d
    return [a[0]*d, a[1]*d, a[2]*d]
  else
    return [0.0,0.0,0.0]
  endif
endfunc

rem lengthsquared = (v3d)
function v3dLength2#(a#[])
  return a[0]*a[0] + a[1]*a[1] + a[2]*a[2]
endfunc

rem dot = (v3d,v3d)
function v3dDotProduct#(a#[],b#[])
  return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
endfunc
rem length = (v3d)
function v3dLength#(a#[])
  l# = a[0]*a[0] + a[1]*a[1] + a[2]*a[2]
  if l<>0.0 then l = sqr(l)
  return l
endfunc
rem distance = (v3d,v3d)
function v3dDistance#(a#[],b#[])
  return v3dLength#(v3dSub(a,b))
endfunc

rem v3d = (v3d)
function v3dNormalize#[](v#[])
  l# = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]
  if l<>0.0
    l=1.0/sqr(l)
    return [v[0]*l,v[1]*l,v[2]*l]
  else
    return [0.0, 0.0, 0.0]
  endif
endfunc

rem v3d = (v3d,v3d)
function v3dCrossProduct#[](a#[],b#[])
  return [a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0]]
endfunc

rem v3d = (v3d,v3d)
function v3dReflect#[](i#[], n#[])
  return v3dSub(i,v3dMul(n,2.0*v3dDotProduct(n, i)))
endfunc

rem v3d = (v3d,v3d,IndexOfRefration#)
function v3dRefract#[](i#[], n#[], ior#)
  d# = n[0]*i[0] + n[1]*i[1] + n[2]*i[2]
  k# = 1.0 - ior * ior * (1.0 - d * d)
  if (k >= 0.0)
    return  v3dSub(v3dMul(i,ior),v3dMul(n,ior * d + sqr(k)))
  else
    return [0.0, 0.0, 0.0]
  endif
endfunc

rem
rem matrix 4x4 math
rem
procedure matPrint(m#[][])
  for i=0 to 3
    for j=0 to 3
      if j<3
        write m[i][j]
        write ","
      else
        wln m[i][j]
      endif
    next
  next
endproc

function matCreate#[][](m00#,m01#,m02#,m04#, m10#,m11#,m12#,m13#, m20#,m21#,m22#,m23#, m30#,m31#,m32#,m33#)
  return [ [m00,m01,m02,m04], [m10,m11,m12,m13], [m20,m21,m22,m23], [m30,m31,m32,m33] ]
endfunc

function matCopy#[][](m#[][])
  return [ [m[0][0],m[0][1],m[0][2],m[0][3]] ,[m[1][0],m[1][1],m[1][2],m[1][3]], [m[2][0],m[2][1],m[2][2],m[2][3]], [m[3][0],m[3][1],m[3][2],m [3][3]] ]
endfunc

rem build a identity matrix4x4
function matIdentity#[][]()
  return [ [1.0,0.0,0.0,0.0], [0.0,1.0,0.0,0.0], [0.0,0.0,1.0,0.0], [0.0,0.0,0.0,1.0]]
endfunc

rem build a scale matrix4x4
function matScale#[][](x#,y#,z#)
 r#[4][4]
 r[0][0] = x
 r[1][1] = y
 r[2][2] = z
 r[3][3] = 1.0
 return r
endfunc

rem build a translation matrix4x4
function matTranslate#[][](x#,y#,z#)
  r#[4][4]
  r[0][0] = 1.0
  r[1][1] = 1.0
  r[2][2] = 1.0
  r[3][3] = 1.0
  r[3][0] = x
  r[3][1] = y
  r[3][2] = z
  return r
endfunc

rem build a rotation matrix4x4
function matRotate#[][](angle#, u#[])
  r#[4][4]
  angle = angle / 180.0 * M_PI

  v#[] = v3dNormalize(u)
  c# = 1.0 - cos(angle)
  s# = sin(angle)

  r[0][0] = 1.0 + c * (v[0] * v[0] - 1.0)
  r[0][1] = c * v[0] * v[1] + v[2] * s
  r[0][2] = c * v[0] * v[2] - v[1] * s
  r[1][0] = c * v[0] * v[1] - v[2] * s
  r[1][1] = 1.0 + c * (v[1] * v[1] - 1.0)
  r[1][2] = c * v[1] * v[2] + v[0] * s
  r[2][0] = c * v[0] * v[2] + v[1] * s
  r[2][1] = c * v[1] * v[2] - v[0] * s
  r[2][2] = 1.0 + c * (v[2] * v[2] - 1.0)
  r[3][3] = 1.0
  return r
endfunc

rem buid a perspective matrix4x4
function matPerspective#[][](fovy#, ratio#, near#, far#)
  r#[4][4]
  coty# = 1.0 / tan(fovy * M_PI / 360.0)
  r[0][0] = coty / ratio
  r[1][1] = coty
  r[2][2] = (near + far) / (near - far)
  r[2][3] = -1.0
  r[3][2] =  2.0 * near * far / (near - far)
  r[3][3] =  0.0
  return r
endfunc

rem buid a view matrix4x4 (from,to,up)
function matLookAt#[][](fx#,fy#,fz#, tx#,ty#,tz#, ux#,uy#,uz#)
  eye#[]    = v3dCreate(fx,fy,fz)
  target#[] = v3dCreate(tx,ty,tz)
  up#[]     = v3dCreate(ux,uy,uz)

  z#[] = v3dNormalize(v3dSub(eye,target))
  x#[] = v3dNormalize(v3dCrossProduct(up, z))
  y#[] = v3dCrossProduct(z, up)
  r#[4][4]
  r[0][0] = x[0]
  r[0][1] = y[0]
  r[0][2] = z[0]
 
  r[1][0] = x[1]
  r[1][1] = y[1]
  r[1][2] = z[1]
 
  r[2][0] = x[2]
  r[2][1] = y[2]
  r[2][2] = z[2]

  r[3][0] = -v3dDotProduct(x, eye)
  r[3][1] = -v3dDotProduct(y, eye)
  r[3][2] = -v3dDotProduct(z, eye)
  r[3][3] = 1.0
  return r
endfunc

rem build a 2D orthogonal matrix4x4 (left,right,bottom,top,near,far)
function matOrtho#[][](l#, r#, b#, t#, n#, f#)
  o#[4][4]
  o[0][0] =  2.0 / (r - l)
  o[1][1] =  2.0 / (t - b)
  o[2][2] = -2.0 / (f - n)
  o[3][0] = -(r + l) / (r - l)
  o[3][1] = -(t + b) / (t - b)
  o[3][2] = -(f + n) / (f - n)
  o[3][3] = 1.0
  return o
endfunc

rem matrix4x4 = matrix4x4 * matrix4x4
function matMat#[][](a#[][],b#[][])
  r#[4][4]
  r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]
  r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]
  r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]
  r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]
 
  r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]
  r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]
  r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]
  r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]
 
  r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]
  r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]
  r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]
  r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]
 
  r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]
  r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]
  r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]
  r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]
  return r
endfunc

rem v3d = v3d * matrix4x4
function v3dMat#[](v#[],m#[][])
  r#[3]
  r[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0]
  r[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1]
  r[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2]
  return r
endfunc



rem Init window.
set window 10, 10,640,480
rem set redraw off

proj#[][] = matPerspective(45.0, float(width(primary))/float(height(primary)), 1.0, 10.0)
wln "projection matrix"
proc matPrint proj
wln

mview#[][] = matLookAt(0.0,5.0,-2.0, 0.0,0.0,0.0, 0.0,1.0,0.0)
wln "view matrix"
proc matPrint mview
wln

a#[] = v3dCreate(0.0,  1.0, -1.0)
b#[] = v3dCreate(0.0, -1.0,  1.0)

a#[] = v3dMat(a,proj)
b#[] = v3dMat(b,proj)

wln "vector a"
proc v3dPrint a
wln

wln "vector b"
proc v3dPrint b
wln

do
  wait 10
until keydown(27)
end

Mopz

  • Guest
Re: LaaNaa 5.x advanced vector and matrix math lib.
« Reply #1 on: May 28, 2013, 07:11:58 AM »
Thank you, and welcome to the forum  ;D  Very sweet usage of array constructs there, looks clean! I'll play around with this library as soon as I can. With some polygon sorting and cohen sutherland clipping, one could probably use this to write some sweet retro 3d vector games. I promise I'll add a triangle/polygon rasterizer for the next naalaa update.

Mopz

  • Guest
Re: LaaNaa 5.x advanced vector and matrix math lib.
« Reply #2 on: May 29, 2013, 05:29:07 PM »
Can you post an example where you use this library for displaying a rotating cube or something (just add the code at the end of the library)? If you don't, I'll do it myself this weekend.

The thing is, I haven't really spent time on 3D maths since I wrote CGE (eight years ago). Since then I've been in the casual games industry, making addictive 2D games for PC/Mac/iOS/Android and developing naalaa at my sparetime. So I feel a little lost with this library of yours.

Edit: If you display a cube, I'll display the statue of Venus, but I really need your help on getting started with the vertex processing in this lib ;)
« Last Edit: May 29, 2013, 05:44:17 PM by Mopz »