TGC Codebase Backup



Extended Math Library by Jack

8th Nov 2016 23:52
Summary

Version 0.6 .. this update adds a whole new dimension of commands Vector2, Vector3, Vector4 and Matrix4 commands for AGK



Description

Version 0.6 .. this update adds a whole new dimension of commands
============

Math Constants
==============
- Math_PI
- Math_Euler
- Math_GoldenRatio
- Math_PythagorasConstant
- Math_BernsteinConstant
- Math_ReciprocalFibonacciConstant
- Math_SierpinskisConstant


Vector 2 Library
================
- CreateVector2
- DeleteVector2
- SetVector2
- PrintVector2
- AddVector2
- SubtractVector2
- GetVector2X
- GetVector2Y
- CatmullRomVector2
- CopyVector2
- DivideVector2
- MultiplyVector2
- DotProductVector2
- BCCVector2
- SquaredLengthVector2
- LengthVector2
- HermiteVector2
- IsEqualVector2
- LinearInterpolateVector2
- MaximizeVector2
- MinimizeVector2
- NormalizeVector2
- ScaleVector2
- CCWVector2
- TransformCoordsVector2


"extended" Vector 3 Library
===========================
- PrintVector3
- AddVector3
- SubtractVector3
- CatmullRomVector3
- CopyVector3
- DivideVector3
- MultiplyVector3
- BCCVector3
- SquaredLengthVector3
- LengthVector3
- HermiteVector3
- IsEqualVector3
- LinearInterpolateVector3
- MaximizeVector3
- MinimizeVector3
- ScaleVector3
- ProjectVector3
- TransformCoordsVector3
- TransformNormalsVector3
- normalizeVector3


Vector 4 Library
================
- CreateVector4
- DeleteVector4
- SetVector4
- PrintVector4
- AddVector4
- SubtractVector4
- GetVector4X
- GetVector4Y
- GetVector4Z
- GetVector4W
- CatmullromVector4
- CopyVector4
- DivideVector4
- MultiplyVector4
- BCCVector4
- SquaredLengthVector4
- LengthVector4
- HermiteVector4
- IsEqualVector4
- LinearInterpolateVector4
- MaximizeVector4
- MinimizeVector4
- NormalizeVector4
- ScaleVector4
- TransformVector4


Matrix 4 Library
================
- CreateMatrix4
- DeleteMatrix4
- CopyMatrix4
- BuildLookAtLHMatrix4
- BuildLookAtRHMatrix4
- BuildOrthoLHMatrix4
- BuildOrthoRHMatrix4
- BuildFOVLHMatrix4
- BuildFOVRHMatrix4
- BuildPerspectiveLHMatrix4
- BuildPerspectiveRHMatrix4
- BuildReflectionMatrix4
- BuildRotationAxisMatrix4
- SetIdentityMatrix4
- IsEqualMatrix4
- IsIdentityMatrix4
- AddMatrix4
- SubtractMatrix4
- MultiplyMatrix4
- MultiplyMatrix4ByValue
- ScaleMatrix4
- TranslateMatrix4
- TransposeMatrix4
- RotateYPRMatrix4
- RotateXMatrix4
- RotateYMatrix4
- RotateZMatrix4
- WorldMatrix4
- ViewMatrix4
- ProjectionMatrix4
- DeterminantMatrix4
- DeterminantMatrix3
- SubMatrix3
- InverseMatrix4


Tween Math Library
==================
- Hermite
- Sinerp
- Coserp
- Bounce
- Berp
- Lerp
- SmoothStep
- Approx
- Clerp
- Clamp


Forum thread: https://forum.thegamecreators.com/thread/217064#msg2582798



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    // ==================================================================================
// ======    Extended math function for AGK    ======================================
// ========================================= 2016================  0.60  ============
// ==================================================================================
// ==================================================================================


/*	Changelog

	Dev Notes: Please test me and verify me....
	.. I may have bugs in the Matrix4 commandset
	

	



	Version 0.6		.. this update adds a whole new dimension of commands
	============
		
	Math Constants
	==============
			- Math_PI
			- Math_Euler
			- Math_GoldenRatio
			- Math_PythagorasConstant
			- Math_BernsteinConstant
			- Math_ReciprocalFibonacciConstant
			- Math_SierpinskisConstant

		
	Vector 2 Library
	================
			- CreateVector2
			- DeleteVector2
			- SetVector2
			- PrintVector2
			- AddVector2
			- SubtractVector2
			- GetVector2X
			- GetVector2Y
			- CatmullRomVector2
			- CopyVector2
			- DivideVector2
			- MultiplyVector2
			- DotProductVector2
			- BCCVector2
			- SquaredLengthVector2
			- LengthVector2
			- HermiteVector2
			- IsEqualVector2
			- LinearInterpolateVector2
			- MaximizeVector2
			- MinimizeVector2
			- NormalizeVector2
			- ScaleVector2
			- CCWVector2
			- TransformCoordsVector2
			
			
	"extended" Vector 3 Library
	===========================
			- PrintVector3
			- AddVector3
			- SubtractVector3
			- CatmullRomVector3
			- CopyVector3
			- DivideVector3
			- MultiplyVector3
			- BCCVector3
			- SquaredLengthVector3
			- LengthVector3
			- HermiteVector3
			- IsEqualVector3
			- LinearInterpolateVector3
			- MaximizeVector3
			- MinimizeVector3
			- ScaleVector3
			- ProjectVector3
			- TransformCoordsVector3
			- TransformNormalsVector3
			- normalizeVector3


	Vector 4 Library
	================
			- CreateVector4
			- DeleteVector4
			- SetVector4
			- PrintVector4
			- AddVector4
			- SubtractVector4
			- GetVector4X
			- GetVector4Y
			- GetVector4Z
			- GetVector4W
			- CatmullromVector4
			- CopyVector4
			- DivideVector4
			- MultiplyVector4
			- BCCVector4
			- SquaredLengthVector4
			- LengthVector4
			- HermiteVector4
			- IsEqualVector4
			- LinearInterpolateVector4
			- MaximizeVector4
			- MinimizeVector4
			- NormalizeVector4
			- ScaleVector4
			- TransformVector4
		

	Matrix 4 Library
	================
			- CreateMatrix4
			- DeleteMatrix4
			- CopyMatrix4
			- BuildLookAtLHMatrix4
			- BuildLookAtRHMatrix4
			- BuildOrthoLHMatrix4
			- BuildOrthoRHMatrix4
			- BuildFOVLHMatrix4
			- BuildFOVRHMatrix4
			- BuildPerspectiveLHMatrix4
			- BuildPerspectiveRHMatrix4
			- BuildReflectionMatrix4
			- BuildRotationAxisMatrix4
			- SetIdentityMatrix4
			- IsEqualMatrix4
			- IsIdentityMatrix4
			- AddMatrix4
			- SubtractMatrix4
			- MultiplyMatrix4
			- MultiplyMatrix4ByValue
			- ScaleMatrix4
			- TranslateMatrix4
			- TransposeMatrix4
			- RotateYPRMatrix4
			- RotateXMatrix4
			- RotateYMatrix4
			- RotateZMatrix4
			- WorldMatrix4
			- ViewMatrix4
			- ProjectionMatrix4
			- DeterminantMatrix4
			- DeterminantMatrix3
			- SubMatrix3
			- InverseMatrix4			


	Tween Math Library
	==================
			- Hermite
			- Sinerp
			- Coserp
			- Bounce
			- Berp
			- Lerp
			- SmoothStep
			- Approx
			- Clerp
			- Clamp	
			

Forum thread: https://forum.thegamecreators.com/thread/217064#msg2582798		
	
========================================================================		
*/





// Math Constants
// ==============

#constant Math_PI								3.141592653
#constant Math_Euler							2.718281824
#constant Math_GoldenRatio						1.618033988
#constant Math_PythagorasConstant				1.414213562
#constant Math_BernsteinConstant				0.280169499
#constant Math_ReciprocalFibonacciConstant		3.359885666
#constant Math_SierpinskisConstant				2.584981759




// Math Types
// ==========
type Vector2_def
	used as integer
	x as float
	y as float
endtype


type Vec4_def
	x as float
	y as float
	z as float
	w as float
endtype

type Vector4_def
	used as integer
	x as float
	y as float
	z as float
	w as float
endtype




type Matrix4_def
	used as integer
	x as Vec4_def
	y as Vec4_def
	z as Vec4_def
	w as Vec4_def
endtype









// ============================================================
// ==================  Advanced Math Libary  ==================
// ============================================================










// vector2 commands Library
// ========================

// create vector2
function CreateVector2()

			if Vector2.length=-1
			
				dim Vector2[] as Vector2_def
			
			endif

		// find free slot
		x = -1 
		repeat
		inc x
		if x>Vector2.length // if no slot exists, create a new one
			Vector2.length=Vector2.length+1	
			exit
		endif

		until Vector2[x].used=0
			
				out=x

			Vector2[out].used=1 // set used to 1

endfunction out

// delete vector2 (in1)
function DeleteVector2(num)
		Vector2[num].used=0
		Vector2[num].x=0.0
		Vector2[num].y=0.0
endfunction

// set vector2
function SetVector2(num, X#, Y#)
		Vector2[num].x=X#
		Vector2[num].y=Y#
endfunction

// PrintVector2
function PrintVector2(num)
	Print("Vector2: "+str(num)+" "+str(Vector2[num].x)+"|"+str(Vector2[num].y))
endfunction



// add vector2 
function AddVector2(resultvec, vec1, vec2)
		Vector2[resultvec].x = Vector2[vec1].x + Vector2[vec2].x
		Vector2[resultvec].y = Vector2[vec1].y + Vector2[vec2].y
endfunction


// subtract vector 2
function SubtractVector2(resultvec, vec1, vec2)
		Vector2[resultvec].x = Vector2[vec1].x - Vector2[vec2].x
		Vector2[resultvec].y = Vector2[vec1].y - Vector2[vec2].y
endfunction

// get vector2 X
function GetVector2X(vec1)
	Result# = Vector2[vec1].x
endfunction Result#

// get vector2 Y
function GetVector2Y(vec1)
	Result# = Vector2[vec1].y
endfunction Result#

// CatmullRomVector2
// This command performs a catmull rom interpolation on the specified vector. This vector
// is defined as a two float vector.
function CatmullRomVector2(resultvec, vec1, vec2, vec3, vec4, Value#)

   tv1=CreateVector2()
   tv2=CreateVector2()
   tv3=CreateVector2()
   tv4=CreateVector2()
	   XA#=GetVector2X(vec1)
	   YA#=GetVector2Y(vec1)
	   XB#=GetVector2X(vec2)
	   YB#=GetVector2Y(vec2)
	   XC#=GetVector2X(vec3)
	   YC#=GetVector2Y(vec3)
	   XD#=GetVector2X(vec4)
	   YD#=GetVector2Y(vec4)
	   SetVector2(tv1, XA#, YA#)
	   SetVector2(tv2, XB#, YB#)
	   SetVector2(tv3, XC#, YC#)
	   SetVector2(tv4, XD#, YD#)
	   MultiplyVector2(tv1, -1.0*Value#^3+2.0*Value#^2-Value#)
	   MultiplyVector2(tv2, 3.0*Value#^3-5.0*Value#^2+2.0)
	   MultiplyVector2(tv3, -3.0*Value#^3+4.0*Value#^2+Value#)
	   MultiplyVector2(tv4, Value#^3-Value#^2)
	   AddVector2(resultvec, tv1, tv2)
	   AddVector2(resultvec, resultvec, tv3)
	   AddVector2(resultvec, resultvec, tv4)
	   DivideVector2(resultvec, 2.0)
   DeleteVector2(tv1)
   DeleteVector2(tv2)
   DeleteVector2(tv3)
   DeleteVector2(tv4)

endfunction



// copy vector2
function CopyVector2(resultvec, vsource)
		Vector2[resultvec].x = Vector2[vsource].x
		Vector2[resultvec].y = Vector2[vsource].y
endfunction








// DivideVector2(VectorResult, Value#)
function DivideVector2(resultvec, Value#)
   Vector2[resultvec].x = Vector2[resultvec].x/Value#
   Vector2[resultvec].y = Vector2[resultvec].y/Value#
endfunction

// MultiplyVector2
function MultiplyVector2(resultvec, Value#)
   Vector2[resultvec].x = Vector2[resultvec].x*Value#
   Vector2[resultvec].y = Vector2[resultvec].y*Value#
endfunction

// DotProductVector2
function DotProductVector2(vec1, vec2)
   Result#=Vector2[vec1].x * Vector2[vec2].x + Vector2[vec1].y * Vector2[vec2].y
endfunction Result#


// BCCVector2
function BCCVector2(resultvec, vec1, vec2, vec3, FValue#, GValue#)
   tv1=CreateVector2()
   tv2=CreateVector2()
	   SubtractVector2(tv1, vec2, vec1)
	   SubtractVector2(tv2, vec3, vec1)
	   MultiplyVector2(tv1, FValue#)
	   MultiplyVector2(tv2, GValue#)
	   AddVector2(resultvec, tv1, tv2)
	   AddVector2(resultvec, vec1, resultvec)
   DeleteVector2(tv1)
   DeleteVector2(tv2)
endfunction

// SquaredLengthVector2
function SquaredLengthVector2(vec1)
   X#=GetVector2X(vec1)
   Y#=GetVector2Y(vec1)
   Result#=X#*X#+Y#*Y#
endfunction Result#

// LengthVector2
function LengthVector2(vec1)
   Result#=SQRT(SquaredLengthVector2(vec1))
endfunction Result#

// HermiteVector2
function HermiteVector2(resultvec, vec1, vec2, vec3, vec4, Value#)
   tv1=CreateVector2()
   tv2=CreateVector2()
   tv3=CreateVector2()
   tv4=CreateVector2()
	   XA#=GetVector2X(vec1)
	   YA#=GetVector2Y(vec1)
	   XB#=GetVector2X(vec2)
	   YB#=GetVector2Y(vec2)
	   XC#=GetVector2X(vec3)
	   YC#=GetVector2Y(vec3)
	   XD#=GetVector2X(vec4)
	   YD#=GetVector2Y(vec4)
	   SetVector2(tv1, XA#, YA#)
	   SetVector2(tv3, XB#, YB#)
	   SetVector2(tv2, XC#, YC#)
	   SetVector2(tv4, XD#, YD#)
	   MultiplyVector2(tv1, 2.0*Value#^3-3.0*Value#^2+1.0)
	   MultiplyVector2(tv2, -2.0*Value#^3+3.0*Value#^2)
	   MultiplyVector2(tv3, Value#^3-2.0*Value#^2+Value#)
	   MultiplyVector2(tv4, Value#^3-Value#^2)
	   AddVector2(resultvec, tv1, tv2)
	   AddVector2(resultvec, resultvec, tv3)
	   AddVector2(resultvec, resultvec, tv4)
   DeleteVector2(tv1)
   DeleteVector2(tv2)
   DeleteVector2(tv3)
   DeleteVector2(tv4)	   
	   
endfunction



// IsEqualVector2
function IsEqualVector2(vec1, vec2)
	If GetVector2X(vec1)<>GetVector2X(vec2) then exitfunction 0
	If GetVector2Y(vec1)<>GetVector2Y(vec2) then exitfunction 0
endfunction 1

// LinearInterpolateVector2
function LinearInterpolateVector2(resultvec, vec1, vec2, Value#)
   SubtractVector2(resultvec, vec2, vec1)
   MultiplyVector2(resultvec, Value#)
   AddVector2(resultvec, resultvec, vec1)
endfunction

// MaximizeVector2
function MaximizeVector2(resultvec, vec1, vec2)
   XA#=GetVector2X(vec1)
   YA#=GetVector2Y(vec1)
   XB#=GetVector2X(vec2)
   YB#=GetVector2Y(vec2)
   If XA# > XB#
      MaxX#=XA#
   Else
      MaxX#=XB#
   EndIf
   If YA# > YB#
      MaxY#=YA#
   Else
      MaxY#=YB#
   EndIf
   SetVector2(resultvec, MaxX#, MaxY#)
endfunction



// MinimizeVector2
function MinimizeVector2(resultvec, vec1, vec2)
   XA#=GetVector2X(vec1)
   YA#=GetVector2Y(vec1)
   XB#=GetVector2X(vec2)
   YB#=GetVector2Y(vec2)
   If XA# < XB#
      MinX#=XA#
   Else
      MinX#=XB#
   EndIf
   If YA# < YB#
      MinY#=YA#
   Else
      MinY#=YB#
   EndIf
   SetVector2(resultvec, MinX#, MinY#)
endfunction

// NormalizeVector2
function NormalizeVector2(resultvec, vsource)
   Length#=LengthVector2(vsource)
   CopyVector2(resultvec, vsource)
   If Length# <> 0.0 Then DivideVector2(resultvec, Length#)
endfunction

// ScaleVector2
function ScaleVector2(resultvec, vsource, Value#)
   CopyVector2(resultvec, vsource)
   MultiplyVector2(resultvec, Value#)
endfunction

// CCWVector2
function CCWVector2(vec1, vec2)
   XA#=GetVector2X(vec1)
   YA#=GetVector2Y(vec1)
   XB#=GetVector2X(vec2)
   YB#=GetVector2Y(vec2)
   Result#=XA#*YB#-YA#*XB#
endfunction Result#

// TransformCoordsVector2
function TransformCoordsVector2(resultvec, vsource, msource)
   X#=GetVector2X(vsource)
   Y#=GetVector2Y(vsource)
   nX#=X#*GetMatrix4Element(msource,1-1)+Y#*GetMatrix4Element(msource,5-1)+GetMatrix4Element(msource,13-1)
   nY#=X#*GetMatrix4Element(msource,2-1)+Y#*GetMatrix4Element(msource,6-1)+GetMatrix4Element(msource,14-1)
   nW#=X#*GetMatrix4Element(msource,4-1)+Y#*GetMatrix4Element(msource,8-1)+GetMatrix4Element(msource,16-1)
   fr#=1.0/nW#
   SetVector2(resultvec, nX#*fr#, nY#*fr#)
endfunction




// =================================================================================================================================
// =======================================   Vector 2 END   ========================================================================













// extended vector3 commands Library
// =================================


// PrintVector3
function PrintVector3(num)
	Print("Vector3: "+str(num)+" "+str(GetVector3X(num))+"|"+str(GetVector3Y(num))+"|"+str(GetVector3Z(num)))
endfunction


// Vector 3 add
function AddVector3(resultvec,vec1,vec2)
	SetVector3(resultvec,GetVector3X(vec1)+GetVector3X(vec2),GetVector3Y(vec1)+GetVector3Y(vec2),GetVector3Z(vec1)+GetVector3Z(vec2))
endfunction 


// Vector3 subtract substract vec2 from vec1 into resultvec
	function SubtractVector3(resultvec,vec1,vec2)
		SetVector3(resultvec,GetVector3X(vec1)-GetVector3X(vec2),GetVector3Y(vec1)-GetVector3Y(vec2),GetVector3Z(vec1)-GetVector3Z(vec2))
	endfunction

// CatmullRomVector3
function CatmullRomVector3(resultvec, vec1, vec2, vec3, vec4, Value#)
   tv1=CreateVector3()
   tv2=CreateVector3()
   tv3=CreateVector3()
   tv4=CreateVector3()
	   XA#=GetVector3X(vec1)
	   YA#=GetVector3Y(vec1)
	   ZA#=GetVector3Z(vec1)
	   XB#=GetVector3X(vec2)
	   YB#=GetVector3Y(vec2)
	   ZB#=GetVector3Z(vec2)
	   XC#=GetVector3X(vec3)
	   YC#=GetVector3Y(vec3)
	   ZC#=GetVector3Z(vec3)
	   XD#=GetVector3X(vec4)
	   YD#=GetVector3Y(vec4)
	   ZD#=GetVector3Z(vec4)
	   SetVector3(tv1, XA#, YA#, ZA#)
	   SetVector3(tv2, XB#, YB#, ZB#)
	   SetVector3(tv3, XC#, YC#, ZC#)
	   SetVector3(tv4, XD#, YD#, ZD#)
	   MultiplyVector3(tv1, -1.0*Value#^3+2.0*Value#^2-Value#)
	   MultiplyVector3(tv2, 3.0*Value#^3-5.0*Value#^2+2.0)
	   MultiplyVector3(tv3, -3.0*Value#^3+4.0*Value#^2+Value#)
	   MultiplyVector3(tv4, Value#^3-Value#^2)
	   AddVector3(resultvec, tv1, tv2)
	   AddVector3(resultvec, resultvec, tv3)
	   AddVector3(resultvec, resultvec, tv4)
	   DivideVector3(resultvec, 2.0)
   DeleteVector3(tv1)
   DeleteVector3(tv2)
   DeleteVector3(tv3)
   DeleteVector3(tv4)
   
endfunction



// CopyVector3
function CopyVector3(resultvec, vsource)
	SetVector3(resultvec,GetVector3X(vsource),GetVector3Y(vsource),GetVector3Z(vsource))
endfunction 



// Divide Vector3
function DivideVector3(resultvec, Value#) 
   SetVector3(resultvec,GetVector3X(resultvec)/Value#,GetVector3Y(resultvec)/Value#,GetVector3Z(resultvec)/Value#)
endfunction



// MultiplyVector3
function MultiplyVector3(resultvec, Value#)
	SetVector3(resultvec,GetVector3X(resultvec)*Value#,GetVector3Y(resultvec)*Value#,GetVector3Z(resultvec)*Value#)
endfunction


// BCCVector3
function BCCVector3(resultvec, vec1, vec2, vec3, FValue#, GValue#)
   tv1=CreateVector3()
   tv2=CreateVector3()
	   SubtractVector3(tv1, vec2, vec1)
	   SubtractVector3(tv2, vec3, vec1)
	   MultiplyVector3(tv1, FValue#)
	   MultiplyVector3(tv2, GValue#)
	   AddVector3(resultvec, tv1, tv2)
	   AddVector3(resultvec, vec1, resultvec)
   DeleteVector3(tv1)
   DeleteVector3(tv2)
endfunction

// SquaredLengthVector3
function SquaredLengthVector3(vsource)
   X#=GetVector3X(vsource)
   Y#=GetVector3Y(vsource)
   Z#=GetVector3Z(vsource)
   Result#=X#*X#+Y#*Y#+Z#*Z#
endfunction Result#


// LengthVector3
function LengthVector3(vsource)
   Result#=SQRT(SquaredLengthVector3(vsource))
endfunction Result#

// HermiteVector3
function HermiteVector3(resultvec, vec1, vec2, vec3, vec4, Value#)

   tv1=CreateVector3()
   tv2=CreateVector3()
   tv3=CreateVector3()
   tv4=CreateVector3()
	   XA#=GetVector3X(vec1)
	   YA#=GetVector3Y(vec1)
	   ZA#=GetVector3Z(vec1)
	   XB#=GetVector3X(vec2)
	   YB#=GetVector3Y(vec2)
	   ZB#=GetVector3Z(vec2)
	   XC#=GetVector3X(vec3)
	   YC#=GetVector3Y(vec3)
	   ZC#=GetVector3Z(vec3)
	   XD#=GetVector3X(vec4)
	   YD#=GetVector3Y(vec4)
	   ZD#=GetVector3Z(vec4)
	   SetVector3(tv1, XA#, YA#, ZA#)
	   SetVector3(tv3, XB#, YB#, ZB#)
	   SetVector3(tv2, XC#, YC#, ZC#)
	   SetVector3(tv4, XD#, YD#, ZD#)
	   MultiplyVector3(tv1, 2.0*Value#^3-3.0*Value#^2+1.0)
	   MultiplyVector3(tv2, -2.0*Value#^3+3.0*Value#^2)
	   MultiplyVector3(tv3, Value#^3-2.0*Value#^2+Value#)
	   MultiplyVector3(tv4, Value#^3-Value#^2)
	   AddVector3(resultvec, tv1, tv2)
	   AddVector3(resultvec, resultvec, tv3)
	   AddVector3(resultvec, resultvec, tv4)
   DeleteVector3(tv1)
   DeleteVector3(tv2)
   DeleteVector3(tv3)
   DeleteVector3(tv4)
      
endfunction

// IsEqualVector3
function IsEqualVector3(vec1, vec2)
	If GetVector3X(vec1)<>GetVector3X(vec2) then exitfunction 0
	If GetVector3Y(vec1)<>GetVector3Y(vec2) then exitfunction 0
	If GetVector3Z(vec1)<>GetVector3Z(vec2) then exitfunction 0
	
endfunction 1

// LinearInterpolateVector3
function LinearInterpolateVector3(resultvec, vec1, vec2, Value#)
   SubtractVector3(resultvec, vec2, vec1)
   MultiplyVector3(resultvec, Value#)
   AddVector3(resultvec, resultvec, vec1)
endfunction

// MaximizeVector3
function MaximizeVector3(resultvec, vec1, vec2)

   XA#=GetVector3X(vec1)
   YA#=GetVector3Y(vec1)
   ZA#=GetVector3Z(vec1)
   XB#=GetVector3X(vec2)
   YB#=GetVector3Y(vec2)
   ZB#=GetVector3Z(vec2)
   If XA# > XB#
      MaxX#=XA#
   Else
      MaxX#=XB#
   EndIf
   If YA# > YB#
      MaxY#=YA#
   Else
      MaxY#=YB#
   EndIf
   If ZA# > ZB#
      MaxZ#=ZA#
   Else
      MaxZ#=ZB#
   EndIf
   SetVector3(resultvec, MaxX#, MaxY#, MaxZ#)
endfunction

// MinimizeVector3
function MinimizeVector3(resultvec, vec1, vec2)

   XA#=GetVector3X(vec1)
   YA#=GetVector3Y(vec1)
   ZA#=GetVector3Z(vec1)
   XB#=GetVector3X(vec2)
   YB#=GetVector3Y(vec2)
   ZB#=GetVector3Z(vec2)
   If XA# < XB#
      MinX#=XA#
   Else
      MinX#=XB#
   EndIf
   If YA# < YB#
      MinY#=YA#
   Else
      MinY#=YB#
   EndIf
   If ZA# < ZB#
      MinZ#=ZA#
   Else
      MinZ#=ZB#
   EndIf
   SetVector3(resultvec, MinX#, MinY#, MinZ#)
endfunction



// ScaleVector3
function ScaleVector3(resultvec, vsource, Value#)
   CopyVector3(resultvec, vsource)
   MultiplyVector3(resultvec, Value#)
endfunction


// ProjectVector3
function ProjectVector3(resultvec, vsource, Matrix4Projection, Matrix4View, Matrix4World)
   tv1=CreateVector3()
   TransformCoordsVector3(tv1, vsource, Matrix4World)
   TransformCoordsVector3(tv1, tv1, Matrix4View)
   TransformCoordsVector3(resultvec, tv1, Matrix4Projection)
   X#=GetVector3X(resultvec)
   Y#=GetVector3Y(resultvec)
   Z#=GetVector3Z(resultvec)
   SetVector3(resultvec,(X#+1.0)*(GetVirtualWidth()/2.0), (1.0-Y#)*(GetVirtualHeight()/2.0), Z#)
   DeleteVector3(tv1)
endfunction


// TransformCoordsVector3
function TransformCoordsVector3(resultvec, vsource, msource)

   X#=GetVector3X(vsource)
   Y#=GetVector3Y(vsource)
   Z#=GetVector3Z(vsource)
   nX#=X#*GetMatrix4Element(msource,1-1)+Y#*GetMatrix4Element(msource,5-1)+Z#*GetMatrix4Element(msource,9-1)+GetMatrix4Element(msource,13-1)
   nY#=X#*GetMatrix4Element(msource,2-1)+Y#*GetMatrix4Element(msource,6-1)+Z#*GetMatrix4Element(msource,10-1)+GetMatrix4Element(msource,14-1)
   nZ#=X#*GetMatrix4Element(msource,3-1)+Y#*GetMatrix4Element(msource,7-1)+Z#*GetMatrix4Element(msource,11-1)+GetMatrix4Element(msource,15-1)
   nW#=X#*GetMatrix4Element(msource,4-1)+Y#*GetMatrix4Element(msource,8-1)+Z#*GetMatrix4Element(msource,12-1)+GetMatrix4Element(msource,16-1)
   fr#=1.0/nW#
   SetVector3(resultvec, nX#*fr#, nY#*fr#, nZ#*fr#)
endfunction



// TransformNormalsVector3
function TransformNormalsVector3(resultvec, vsource, msource)

   X#=GetVector3X(vsource)
   Y#=GetVector3Y(vsource)
   Z#=GetVector3Z(vsource)
   nX#=X#*GetMatrix4Element(msource,1-1)+Y#*GetMatrix4Element(msource,5-1)+Z#*GetMatrix4Element(msource,9-1)
   nY#=X#*GetMatrix4Element(msource,2-1)+Y#*GetMatrix4Element(msource,6-1)+Z#*GetMatrix4Element(msource,10-1)
   nZ#=X#*GetMatrix4Element(msource,3-1)+Y#*GetMatrix4Element(msource,7-1)+Z#*GetMatrix4Element(msource,11-1)
   SetVector3(resultvec, nX#, nY#, nZ#)
endfunction

// normalize vector (from source to result)
	function normalizeVector3(vsource)
		
		d# = getVector3Length(vsource)
		
		 x# = GetVector3X(vsource) / d#
		 y# = GetVector3Y(vsource) / d#
		 z# = GetVector3Z(vsource) / d#
		
		SetVector3(vsource,x#,y#,z#) // update source vector
		
	endfunction 






// =================================================================================================================================
// =======================================   Vector 3 END   ========================================================================










// vector4 commands Library
// ========================


// create vector4
function CreateVector4()

			if Vector4.length=-1
			
				dim Vector4[] as Vector4_def
			
			endif

		// find free slot
		x = -1 
		repeat
		inc x
		if x>Vector4.length // if no slot exists, create a new one
			Vector4.length=Vector4.length+1	
			exit
		endif

		until Vector4[x].used=0
			
				out=x

			Vector4[out].used=1 // set used to 1

endfunction out

// delete vector4 (in1)
	function DeleteVector4(num)

		// Vector4.remove(num)
		Vector4[num].used=0
		Vector4[num].x=0.0
		Vector4[num].y=0.0
		Vector4[num].z=0.0
		Vector4[num].w=0.0



	endfunction



// Vector4 set (vec,x,y,z,w)
	function SetVector4(resultvec,x as float,y as float,z as float,w as float)
	
		Vector4[resultvec].x=x
		Vector4[resultvec].y=y
		Vector4[resultvec].z=z
		Vector4[resultvec].w=w

	endfunction
	
// PrintVector4
function PrintVector4(num)
	Print("Vector4: "+str(num)+" "+str(Vector4[num].x)+"|"+str(Vector4[num].y)+"|"+str(Vector4[num].z)+"|"+str(Vector4[num].w))
endfunction 



// Vector4 add (result,in1,in2)
	function AddVector4(resultvec,vec1,vec2)
	
		Vector4[resultvec].x=Vector4[vec1].x + Vector4[vec2].x
		Vector4[resultvec].y=Vector4[vec1].y + Vector4[vec2].y
		Vector4[resultvec].z=Vector4[vec1].z + Vector4[vec2].z
		Vector4[resultvec].w=Vector4[vec1].w + Vector4[vec2].w

	endfunction

// Vector4 substract substract vec2 from vec1 into resultvec
	function SubtractVector4(resultvec,vec1,vec2)
	
		Vector4[resultvec].x=Vector4[vec1].x - Vector4[vec2].x
		Vector4[resultvec].y=Vector4[vec1].y - Vector4[vec2].y
		Vector4[resultvec].z=Vector4[vec1].z - Vector4[vec2].z
		Vector4[resultvec].w=Vector4[vec1].w - Vector4[vec2].w

	endfunction



// get vector4 x
	function GetVector4X(vec)
		out# = Vector4[vec].x
	endfunction out#

// get vector4 y
	function GetVector4Y(vec)
		out# = Vector4[vec].y
	endfunction out#	

// get vector4 z
	function GetVector4Z(vec)
		out# = Vector4[vec].z
	endfunction out#

// get vector4 w
	function GetVector4W(vec)
		out# = Vector4[vec].w
	endfunction out#





// CatmullromVector4
function CatmullromVector4(resultvec, vec1, vec2, vec3, vec4, Value#)
   tv1=CreateVector4()
   tv2=CreateVector4()
   tv3=CreateVector4()
   tv4=CreateVector4()
	   XA#=GetVector4X(vec1)
	   YA#=GetVector4Y(vec1)
	   ZA#=GetVector4Z(vec1)
	   WA#=GetVector4W(vec1)
	   XB#=GetVector4X(vec2)
	   YB#=GetVector4Y(vec2)
	   ZB#=GetVector4Z(vec2)
	   WB#=GetVector4W(vec2)
	   XC#=GetVector4X(vec3)
	   YC#=GetVector4Y(vec3)
	   ZC#=GetVector4Z(vec3)
	   WC#=GetVector4W(vec3)
	   XD#=GetVector4X(vec4)
	   YD#=GetVector4Y(vec4)
	   ZD#=GetVector4Z(vec4)
	   WD#=GetVector4W(vec4)
	   SetVector4(tv1, XA#, YA#, ZA#, WA#)
	   SetVector4(tv2, XB#, YB#, ZB#, WB#)
	   SetVector4(tv3, XC#, YC#, ZC#, WC#)
	   SetVector4(tv4, XD#, YD#, ZD#, WD#)
	   MultiplyVector4(tv1, -1.0*Value#^3+2.0*Value#^2-Value#)
	   MultiplyVector4(tv2, 3.0*Value#^3-5.0*Value#^2+2.0)
	   MultiplyVector4(tv3, -3.0*Value#^3+4.0*Value#^2+Value#)
	   MultiplyVector4(tv4, Value#^3-Value#^2)
	   AddVector4(resultvec, tv1, tv2)
	   AddVector4(resultvec, resultvec, tv3)
	   AddVector4(resultvec, resultvec, tv4)
	   DivideVector4(resultvec, 2.0)
   DeleteVector4(tv1)
   DeleteVector4(tv2)
   DeleteVector4(tv3)
   DeleteVector4(tv4)
   
endfunction



// CopyVector4
function CopyVector4(resultvec, vsource)
	SetVector4(resultvec,GetVector4X(vsource),GetVector4Y(vsource),GetVector4Z(vsource),GetVector4W(vsource))
endfunction

// DivideVector4
function DivideVector4(resultvec, Value#)
	SetVector4(resultvec,GetVector4X(resultvec)/Value#,GetVector4Y(resultvec)/Value#,GetVector4Z(resultvec)/Value#,GetVector4W(resultvec)/Value#)
endfunction

// MultiplyVector4
function MultiplyVector4(resultvec, Value#)
	SetVector4(resultvec,GetVector4X(resultvec)*Value#,GetVector4Y(resultvec)*Value#,GetVector4Z(resultvec)*Value#,GetVector4W(resultvec)*Value#)
endfunction

// BCCVector4
function BCCVector4(resultvec, vec1, vec2, vec3, FValue#, GValue#)
   tv1=CreateVector4()
   tv2=CreateVector4()
	   SubtractVector4(tv1, vec2, vec1)
	   SubtractVector4(tv2, vec3, vec1)
	   MultiplyVector4(tv1, FValue#)
	   MultiplyVector4(tv2, GValue#)
	   AddVector4(resultvec, tv1, tv2)
	   AddVector4(resultvec, vec1, resultvec)
   DeleteVector4(tv1)
   DeleteVector4(tv2)
      
endfunction

// SquaredLengthVector4
function SquaredLengthVector4(vsource)
   X#=GetVector4X(vsource)
   Y#=GetVector4Y(vsource)
   Z#=GetVector4Z(vsource)
   W#=GetVector4W(vsource)
   Result#=X#*X#+Y#*Y#+Z#*Z#+W#*W#
endfunction Result#

// LengthVector4
function LengthVector4(vsource)
   Result#=SQRT(SquaredLengthVector4(vsource))
endfunction Result#


// HermiteVector4
function HermiteVector4(resultvec, vec1, vec2, vec3, vec4, Value#)
   tv1=CreateVector4()
   tv2=CreateVector4()
   tv3=CreateVector4()
   tv4=CreateVector4()
	   XA#=GetVector4X(vec1)
	   YA#=GetVector4Y(vec1)
	   ZA#=GetVector4Z(vec1)
	   WA#=GetVector4W(vec1)
	   XB#=GetVector4X(vec2)
	   YB#=GetVector4Y(vec2)
	   ZB#=GetVector4Z(vec2)
	   WB#=GetVector4W(vec2)
	   XC#=GetVector4X(vec3)
	   YC#=GetVector4Y(vec3)
	   ZC#=GetVector4Z(vec3)
	   WC#=GetVector4W(vec3)
	   XD#=GetVector4X(vec4)
	   YD#=GetVector4Y(vec4)
	   ZD#=GetVector4Z(vec4)
	   WD#=GetVector4W(vec4)
	   SetVector4(tv1, XA#, YA#, ZA#, WA#)
	   SetVector4(tv3, XB#, YB#, ZB#, WB#)
	   SetVector4(tv2, XC#, YC#, ZC#, WC#)
	   SetVector4(tv4, XD#, YD#, ZD#, WD#)
	   MultiplyVector4(tv1, 2.0*Value#^3-3.0*Value#^2+1.0)
	   MultiplyVector4(tv2, -2.0*Value#^3+3.0*Value#^2)
	   MultiplyVector4(tv3, Value#^3-2.0*Value#^2+Value#)
	   MultiplyVector4(tv4, Value#^3-Value#^2)
	   AddVector4(resultvec, tv1, tv2)
	   AddVector4(resultvec, resultvec, tv3)
	   AddVector4(resultvec, resultvec, tv4)
   DeleteVector4(tv1)
   DeleteVector4(tv2)
   DeleteVector4(tv3)
   DeleteVector4(tv4)
      
endfunction

// IsEqualVector4
function IsEqualVector4(vec1, vec2)
	If GetVector4X(vec1)<>GetVector4X(vec2) then exitfunction 0
	If GetVector4Y(vec1)<>GetVector4Y(vec2) then exitfunction 0
	If GetVector4Z(vec1)<>GetVector4Z(vec2) then exitfunction 0
	If GetVector4W(vec1)<>GetVector4W(vec2) then exitfunction 0	
endfunction 1

// LinearInterpolateVector4
function LinearInterpolateVector4(resultvec, vec1, vec2, Value#)
   SubtractVector4(resultvec, vec2, vec1)
   MultiplyVector4(resultvec, Value#)
   AddVector4(resultvec, resultvec, vec1)
endfunction





// MaximizeVector4
function MaximizeVector4(resultvec, vec1, vec2)
   XA#=GetVector4X(vec1)
   YA#=GetVector4Y(vec1)
   ZA#=GetVector4Z(vec1)
   WA#=GetVector4W(vec1)
   XB#=GetVector4X(vec2)
   YB#=GetVector4Y(vec2)
   ZB#=GetVector4Z(vec2)
   WB#=GetVector4W(vec2)
   If XA# > XB#
      MaxX#=XA#
   Else
      MaxX#=XB#
   EndIf
   If YA# > YB#
      MaxY#=YA#
   Else
      MaxY#=YB#
   EndIf
   If ZA# > ZB#
      MaxZ#=ZA#
   Else
      MaxZ#=ZB#
   EndIf
   If WA# > WB#
      MaxW#=WA#
   Else
      MaxW#=WB#
   EndIf
   SetVector4(resultvec, MaxX#, MaxY#, MaxZ#, MaxW#)
endfunction

// MinimizeVector4
function MinimizeVector4(resultvec, vec1, vec2)
   XA#=GetVector4X(vec1)
   YA#=GetVector4Y(vec1)
   ZA#=GetVector4Z(vec1)
   WA#=GetVector4W(vec1)
   XB#=GetVector4X(vec2)
   YB#=GetVector4Y(vec2)
   ZB#=GetVector4Z(vec2)
   WB#=GetVector4W(vec2)
   If XA# < XB#
      MinX#=XA#
   Else
      MinX#=XB#
   EndIf
   If YA# < YB#
      MinY#=YA#
   Else
      MinY#=YB#
   EndIf
   If ZA# < ZB#
      MinZ#=ZA#
   Else
      MinZ#=ZB#
   EndIf
   If WA# < WB#
      MinW#=WA#
   Else
      MinW#=WB#
   EndIf
   SetVector4(resultvec, MinX#, MinY#, MinZ#, MinW#)
endfunction

// NormalizeVector4
function NormalizeVector4(resultvec, vsource)
   Length#=LengthVector4(vsource)
   CopyVector4(resultvec, vsource)
   If Length# <> 1.0 Then DivideVector4(resultvec, Length#)
endfunction

// ScaleVector4
function ScaleVector4(resultvec, vsource, Value#)
   CopyVector4(resultvec, vsource)
   MultiplyVector4(resultvec, Value#)
endfunction

// TransformVector4
function TransformVector4(resultvec, vsource, msource)
   X#=GetVector4X(vsource)
   Y#=GetVector4Y(vsource)
   Z#=GetVector4Z(vsource)
   W#=GetVector4W(vsource)
   nX#=X#*GetMatrix4Element(msource,1-1)+Y#*GetMatrix4Element(msource,5-1)+Z#*GetMatrix4Element(msource,9-1)+W#*GetMatrix4Element(msource,13-1)
   nY#=X#*GetMatrix4Element(msource,2-1)+Y#*GetMatrix4Element(msource,6-1)+Z#*GetMatrix4Element(msource,10-1)+W#*GetMatrix4Element(msource,14-1)
   nZ#=X#*GetMatrix4Element(msource,3-1)+Y#*GetMatrix4Element(msource,7-1)+Z#*GetMatrix4Element(msource,11-1)+W#*GetMatrix4Element(msource,15-1)
   nW#=X#*GetMatrix4Element(msource,4-1)+Y#*GetMatrix4Element(msource,8-1)+Z#*GetMatrix4Element(msource,12-1)+W#*GetMatrix4Element(msource,16-1)
   SetVector4(resultvec, nX#, nY#, nZ#, nW#)
endfunction



// =================================================================================================================================
// =======================================   Vector 4 END   ========================================================================































// matrix4 commands Library
// ========================


// create matrix4 (creates a new slot in the matrix4 4x4 array)
	function CreateMatrix4()

		if Matrix4.length=-1	// if the matrix4 array is empty, create a new one

			dim Matrix4[] as Matrix4_def

		endif

	
		// find free slot
			x = -1 
			repeat
			inc x
			if x>Matrix4.length // if no slot exists, create a new one
				Matrix4.length=Matrix4.length+1	
				exit
			endif

			until Matrix4[x].used=0
	
		out=x

	Matrix4[out].used=1 // set used to 1
		


	endfunction out
	
// deletes matrix4 from the matrix4 array
	function DeleteMatrix4(num)

				// Vector4.remove(num)
		Matrix4[num].used=0
		
		Matrix4[num].x.x=0.0 : Matrix4[num].y.x=0.0 : Matrix4[num].z.x=0.0 : Matrix4[num].w.x=0.0	// 1	5	9	13
		Matrix4[num].x.y=0.0 : Matrix4[num].y.y=0.0 : Matrix4[num].z.y=0.0 : Matrix4[num].w.y=0.0	// 2	6	10	14
		Matrix4[num].x.z=0.0 : Matrix4[num].y.z=0.0 : Matrix4[num].z.z=0.0 : Matrix4[num].w.z=0.0	// 3	7	11	15
		Matrix4[num].x.w=0.0 : Matrix4[num].y.w=0.0 : Matrix4[num].z.w=0.0 : Matrix4[num].w.w=0.0	// 4	8	12	16
		
		
	endfunction

Function CopyMatrix4(resultmat, msource)
		Matrix4[resultmat].x.x=Matrix4[msource].x.x : Matrix4[resultmat].y.x=Matrix4[msource].y.x : Matrix4[resultmat].z.x=Matrix4[msource].z.x : Matrix4[resultmat].w.x=Matrix4[msource].w.x	// 1	5	9	13
		Matrix4[resultmat].x.y=Matrix4[msource].x.y : Matrix4[resultmat].y.y=Matrix4[msource].y.y : Matrix4[resultmat].z.y=Matrix4[msource].z.y : Matrix4[resultmat].w.y=Matrix4[msource].w.y	// 2	6	10	14
		Matrix4[resultmat].x.z=Matrix4[msource].x.z : Matrix4[resultmat].y.z=Matrix4[msource].y.z : Matrix4[resultmat].z.z=Matrix4[msource].z.z : Matrix4[resultmat].w.z=Matrix4[msource].w.z	// 3	7	11	15
		Matrix4[resultmat].x.w=Matrix4[msource].x.w : Matrix4[resultmat].y.w=Matrix4[msource].y.w : Matrix4[resultmat].z.w=Matrix4[msource].z.w : Matrix4[resultmat].w.w=Matrix4[msource].w.w	// 4	8	12	16
EndFunction

// set matrix4 element (ele = 0 to 15)
function SetMatrix4Element(mat,ele,value#)
		
		select ele
			
// x 
			case 0:
				Matrix4[mat].x.x = value#
			endcase

			case 1:
				Matrix4[mat].x.y = value#
			endcase

			case 2:
				Matrix4[mat].x.z = value#
			endcase			

			case 3:
				Matrix4[mat].x.w = value#
			endcase

// y 
			case 4:
				Matrix4[mat].y.x = value#
			endcase

			case 5:
				Matrix4[mat].y.y = value#
			endcase

			case 6:
				Matrix4[mat].y.z = value#
			endcase			

			case 7:
				Matrix4[mat].y.w = value#
			endcase

// z 
			case 8:
				Matrix4[mat].z.x = value#
			endcase

			case 9:
				Matrix4[mat].z.y = value#
			endcase

			case 10:
				Matrix4[mat].z.z = value#
			endcase			

			case 11:
				Matrix4[mat].z.w = value#
			endcase

// z 
			case 12:
				Matrix4[mat].w.x = value#
			endcase

			case 13:
				Matrix4[mat].w.y = value#
			endcase

			case 14:
				Matrix4[mat].w.z = value#
			endcase			

			case 15:
				Matrix4[mat].w.w = value#
			endcase
		
		endselect
		
	
endfunction

// get matrix4 element (ele = 0 to 15)
function GetMatrix4Element(mat,ele)
		
		select ele
			
// x 
			case 0:
				result# = Matrix4[mat].x.x
			endcase

			case 1:
				result# = Matrix4[mat].x.y
			endcase

			case 2:
				result# = Matrix4[mat].x.z
			endcase			

			case 3:
				result# = Matrix4[mat].x.w
			endcase

// y 
			case 4:
				result# = Matrix4[mat].y.x
			endcase

			case 5:
				result# = Matrix4[mat].y.y
			endcase

			case 6:
				result# = Matrix4[mat].y.z
			endcase			

			case 7:
				result# = Matrix4[mat].y.w
			endcase

// z 
			case 8:
				result# = Matrix4[mat].z.x
			endcase

			case 9:
				result# = Matrix4[mat].z.y
			endcase

			case 10:
				result# = Matrix4[mat].z.z
			endcase			

			case 11:
				result# = Matrix4[mat].z.w
			endcase

// z 
			case 12:
				result# = Matrix4[mat].w.x
			endcase

			case 13:
				result# = Matrix4[mat].w.y
			endcase

			case 14:
				result# = Matrix4[mat].w.z
			endcase			

			case 15:
				result# = Matrix4[mat].w.w
			endcase
		
		endselect
		
	
endfunction result#

// BuildLookAtLHMatrix4
function BuildLookAtLHMatrix4(resultmat, VectorEye, VectorAt, VectorUp)
   tv1=CreateVector3()
   tv2=CreateVector3()
   tv3=CreateVector3()
	   SubtractVector3(tv1, VectorAt, VectorEye)
	   NormalizeVector3(tv1)
	   GetVector3Cross(tv2, VectorUp, tv1)
	   NormalizeVector3(tv2)
	   GetVector3Cross(tv3, tv1, tv2)
		SetMatrix4Element(resultmat,0,GetVector3X(tv2))
		SetMatrix4Element(resultmat,1,GetVector3X(tv3))
		SetMatrix4Element(resultmat,2,GetVector3X(tv1))
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,GetVector3Y(tv2))
		SetMatrix4Element(resultmat,5,GetVector3Y(tv3))
		SetMatrix4Element(resultmat,6,GetVector3Y(tv1))
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,GetVector3Z(tv2))
		SetMatrix4Element(resultmat,9,GetVector3Z(tv3))
		SetMatrix4Element(resultmat,10,GetVector3Z(tv1))
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,-1.0*GetVector3Dot(tv2, VectorEye))
		SetMatrix4Element(resultmat,13,-1.0*GetVector3Dot(tv3, VectorEye))
		SetMatrix4Element(resultmat,14,-1.0*GetVector3Dot(tv1, VectorEye))
		SetMatrix4Element(resultmat,15,1.0)
   DeleteVector3(tv1)
   DeleteVector3(tv2)
   DeleteVector3(tv3)
endfunction

// BuildLookAtRHMatrix4
function BuildLookAtRHMatrix4(resultmat, VectorEye, VectorAt, VectorUp)
   tv1=CreateVector3()
   tv2=CreateVector3()
   tv3=CreateVector3()	
	   SubtractVector3(tv1, VectorEye, VectorAt)
	   NormalizeVector3(tv1)
	   GetVector3Cross(tv2, VectorUp, tv1)
	   NormalizeVector3(tv2)
	   GetVector3Cross(tv3, tv1, tv2)
		SetMatrix4Element(resultmat,0,GetVector3X(tv2))
		SetMatrix4Element(resultmat,1,GetVector3X(tv3))
		SetMatrix4Element(resultmat,2,GetVector3X(tv1))
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,GetVector3Y(tv2))
		SetMatrix4Element(resultmat,5,GetVector3Y(tv3))
		SetMatrix4Element(resultmat,6,GetVector3Y(tv1))
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,GetVector3Z(tv2))
		SetMatrix4Element(resultmat,9,GetVector3Z(tv3))
		SetMatrix4Element(resultmat,10,GetVector3Z(tv1))
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,-1.0*GetVector3Dot(tv2, VectorEye))
		SetMatrix4Element(resultmat,13,-1.0*GetVector3Dot(tv3, VectorEye))
		SetMatrix4Element(resultmat,14,-1.0*GetVector3Dot(tv1, VectorEye))
		SetMatrix4Element(resultmat,15,1.0)
   DeleteVector3(tv1)
   DeleteVector3(tv2)
   DeleteVector3(tv3)   
endfunction

// BuildOrthoLHMatrix4
function BuildOrthoLHMatrix4(resultmat, Width#, Height#, Near#, Far#)
		SetMatrix4Element(resultmat,0,2.0/Width#)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,2.0/Height#)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,1.0/(Far#-Near#))
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,1.0*Near#/(Near#-Far#))
		SetMatrix4Element(resultmat,15,1.0)
endfunction

// BuildOrthoRHMatrix4 
Function BuildOrthoRHMatrix4(resultmat, Width#, Height#, Near#, Far#)
		SetMatrix4Element(resultmat,0,2.0/Width#)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,2.0/Height#)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,1.0/(Far#-Near#))
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,1.0*Near#/(Near#-Far#))
		SetMatrix4Element(resultmat,15,1.0)
EndFunction

// BuildFOVLHMatrix4
function BuildFOVLHMatrix4(resultmat, FOV#, Aspect#, Near#, Far#)
   FOV#=FOV#/(Math_PI/180.0)
   Height#=1.0/Tan(FOV#/2.0)
   Width#=Height#/Aspect#
		SetMatrix4Element(resultmat,0,Width#)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,Height#)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,Far#/(Far#-Near#))
		SetMatrix4Element(resultmat,11,1.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,-1.0*Near#*(Far#/(Far#-Near#)))
		SetMatrix4Element(resultmat,15,0.0)
endfunction

// BuildFOVRHMatrix4
function BuildFOVRHMatrix4(resultmat, FOV#, Aspect#, Near#, Far#)
   FOV#=FOV#/(Math_PI/180.0)
   Height#=1.0/Tan(FOV#/2.0)
   Width#=Height#/Aspect#
		SetMatrix4Element(resultmat,0,Width#)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,Height#)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,1.0*Far#/(Near#-Far#))
		SetMatrix4Element(resultmat,11,-1.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,1.0*Near#*Far#/(Near#-Far#))
		SetMatrix4Element(resultmat,15,0.0)
endfunction

// BuildPerspectiveLHMatrix4
function BuildPerspectiveLHMatrix4(resultmat, Width#, Height#, Near#, Far#)
		SetMatrix4Element(resultmat,0,2.0*Near#/Width#)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,2.0*Near#/Height#)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,1.0*Far#/(Far#-Near#))
		SetMatrix4Element(resultmat,11,1.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,1.0*Near#*Far#/(Near#-Far#))
		SetMatrix4Element(resultmat,15,0.0)
endfunction

// BuildPerspectiveRHMatrix4
function BuildPerspectiveRHMatrix4(resultmat, Width#, Height#, Near#, Far#)
		SetMatrix4Element(resultmat,0,2.0*Near#/Width#)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,2.0*Near#/Height#)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,1.0*Far#/(Near#-Far#))
		SetMatrix4Element(resultmat,11,1.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,1.0*Near#*Far#/(Near#-Far#))
		SetMatrix4Element(resultmat,15,0.0)
endfunction

// BuildReflectionMatrix4
function BuildReflectionMatrix4(resultmat, PlaneA#, PlaneB#, PlaneC#, PlaneD#)
   tv1=CreateVector3()
	   SetVector3(tv1, PlaneA#, PlaneB#, PlaneC#)
	   PlaneD#=PlaneD#/GetVector3Length(tv1)
	   NormalizeVector3(tv1)
	   PlaneA#=GetVector3X(tv1)
	   PlaneB#=GetVector3Y(tv1)
	   PlaneC#=GetVector3Z(tv1)
		SetMatrix4Element(resultmat,0,-2.0*PlaneA#*PlaneA#+1.0)
		SetMatrix4Element(resultmat,1,-2.0*PlaneB#*PlaneA#)
		SetMatrix4Element(resultmat,2,-2.0*PlaneC#*PlaneA#)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,-2.0*PlaneA#*PlaneB#)
		SetMatrix4Element(resultmat,5,-2.0*PlaneB#*PlaneB#+1.0)
		SetMatrix4Element(resultmat,6,-2.0*PlaneC#*PlaneB#)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,-2.0*PlaneA#*PlaneC#)
		SetMatrix4Element(resultmat,9,-2.0*PlaneB#*PlaneC#)
		SetMatrix4Element(resultmat,10,-2.0*PlaneC#*PlaneC#+1.0)
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,-2.0*PlaneA#*PlaneD#)
		SetMatrix4Element(resultmat,13,-2.0*PlaneB#*PlaneD#)
		SetMatrix4Element(resultmat,14,-2.0*PlaneC#*PlaneD#)
		SetMatrix4Element(resultmat,15,1.0)
   DeleteVector3(tv1)
endfunction

// BuildRotationAxisMatrix4
function BuildRotationAxisMatrix4(resultmat, VectorAxis, Angle#)
   Angle#=Angle#/(Math_PI/180.0)
   Cos#=Cos(Angle#)
   Sin#=Sin(Angle#)
   t#=1.0-Cos#
   Length#=GetVector3Length(VectorAxis)
   U#=GetVector3X(VectorAxis)/Length#
   V#=GetVector3Y(VectorAxis)/Length#
   W#=GetVector3Z(VectorAxis)/Length#
		SetMatrix4Element(resultmat,0,Cos#+U#*U#*t#)
		SetMatrix4Element(resultmat,1,W#*Sin#+V#*U#*t#)
		SetMatrix4Element(resultmat,2,W#*U#*t#-V#*Sin#)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,U#*V#*t#-W#*Sin#)
		SetMatrix4Element(resultmat,5,Cos#+V#*V#*t#)
		SetMatrix4Element(resultmat,6,U#*Sin#+W#*V#*t#)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,V#*Sin#+U#*W#*t#)
		SetMatrix4Element(resultmat,9,V#*W#*t#-U#*Sin#)
		SetMatrix4Element(resultmat,10,Cos#+W#*W#*t#)
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,0.0)
		SetMatrix4Element(resultmat,15,1.0)
endfunction

// SetIdentityMatrix4
function SetIdentityMatrix4(resultmat)
		SetMatrix4Element(resultmat,0,1.0)
		SetMatrix4Element(resultmat,1,0.0)
		SetMatrix4Element(resultmat,2,0.0)
		SetMatrix4Element(resultmat,3,0.0)
		SetMatrix4Element(resultmat,4,0.0)
		SetMatrix4Element(resultmat,5,1.0)
		SetMatrix4Element(resultmat,6,0.0)
		SetMatrix4Element(resultmat,7,0.0)
		SetMatrix4Element(resultmat,8,0.0)
		SetMatrix4Element(resultmat,9,0.0)
		SetMatrix4Element(resultmat,10,1.0)
		SetMatrix4Element(resultmat,11,0.0)
		SetMatrix4Element(resultmat,12,0.0)
		SetMatrix4Element(resultmat,13,0.0)
		SetMatrix4Element(resultmat,14,0.0)
		SetMatrix4Element(resultmat,15,1.0)
endfunction

// IsEqualMatrix4
function IsEqualMatrix4(mata, matb)
   Result=1
   For I=0 To 15
      If GetMatrix4Element(mata,I)<>GetMatrix4Element(matb,I) Then Result=0
   Next I
endfunction Result

// IsIdentityMatrix4
function IsIdentityMatrix4(resultmat)
   m1=CreateMatrix4()
	   SetIdentityMatrix4(m1)
	   Result=IsEqualMatrix4(resultmat, m1)
   DeleteMatrix4(m1)
endfunction Result

// AddMatrix4
function AddMatrix4(resultmat, mata, matb)
   For I=0 To 15
	   SetMatrix4Element(resultmat,I,GetMatrix4Element(mata,I)+GetMatrix4Element(matb,I))
   Next I
endfunction

// SubtractMatrix4
function SubtractMatrix4(resultmat, mata, matb)
   For I=0 To 15
	   SetMatrix4Element(resultmat,I,GetMatrix4Element(mata,I)-GetMatrix4Element(matb,I))
   Next I
endfunction

// MultiplyMatrix4
function MultiplyMatrix4(resultmat, mata, matb)
   m1=CreateMatrix4()
	   SetMatrix4Element(m1,0,	Getmatrix4Element(mata, -1+1)*Getmatrix4Element(matb, -1+1)+Getmatrix4Element(mata, -1+2)*Getmatrix4Element(matb, -1+5)+Getmatrix4Element(mata, -1+3)*Getmatrix4Element(matb, -1+9)+Getmatrix4Element(mata, -1+4)*Getmatrix4Element(matb, -1+13)	)
	   SetMatrix4Element(m1,1,	Getmatrix4Element(mata, -1+1)*Getmatrix4Element(matb, -1+2)+Getmatrix4Element(mata, -1+2)*Getmatrix4Element(matb, -1+6)+Getmatrix4Element(mata, -1+3)*Getmatrix4Element(matb, -1+10)+Getmatrix4Element(mata, -1+4)*Getmatrix4Element(matb, -1+14)	)
	   SetMatrix4Element(m1,2,	Getmatrix4Element(mata, -1+1)*Getmatrix4Element(matb, -1+3)+Getmatrix4Element(mata, -1+2)*Getmatrix4Element(matb, -1+7)+Getmatrix4Element(mata, -1+3)*Getmatrix4Element(matb, -1+11)+Getmatrix4Element(mata, -1+4)*Getmatrix4Element(matb, -1+15)	)
	   SetMatrix4Element(m1,3,	Getmatrix4Element(mata, -1+1)*Getmatrix4Element(matb, -1+4)+Getmatrix4Element(mata, -1+2)*Getmatrix4Element(matb, -1+8)+Getmatrix4Element(mata, -1+3)*Getmatrix4Element(matb, -1+12)+Getmatrix4Element(mata, -1+4)*Getmatrix4Element(matb, -1+16)	)
	   SetMatrix4Element(m1,4,	Getmatrix4Element(mata, -1+5)*Getmatrix4Element(matb, -1+1)+Getmatrix4Element(mata, -1+6)*Getmatrix4Element(matb, -1+5)+Getmatrix4Element(mata, -1+7)*Getmatrix4Element(matb, -1+9)+Getmatrix4Element(mata, -1+8)*Getmatrix4Element(matb, -1+13)	)
	   SetMatrix4Element(m1,5,	Getmatrix4Element(mata, -1+5)*Getmatrix4Element(matb, -1+2)+Getmatrix4Element(mata, -1+6)*Getmatrix4Element(matb, -1+6)+Getmatrix4Element(mata, -1+7)*Getmatrix4Element(matb, -1+10)+Getmatrix4Element(mata, -1+8)*Getmatrix4Element(matb, -1+14)	)
	   SetMatrix4Element(m1,6,	Getmatrix4Element(mata, -1+5)*Getmatrix4Element(matb, -1+3)+Getmatrix4Element(mata, -1+6)*Getmatrix4Element(matb, -1+7)+Getmatrix4Element(mata, -1+7)*Getmatrix4Element(matb, -1+11)+Getmatrix4Element(mata, -1+8)*Getmatrix4Element(matb, -1+15)	)
	   SetMatrix4Element(m1,7,	Getmatrix4Element(mata, -1+5)*Getmatrix4Element(matb, -1+4)+Getmatrix4Element(mata, -1+6)*Getmatrix4Element(matb, -1+8)+Getmatrix4Element(mata, -1+7)*Getmatrix4Element(matb, -1+12)+Getmatrix4Element(mata, -1+8)*Getmatrix4Element(matb, -1+16)	)
	   SetMatrix4Element(m1,8,	Getmatrix4Element(mata, -1+9)*Getmatrix4Element(matb, -1+1)+Getmatrix4Element(mata, -1+10)*Getmatrix4Element(matb, -1+5)+Getmatrix4Element(mata, -1+11)*Getmatrix4Element(matb, -1+9)+Getmatrix4Element(mata, -1+12)*Getmatrix4Element(matb, -1+13)	)
	   SetMatrix4Element(m1,9,	Getmatrix4Element(mata, -1+9)*Getmatrix4Element(matb, -1+2)+Getmatrix4Element(mata, -1+10)*Getmatrix4Element(matb, -1+6)+Getmatrix4Element(mata, -1+11)*Getmatrix4Element(matb, -1+10)+Getmatrix4Element(mata, -1+12)*Getmatrix4Element(matb, -1+14)	)
	   SetMatrix4Element(m1,10, Getmatrix4Element(mata, -1+9)*Getmatrix4Element(matb, -1+3)+Getmatrix4Element(mata, -1+10)*Getmatrix4Element(matb, -1+7)+Getmatrix4Element(mata, -1+11)*Getmatrix4Element(matb, -1+11)+Getmatrix4Element(mata, -1+12)*Getmatrix4Element(matb, -1+15)	)
	   SetMatrix4Element(m1,11, Getmatrix4Element(mata, -1+9)*Getmatrix4Element(matb, -1+4)+Getmatrix4Element(mata, -1+10)*Getmatrix4Element(matb, -1+8)+Getmatrix4Element(mata, -1+11)*Getmatrix4Element(matb, -1+12)+Getmatrix4Element(mata, -1+12)*Getmatrix4Element(matb, -1+16)	)
	   SetMatrix4Element(m1,12, Getmatrix4Element(mata, -1+13)*Getmatrix4Element(matb, -1+1)+Getmatrix4Element(mata, -1+14)*Getmatrix4Element(matb, -1+5)+Getmatrix4Element(mata, -1+15)*Getmatrix4Element(matb, -1+9)+Getmatrix4Element(mata, -1+16)*Getmatrix4Element(matb, -1+13)	)
	   SetMatrix4Element(m1,13, Getmatrix4Element(mata, -1+13)*Getmatrix4Element(matb, -1+2)+Getmatrix4Element(mata, -1+14)*Getmatrix4Element(matb, -1+6)+Getmatrix4Element(mata, -1+15)*Getmatrix4Element(matb, -1+10)+Getmatrix4Element(mata, -1+16)*Getmatrix4Element(matb, -1+14)	)
	   SetMatrix4Element(m1,14, Getmatrix4Element(mata, -1+13)*Getmatrix4Element(matb, -1+3)+Getmatrix4Element(mata, -1+14)*Getmatrix4Element(matb, -1+7)+Getmatrix4Element(mata, -1+15)*Getmatrix4Element(matb, -1+11)+Getmatrix4Element(mata, -1+16)*Getmatrix4Element(matb, -1+15)	)
	   SetMatrix4Element(m1,15, Getmatrix4Element(mata, -1+13)*Getmatrix4Element(matb, -1+4)+Getmatrix4Element(mata, -1+14)*Getmatrix4Element(matb, -1+8)+Getmatrix4Element(mata, -1+15)*Getmatrix4Element(matb, -1+12)+Getmatrix4Element(mata, -1+16)*Getmatrix4Element(matb, -1+16) 	)
	   CopyMatrix4(resultmat, m1)
   DeleteMatrix4(m1)
endfunction

// MultiplyMatrix4ByValue
function MultiplyMatrix4ByValue(resultmat, Value#)
   For I=0 To 15
	   SetMatrix4Element(resultmat, I, GetMatrix4Element(resultmat, I) * Value#)
   Next I   
endfunction

// ScaleMatrix4
function ScaleMatrix4(resultmat, X#, Y#, Z#)
	SetIdentityMatrix4(resultmat)
	SetMatrix4Element(resultmat,1-1,X#)
	SetMatrix4Element(resultmat,6-1,Y#)
	SetMatrix4Element(resultmat,11-1,Z#)
endfunction

// TranslateMatrix4
function TranslateMatrix4(resultmat, X#, Y#, Z#)
   SetIdentityMatrix4(resultmat)
	SetMatrix4Element(resultmat,13-1,X#)
	SetMatrix4Element(resultmat,14-1,Y#)
	SetMatrix4Element(resultmat,15-1,Z#)
endfunction

// TransposeMatrix4
function TransposeMatrix4(resultmat, msource)
   tv1=CreateMatrix4()
		SetMatrix4Element(tv1,0,GetMatrix4Element(msource,1-1))
		SetMatrix4Element(tv1,1,GetMatrix4Element(msource,5-1))
		SetMatrix4Element(tv1,2,GetMatrix4Element(msource,9-1))
		SetMatrix4Element(tv1,3,GetMatrix4Element(msource,13-1))
		SetMatrix4Element(tv1,4,GetMatrix4Element(msource,2-1))
		SetMatrix4Element(tv1,5,GetMatrix4Element(msource,6-1))
		SetMatrix4Element(tv1,6,GetMatrix4Element(msource,10-1))
		SetMatrix4Element(tv1,7,GetMatrix4Element(msource,14-1))
		SetMatrix4Element(tv1,8,GetMatrix4Element(msource,3-1))
		SetMatrix4Element(tv1,9,GetMatrix4Element(msource,7-1))
		SetMatrix4Element(tv1,10,GetMatrix4Element(msource,11-1))
		SetMatrix4Element(tv1,11,GetMatrix4Element(msource,15-1))
		SetMatrix4Element(tv1,12,GetMatrix4Element(msource,4-1))
		SetMatrix4Element(tv1,13,GetMatrix4Element(msource,8-1))
		SetMatrix4Element(tv1,14,GetMatrix4Element(msource,12-1))
		SetMatrix4Element(tv1,15,GetMatrix4Element(msource,16-1))
	   CopyMatrix4(resultmat, tv1)
   DeleteMatrix4(tv1)
endfunction

// RotateYPRMatrix4
function RotateYPRMatrix4(resultmat, Yaw#, Pitch#, Roll#)
   Yaw#=Yaw#/(Math_PI/180.0)
   Pitch#=Pitch#/(Math_PI/180.0)
   Roll#=Roll#/(Math_PI/180.0)
   
   tv1=CreateMatrix4()
   SetIdentityMatrix4(tv1)
   tv2=CreateMatrix4()
   SetIdentityMatrix4(tv2)
   tv3=CreateMatrix4()
   SetIdentityMatrix4(tv3)
   tv4=CreateMatrix4()
   SetIdentityMatrix4(tv4)
	   CX#=Cos(Pitch#)
	   SX#=Sin(Pitch#)
	   CY#=Cos(Yaw#)
	   SY#=Sin(Yaw#)
	   CZ#=Cos(Roll#)
	   SZ#=Sin(Roll#)

		SetMatrix4Element(tv1,6-1,CX#)
		SetMatrix4Element(tv1,7-1,SX#)
		SetMatrix4Element(tv1,10-1,-1.0*SX#)
		SetMatrix4Element(tv1,11-1,CX#)

		SetMatrix4Element(tv2,1-1,CY#)
		SetMatrix4Element(tv2,3-1,-1.0*SY#)
		SetMatrix4Element(tv2,9-1,SY#)
		SetMatrix4Element(tv2,11-1,CY#)

		SetMatrix4Element(tv3,1-1,CZ#)
		SetMatrix4Element(tv3,2-1,SZ#)
		SetMatrix4Element(tv3,5-1,-1.0*SZ#)
		SetMatrix4Element(tv3,6-1,CZ#)
   
	   MultiplyMatrix4(tv4, tv3, tv1)
	   MultiplyMatrix4(resultmat, tv4, tv2)
   DeleteMatrix4(tv1)
   DeleteMatrix4(tv2)
   DeleteMatrix4(tv3)
   DeleteMatrix4(tv4)
   
endfunction

// RotateXMatrix4
function RotateXMatrix4(resultmat, Angle#)
   Angle#=Angle#/(Math_PI/180.0)
   SetIdentityMatrix4(resultmat)
	SetMatrix4Element(resultmat,6-1,Cos(Angle#))
	SetMatrix4Element(resultmat,7-1,Sin(Angle#))
	SetMatrix4Element(resultmat,10-1,-1.0*Sin(Angle#))
	SetMatrix4Element(resultmat,11-1,Cos(Angle#))
endfunction

// RotateYMatrix4
function RotateYMatrix4(resultmat, Angle#)
   Angle#=Angle#/(Math_PI/180.0)
   SetIdentityMatrix4(resultmat)
	SetMatrix4Element(resultmat,1-1,Cos(Angle#))
	SetMatrix4Element(resultmat,3-1,-1.0*Sin(Angle#))
	SetMatrix4Element(resultmat,9-1,Sin(Angle#))
	SetMatrix4Element(resultmat,11-1,Cos(Angle#))
endfunction

// RotateZMatrix4
function RotateZMatrix4(resultmat, Angle#)
   Angle#=Angle#/(Math_PI/180.0)
   SetIdentityMatrix4(resultmat)
	SetMatrix4Element(resultmat,1-1,Cos(Angle#))
	SetMatrix4Element(resultmat,2-1,Sin(Angle#))
	SetMatrix4Element(resultmat,5-1,-1.0*Sin(Angle#))
	SetMatrix4Element(resultmat,6-1,Cos(Angle#))
endfunction

// WorldMatrix4
function WorldMatrix4(resultmat)
   SetIdentityMatrix4(resultmat)
endfunction

// ViewMatrix4
function ViewMatrix4(resultmat)
   CX#=Cos(GetCameraAngleX(1))
   SX#=Sin(GetCameraAngleX(1))
   CY#=Cos(GetCameraAngleY(1))
   SY#=Sin(GetCameraAngleY(1))
   CZ#=Cos(GetCameraAngleZ(1))
   SZ#=Sin(GetCameraAngleZ(1))
   tv1=CreateVector3()
   tv2=CreateVector3()
   tv3=CreateVector3()
	   SetVector3(tv1, GetCameraX(1), GetCameraY(1), GetCameraZ(1))
	   SetVector3(tv2, -1.0*SZ#*(-1.0*SX#)+CZ#*SY#*CX#+GetCameraX(1), CZ#*(-1.0*SX#)+SZ#*SY#*CX#+GetCameraY(1), CY#*CX#+GetCameraZ(1))
	   SetVector3(tv3, -1.0*SZ#*CX#+CZ#*SY#*SX#, CZ#*CX#+SZ#*SY#*SX#, CY#*SX#)
	   BuildLookAtLHMatrix4(resultmat, tv1, tv2, tv3)
   DeleteVector3(tv1)
   DeleteVector3(tv2)
   DeleteVector3(tv3)
   
endfunction

// ProjectionMatrix4
function ProjectionMatrix4(resultmat)
   BuildFOVLHMatrix4(resultmat, 61.962139129638672*(Math_PI/180.0), (GetVirtualWidth()*1.0)/(GetVirtualHeight()*1.0), 1.0, 3000.0)
endfunction

// DeterminantMatrix4
function DeterminantMatrix4(msource)
   I#=1.0
   tv1=CreateMatrix4()
	   For N=1 To 4
		  SubMatrix3(tv1, msource, 1, N)
		  Determinant#=DeterminantMatrix3(tv1)
		  Result#=Result#+GetMatrix4Element(msource, N-1)*Determinant#*I#
		  I#=-1.0*I#
	   Next N
   DeleteMatrix4(tv1)
   
endfunction Result#

// DeterminantMatrix3
function DeterminantMatrix3(msource)
Result#=GetMatrix4Element(msource,1-1) * ((GetMatrix4Element(msource, 6-1)*GetMatrix4Element(msource, 11-1))-(GetMatrix4Element(msource, 7-1)*GetMatrix4Element(msource, 10-1)))
Result#=Result#-GetMatrix4Element(msource,2-1) * ((GetMatrix4Element(msource, 5-1)*GetMatrix4Element(msource, 11-1))-(GetMatrix4Element(msource, 7-1)*GetMatrix4Element(msource, 9-1)))
Result#=Result#+GetMatrix4Element(msource,3-1) * ((GetMatrix4Element(msource, 5-1)*GetMatrix4Element(msource, 10-1))-(GetMatrix4Element(msource, 6-1)*GetMatrix4Element(msource, 9-1)))
endfunction Result#

// SubMatrix3
function SubMatrix3(resultmat, msource, I, J)
   SetIdentityMatrix4(resultmat)
   For DI=0 To 2
      For DJ=0 To 2
         If DI >= I-1
            SI=DI+1
         Else
            SI=DI
         EndIf
         If DJ >= J-1
            SJ=DJ+1
         Else
            SJ=DJ
         EndIf
         SetMatrix4Element(resultmat, 1+DI*4+DJ-1,GetMatrix4Element(msource, 1+SI*4+SJ-1))
      NeXt DJ
   Next DI
endfunction 1

// InverseMatrix4
function InverseMatrix4(resultmat, msource)
   tv1=CreateMatrix4()
   tv2=CreateMatrix4()
	   MDet#=DeterminantMatrix4(msource)
	   If Abs(MDet#) < 0.0005
		  SetIdentityMatrix4(resultmat)
		  exitfunction 0
	   EndIf
	   For I=0 To 3
		  For J=0 To 3
			 If ((I+J)/2.0-Abs((I+J)/2)) > 0.0
				Sign#=-1.0
			 Else
				Sign#=1.0
			 EndIf
			 SubMatrix3(tv2, msource, I+1, J+1)
			 m3det#=DeterminantMatrix3(tv2)
			 SetMatrix4Element(tv1,1+I+J*4-1,(m3det#*Sign#)/MDet#)
		  Next J
	   Next I
   CopyMatrix4(resultmat, tv1)
   DeleteMatrix4(tv1)
   DeleteMatrix4(tv2)
endfunction 1

// DivideMatrix4
function DivideMatrix4(resultmat, Value#)
   For I=0 To 15
      SetMatrix4Element(resultmat, I,GetMatrix4Element(resultmat, I)/Value#)
   Next I
endfunction



// tween math library
// ==================

// Hermite - This method will interpolate while easing in and out at the limits.
function Hermite( startValue as float, endValue as float, value as float)
    result# = Lerp(startValue, endValue, value * value * (3.0 - 2.0 * value))
endfunction result#


// Sinerp - Short for 'sinusoidal interpolation', this method will interpolate while easing around the end, when value is near one.
function Sinerp( startValue as float, endValue as float, value as float)
    result# = Lerp( startValue, endValue, sin(value * Math_PI * 0.5))
endfunction result#


// Coserp - Similar to Sinerp, except it eases in, when value is near zero, instead of easing out (and uses cosine instead of sine).
function Coserp( startValue as float, endValue as float, value as float)
    result# = Lerp(startValue, endValue, 1.0 - cos(value * Math_PI * 0.5))
endfunction result#


// Bounce - Returns a value between 0 and 1 that can be used to easily make bouncing GUI items (a la OS X's Dock)
function Bounce(x as float)
    result# =  abs(sin(6.28*(x+1)*(x+1)) * (1-x))
endFunction result#


// Berp - Short for 'boing-like interpolation', this method will first overshoot, then waver back and forth around the end value before coming to a rest.
function Berp( startValue as float, endValue as float , value as float )
    value = Clamp(0, 1, value)
    value = (sin(value * Math_PI * (0.2 + 2.5 * value * value * value)) * Pow(1.0 - value, 2.2) + value) * (1.0 + (1.2 * (1.0 - value)))
    result# = startValue + (endValue - startValue) * value
endfunction result#


// Lerp - Short for 'linearly interpolate'
function Lerp( startValue as float, endValue as float , value as float )
    result# = ((1.0 - value) * startValue) + (value * endValue)
endfunction result#


// SmoothStep - Works like Lerp, but has ease-in and ease-out of the values.
function SmoothStep( x as float, min as float, max as float)
        x = Clamp (x, min, max)
        v1# = (x-min)/(max-min)
        v2# = (x-min)/(max-min)
        result# = -2*v1# * v1# *v1# + 3*v2# * v2#
endfunction result#


// Approx - Check for a value that is close enough to the target (floating point inprecision)
function Approx( value as float, target as float, range as float)
    result = (( abs(value - target) < range) )
endfunction result

// Clerp (Circular lerp) is like a lerp but handles the wrap-around from 0-360)
function Clerp( startValue as float, endValue as float, value as float )
        min# = 0.0
        max# = 360.0
        half# = abs((max# - min#)/2.0)
        retval# = 0.0
        diff# = 0.0
 
        if (endValue - startValue) < -half#
            diff = ((max# - startValue) + endValue) * value
            retval# =  startValue + diff#
        elseif (endValue - startValue) > half#
            diff# = -((max# - endValue) + startValue) * value
            retval# =  startValue + diff#
        else
            retval# = startValue + (endValue - startValue) * value
        endif
endfunction retval#



// Clamp - forces a value to remain within the constraints of min and max
function Clamp( min as float, max as float, value as float)
    if value < min then exitfunction min
    if value > max then exitfunction max
endfunction value
 




// various math commands
// =====================

// this function will convert an euler angle to a radian angle
	function radian(eul#)

		out# = eul# * 180 / Math_PI // conversion to degrees
		if( out# < 0 ) then out# = out# + 360.0 // convert negative to positive angles
		
	endfunction out#