July 27, 2021, 23:23:04

Author Topic: [bmx] Cower.Math3D by N [ 1+ years ago ]  (Read 993 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Cower.Math3D by N [ 1+ years ago ]
« on: June 29, 2017, 00:28:39 »
Title : Cower.Math3D
Author : N
Posted : 1+ years ago

Description : Place this under mod/cower.mod/math3d.mod/math3d.bmx

Have fun.


Code :
Code: BlitzMax
  1. Rem
  2.         This software is written by Noel R. Cower
  3.         <hooker.with.a.penis@gmail.com>
  4.        
  5.         Copyright (C) 2005 Noel Raymond Cower
  6. EndRem
  7.  
  8. Rem bbdoc: 3D Maths
  9. EndRem
  10. Module Cower.Math3D
  11.  
  12. Import Brl.Math
  13.  
  14. Strict
  15.  
  16. Private
  17.  
  18. Const RAD_TO_DEGREE! = 180!/Pi
  19. Const DEGREE_TO_RAD! = Pi/180!
  20.  
  21. Public
  22.  
  23. Rem bbdoc: Converts degrees to radians
  24. End Rem
  25. Function DegreeToRad!( d! )
  26.         Return d*DEGREE_TO_RAD
  27. End Function
  28.  
  29. Rem bbdoc: Converts radians to degrees
  30. End Rem
  31. Function RadToDegree!( r! )
  32.         Return r*RAD_TO_DEGREE
  33. End Function
  34.  
  35. Rem bbdoc: Gets the cotangent of an angle
  36. End Rem
  37. Function Cotangent!( A! )
  38.         Return Tan( 90! - A )
  39. End Function
  40.  
  41. Rem bbdoc: Gets the nearest power of two to an integer
  42. End Rem
  43. Function NearestPower:Int( i:Int )
  44.         Local q:Int,r:Int=1
  45.         While Not ( i < r And i > q )
  46.                 q=r
  47.                 r=q*2
  48.         Wend
  49.         Local da:Int=i-q
  50.         Local db:Int=r-i
  51.         If da > db Then
  52.                 Return r
  53.         Else
  54.                 Return q
  55.         EndIf
  56. End Function
  57.  
  58. Rem bbdoc: Gets the slope of two points
  59. End Rem
  60. Function Slope!( x1!, y1!, x2!, y2! )
  61.         Local m! = ( y1-y2 )/( x1-x2 )
  62.         If m <= .0001! And m > 0! Then Return .0001!
  63.         If m >= -.0001! And m < 0! Then Return -.0001!
  64.         Return m
  65. End Function
  66.  
  67. Rem bbdoc: Gets the Y intercept of two points
  68. End Rem
  69. Function YIntercept!( x1!, y1!, x2!, y2! )
  70.         Return y1 - ( Slope( x1, y1, x2, y2 ) * x1 )
  71. End Function
  72.  
  73. Rem bbdoc: Gets the Y value of X along the line made by two points
  74. End Rem
  75. Function ReturnedY!( x!, x1!, y1!, x2!, y2! )
  76.         Return Slope( x1, y1, x2, y2 ) * x + YIntercept( x1, y1, x2, y2 )
  77. End Function
  78.  
  79. Rem bbdoc: 4-by-4 homogenous matrix class
  80. about:
  81. Keep in mind that aside from Translate and Scale, all methods
  82. will return a new matrix with the requested operations performed.
  83. End Rem
  84. Type Matrix
  85.         Field m00! = 1, m01! = 0, m02! = 0, m03! = 0
  86.         Field m10! = 0, m11! = 1, m12! = 0, m13! = 0
  87.         Field m20! = 0, m21! = 0, m22! = 1, m23! = 0
  88.         Field m30! = 0, m31! = 0, m32! = 0, m33! = 1
  89.        
  90.         Rem bbdoc: Copies the Matrix class
  91.         End Rem
  92.         Method Copy:Matrix( )
  93.                 Local i:Matrix = New Matrix
  94.                 MemCopy( Varptr i.m00, Varptr m00, 64 )
  95.                 Return i
  96.         End Method
  97.        
  98.         Rem bbdoc: Sets the translation elements of the matrix
  99.         End Rem
  100.         Method Translate( x!, y!, z! )
  101.                 m03 = x
  102.                 m13 = y
  103.                 m23 = z
  104.         End Method
  105.        
  106.         Rem bbdoc: Gets the translation elements of the matrix
  107.         End Rem
  108.         Method GetTranslation( x! Var, y! Var, z! Var )
  109.                 x = m03
  110.                 y = m13
  111.                 z = m23
  112.         End Method
  113.        
  114.         Rem bbdoc: Scales the rotation elements of the matrix
  115.         End Rem
  116.         Method Scale( x!, y!, z! )
  117.                 m00 :* x
  118.                 m10 :* x
  119.                 m20 :* x
  120.                
  121.                 m01 :* y
  122.                 m11 :* y
  123.                 m21 :* y
  124.                
  125.                 m02 :* z
  126.                 m12 :* z
  127.                 m22 :* z
  128.         End Method
  129.        
  130.         Rem bbdoc: Transforms the matrix by another matrix
  131.         End Rem
  132.         Method TransformMat:Matrix( i:Matrix )
  133.                 Local r:Matrix = New Matrix
  134.                
  135.                 r.m00 = m00 * i.m00 + m01 * i.m10 + m02 * i.m20 + m03 * i.m30
  136.                 r.m01 = m00 * i.m01 + m01 * i.m11 + m02 * i.m21 + m03 * i.m31
  137.                 r.m02 = m00 * i.m02 + m01 * i.m12 + m02 * i.m22 + m03 * i.m32
  138.                 r.m03 = m00 * i.m03 + m01 * i.m13 + m02 * i.m23 + m03 * i.m33
  139.                
  140.                 r.m10 = m10 * i.m00 + m11 * i.m10 + m12 * i.m20 + m13 * i.m30
  141.                 r.m11 = m10 * i.m01 + m11 * i.m11 + m12 * i.m21 + m13 * i.m31
  142.                 r.m12 = m10 * i.m02 + m11 * i.m12 + m12 * i.m22 + m13 * i.m32
  143.                 r.m13 = m10 * i.m03 + m11 * i.m13 + m12 * i.m23 + m13 * i.m33
  144.                
  145.                 r.m20 = m20 * i.m00 + m21 * i.m10 + m22 * i.m20 + m23 * i.m30
  146.                 r.m21 = m20 * i.m01 + m21 * i.m11 + m22 * i.m21 + m23 * i.m31
  147.                 r.m22 = m20 * i.m02 + m21 * i.m12 + m22 * i.m22 + m23 * i.m32
  148.                 r.m23 = m20 * i.m03 + m21 * i.m13 + m22 * i.m23 + m23 * i.m33
  149.                
  150.                 r.m30 = m30 * i.m00 + m31 * i.m10 + m32 * i.m20 + m33 * i.m30
  151.                 r.m31 = m30 * i.m01 + m31 * i.m11 + m32 * i.m21 + m33 * i.m31
  152.                 r.m32 = m30 * i.m02 + m31 * i.m12 + m32 * i.m22 + m33 * i.m32
  153.                 r.m33 = m30 * i.m03 + m31 * i.m13 + m32 * i.m23 + m33 * i.m33
  154.                
  155.                 Return r
  156.         End Method
  157.        
  158.         Rem bbdoc: Transforms a vector by the matrix
  159.         End Rem
  160.         Method TransformVec:Vector3( i:Vector3, addTranslation:Int = 0 )
  161.                 Local r:Vector3 = New Vector3
  162.                 Local w! = 1.0/( m30 + m31 + m32 + m33 )
  163.                
  164.                 addTranslation = Min( Max( addTranslation, 0 ), 1 )
  165.                
  166.                 r.x = ( ( m00*i.x ) + ( m01*i.y ) + ( m02*i.z ) + m03 * addTranslation ) * w
  167.                 r.y = ( ( m10*i.x ) + ( m11*i.y ) + ( m12*i.z ) + m13 * addTranslation ) * w
  168.                 r.z = ( ( m20*i.x ) + ( m21*i.y ) + ( m22*i.z ) + m23 * addTranslation ) * w
  169.                
  170.                 Return r
  171.         End Method
  172.        
  173.         Rem bbdoc: Adds two matrices
  174.         End Rem
  175.         Method Add:Matrix( i:Matrix )
  176.                 Local a:Double Ptr = GetPtr( )
  177.                 Local b:Double Ptr = GetPtr( )
  178.                 Local r:Matrix = New Matrix
  179.                 Local c:Double Ptr = r.GetPtr( )
  180.                 For Local n:Int = 0 To 15
  181.                         c[n]=a[n]+b[n]
  182.                 Next
  183.                 Return r
  184.         End Method
  185.        
  186.         Rem bbdoc: Subtracts two matrices
  187.         End Rem
  188.         Method Subtract:Matrix( i:Matrix )
  189.          Local a:Double Ptr = GetPtr( )
  190.                 Local b:Double Ptr = GetPtr( )
  191.                 Local r:Matrix = New Matrix
  192.                 Local c:Double Ptr = r.GetPtr( )
  193.                 For Local n:Int = 0 To 15
  194.                         c[n]=a[n]-b[n]
  195.                 Next
  196.                 Return r
  197.         End Method
  198.        
  199.         Rem bbdoc: Transposes the matrix
  200.         End Rem
  201.         Method Transpose:Matrix( )
  202.          Local x:Int,y:Int
  203.          Local r:Matrix = New Matrix
  204.          Local a:Double Ptr = GetPtr( )
  205.          Local b:Double Ptr = r.GetPtr( )
  206.          For x = 0 To 3
  207.                  For y = 0 To 3
  208.                          b[x*4+y] = a[y*4+x]
  209.                  Next
  210.          Next
  211.          Return r
  212.         End Method
  213.        
  214.         Rem bbdoc: Returns a pointer to the first matrix element
  215.         End Rem
  216.         Method GetPtr:Double Ptr( )
  217.                 Return Varptr m00
  218.         End Method
  219.        
  220.         Rem bbdoc: Returns an array made from the elements of the matrix
  221.         End Rem
  222.         Method ToArray:Double[]( )
  223.                 Local r:Double[16]
  224.                 MemCopy( Varptr r[0], GetPtr( ), 64 )
  225.                 Return r
  226.         End Method
  227.        
  228.         Rem bbdoc: Creates a matrix from an array of Doubles
  229.         End Rem
  230.         Function FromArray:Matrix( arr:Double[] )
  231.                 Return FromPtr( Varptr arr[0] )
  232.         End Function
  233.        
  234.         Rem bbdoc: Creates an array from a pointer to an array of Doubles
  235.         End Rem
  236.         Function FromPtr:Matrix( arr:Double Ptr )
  237.                 Local r:Matrix = New Matrix
  238.                 Local p:Double Ptr = r.GetPtr( )
  239.                 MemCopy( p, arr, 64 )
  240.                 Return r
  241.         End Function
  242. End Type
  243.  
  244. Rem bbdoc: Three-component vector class
  245. about:
  246. Keep in mind that aside from Dot, Magnitude, Normalize, Floor, and Ceil,
  247. all methods will return a new Vector3 with the requested operations performed.
  248. End Rem
  249. Type Vector3
  250.         Rem bbdoc: X component
  251.         End Rem
  252.         Field x!
  253.         Rem bbdoc: Y component
  254.         End Rem
  255.         Field y!
  256.         Rem bbdoc: Z component
  257.         End Rem
  258.         Field z!
  259.        
  260.         Rem bbdoc: Adds a vector
  261.         End Rem
  262.         Method Add:Vector3( i:Vector3 )
  263.                 Local r:Vector3 = New Vector3
  264.                 r.x = x+i.x
  265.                 r.y = y+i.y
  266.                 r.z = z+i.z
  267.                 Return r
  268.         End Method
  269.        
  270.         Rem bbdoc: Subtracts a vector
  271.         End Rem
  272.         Method Subtract:Vector3( i:Vector3 )
  273.                 Local r:Vector3 = New Vector3
  274.                 r.x = x-i.x
  275.                 r.y = y-i.y
  276.                 r.z = z-i.z
  277.                 Return r
  278.         End Method
  279.        
  280.         Rem bbdoc: Multiplies a vector with another vector
  281.         End Rem
  282.         Method Multiply:Vector3( i:Vector3 )
  283.                 Local r:Vector3 = New Vector3
  284.                 r.x = x*i.x
  285.                 r.y = y*i.y
  286.                 r.z = z*i.z
  287.                 Return r
  288.         End Method
  289.        
  290.         Rem bbdoc: Divides a vector by another vector
  291.         End Rem
  292.         Method Divide:Vector3( i:Vector3 )
  293.                 Local r:Vector3 = New Vector3
  294.                 r.x = x/i.x
  295.                 r.y = y/i.y
  296.                 r.z = z/i.z
  297.                 Return r
  298.         End Method
  299.        
  300.         Rem bbdoc: Scales a vector by a scalar
  301.         End Rem
  302.         Method Scale:Vector3( i:Double )
  303.                 Local r:Vector3 = New Vector3
  304.                 r.x = x*i
  305.                 r.y = y*i
  306.                 r.z = z*i
  307.                 Return r
  308.         End Method
  309.        
  310.         Rem bbdoc: Gets the dot product of two vectors (Self and another)
  311.         End Rem
  312.         Method Dot:Double( i:Vector3 )
  313.                 Return x*i.x+y*i.y+z*i.z
  314.         End Method
  315.        
  316.         Rem bbdoc: Gets the magnitude of the vector
  317.         End Rem
  318.         Method Magnitude:Double( )
  319.                 Return Sqr( x*x + y*y + z*z )
  320.         End Method
  321.        
  322.         Rem bbdoc: Normalizes the vector
  323.         End Rem
  324.         Method Normalize( )
  325.                 Local s:Double = 1.0 / Magnitude( )
  326.                 x:*s
  327.                 y:*s
  328.                 z:*s
  329.         End Method
  330.        
  331.         Rem bbdoc: Gets the cross product of two vectors (Self and another)
  332.         End Rem
  333.         Method Cross:Vector3( i:Vector3 )
  334.                 Local r:Vector3 = New Vector3
  335.                 r.x = y*i.z - z*i.y
  336.                 r.y = x*i.z - z*i.x
  337.                 r.z = x*i.y - y*i.x
  338.                 Return r
  339.         End Method
  340.        
  341.         Rem bbdoc: Returns a reflection vector
  342.         End Rem
  343.         Method Reflect:Vector3( i:Vector3 )
  344.                 Local f:Double = 2*Dot( i )
  345.                 Return Subtract( i.Scale( f ) )
  346.         End Method
  347.        
  348.         Rem bbdoc: Returns a quaternion containing the rotation between two vectors
  349.         End Rem
  350.         Method RotationTo:Quaternion( dest:Vector3 )
  351.                 ' Based on the Axiom engine's Vector3.GetRotationTo method code
  352.                 ' Which is in turn based on Stan Melax's article in Game Programming Gems
  353.                 Local q:Quaternion = New Quaternion
  354.                
  355.                 Local v0:Vector3 = Vector3.Create( x, y, z )
  356.                 Local v1:Vector3 = New Vector3
  357.          
  358.                 Local c:Vector3 = v0.Cross( v1 )
  359.                 Local d:Double = v0.Dot( v1 )
  360.                
  361.                 If d >= 1.0 Then Return New Quaternion
  362.          
  363.                 Local s:Double = Sqr( ( 1+d ) * 2 )
  364.                 Local inverse:Double = 1.0 / s
  365.                
  366.                 q.x = c.x * inverse
  367.                 q.y = c.y * inverse
  368.                 q.z = c.z * inverse
  369.                 q.w = s*.5
  370.          
  371.                 Return q
  372.         End Method
  373.        
  374.         Rem bbdoc: Floors a vector
  375.         End Rem
  376.         Method Floor( i:Vector3 )
  377.                 If i.x < x Then x = i.x
  378.                 If i.y < y Then y = i.y
  379.                 If i.z < z Then z = i.z
  380.         End Method
  381.        
  382.         Rem bbdoc: Ceils a vector
  383.         End Rem
  384.         Method Ceil( i:Vector3 )
  385.                 If i.x > x Then x = i.x
  386.                 If i.y > y Then y = i.y
  387.                 If i.z > z Then z = i.z
  388.         End Method
  389.        
  390.         Rem bbdoc: Returns a pointer to the first component of the vector
  391.         End Rem
  392.         Method GetPtr:Double Ptr( )
  393.                 Return Varptr x
  394.         End Method
  395.        
  396.         Rem bbdoc: Converts the vector to a Double array
  397.         End Rem
  398.         Method ToArray:Double[]( )
  399.                 Local r:Double[3]
  400.                 MemCopy( Varptr r[0], GetPtr( ), 12 )
  401.                 Return r
  402.         End Method
  403.        
  404.         Rem bbdoc: Copies the Vector3 class
  405.         End Rem
  406.         Method Copy:Vector3( )
  407.                 Local i:Vector3 = New Vector3
  408.                 MemCopy( i.GetPtr( ), GetPtr( ), 12 )
  409.                 Return i
  410.         End Method
  411.        
  412.         Rem bbdoc: Creates a new vector
  413.         End Rem
  414.         Function Create:Vector3( x!, y!, z! )
  415.                 Local i:Vector3 = New Vector3
  416.                 i.x = x
  417.                 i.y = y
  418.                 i.z = z
  419.                 Return i
  420.         End Function
  421.        
  422.         Rem bbdoc: Creates a vector from an array of Doubles
  423.         End Rem
  424.         Function FromArray:Vector3( arr:Double[] )
  425.                 Return FromPtr( Varptr arr[0] )
  426.         End Function
  427.        
  428.         Rem bbdoc: Creates a vector from a pointer to a Double array
  429.         End Rem
  430.         Function FromPtr:Vector3( arr:Double Ptr )
  431.                 Local r:Vector3 = New Vector3
  432.                 Local p:Double Ptr = r.GetPtr( )
  433.                 MemCopy( p, arr, 12 )
  434.                 Return r
  435.         End Function
  436. End Type
  437.  
  438. Rem bbdoc: Quaternion class.
  439. about:
  440. A lot of code in this class is based off of that in the
  441. <a href="http://www.axiom3d.org">Axiom engine</a>.<br/><br/>
  442. Aside from Magnitude, Normalize, and Dot, all methods will
  443. return a new Quaternion with the requested operations performed.
  444. End Rem
  445. Type Quaternion
  446.         Rem bbdoc: W component
  447.         End Rem
  448.         Field w!=1
  449.         Rem bbdoc: X component
  450.         End Rem
  451.         Field x!=0
  452.         Rem bbdoc: Y component
  453.         End Rem
  454.         Field y!=0
  455.         Rem bbdoc: Z component
  456.         End Rem
  457.         Field z!=0
  458.        
  459.         Rem bbdoc: Gets the magnitude of the quaternion
  460.         End Rem
  461.         Method Magnitude:Double( )
  462.                 Return Sqr( w*w + x*x + y*y + z*z )
  463.         End Method
  464.        
  465.         Rem bbdoc: Normalizes a quaternion
  466.         End Rem
  467.         Method Normalize( )
  468.                 Local s:Double = 1.0 / Magnitude( )
  469.                 w:*s
  470.                 x:*s
  471.                 y:*s
  472.                 z:*s
  473.         End Method
  474.        
  475.         Rem bbdoc: Multiplies a quaternion
  476.         End Rem
  477.         Method MultiplyQuat:Quaternion( i:Quaternion )
  478.                 Local r:Quaternion = New Quaternion
  479.                
  480.                 r.w = w*i.w - x*i.x - y*i.y - z*i.z
  481.                 r.x = w*i.x - x*i.w - y*i.z - z*i.y
  482.                 r.y = w*i.y - y*i.w - z*i.x - x*i.z
  483.                 r.z = w*i.z - z*i.w - x*i.y - y*i.x
  484.                
  485.                 Return r
  486.         End Method
  487.        
  488.         Rem bbdoc: Multiplies a vector
  489.         End Rem
  490.         Method MultiplyVec:Vector3( i:Vector3 )
  491.                 Local a:Vector3,b:Vector3,c:Vector3=Vector3.FromArray( [x,y,z] )
  492.                 a=c.Cross( i )
  493.                 b=c.Cross( a )
  494.                 a.Scale( 2*w )
  495.                 b.Scale( 2 )
  496.                
  497.                 Return i.Add( a.Add( b ) )
  498.         End Method
  499.        
  500.         Rem bbdoc: Scales the quaternion
  501.         End Rem
  502.         Method Scale:Quaternion( f:Double )
  503.                 Local r:Quaternion = New Quaternion
  504.                 r.w = w*f
  505.                 r.x = x*f
  506.                 r.y = y*f
  507.                 r.z = z*f
  508.                 Return r
  509.         End Method
  510.        
  511.         Rem bbdoc: Adds the quaternion
  512.         End Rem
  513.         Method Add:Quaternion( i:Quaternion )
  514.                 Local r:Quaternion = New Quaternion
  515.                 r.w = w+i.w
  516.                 r.x = x+i.x
  517.                 r.y = y+i.y
  518.                 r.z = z+i.z
  519.                 Return r
  520.         End Method
  521.        
  522.         Rem bbdoc: Subtracts the quaternion
  523.         End Rem
  524.         Method Subtract:Quaternion( i:Quaternion )
  525.                 Local r:Quaternion = New Quaternion
  526.                 r.w = w+i.w
  527.                 r.x = x+i.x
  528.                 r.y = y+i.y
  529.                 r.z = z+i.z
  530.                 Return r
  531.         End Method
  532.        
  533.         Rem bbdoc: Gets the dot product of two quaternions (Self and another)
  534.         End Rem
  535.         Method Dot:Double( i:Quaternion )
  536.                 Return w*i.w + x*i.x + y*i.y + z*i.z
  537.         End Method
  538.        
  539.         Rem bbdoc: Gets the quaternion slerp of two quaternions
  540.         End Rem
  541.         Function Slerp:Quaternion( time:Double, a:Quaternion, b:Quaternion, useShortest = False )
  542.                 ' Based off of code in Axiom
  543.                 Local cs:Double = a.Dot( b )
  544.                 Local angle:Double = ACos( cs )
  545.                
  546.                 If Abs(angle) < .0001 Then Return a.Copy( )
  547.                
  548.                 Local sn:Double = Sin( angle )
  549.                 Local iSin:Double = 1.0/sn
  550.                 Local co1:Double = Sin( ( 1.0-time ) * angle ) * iSin
  551.                 Local co2:Double = Sin( time * angle ) * iSin
  552.                
  553.                 Local r:Quaternion
  554.                
  555.                 If cs < .0 And useShortest > 0 Then
  556.                         co1 = -co1
  557.                         r = a.Scale( co1 ).Add( b.Scale( co2 ) )
  558.                         r.Normalize( )
  559.                 Else
  560.                         r = a.Scale( co1 ).Add( b.Scale( co2 ) )
  561.                 EndIf
  562.                
  563.                 Return r
  564.         End Function
  565.        
  566.         Rem bbdoc: Creates a quaternion from an angle and an axis
  567.         End Rem
  568.         Function FromAngleAxis:Quaternion( a:Double, ax:Vector3 )
  569.                 ' Based off of code in Axiom
  570.                 Local r:Quaternion = New Quaternion
  571.                
  572.                 Local ha:Double = .5*a
  573.                 Local sn:Double = Sin( ha )
  574.                
  575.                 r.w = Cos( ha )
  576.                 r.x = sn*ax.x
  577.                 r.y = sn*ax.y
  578.                 r.z = sn*ax.z
  579.                
  580.                 Return r
  581.         End Function
  582.        
  583.         Rem bbdoc: Blank
  584.         End Rem
  585.         Function Squad:Quaternion( t:Double, p:Quaternion, a:Quaternion, b:Quaternion, q:Quaternion, useShortest = False )
  586.                 ' Based off of code in Axiom
  587.                 Local time:Double = 2*t*( 1.0-t )
  588.                
  589.                 Local slerpA:Quaternion = Slerp( t, p, q, useShortest )
  590.                 Local slerpB:Quaternion = Slerp( t, a, b )
  591.                
  592.                 Return Slerp( time, slerpA, slerpB )
  593.         End Function
  594.        
  595.         Rem bbdoc: Sets @angle to the angle of the quaternion and @ax to the axis.
  596.         End Rem
  597.         Method ToAngleAxis( angle:Double Var, ax:Vector3 Var )
  598.                 ' Based off of code in Axiom
  599.                 Local sqrLen:Double = x*x + y*y + z*z
  600.                
  601.                 If sqrLen > 0 Then
  602.                         angle = 2 * ACos( w )
  603.                         Local invLength:Double = 1.0 / Sqr( sqrLen )
  604.                         ax.x = x * invLength
  605.                         ax.y = y * invLength
  606.                         ax.z = z * invLength
  607.                 Else
  608.                         angle = 0
  609.                         ax.x = 1
  610.                         ax.y = 0
  611.                         ax.z = 0
  612.                 EndIf
  613.         End Method
  614.        
  615.         Rem bbdoc: Returns a matrix made from the quaternion
  616.         End Rem
  617.         Method ToMatrix:Matrix( )
  618.                 ' Based off of code in Axiom
  619.                 Local m:Matrix = New Matrix
  620.                
  621.                 Local tx! = 2*x
  622.                 Local ty! = 2*y
  623.                 Local tz! = 2*z
  624.                 Local twx! = tx*w
  625.                 Local twy! = ty*w
  626.                 Local twz! = tz*w
  627.                 Local txx! = tx*x
  628.                 Local txy! = ty*x
  629.                 Local txz! = tz*x
  630.                 Local tyy! = ty*y
  631.                 Local tyz! = tz*y
  632.                 Local tzz! = tz*z
  633.                
  634.                 m.m00 = 1.0-(tyy+tzz)
  635.                 m.m01 = txy-twz
  636.                 m.m02 = txz+twy
  637.                 m.m10 = txy+twz
  638.                 m.m11 = 1.0-(txx+tzz)
  639.                 m.m12 = tyz-twx
  640.                 m.m20 = txz-twy
  641.                 m.m21 = tyz+twx
  642.                 m.m22 = 1.0-(txx+tyy)
  643.                
  644.                 Return m
  645.         End Method
  646.        
  647.         Rem bbdoc: Returns the inverse of the quaternion
  648.         End Rem
  649.         Method Inverse:Quaternion( )
  650.                 Local norm:Double = Dot( Self )
  651.                 If norm > 0 Then
  652.                         Local r:Quaternion = New Quaternion
  653.                         Local inorm:Double = 1.0 / norm
  654.                         r.w = w * inorm
  655.                         r.x = -x * inorm
  656.                         r.y = -y * inorm
  657.                         r.z = -z * inorm
  658.                         Return r
  659.                 EndIf
  660.                
  661.                 Return Quaternion.Zero( )
  662.         End Method
  663.        
  664.         Rem bbdoc: Returns the axises of the quaternion
  665.         End Rem
  666.         Method ToAxes( xAxis:Vector3 Var, yAxis:Vector3 Var, zAxis:Vector3 Var )
  667.                 xAxis = New Vector3
  668.                 yAxis = New Vector3
  669.                 zAxis = New Vector3
  670.                
  671.                 Local rot:Matrix = ToMatrix( )
  672.                
  673.                 xAxis.x = rot.m00
  674.                 xAxis.y = rot.m10
  675.                 xAxis.z = rot.m20
  676.                
  677.                 yAxis.x = rot.m01
  678.                 yAxis.y = rot.m11
  679.                 yAxis.z = rot.m21
  680.                
  681.                 zAxis.x = rot.m02
  682.                 zAxis.y = rot.m12
  683.                 zAxis.z = rot.m22
  684.         End Method
  685.        
  686.         Rem bbdoc: Creates a quaternion from axises
  687.         End Rem
  688.         Method FromAxes( xAxis:Vector3, yAxis:Vector3, zAxis:Vector3 )
  689.                 Local rot:Matrix = New Matrix
  690.                
  691.                 rot.m00 = xAxis.x
  692.                 rot.m10 = xAxis.y
  693.                 rot.m20 = xAxis.z
  694.                
  695.                 rot.m01 = yAxis.x
  696.                 rot.m11 = yAxis.y
  697.                 rot.m21 = yAxis.z
  698.                
  699.                 rot.m02 = zAxis.x
  700.                 rot.m12 = zAxis.y
  701.                 rot.m22 = zAxis.z
  702.                
  703.                 Local q:Quaternion = FromRotationMatrix( rot )
  704.                 MemCopy( GetPtr( ), q.GetPtr( ), 16 )
  705.         End Method
  706.        
  707.         Rem bbdoc: Creates a quaternion from a matrix
  708.         End Rem
  709.         Function FromRotationMatrix:Quaternion( mat:Matrix )
  710.                 Local this:Quaternion = New Quaternion
  711.                
  712.                 Local trace:Double = mat.m00 + mat.m11 + mat.m22
  713.                 Local root:Double = 0
  714.                
  715.                 If trace > 0 Then
  716.                         root = Sqr( trace + 1 )
  717.                         this.w = .5 * root
  718.                         root = .5 / root
  719.                         this.x = ( mat.m21-mat.m12 ) * root
  720.                         this.y = ( mat.m02-mat.m20 ) * root
  721.                         this.z = ( mat.m10-mat.m01 ) * root
  722.                 Else
  723.                         Local p:Double Ptr = mat.GetPtr( )
  724.                         Local i:Int = 0
  725.                         If mat.m11 > mat.m00 Then i=1
  726.                         If mat.m22 > p[i*4+i] Then i=2
  727.                        
  728.                         Local j:Int = _next( i )
  729.                         Local k:Int = _next( j )
  730.                        
  731.                         root = Sqr( p[i*4+i] - p[j*4+j] - p[k*4+k] + 1.0 )
  732.                        
  733.                         Local aq:Double Ptr = this.GetPtr( )
  734.                         aq[i] = .5 * root
  735.                         this.w = .5 / root
  736.                         aq[j] = (p[j+i*4] + p[i+j*4])*root
  737.                         aq[k] = (p[k+i*4] + p[i+k*4])*root
  738.                 EndIf
  739.                
  740.                 Return this
  741.                
  742.                 Function _next( i:Int )
  743.                         Select i
  744.                                 Case 0
  745.                                         Return 1
  746.                                 Case 1
  747.                                         Return 2
  748.                                 Case 2
  749.                                         Return 0
  750.                         End Select
  751.                 End Function
  752.         End Function
  753.        
  754.         Rem bbdoc: Blank
  755.         End Rem
  756.         Method Log:Quaternion( )
  757.                 Local r:Quaternion = Quaternion.Zero( )
  758.                 If Abs( w ) < 1.0 Then
  759.                         Local angle:Double = ACos( w )
  760.                         Local sn:Double = Sin( angle )
  761.                        
  762.                         If Abs( sn ) > .0001 Then
  763.                                 Local co:Double = angle / sn
  764.                                 r.x = co*x
  765.                                 r.y = co*y
  766.                                 r.z = co*z
  767.                         Else
  768.                                 r.x = x
  769.                                 r.y = y
  770.                                 r.z = z
  771.                         EndIf
  772.                 EndIf
  773.                
  774.                 Return r
  775.         End Method
  776.        
  777.         Rem bbdoc: Gets a zero-ed quaternion
  778.         End Rem
  779.         Function Zero:Quaternion( )
  780.                 Return Create( 0, 0, 0, 0 )
  781.         End Function
  782.        
  783.         Rem bbdoc: Creates a new quaternion
  784.         End Rem
  785.         Function Create:Quaternion( w! = 1, x! = 0, y! = 0, z! = 0 )
  786.                 Local r:Quaternion = New Quaternion
  787.                 r.w = w; r.x = x; r.y = y; r.z = z
  788.                 Return r
  789.         End Function
  790.        
  791.         Rem bbdoc: Converts the quaternion to a Double array
  792.         End Rem
  793.         Method ToArray:Double[]( )
  794.                 Local r:Double[4]
  795.                 MemCopy( Varptr r[0], GetPtr( ), 16 )
  796.                 Return r
  797.         End Method
  798.        
  799.         Rem bbdoc: Returns a Double pointer to the first component of the quaternion
  800.         End Rem
  801.         Method GetPtr:Double Ptr( )
  802.                 Return Varptr w
  803.         End Method
  804.        
  805.         Rem bbdoc: Creates a quaternion from an array
  806.         End Rem
  807.         Function FromArray:Quaternion( arr:Double[] )
  808.                 Return FromPtr( Varptr arr[0] )
  809.         End Function
  810.        
  811.         Rem bbdoc: Creates a quaternion from a pointer to a Double array
  812.         End Rem
  813.         Function FromPtr:Quaternion( arr:Double Ptr )
  814.                 Local r:Quaternion = New Quaternion
  815.                 MemCopy( r.GetPtr( ), arr, 16 )
  816.                 Return r
  817.         End Function
  818.        
  819.         Rem bbdoc: Copies the quaternion class
  820.         End Rem
  821.         Method Copy:Quaternion( )
  822.                 Local r:Quaternion = New Quaternion
  823.                 MemCopy( r.GetPtr( ), GetPtr( ), 16 )
  824.                 Return r
  825.         End Method
  826. End Type
  827.  
  828. Rem bbdoc: Plane class
  829. End Rem
  830. Type Plane
  831.         Field norm:Vector3, d!
  832.        
  833.         Method New( )
  834.                 norm = Vector3.Create( 0, 1, 0 )
  835.                 d = 1
  836.         End Method
  837.        
  838.         Rem bbdoc: Gets the distance from a vector to the plane
  839.         End Rem
  840.         Method Distance!( p:Vector3 )
  841.                 Return norm.Dot( p ) + d
  842.         End Method
  843.        
  844.         Rem bbdoc: Returns which side of the plane a vector is on
  845.         End Rem
  846.         Method Side( p:Vector3 )
  847.                 Local di:Double = Distance( p )
  848.                
  849.                 If di > 0 Then
  850.                         Return 1
  851.                 ElseIf di < 0 Then
  852.                         Return -1
  853.                 EndIf
  854.                 Return 0
  855.         End Method
  856.        
  857.         Rem bbdoc: Gets the plane normal vector
  858.         End Rem
  859.         Method GetNormal:Vector3( )
  860.                 Return norm.Copy( )
  861.         End Method
  862.        
  863.         Rem bbdoc: Creates a new plane
  864.         End Rem
  865.         Function Create:Plane( normal:Vector3, d! )
  866.                 Local i:Plane = New Plane
  867.                 i.norm = normal.Copy( )
  868.                 i.d = d
  869.                 Return i
  870.         End Function
  871.        
  872.         Rem bbdoc: Creates a plane from an array of Doubles
  873.         End Rem
  874.         Function FromArray:Plane( arr:Double[] )
  875.                 Return FromPtr( Varptr arr[0] )
  876.         End Function
  877.        
  878.         Rem bbdoc: Creates a plane from a pointer to an array of Doubles
  879.         End Rem
  880.         Function FromPtr:Plane( arr:Double Ptr )
  881.                 Local i:Plane = New Plane
  882.                 i.norm = Vector3.FromPtr( arr )
  883.                 i.d = arr[3]
  884.                 Return i
  885.         End Function
  886.        
  887.         '' Can't do a standard memory copy for Planes, as they have a Vector3 reference
  888.         Rem bbdoc: Copies the Plane class
  889.         End Rem
  890.         Method Copy:Plane( )
  891.                 Local i:Plane = New Plane
  892.                 i.d = d
  893.                 i.norm = norm.Copy( )
  894.                 Return i
  895.         End Method
  896. End Type
  897.  
  898. Rem bbdoc: Rectangle class
  899. End Rem
  900. Type Rectangle
  901.         Rem bbdoc: X component
  902.         End Rem
  903.         Field x!
  904.         Rem bbdoc: Y component
  905.         End Rem
  906.         Field y!
  907.         Rem bbdoc: Width component
  908.         End Rem
  909.         Field w!
  910.         Rem bbdoc: Height component
  911.         End Rem
  912.         Field h!
  913.        
  914.         Rem bbdoc: Whether or not the rectangle intersects with another rectangle
  915.         End Rem
  916.         Method Intersects( other:Rectangle )
  917.                 If x > other.x+other.w Or..
  918.                         x+w < other.x Or..
  919.                         y > other.y+other.h Or..
  920.                         y+h < other.y Then Return 0
  921.                 Return 1
  922.         End Method
  923.        
  924.         Rem bbdoc: Returns whether or not @p is inside the rectangle
  925.         End Rem
  926.         Method PointInside( p:Vector2 )
  927.                 If p.x < x+w And p.y < y+h And p.x > x And p.y > y Then Return 1
  928.                 Return 0
  929.         End Method
  930. End Type
  931.  
  932. Rem bbdoc: Vector2 class
  933. End Rem
  934. Type Vector2
  935.         Rem bbdoc: X component
  936.         End Rem
  937.         Field x!
  938.         Rem bbdoc: Y component
  939.         End Rem
  940.         Field y!
  941.        
  942.         Rem bbdoc: Returns the magnitude of the point
  943.         End Rem
  944.         Method Magnitude!( )
  945.                 Return Sqr( x*x + y*y )
  946.         End Method
  947.        
  948.         Rem bbdoc: Returns the difference of two points
  949.         End Rem
  950.         Method Subtract:Vector2( i:Vector2 )
  951.                 Return Create( x-i.x, y-i.y )
  952.         End Method
  953.        
  954.         Rem bbdoc: Returns the sum of two points
  955.         End Rem
  956.         Method Add:Vector2( i:Vector2 )
  957.                 Return Create( x+i.x, y+i.y )
  958.         End Method
  959.        
  960.         Rem bbdoc: Returns the product of two points
  961.         End Rem
  962.         Method Multiply:Vector2( i:Vector2 )
  963.                 Return Create( x*i.x, y*i.y )
  964.         End Method
  965.        
  966.         Rem bbdoc: Returns the divisor of two points
  967.         End Rem
  968.         Method Divide:Vector2( i:Vector2 )
  969.                 Return Create( x/i.x, y/i.y )
  970.         End Method
  971.        
  972.         Rem bbdoc: Creates a new point
  973.         End Rem
  974.         Function Create:Vector2( x!, y! )
  975.                 Local i:Vector2 = New Vector2
  976.                 i.x = x
  977.                 i.y = y
  978.                 Return i
  979.         End Function
  980.        
  981.         Rem bbdoc: Copies the point
  982.         End Rem
  983.         Method Copy:Vector2( )
  984.                 Return Create( x, y )
  985.         End Method
  986. End Type


Comments :


Warren(Posted 1+ years ago)

 Nice one, Noel!  This should be useful when the 3D module hits...


N(Posted 1+ years ago)

 Thanks, skid.


Dubious Drewski(Posted 1+ years ago)

 That is quite extensive too.  Very nice.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal