Code archives/3D Graphics - Maths/BMax Math Lib v3.0

This code has been declared by its author to be Public Domain code.

Download source code

BMax Math Lib v3.0 by Chroma2007
This math lib is a drastic speed increase over previous libs. I've done extensive speed testing in massive loops and went with the fastest method every time. Creating and returning a local type inside a method is very inefficient and slow. I gained about a 60-100% speed increase by eliminating it. Give this math lib a shot, you'll notice the difference.

Updating Matrix soon and throwing in some other advanced functions for good measure.

Please post any errors or bugs.

Fixed 2 errors. Thanks for pointing em out.
' BMax Math Lib v3.0
' by Chroma


' Internal Math Vars - Do Not Alter
Const Tol:Float = 0.0001
Global vTmp:TVector3 = New TVector3
Global qTmp:TQuaternion = New TQuaternion


'	----------
'	----------
'	----------


' Vector Class

Type TVector3

	Field x:Double, y:Double, z:Double
	
'	----------
	
	'Example1: v1:TVector3 = TVector3.Create(1,2,3)
	Function Create:TVector3(x:Double = 0, y:Double = 0, z:Double = 0)
		Local v:TVector3 = New TVector3
		v.x = x
		v.y = y
		v.z = z
		Return v
	End Function
	
	'Example1: v.Set(1,2,3)
	Method Set(x:Double = 0, y:Double = 0, z:Double = 0)
		self.x = x
		self.y = y
		self.z = z
	End Method

'	----------

	'Example: v1 = v1 + v2 is written v1.Add( v1, v2 )
	Method Add(a:TVector3, b:TVector3)
		self.x = a.x + b.x
		self.y = a.y + b.y
		self.z = a.z + b.z
	End Method

	'Example: v1 = v2 + 5 is written v1.AddScalar( v2, 5 )
	Method AddScalar(a:TVector3, s:Double)
		self.x = a.x + s
		self.y = a.y + s
		self.z = a.z + s
	End Method

'	----------

	'Example: v1 = v2 - v3 is written v1.Sub( v2, v3 )
	Method Sub(a:TVector3, b:TVector3)
		self.x = a.x - b.x
		self.y = a.y - b.y
		self.z = a.z - b.z
	End Method
	
	'Example: v1 = v2 - 5 is written v1.SubScalar( v2, 5 )
	Method SubScalar(a:TVector3, s:Double)
		self.x = a.x - s
		self.y = a.y - s
		self.z = a.z - s
	End Method

'	----------

	'Example: v1 = v2 * v3 is written v1.Mul( v2, v3 )
	Method Mul(a:TVector3, b:TVector3)
		self.x = a.x * b.x
		self.y = a.y * b.y
		self.z = a.z * b.z
	End Method

	'Example: v1 = v2 * 5 is written v1.MulScalar( v2, 5 )
	Method MulScalar(a:TVector3, s:Double)
		self.x = a.x * s
		self.y = a.y * s
		self.z = a.z * s
	End Method

'	----------

	'Example: v1 = v2 / v3 is written v1.Div( v2, v3 )
	Method Div(a:TVector3, b:TVector3)
		self.x = a.x / b.x
		self.y = a.y / b.y
		self.z = a.z / b.z
	End Method

	'Example: v1 = v2 / 5 is written v1.DivScalar( v2, 5 )
	Method DivScalar(a:TVector3, s:Double)
		self.x = a.x / s
		self.y = a.y / s
		self.z = a.z / s
	End Method

'	----------
	
	'Example: mag:Double = v.Magnitude()
	Method Magnitude:Double()
		Return Sqr(self.x * self.x + self.y * self.y + self.z * self.z)
	End Method
	
	'Example: v.Normalize()
	Method Normalize()
		Local mag:Double = self.Magnitude()
		self.x :/ mag
		self.y :/ mag
		self.z :/ mag
		If Abs(self.x) < Tol self.x = 0
		If Abs(self.y) < Tol self.y = 0
		If Abs(self.z) < Tol self.z = 0
	End Method
	
'	----------

	'Example: v1 = v2 ^ v3 is written v1.CrossProduct( v2, v3 )
	Method CrossProduct(a:TVector3, b:TVector3)
		self.x =  a.y * b.z - a.z * b.y
		self.y = -a.x * b.z + a.z * b.x
		self.z =  a.x * b.y - a.y * b.x
	EndMethod

	'Example1: dotp:double = v1.DotProduct( v2 )
	Method DotProduct:Double( a:TVector3 )
		Return self.x * a.x + self.y * a.y + self.z * a.z
	End Method

'	----------
	
	'Returns Inverse Instance of a Vector
	Method Inverse:TVector3()
		vTmp.x = -self.x
		vTmp.y = -self.y
		vTmp.z = -self.z
		Return vTmp
	End Method

	' Example: v.GetVecFromQuat( q )
	Method GetVecFromQuat(a:TQuaternion)
		self.x = a.x
		self.y = a.y
		self.z = a.z
	End Method

	'Example: v.MakeEulerFromQuat( q )
	Method MakeEulerFromQuat(q:TQuaternion)
		Local	r11#, r21#, r31#, r32#, r33#, r12#, r13#
		Local	q00#, q11#, q22#, q33#
		Local	tmp#
	
		q00 = q.n * q.n
		q11 = q.x * q.x
		q22 = q.y * q.y
		q33 = q.z * q.z
	
		r11 = q00 + q11 - q22 - q33
		r21 = 2 * (q.x*q.y + q.n*q.z)
		r31 = 2 * (q.x*q.z - q.n*q.y)
		r32 = 2 * (q.y*q.z + q.n*q.x)
		r33 = q00 - q11 - q22 + q33
	
		tmp = Abs(r31)
		If (tmp > 0.999999)
			r12 = 2 * (q.x*q.y - q.n*q.z)
			r13 = 2 * (q.x*q.z + q.n*q.y)
	
			self.x = RadiansToDegrees(0.0)							' roll
			self.y = RadiansToDegrees( Float (-(Pi/2) * r31/tmp))	' pitch
			self.z = RadiansToDegrees( Float ATan2(-r12, -r31*r13))' yaw
		Else
			self.x = RadiansToDegrees( Float ATan2(r32, r33))		' roll
			self.y = RadiansToDegrees( Float ASin(-r31))			' pitch
			self.z = RadiansToDegrees( Float ATan2(r21, r11))		' yaw
		EndIf
	End Method

'	----------

	'Example: vPos.AddTimeStep( vVel, dt )
	Method AddTimeStep(a:TVector3, timestep:Float)
		self.x :+ a.x * timestep
		self.y :+ a.y * timestep
		self.z :+ a.z * timestep
	End Method

	'Example: vVel.AddGravity(  , dt )
	Method AddGravity(g:Float = 9.8, timestep:Float)
		self.y :- g * timestep
	End Method

	'Example1: v.Show("v",5,5)
	Method Show(cap:String, xpos:Int, ypos:Int, spc:Int = 12)
		DrawText cap + "_x:" + self.x,xpos,ypos
		DrawText cap + "_y:" + self.y,xpos,ypos + spc
		DrawText cap + "_z:" + self.z,xpos,ypos + spc * 2
	End Method

End Type


'	----------
'	----------
'	----------


' Quaternion Class

Type TQuaternion

	Field n:Double, x:Double, y:Double, z:Double
	
'	----------
	
	Function Create:TQuaternion(n:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)
		Local q:TQuaternion = New TQuaternion
		q.n = n
		q.x = x
		q.y = y
		q.z = z
		Return q
	End Function

'	----------

	' Example: q1=q2+q3 would be q1.Add( q2, q3 )
	Method Add(a:TQuaternion, b:TQuaternion)
		self.n = a.n + b.n
		self.x = a.x + b.x
		self.y = a.y + b.y
		self.z = a.z + b.z
	End Method

'	----------

	' Example: q1=q2-q3 would be q1.Sub( q2, q3 )
	Method Sub(a:TQuaternion, b:TQuaternion)
		self.n = a.n - b.n
		self.x = a.x - b.x
		self.y = a.y - b.y
		self.z = a.z - b.z
	End Method

'	----------

	' Example: q1=q2*q3 would be q1.Mul( q2, q3 )
	Method Mul(a:TQuaternion, b:TQuaternion)
		self.n = a.n * b.n - a.x * b.x - a.y * b.y - a.z * b.z
		self.x = a.n * b.x + a.x * b.n + a.y * b.z - a.z * b.y
		self.y = a.n * b.y + a.y * b.n + a.z * b.x - a.x * b.z
		self.z = a.n * b.y + a.y * b.n + a.z * b.x - a.x * b.z
	End Method

	' Example: q1=q2*2 would be q1.MulScalar( q2, 2 )
	Method MulScalar( a:TQuaternion, s:Double )
		self.n = a.n * s
		self.x = a.x * s
		self.y = a.y * s
		self.z = a.z * s
	End Method
	
'	----------
	
	' Example: q1=q2/2 would be q1.DivS( q2, 2 )
	Method DivScalar(a:TQuaternion, s:Double )
		self.n = a.n / s
		self.x = a.x / s
		self.y = a.y / s
		self.z = a.z / s
	End Method
	
'	----------

	' Example: Local qmag:Double = q.Magnitude()
	Method Magnitude:Double( a:TQuaternion )
		Return Sqr( a.n * a.n + a.x * a.x + a.y * a.y + a.z * a.z )
	End Method

'	----------

	'Returns Inverse Instance of a Quaternion
	Method Inverse:TQuaternion()
		qTmp.n =  self.n
		qTmp.x = -self.x
		qTmp.y = -self.y
		qTmp.z = -self.z
		Return qTmp
	End Method

'	----------

	'Example: q.MakeQuatFromEuler( pitch, yaw, roll )
	Method MakeQuatFromEuler(x:Float, y:Float, z:Float)
		Local roll:Float = DegreesToRadians(x)
		Local pitch:Float = DegreesToRadians(y)
		Local yaw:Float = DegreesToRadians(z)
		
		Local cyaw#, cpitch#, croll#, syaw#, spitch#, sroll#
		Local cyawcpitch#, syawspitch#, cyawspitch#, syawcpitch#

		cyaw = Cos(0.5 * yaw)
		cpitch = Cos(0.5 * pitch)
		croll = Cos(0.5 * roll)
		syaw = Sin(0.5 * yaw)
		spitch = Sin(0.5 * pitch)
		sroll = Sin(0.5 * roll)
	
		cyawcpitch = cyaw*cpitch
		syawspitch = syaw*spitch
		cyawspitch = cyaw*spitch
		syawcpitch = syaw*cpitch

		self.n = Float (cyawcpitch * croll + syawspitch * sroll)
		self.x = Float (cyawcpitch * sroll - syawspitch * croll) 
		self.y = Float (cyawspitch * croll + syawcpitch * sroll)
		self.z = Float (syawcpitch * croll - cyawspitch * sroll)
	End Method

'	----------


	Method Show(cap:String = "", xpos:Int, ypos:Int, spc:Int = 12)
		DrawText cap + "_w:" + self.n,xpos,ypos
		DrawText cap + "_x:" + self.x,xpos,ypos + spc 
		DrawText cap + "_y:" + self.y,xpos,ypos + spc * 2
		DrawText cap + "_z:" + self.z,xpos,ypos + spc * 3
	End Method

End Type



'	----------
'	----------
'	----------

' Matrix Class

Type TMatrix

	Field e11:Double, e12:Double, e13:Double
	Field e21:Double, e22:Double, e23:Double
	Field e31:Double, e32:Double, e33:Double

'	----------

	Function Create:TMatrix(e11!=0, e12!=0, e13!=0, e21!=0, e22!=0, e23!=0, e31!=0, e32!=0, e33!=0)
		Local m:TMatrix = New TMatrix
		m.e11 = e11
		m.e12 = e12
		m.e13 = e13
		m.e21 = e21
		m.e22 = e22
		m.e23 = e23
		m.e31 = e31
		m.e32 = e32
		m.e33 = e33
		Return m
	End Function
	
'	----------


'	----------


End Type


'	----------
'	----------
'	----------


' Degrees To Radians Conversion
Function DegreesToRadians:Float(deg:Float)
	Return deg * Pi / 180.0
End Function

' Radians To Degrees Conversion
Function RadiansToDegrees:Float(rad:Float)
	Return rad * 180.0 / Pi
End Function

Comments

DaMaul2007
Hi, this is great :)
But could you delete the old version as I managed to discover that before this!


DaMaul2007
By the way, I believe there's a couple of small errors in this.
This line:
Function Create:TQuaternion(w:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)
Should be:
Function Create:TQuaternion(n:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)

And also the line ( in the method "AddGravity" ):
self.y :- g * time_step
Should be:
self.y :- g * timestep

Cheers!


bradford62007
very nice.
Question: Would using Floats instead of Doubles increase speed?


DJWoodgate2007
Yes, but not by much.


Code Archives Forum