November 25, 2020, 05:33:00 AM

Author Topic: [bmx] BMax Math Lib v3.0 by Chroma [ 1+ years ago ]  (Read 595 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] BMax Math Lib v3.0 by Chroma [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : BMax Math Lib v3.0
Author : Chroma
Posted : 1+ years ago

Description : 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.


Code :
Code: BlitzMax
  1. ' BMax Math Lib v3.0
  2. ' by Chroma
  3.  
  4.  
  5. ' Internal Math Vars - Do Not Alter
  6. Const Tol:Float = 0.0001
  7. Global vTmp:TVector3 = New TVector3
  8. Global qTmp:TQuaternion = New TQuaternion
  9.  
  10.  
  11. '       ----------
  12. '       ----------
  13. '       ----------
  14.  
  15.  
  16. ' Vector Class
  17.  
  18. Type TVector3
  19.  
  20.         Field x:Double, y:Double, z:Double
  21.        
  22. '       ----------
  23.        
  24.         'Example1: v1:TVector3 = TVector3.Create(1,2,3)
  25.         Function Create:TVector3(x:Double = 0, y:Double = 0, z:Double = 0)
  26.                 Local v:TVector3 = New TVector3
  27.                 v.x = x
  28.                 v.y = y
  29.                 v.z = z
  30.                 Return v
  31.         End Function
  32.        
  33.         'Example1: v.Set(1,2,3)
  34.         Method Set(x:Double = 0, y:Double = 0, z:Double = 0)
  35.                 self.x = x
  36.                 self.y = y
  37.                 self.z = z
  38.         End Method
  39.  
  40. '       ----------
  41.  
  42.         'Example: v1 = v1 + v2 is written v1.Add( v1, v2 )
  43.         Method Add(a:TVector3, b:TVector3)
  44.                 self.x = a.x + b.x
  45.                 self.y = a.y + b.y
  46.                 self.z = a.z + b.z
  47.         End Method
  48.  
  49.         'Example: v1 = v2 + 5 is written v1.AddScalar( v2, 5 )
  50.         Method AddScalar(a:TVector3, s:Double)
  51.                 self.x = a.x + s
  52.                 self.y = a.y + s
  53.                 self.z = a.z + s
  54.         End Method
  55.  
  56. '       ----------
  57.  
  58.         'Example: v1 = v2 - v3 is written v1.Sub( v2, v3 )
  59.         Method Sub(a:TVector3, b:TVector3)
  60.                 self.x = a.x - b.x
  61.                 self.y = a.y - b.y
  62.                 self.z = a.z - b.z
  63.         End Method
  64.        
  65.         'Example: v1 = v2 - 5 is written v1.SubScalar( v2, 5 )
  66.         Method SubScalar(a:TVector3, s:Double)
  67.                 self.x = a.x - s
  68.                 self.y = a.y - s
  69.                 self.z = a.z - s
  70.         End Method
  71.  
  72. '       ----------
  73.  
  74.         'Example: v1 = v2 * v3 is written v1.Mul( v2, v3 )
  75.         Method Mul(a:TVector3, b:TVector3)
  76.                 self.x = a.x * b.x
  77.                 self.y = a.y * b.y
  78.                 self.z = a.z * b.z
  79.         End Method
  80.  
  81.         'Example: v1 = v2 * 5 is written v1.MulScalar( v2, 5 )
  82.         Method MulScalar(a:TVector3, s:Double)
  83.                 self.x = a.x * s
  84.                 self.y = a.y * s
  85.                 self.z = a.z * s
  86.         End Method
  87.  
  88. '       ----------
  89.  
  90.         'Example: v1 = v2 / v3 is written v1.Div( v2, v3 )
  91.         Method Div(a:TVector3, b:TVector3)
  92.                 self.x = a.x / b.x
  93.                 self.y = a.y / b.y
  94.                 self.z = a.z / b.z
  95.         End Method
  96.  
  97.         'Example: v1 = v2 / 5 is written v1.DivScalar( v2, 5 )
  98.         Method DivScalar(a:TVector3, s:Double)
  99.                 self.x = a.x / s
  100.                 self.y = a.y / s
  101.                 self.z = a.z / s
  102.         End Method
  103.  
  104. '       ----------
  105.        
  106.         'Example: mag:Double = v.Magnitude()
  107.         Method Magnitude:Double()
  108.                 Return Sqr(self.x * self.x + self.y * self.y + self.z * self.z)
  109.         End Method
  110.        
  111.         'Example: v.Normalize()
  112.         Method Normalize()
  113.                 Local mag:Double = self.Magnitude()
  114.                 self.x :/ mag
  115.                 self.y :/ mag
  116.                 self.z :/ mag
  117.                 If Abs(self.x) < Tol self.x = 0
  118.                 If Abs(self.y) < Tol self.y = 0
  119.                 If Abs(self.z) < Tol self.z = 0
  120.         End Method
  121.        
  122. '       ----------
  123.  
  124.         'Example: v1 = v2 ^ v3 is written v1.CrossProduct( v2, v3 )
  125.         Method CrossProduct(a:TVector3, b:TVector3)
  126.                 self.x =  a.y * b.z - a.z * b.y
  127.                 self.y = -a.x * b.z + a.z * b.x
  128.                 self.z =  a.x * b.y - a.y * b.x
  129.         EndMethod
  130.  
  131.         'Example1: dotp:double = v1.DotProduct( v2 )
  132.         Method DotProduct:Double( a:TVector3 )
  133.                 Return self.x * a.x + self.y * a.y + self.z * a.z
  134.         End Method
  135.  
  136. '       ----------
  137.        
  138.         'Returns Inverse Instance of a Vector
  139.         Method Inverse:TVector3()
  140.                 vTmp.x = -self.x
  141.                 vTmp.y = -self.y
  142.                 vTmp.z = -self.z
  143.                 Return vTmp
  144.         End Method
  145.  
  146.         ' Example: v.GetVecFromQuat( q )
  147.         Method GetVecFromQuat(a:TQuaternion)
  148.                 self.x = a.x
  149.                 self.y = a.y
  150.                 self.z = a.z
  151.         End Method
  152.  
  153.         'Example: v.MakeEulerFromQuat( q )
  154.         Method MakeEulerFromQuat(q:TQuaternion)
  155.                 Local   r11#, r21#, r31#, r32#, r33#, r12#, r13#
  156.                 Local   q00#, q11#, q22#, q33#
  157.                 Local   tmp#
  158.        
  159.                 q00 = q.n * q.n
  160.                 q11 = q.x * q.x
  161.                 q22 = q.y * q.y
  162.                 q33 = q.z * q.z
  163.        
  164.                 r11 = q00 + q11 - q22 - q33
  165.                 r21 = 2 * (q.x*q.y + q.n*q.z)
  166.                 r31 = 2 * (q.x*q.z - q.n*q.y)
  167.                 r32 = 2 * (q.y*q.z + q.n*q.x)
  168.                 r33 = q00 - q11 - q22 + q33
  169.        
  170.                 tmp = Abs(r31)
  171.                 If (tmp > 0.999999)
  172.                         r12 = 2 * (q.x*q.y - q.n*q.z)
  173.                         r13 = 2 * (q.x*q.z + q.n*q.y)
  174.        
  175.                         self.x = RadiansToDegrees(0.0)                                                  ' roll
  176.                         self.y = RadiansToDegrees( Float (-(Pi/2) * r31/tmp))   ' pitch
  177.                         self.z = RadiansToDegrees( Float ATan2(-r12, -r31*r13))' yaw
  178.                 Else
  179.                         self.x = RadiansToDegrees( Float ATan2(r32, r33))               ' roll
  180.                         self.y = RadiansToDegrees( Float ASin(-r31))                    ' pitch
  181.                         self.z = RadiansToDegrees( Float ATan2(r21, r11))               ' yaw
  182.                 EndIf
  183.         End Method
  184.  
  185. '       ----------
  186.  
  187.         'Example: vPos.AddTimeStep( vVel, dt )
  188.         Method AddTimeStep(a:TVector3, timestep:Float)
  189.                 self.x :+ a.x * timestep
  190.                 self.y :+ a.y * timestep
  191.                 self.z :+ a.z * timestep
  192.         End Method
  193.  
  194.         'Example: vVel.AddGravity(  , dt )
  195.         Method AddGravity(g:Float = 9.8, timestep:Float)
  196.                 self.y :- g * timestep
  197.         End Method
  198.  
  199.         'Example1: v.Show("v",5,5)
  200.         Method Show(cap:String, xpos:Int, ypos:Int, spc:Int = 12)
  201.                 DrawText cap + "_x:" + self.x,xpos,ypos
  202.                 DrawText cap + "_y:" + self.y,xpos,ypos + spc
  203.                 DrawText cap + "_z:" + self.z,xpos,ypos + spc * 2
  204.         End Method
  205.  
  206. End Type
  207.  
  208.  
  209. '       ----------
  210. '       ----------
  211. '       ----------
  212.  
  213.  
  214. ' Quaternion Class
  215.  
  216. Type TQuaternion
  217.  
  218.         Field n:Double, x:Double, y:Double, z:Double
  219.        
  220. '       ----------
  221.        
  222.         Function Create:TQuaternion(n:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)
  223.                 Local q:TQuaternion = New TQuaternion
  224.                 q.n = n
  225.                 q.x = x
  226.                 q.y = y
  227.                 q.z = z
  228.                 Return q
  229.         End Function
  230.  
  231. '       ----------
  232.  
  233.         ' Example: q1=q2+q3 would be q1.Add( q2, q3 )
  234.         Method Add(a:TQuaternion, b:TQuaternion)
  235.                 self.n = a.n + b.n
  236.                 self.x = a.x + b.x
  237.                 self.y = a.y + b.y
  238.                 self.z = a.z + b.z
  239.         End Method
  240.  
  241. '       ----------
  242.  
  243.         ' Example: q1=q2-q3 would be q1.Sub( q2, q3 )
  244.         Method Sub(a:TQuaternion, b:TQuaternion)
  245.                 self.n = a.n - b.n
  246.                 self.x = a.x - b.x
  247.                 self.y = a.y - b.y
  248.                 self.z = a.z - b.z
  249.         End Method
  250.  
  251. '       ----------
  252.  
  253.         ' Example: q1=q2*q3 would be q1.Mul( q2, q3 )
  254.         Method Mul(a:TQuaternion, b:TQuaternion)
  255.                 self.n = a.n * b.n - a.x * b.x - a.y * b.y - a.z * b.z
  256.                 self.x = a.n * b.x + a.x * b.n + a.y * b.z - a.z * b.y
  257.                 self.y = a.n * b.y + a.y * b.n + a.z * b.x - a.x * b.z
  258.                 self.z = a.n * b.y + a.y * b.n + a.z * b.x - a.x * b.z
  259.         End Method
  260.  
  261.         ' Example: q1=q2*2 would be q1.MulScalar( q2, 2 )
  262.         Method MulScalar( a:TQuaternion, s:Double )
  263.                 self.n = a.n * s
  264.                 self.x = a.x * s
  265.                 self.y = a.y * s
  266.                 self.z = a.z * s
  267.         End Method
  268.        
  269. '       ----------
  270.        
  271.         ' Example: q1=q2/2 would be q1.DivS( q2, 2 )
  272.         Method DivScalar(a:TQuaternion, s:Double )
  273.                 self.n = a.n / s
  274.                 self.x = a.x / s
  275.                 self.y = a.y / s
  276.                 self.z = a.z / s
  277.         End Method
  278.        
  279. '       ----------
  280.  
  281.         ' Example: Local qmag:Double = q.Magnitude()
  282.         Method Magnitude:Double( a:TQuaternion )
  283.                 Return Sqr( a.n * a.n + a.x * a.x + a.y * a.y + a.z * a.z )
  284.         End Method
  285.  
  286. '       ----------
  287.  
  288.         'Returns Inverse Instance of a Quaternion
  289.         Method Inverse:TQuaternion()
  290.                 qTmp.n =  self.n
  291.                 qTmp.x = -self.x
  292.                 qTmp.y = -self.y
  293.                 qTmp.z = -self.z
  294.                 Return qTmp
  295.         End Method
  296.  
  297. '       ----------
  298.  
  299.         'Example: q.MakeQuatFromEuler( pitch, yaw, roll )
  300.         Method MakeQuatFromEuler(x:Float, y:Float, z:Float)
  301.                 Local roll:Float = DegreesToRadians(x)
  302.                 Local pitch:Float = DegreesToRadians(y)
  303.                 Local yaw:Float = DegreesToRadians(z)
  304.                
  305.                 Local cyaw#, cpitch#, croll#, syaw#, spitch#, sroll#
  306.                 Local cyawcpitch#, syawspitch#, cyawspitch#, syawcpitch#
  307.  
  308.                 cyaw = Cos(0.5 * yaw)
  309.                 cpitch = Cos(0.5 * pitch)
  310.                 croll = Cos(0.5 * roll)
  311.                 syaw = Sin(0.5 * yaw)
  312.                 spitch = Sin(0.5 * pitch)
  313.                 sroll = Sin(0.5 * roll)
  314.        
  315.                 cyawcpitch = cyaw*cpitch
  316.                 syawspitch = syaw*spitch
  317.                 cyawspitch = cyaw*spitch
  318.                 syawcpitch = syaw*cpitch
  319.  
  320.                 self.n = Float (cyawcpitch * croll + syawspitch * sroll)
  321.                 self.x = Float (cyawcpitch * sroll - syawspitch * croll)
  322.                 self.y = Float (cyawspitch * croll + syawcpitch * sroll)
  323.                 self.z = Float (syawcpitch * croll - cyawspitch * sroll)
  324.         End Method
  325.  
  326. '       ----------
  327.  
  328.  
  329.         Method Show(cap:String = "", xpos:Int, ypos:Int, spc:Int = 12)
  330.                 DrawText cap + "_w:" + self.n,xpos,ypos
  331.                 DrawText cap + "_x:" + self.x,xpos,ypos + spc
  332.                 DrawText cap + "_y:" + self.y,xpos,ypos + spc * 2
  333.                 DrawText cap + "_z:" + self.z,xpos,ypos + spc * 3
  334.         End Method
  335.  
  336. End Type
  337.  
  338.  
  339.  
  340. '       ----------
  341. '       ----------
  342. '       ----------
  343.  
  344. ' Matrix Class
  345.  
  346. Type TMatrix
  347.  
  348.         Field e11:Double, e12:Double, e13:Double
  349.         Field e21:Double, e22:Double, e23:Double
  350.         Field e31:Double, e32:Double, e33:Double
  351.  
  352. '       ----------
  353.  
  354.         Function Create:TMatrix(e11!=0, e12!=0, e13!=0, e21!=0, e22!=0, e23!=0, e31!=0, e32!=0, e33!=0)
  355.                 Local m:TMatrix = New TMatrix
  356.                 m.e11 = e11
  357.                 m.e12 = e12
  358.                 m.e13 = e13
  359.                 m.e21 = e21
  360.                 m.e22 = e22
  361.                 m.e23 = e23
  362.                 m.e31 = e31
  363.                 m.e32 = e32
  364.                 m.e33 = e33
  365.                 Return m
  366.         End Function
  367.        
  368. '       ----------
  369.  
  370.  
  371. '       ----------
  372.  
  373.  
  374. End Type
  375.  
  376.  
  377. '       ----------
  378. '       ----------
  379. '       ----------
  380.  
  381.  
  382. ' Degrees To Radians Conversion
  383. Function DegreesToRadians:Float(deg:Float)
  384.         Return deg * Pi / 180.0
  385. End Function
  386.  
  387. ' Radians To Degrees Conversion
  388. Function RadiansToDegrees:Float(rad:Float)
  389.         Return rad * 180.0 / Pi
  390. End Function


Comments :


DaMaul(Posted 1+ years ago)

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


DaMaul(Posted 1+ years ago)

 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_stepShould be:self.y :- g * timestepCheers!


bradford6(Posted 1+ years ago)

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


DJWoodgate(Posted 1+ years ago)

 Yes, but not by much.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal