Sets up some basic Math for transforming objects or an environement in 3D Structures,ideas,Matix and Vertex Math.
API Declarations
Teaser for the inquisitive people out there
I'm still learning and share what a have so far. Warts and all...
'**************************************************************************************************************************** 'Conversion from Degrees to Radials used in Math.Cos and Math.Sin Public Const rad As Double = Math.PI/180 '**************************************************************************************************************************** 'Camera structure 'Movement: Concider stepping when changing dx,dy,dz as a variance of speed? ' remember INVERT : walk forward = -z etc. as the world moves against the grain on your static monitor display!!! 'Rotation: Convert angles 0 to 360 to radial equivalens , degrees * rad (the const!) ' remember INVERT : Left = right , up = down etc. 'Scale: 2 = twice at large !!! Use fractions Public Structure Camera ' Location 'd' for displasement Friend dx As Double Friend dy As Double Friend dz As Double ' Angles 'a' for angle Friend ax As Double Friend ay As Double Friend az As Double ' Zoom or Scale 's' for Scale Friend sx As Double Friend sy As Double Friend sz As Double 'friend lives as integer 'friend health as integer 'AliveDead as boolean 'Props... End Structure Public Cam As Camera = New Camera ' Camera: Cam = ready for you! ' The Structure Camera is a good place to start creating a Player ? Add some Lives,Health,AliveDead...Props... ' Just keep there behaviour in sinc : movement,rotation ...Ore replace Cam by your extended Player Srtuctur? '**************************************************************************************************************************** Public matX(4,4) as double 'Rotation on the x-axis Public matY(4,4) as double 'Rotation on the y-axis Public matZ(4,4) as double 'Rotation on the z-axis Public matMove(4,4) as double 'Movement in dx,dy and dz : invers of the Camera-movement !!! Public matScale(4,4) as double 'Scaling sx,sy and sz invers of the Camera-rotations !!! Public matMaster(4,4) as double 'Master transformation matrix '**************************************************************************************************************************** 'Initialize all transforms and cocatinate th Master Transformation Matrix :-) Public Sub CreatMasterTransformer() SetMatX() 'Set x-rotation SetMatY() 'Set y-rotation SetMatZ() 'Set z-rotation SetMatMove() 'Set Movement SetMatScale() 'Set Scaling Concat() 'Master Transformation matrix is ready End Sub '**************************************************************************************************************************** 'Set x-rotation Public Sub SetMatX() for c = 0 to 3 for r = 0 to 3 matX(c,r) = 0 Next r Next c matX(0,0) = 1 '1 0 0 0 matX(1,1) = Math.cos(Cam.ax) : matX(2,1) = Math.sin(Cam.ax) '0 cos sin 0 matX(1,2) = -Math.sin(Cam.ax) : matX(2,2) = Math.cos(Cam.ax) '0 -sin cos 0 matX(3,3) = 1 '0 0 0 1 End Sub '**************************************************************************************************************************** ' // Set y-rotation Public Sub SetMatY() ' Initialize matrix to identiy matrix for c = 0 to 3 for r = 0 to 3 MatY(c,r) = 0 Next r Next c MatY(0,0) = Math.cos(Cam.ay) : matY(2,0) = Math.sin(Cam.ay) 'cos 0 sin 0 MatY(1,1) = 1 '0 1 0 0 MatY(0,2) = -Math.sin(Cam.ay) : matY(2,2) = Math.cos(Cam.ay) '-sin 0 cos 0 MatY(3,3) = 1 '0 0 0 1 End Sub '**************************************************************************************************************************** ' // Set z-rotation Public Sub SetMatZ() ' Initialize matrix to identiy matrix for c = 0 to 3 for r = 0 to 3 MatZ(c,r) = 0 Next r Next c MatZ(0,0) = Math.cos(Cam.az) : matZ(1,0) = Math.sin(Cam.az) 'cos sin 0 0 MatZ(1,1) = -Math.sin(Cam.az) : matZ(2,2) = Math.cos(Cam.az) '-sin cos 0 0 MatZ(2,2) = 1 '0 0 1 0 MatZ(3,3) = 1 '0 0 0 1 End Sub '**************************************************************************************************************************** ' // Set Movement Public Sub SetMatMove() ' Initialize matrix to identiy matrix for c = 0 to 3 for r = 0 to 3 MatMove(c,r) = 0 Next r Next c MatMove(0,0) = 1 : MatMove(3,0) = Cam.dx '1 0 0 dx MatMove(1,1) = 1 : MatMove(3,1) = Cam.dy '0 1 0 dy MatMove(2,2) = 1 : MatMove(3,2) = Cam.dz '0 0 1 dz MatMove(3,3) = 1 '0 0 0 1 End Sub '**************************************************************************************************************************** ' // Set Scaling Public Sub SetMatScale() ' Initialize matrix to identiy matrix for c = 0 to 3 for r = 0 to 3 MatScale(c,r) = 0 Next r Next c MatScale(0,0) = Cam.sx 'sx 0 0 0 MatScale(1,1) = Cam.sy '0 xy 0 0 MatScale(2,2) = Cam.sz '0 0 sz 0 MatScale(3,3) = 1 '0 0 0 1 End Sub '**************************************************************************************************************************** ' // set MatMaster to Identiy matrix conditions Public Sub SetmatMasterID() ' Initialize matrix to identiy matrix for c = 0 to 3 for r = 0 to 3 matMaster(c,r) = 0 Next r Next c MatScale(0,0) = 1 '1 0 0 0 MatScale(1,1) = 1 '0 1 0 0 MatScale(2,2) = 1 '0 0 1 0 MatScale(3,3) = 1 '0 0 0 1 End Sub '**************************************************************************************************************************** ' // Concatinate Master Transformation matrix ' The camera moves then looks left/right than up/dow and eventualy tilts if need me ' Separate movements, rotations and scaleing ca n be done by leaving all other transforms set to ZERO! ' Example: ' ax = 0 , ay = 0 , az = 0 ,dx = 0 , dy = 10 , sx = 2 sy = 0 sz = 0 ' These settings would result in movin 10 units up and making the object rezise in the y direction by a factor of 2 '**************************************************************************************************************************** Public Sub Concat() Dim temp1(4,4) As Double ' // Initialize temp1 to identiy matrix for c = 0 to 3 for r = 0 to 3 temp1(c,r) = 0 Next r Next c temp1(0,0) = 1 '1 0 0 0 temp1(1,1) = 1 '0 1 0 0 temp1(2,2) = 1 '0 0 1 0 temp1(3,3) = 1 '0 0 0 1 Dim temp2(4,4) As Double ' // Initialize temp2 to identiy matrix for c = 0 to 3 for r = 0 to 3 temp2(c,r) = 0 Next r Next c temp2(0,0) = 1 '1 0 0 0 temp2(1,1) = 1 '0 1 0 0 temp2(2,2) = 1 '0 0 1 0 temp2(3,3) = 1 '0 0 0 1 ' // temp1() = MatMove() + MatY() For i = 0 to 3 For j = 0 to 3 For k = 0 to 3 temp1(i,j) += MatMove(i,k) * MatY(k,j) Next k Next j Next i ' // temp2() = temp1() + MatX() For i = 0 to 3 For j = 0 to 3 For k = 0 to 3 temp2(i,j) += temp1(i,k) * MatX(k,j) Next k Next j Next i ' // Prep matMaster() to Identity matrix SetmatMasterID() ' // matMaster() = Temp2() + MatZ() For i = 0 to 3 For j = 0 to 3 For k = 0 to 3 matMaster(i,j) += temp2(i,k) * MatX(k,j) Next k Next j Next i ' *** DONE !!! Ready to transfor shapes,objects or the whole environement *** End Sub '**************************************************************************************************************************** 'What does the world consit of? Public Structure Vertex3D Friend x As Double Friend y As Double Friend z As Double Friend w As Double 'Must have for transforms = 1 always ? 'Friend c As vbColor ore something like it... End Structure '**************************************************************************************************************************** 'The world is solid Geometry and never changes accept when editing? Public World(Sizeofworld) As vertex3D 'The Scene holds the transformed Geometry ... Public Scene(Sizeofworld) As Vertex3D '**************************************************************************************************************************** Public Sub Transform() 'Use the number of vertecies in the world to set up the Vertex Counter ! 'Transform the world... For i = 0 to Sizeofworld Scene(i).x = World(i).x * matMaster(0,0)+World(i).y * matMaster(1,0)+World(i).z * matMaster(2,0) + World(i).w * matMaster(3,0) Scene(i).y = World(i).x * matMaster(0,1)+World(i).y * matMaster(1,1)+World(i).z * matMaster(2,1) + World(i).w * matMaster(3,1) Scene(i).z = World(i).x * matMaster(0,2)+World(i).y * matMaster(1,2)+World(i).z * matMaster(2,2) + World(i).w * matMaster(3,2) Scene(i).w = World(i).x * matMaster(0,3)+World(i).y * matMaster(1,3)+World(i).z * matMaster(2,2) + World(i).w * matMaster(3,2) Next i End Sub '**************************************************************************************************************************** ' // Not Done yet !!! Som vector manipultion please... '**************************************************************************************************************************** 'Vector Addition Public Function AddVector(ByVal v1 As Vertex3D,ByVal v2 As Vertex3d) As Vertex3D Dim result As Vertex3d result.x = v1.x + v2.x result.y = v1.y + v2.y result.z = v1.z + v2.z result.w = 1 Return result End Function '**************************************************************************************************************************** 'Vector Subtraction Public Function SubVector(ByVal v1 As Vertex3D,ByVal v2 As Vertex3d) As Vertex3D Dim result As Vertex3d result.x = v1.x - v2.x result.y = v1.y - v2.y result.z = v1.z - v2.z result.w = 1 Return result End Function '**************************************************************************************************************************** ' // Vector multiplication Public Function SubVector(ByVal v1 As Vertex3D,ByVal v2 As Vertex3d) As Vertex3D Dim result As Vertex3d result.x = v1.x * v2.x result.y = v1.y * v2.y result.z = v1.z * v2.z result.w = 1 Return result End Function '**************************************************************************************************************************** ' // Vector Length ? Public Function SubVector(ByVal v1 As Vertex3D,ByVal v2 As Vertex3d) As double Dim result As Double result =math.sqrt(math.pow((v1.x - v2.x , 2)) + math.pow((v1.y - v2.y , 2))math.pow((v1.z - v2.z , 2))) Return result End Function '**************************************************************************************************************************** 'Getting the Normal vector : perpendicular to the plane ? 'Needed for light calulations 'Useful to dedermin if somthing is visible or not ? ' ' (Normal.z * Normam.y * Normal.z) > 0 VISIBLE ' ' (Normal.z * Normam.y * Normal.z) <= 0 INVISIBLE Visible, facing away... ' 'Normal vertecies can be precomputed as part of the world but must than also be transformed with it! 'Normal vertecies could be computed after transform on fewer vertecies after deciding what can be visible 'BSP : Lots of reading to do on that subject, reduced dramaticly the need for CPU overhead 'What's behind you needs no computing at all !!! etc. Public Function NormalVector(ByVal v1 As Vertex3D,ByVal v2 As Vertex3d) As Vertex3D Dim Normal As Vertex3d Normal.x = (v1.y * v2.z) - (v1.z * v2.y) Normal.y = (v1.z * v2.x) - (v1.x * v2.z) Normal.z = (v1.x * v2.y) - (v1.y * v2.x) Normal.w = 1 Return result End Function '**************************************************************************************************************************** 'CACH THE DREADED : "DIVISION_BY_ZERO" Error ! '**************************************************************************************************************************** ' // Unit vector math : pass length of corresponding Normal vector !!!!! Public sub UnitVector(ByRef v As Vertex3D,ByVal Length As Double) Length = math.abs(Length) 'A positive number is usefull... If lenght > 0.001 Then 'DIVISION_BY_ZERO Error Cought !!! v.x = v.x / Length v.y = v.y / Length v.z = v.z / Length End if End Sub '****************************************************************************************************************************