

'created 2023 06/30 - Tim Keal
Function PolygonOffset ( ByRef Polygon As PolygonType ) As UByte
	
	For ABCIndex As Long = Vec.A To Vec.C Step 1
	For XYZIndex As Long = Vec.X To Vec.Z Step 1

		Polygon.Offset ( ABCIndex ). XYZ ( XYZIndex ) = Polygon.Center ( ABCIndex ). XYZ ( XYZIndex ) - Polygon.Offset ( ABCIndex ). XYZ ( XYZIndex )

	Next XYZIndex
	Next ABCIndex
	
	Return 1
	
End Function

'created 2023 06/30 - Tim Keal
Function Polygon_Twist ( ByRef Polygon As PolygonType ) As UByte
	
	For ABCIndex As Long = Vec.A To Vec.C Step 1
	For XYZIndex As Long = Vec.X To Vec.Z Step 1

		Polygon.Twist ( ABCIndex ). XYZ ( XYZIndex ) = VectorToDecimal ( VertexFunnel ( Polygon.Offset ( ABCIndex ). XYZ ( XYZIndex ), Polygon.Offset ( ( XYZIndex Mod Vec.Z ) + 1 ). XYZ ( Vec.Y ) ) )
	
	Next XYZIndex
	Next ABCIndex	

	Return 1
	
End Function

'created 2023 06/30 - Tim Keal
Function Polygon_Radius ( ByRef Polygon As PolygonType ) As UByte
	
	For ABCIndex As Long = Vec.A To Vec.C Step 1
	For XYZIndex As Long = Vec.X To Vec.Z Step 1

		Polygon.Radius ( ABCIndex ). XYZ ( XYZIndex ) = VectorToDecimal ( VertexFunnel ( Polygon.Offset ( ABCIndex ). XYZ ( XYZIndex ), Polygon.Offset ( ( XYZIndex Mod Vec.Z ) + 1 ). XYZ ( Vec.Y ) ) )
	
	Next XYZIndex
	Next ABCIndex	

	Return 1
	
End Function

'created 2023 06/30 - Tim Keal
Function PolygonFacing ( ByRef Polygon As PolygonType ) As UByte
	
	Dim As Long Check = 0
	
	For ABCIndex As Long = Vec.A To Vec.C Step 1
	For XYZIndex As Long = Vec.X To Vec.Z Step 1
		
		Check = 0
		If Check = 0 Then
			If Polygon.Twist ( ABCIndex ). XYZ ( XYZIndex ) <= _
			Polygon.Twist ( ( ABCIndex Mod Vec.C ) + 1 ). XYZ ( XYZIndex ) Then
				Check += 1
			End If
			If Check = 1 Then
				If Polygon.Twist ( ( ABCIndex Mod Vec.C ) + 1 ). XYZ ( XYZIndex ) <= _
				Polygon.Twist ( ( ( ABCIndex + 1 ) Mod Vec.C ) + 1 ). XYZ ( XYZIndex ) Then
					Check += 1
				End If
				If Check = 2 Then
					If Polygon.Twist ( ( ( ABCIndex + 1 ) Mod Vec.C ) + 1 ). XYZ ( XYZIndex ) >= _
					Polygon.Twist ( ( ( ABCIndex + 2 ) Mod Vec.C ) + 1 ). XYZ ( 	XYZIndex ) Then
						Check += 1
						If Check = 3 Then
							Polygon.Facing ( ABCIndex ). XYZ ( Vec.D ) = 1
							Polygon.Facing ( Vec.D ). XYZ ( Vec.D ) = 1
							Return Polygon.Facing ( Vec.D ). XYZ ( Vec.D )
						End If
					End If
				End If 
			End If
		End If
			
	Next XYZIndex
	Next ABCIndex	

	Return 0
		
End Function

'created 2023 06/30 - Tim Keal
Function RenderPolygon ( ByRef Polygon As PolygonType , Ink As Long = &HFFFFFFFF ) As UByte
	
	PSet ( Polygon.Offset ( Vec.A ). XYZ ( Vec.X ), Polygon.Offset ( Vec.A ). XYZ ( Vec.Y ) ), Ink
	
	For ABCIndex As Long = Vec.B To Vec.C Step 1
	For XYZIndex As Long = Vec.X To Vec.Z Step 1

		Line - Step ( Polygon.Offset ( ABCIndex ). XYZ ( Vec.X ), Polygon.Offset ( ABCIndex ). XYZ ( Vec.Y ) ), Ink

	Next XYZIndex
	Next ABCIndex

	Line - Step ( Polygon.Offset ( Vec.A ). XYZ ( Vec.X ), Polygon.Offset ( Vec.A ). XYZ ( Vec.Y ) ), Ink
	
	Return 1
	
End Function

'created circa 1995 - jargon {AG47}
'update 19990207 - jargon {AG47}
'updated 2023 06/30 - Tim Keal
SUB Triangle ( Triv As PolygonType, Ink As Long, Tri_Fill AS LONG, Stp AS DOUBLE, Center As VertexType )
	
	Dim As VertexIntType Corner
	
	Dim As PolygonType TrivII	
	Dim As VertexType Pixel
	Dim As Long Tri_Scanline ( 0 To 0 ), Tri_Column ( 0 To 2 )
	
	'Tri_Fill as a 50% Dither Fill
    '2 ^ 0 + 2 ^ 2 + 2 ^ 4 + 2 ^ 6 + 2 ^ 8 + 2 ^ 10 + 2 ^ 12 + 2 ^ 14

	Corner.XYZ ( Vec.E ) = 1
	
	Do
		
		Corner.XYZ ( Vec.A ) = Corner.XYZ ( Vec.E )
		Corner.XYZ ( Vec.B ) = (Corner.XYZ ( Vec.A ) MOD 3) + 1
		Corner.XYZ ( Vec.C ) = (Corner.XYZ ( Vec.B ) MOD 3) + 1
        
		IF Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y ) <= Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) AND Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y ) <= Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.Y ) THEN
            
			IF Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) > Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.Y ) THEN SWAP Corner.XYZ ( Vec.B ), Corner.XYZ ( Vec.C )
            
			IF Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) > Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y ) THEN
                
				TrivII.ABC ( Vec.X ).XYZ ( Vec.X ) = Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )

                TrivII.ABC ( Vec.Y ).XYZ ( Vec.X ) = Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.X ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.X )

                TrivII.ABC ( Vec.X ).XYZ ( Vec.Y ) = Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )

                TrivII.ABC ( Vec.Y ).XYZ ( Vec.Y ) = Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.X ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.X )

				Tri_Scanline ( 0 ) = Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )
	
				Do

                    Tri_Column ( 1 ) = TrivII.ABC ( Vec.Y ).XYZ ( Vec.X ) / TrivII.ABC ( Vec.X ).XYZ ( Vec.X ) * (Pixel.XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )) + Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.X )

                    Tri_Column ( 2 ) = TrivII.ABC ( Vec.Y ).XYZ ( Vec.Y ) / TrivII.ABC ( Vec.x ).XYZ ( Vec.Y ) * (Pixel.XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )) + Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.X )

                    IF Tri_Fill > 0 THEN

                        LINE (Center.XYZ ( Vec.X ) + Tri_Column ( 1 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y ))-(Center.XYZ ( Vec.X ) + Tri_Column ( 2 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y )), Ink, , Tri_Fill
                    
					ELSE

                        LINE (Center.XYZ ( Vec.X ) + Tri_Column ( 1 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y ))-(Center.XYZ ( Vec.X ) + Tri_Column ( 2 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y )), Ink

                    END IF

                    'IF Tri_Column ( 1 ) > Tri_Column ( 2 ) THEN SWAP Tri_Column ( 1 ), Tri_Column ( 2 )
                    'FOR Pixel.XYZ ( Vec.X ) = Tri_Column ( 1 ) TO Tri_Column ( 2 ) STEP 1
                        'PSET (Pixel.XYZ ( Vec.X ), Pixel.XYZ ( Vec.Y )), Ink
                    'NEXT Pixel.XYZ ( Vec.X )

					If Tri_Scanline ( 0 ) >= Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) Then Exit Do Else Tri_Scanline ( 0 ) += Stp
				
				Loop
				
            END IF
            IF Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.Y ) > Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) THEN
                TrivII.ABC ( Vec.X ).XYZ ( Vec.X ) = Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.Y )
                TrivII.ABC ( Vec.Y ).XYZ ( Vec.X ) = Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.X ) - Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.X )
                TrivII.ABC ( Vec.X ).XYZ ( Vec.Y ) = Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )
                TrivII.ABC ( Vec.Y ).XYZ ( Vec.Y ) = Triv.ABC ( Corner.XYZ ( Vec.C ) ).XYZ ( Vec.X ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.X )

				Tri_Scanline ( 0 ) = Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )
	
				Do

                    Tri_Column ( 1 ) = TrivII.ABC ( Vec.Y ).XYZ ( Vec.X ) / TrivII.ABC ( Vec.X ).XYZ ( Vec.X ) * (Pixel.XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y )) + Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.X )
                    Tri_Column ( 2 ) = TrivII.ABC ( Vec.Y ).XYZ ( Vec.Y ) / TrivII.ABC ( Vec.x ).XYZ ( Vec.Y ) * (Pixel.XYZ ( Vec.Y ) - Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.Y )) + Triv.ABC ( Corner.XYZ ( Vec.A ) ).XYZ ( Vec.X )
                    IF Tri_Fill > 0 THEN
                        LINE (Center.XYZ ( Vec.X ) + Tri_Column ( 1 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y ))-(Center.XYZ ( Vec.X ) + Tri_Column ( 2 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y )), Ink, , Tri_Fill
                    ELSE
                        LINE (Center.XYZ ( Vec.X ) + Tri_Column ( 1 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y ))-(Center.XYZ ( Vec.X ) + Tri_Column ( 2 ), Center.XYZ ( Vec.Y ) + Pixel.XYZ ( Vec.Y )), Ink
                    END IF
                    'IF Tri_Column ( 1 ) > Tri_Column ( 2 ) THEN SWAP Tri_Column ( 1 ), Tri_Column ( 2 )
                    'FOR Pixel.XYZ ( Vec.X ) = Tri_Column ( 1 ) TO Tri_Column ( 2 ) STEP 1
                        'PSET (Pixel.XYZ ( Vec.X ), Pixel.XYZ ( Vec.Y )), Ink
                    'NEXT Pixel.XYZ ( Vec.X )
                
					If Tri_Scanline ( 0 ) >= Triv.ABC ( Corner.XYZ ( Vec.B ) ).XYZ ( Vec.Y ) Then Exit Do Else Tri_Scanline ( 0 ) += Stp
				
				Loop

            END IF
        END IF
		If Corner.XYZ ( Vec.E ) >= 3 Then Exit Do Else Corner.XYZ ( Vec.E ) += 1
    Loop
	
END SUB


'placeholder 2023 06/30 - Tim Keal
Sub RenderQuad ( Quad As QuadType )
End Sub

'created circa 1995 - jargon (Tim Keal)
'updated 2023 06/30 - Tim Keal
SUB Render_Axis_Set ( Translation As TranslationType, Axis As PolygonType )
    	
	Axis.ABC ( Vec.A ).XYZ ( Vec.X ) = COS(2 * Pi * Translation.Rotation.XYZ ( Vec.X ))
    
	Axis.ABC ( Vec.A ).XYZ ( Vec.Y ) = -SIN(2 * Pi * Translation.Rotation.XYZ ( Vec.X ))
    Axis.ABC ( Vec.A ).XYZ ( Vec.Z ) = 0
    
	
	Axis.ABC ( Vec.B ).XYZ ( Vec.X ) = -SIN(2 * Pi * Translation.Rotation.XYZ ( Vec.Y )) * SIN(2 * Pi * Translation.Rotation.XYZ ( Vec.X ))
    
	Axis.ABC ( Vec.B ).XYZ ( Vec.Y ) = -SIN(2 * Pi * Translation.Rotation.XYZ ( Vec.Y )) * COS(2 * Pi * Translation.Rotation.XYZ ( Vec.X ))
    
	Axis.ABC ( Vec.B ).XYZ ( Vec.Z ) = COS(2 * Pi * Translation.Rotation.XYZ ( Vec.Y ))
    
	
	Axis.ABC ( Vec.C ).XYZ ( Vec.X ) = COS(2 * Pi * Translation.Rotation.XYZ ( Vec.Y )) * SIN(2 * Pi * Translation.Rotation.XYZ ( Vec.X ))
    
	Axis.ABC ( Vec.C ).XYZ ( Vec.Y ) = COS(2 * Pi * Translation.Rotation.XYZ ( Vec.Y )) * COS(2 * Pi * Translation.Rotation.XYZ ( Vec.X ))
    
	Axis.ABC ( Vec.C ).XYZ ( Vec.Z ) = SIN(2 * Pi * Translation.Rotation.XYZ ( Vec.Y ))
	
END SUB

Function VertexConvert Overload ( VI As VertexIntType ) As VertexType

	Return VertexFunnel ( CDbl ( VI.XYZ ( Vec.X ) ), CDbl ( VI.XYZ ( Vec.Y ) ), CDbl ( VI.XYZ ( Vec.Z ) ) )

End Function
	
Function VertexConvert Overload ( VF As VertexType ) As VertexIntType

	Return VertexFunnel ( CLng ( VF.XYZ ( Vec.X ) ), CLng ( VF.XYZ ( Vec.Y ) ), CLng ( VF.XYZ ( Vec.Z ) ) )

End Function

Function VertexFunnel Overload ( X As Double = 0.0, Y As Double = 0.0, Z As Double = 0.0 ) As VertexType
	
	Dim Vertex As VertexType
	
	Vertex.XYZ ( Vec.X ) = X
	Vertex.XYZ ( Vec.Y ) = Y
	Vertex.XYZ ( Vec.Z ) = Z

	Return Vertex

End Function

Function VertexFunnel Overload ( X As Long = 0, Y As Long = 0, Z As Long = 0 ) As VertexIntType
	
	Dim Vertex As VertexIntType
	
	Vertex.XYZ ( Vec.X ) = X
	Vertex.XYZ ( Vec.Y ) = Y
	Vertex.XYZ ( Vec.Z ) = Z

	Return Vertex

End Function

'created circa 1995 - jargon (Tim Keal)
SUB Plot ( Center As VertexType, Offset As VertexType, Pt As VertexType, Ink AS Long, PlotMode AS STRING, Pattern AS LONG, Scale As VertexType )
    

	Dim As Long XYZ = 0
	Dim As VertexType Pix
	
	For XYZ = Vec.X To Vec.Z Step 1
		
		Pix.XYZ ( XYZ ) = Pt.XYZ ( XYZ ) * Scale.XYZ ( XYZ ) + Center.XYZ ( XYZ )
		
	 Next XYZ
	 
	Select Case LCase ( Plotmode ) 
	Case "point"
        
		PSet ( Pix.XYZ ( Vec.X ), Pix.XYZ ( Vec.Y ) ), VGA_Lookup ( Ink )

	Case "line"
        
		Select Case Pattern
		Case 0
			Line - ( Pix.XYZ ( Vec.X ), Pix.XYZ ( Vec.Y ) ), VGA_Lookup ( Ink )
		Case Else
			Line - ( Pix.XYZ ( Vec.X ), Pix.XYZ ( Vec.Y ) ), VGA_Lookup ( Ink ), , Pattern
		End Select
		
    End Select

END SUB

'created circa 1995 - jargon (Tim Keal)
'updated 2023 06/30 - Tim Keal
Function Render_ThreeToTwo ( Vertex As VertexType, Offset As VertexType, Axis As PolygonType, Scale As VertexType ) As VertexType

    Dim As VertexType Pt
	Dim As Long VXYZ = 0, ABC = 0, XYZ = 0
	
	
	For VXYZ = Vec.Y To Vec.Z Step 1
		
		Pt.XYZ ( VXYZ ) = 0.0		
	
		For ABC = Vec.A To Vec.C Step 1
		For XYZ = Vec.X To Vec.Z Step 1
	
			Pt.XYZ ( VXYZ ) += Vertex.XYZ ( XYZ ) * Axis.ABC ( ABC ).XYZ ( XYZ ) 
	
		Next XYZ
		Next ABC
	
	Next VXYZ

	Return Pt

END Function

Function VectorToDecimal ( Vector As VertexType ) As Double

	Dim As PolygonType V	
	
	V.ABC ( Vec.A ) = VertexFunnel ( Vector.XYZ ( Vec.X ), Vector.XYZ ( Vec.Y ) )
	
	Return Polygon_Twist ( V )

End Function

Function VectorToRadius ( Vector As VertexType ) As Double
	
	Dim As PolygonType V	
	
	V.ABC ( Vec.A ) = Vector
	
	Return Polygon_Radius ( V )
	
End Function
