Attribute VB_Name = "EngineShell"
'Break and show error messages from the graphics engine
'This should be placed after every call to the engine that can give error messages so that the application will break in debug mode when an error has occured.
'It will continue to break on each point until the error message is deleted by reading it.
'   String buffer methods don't give error messages because they are used to show the message.
'   Matrix buffer methods don't have any preconditions.
Public Sub RE()
    Static Messages As String
    If frmMain.DGE.Message_GetCount > 0 Then
        frmMain.DGE.Message_GetContent_OutSB
        Messages = GetStringFromEngine()
        Do While frmMain.DGE.Message_GetCount > 0
            frmMain.DGE.Message_GetContent_OutSB
            Messages = Messages & vbNewLine & vbNewLine & GetStringFromEngine()
        Loop
        MsgBox Messages, vbCritical, "Messages from the graphics engine!"
        MDLeft_Flat = False
        MDRight_Flat = False
        MDLeft_P = False
        MDRight_P = False
        Debug.Assert False 'Stop debug execution to see where the error occured using the call stack.
    End If
End Sub

Public Function GetNumberOfParts(Model As Long) As Long
    GetNumberOfParts = frmMain.DGE.Model_GetNumberOfParts(Model): RE
End Function

Public Function GetTriangleCount(Model As Long, Part As Long) As Long
    GetTriangleCount = frmMain.DGE.Model_Part_GetTriangleCount(Model, Part): RE
End Function

Public Function GetNumberOfBones(Model As Long) As Long
    GetNumberOfBones = frmMain.DGE.Model_GetNumberOfBones(Model): RE
End Function

Public Function GetNumberOfShapes(Model As Long) As Long
    GetNumberOfShapes = frmMain.DGE.Model_GetNumberOfShapes(Model): RE
End Function

Public Function VertexIsSelected(Model As Long, Part As Long, Tri As Long, Vert As Long) As Boolean
    VertexIsSelected = frmMain.DGE.Model_Part_Vertice_GetSelected(Model, Part, Tri, Vert) > 0.5: RE
End Function

Public Function GetShapePoint(Model As Long, ShapeIndex As Long, PointIndex As Long) As Vector3
    frmMain.DGE.Model_Shape_GetPoint_OutV3 Model_Main, ShapeIndex, PointIndex: GetShapePoint = GetVector3FromMatrixBuffer: RE
End Function

Public Function Model_Part_Vertice_GetPos(Model As Long, PartIndex As Long, TriangleIndex As Long, VerticeIndex As Long) As Vector3
    frmMain.DGE.Model_Part_Vertice_GetPos_OutV3 Model, PartIndex, TriangleIndex, VerticeIndex: Model_Part_Vertice_GetPos = GetVector3FromMatrixBuffer: RE
End Function

Public Function Model_Part_Vertice_GetNormal(Model As Long, PartIndex As Long, TriangleIndex As Long, VerticeIndex As Long) As Vector3
    frmMain.DGE.Model_Part_Vertice_GetNormal_OutV3 Model, PartIndex, TriangleIndex, VerticeIndex: Model_Part_Vertice_GetNormal = GetVector3FromMatrixBuffer: RE
End Function

Public Function CollisionShape_ConvexHull_GetPoint(ConvexHullShape As Long, Index As Long) As Vector3
    frmMain.DGE.CollisionShape_ConvexHull_GetPoint_OutV3 ConvexHullShape, Index: CollisionShape_ConvexHull_GetPoint = GetVector3FromMatrixBuffer: RE
End Function

Public Sub InsertStringToEngine(T As String)
    Static I As Long
    frmMain.DGE.SetLengthOfStringBuffer Len(T)
    For I = 1 To Len(T)
        frmMain.DGE.WriteToStringBuffer I, Asc(Mid(T, I, 1))
    Next I
End Sub

Public Function GetStringFromEngine() As String
    Static I As Long
    GetStringFromEngine = ""
    For I = 1 To frmMain.DGE.GetLengthOfStringBuffer
        GetStringFromEngine = GetStringFromEngine & Chr(frmMain.DGE.ReadFromStringBuffer(I))
    Next I
End Function

Public Function GetVector2FromMatrixBuffer() As Vector2
    GetVector2FromMatrixBuffer = MakeVector2(frmMain.DGE.GetX1, frmMain.DGE.GetY1)
End Function

Public Function GetVector3FromMatrixBuffer() As Vector3
    GetVector3FromMatrixBuffer = MakeVector3(frmMain.DGE.GetX1, frmMain.DGE.GetY1, frmMain.DGE.GetZ1)
End Function

Public Function GetVector4FromMatrixBuffer() As Vector4
    GetVector4FromMatrixBuffer = MakeVector4(frmMain.DGE.GetX1, frmMain.DGE.GetY1, frmMain.DGE.GetZ1, frmMain.DGE.GetW1)
End Function

Public Function GetMatrix3FromMatrixBuffer() As Matrix3
    GetMatrix3FromMatrixBuffer.XAxis = MakeVector3(frmMain.DGE.GetX1, frmMain.DGE.GetY1, frmMain.DGE.GetZ1)
    GetMatrix3FromMatrixBuffer.YAxis = MakeVector3(frmMain.DGE.GetX2, frmMain.DGE.GetY2, frmMain.DGE.GetZ2)
    GetMatrix3FromMatrixBuffer.ZAxis = MakeVector3(frmMain.DGE.GetX3, frmMain.DGE.GetY3, frmMain.DGE.GetZ3)
End Function

Public Function GetMatrix4FromMatrixBuffer() As Matrix4
    GetMatrix4FromMatrixBuffer.XAxis = MakeVector4(frmMain.DGE.GetX1, frmMain.DGE.GetY1, frmMain.DGE.GetZ1, frmMain.DGE.GetW1)
    GetMatrix4FromMatrixBuffer.YAxis = MakeVector4(frmMain.DGE.GetX2, frmMain.DGE.GetY2, frmMain.DGE.GetZ2, frmMain.DGE.GetW2)
    GetMatrix4FromMatrixBuffer.ZAxis = MakeVector4(frmMain.DGE.GetX3, frmMain.DGE.GetY3, frmMain.DGE.GetZ3, frmMain.DGE.GetW3)
    GetMatrix4FromMatrixBuffer.WAxis = MakeVector4(frmMain.DGE.GetX4, frmMain.DGE.GetY4, frmMain.DGE.GetZ4, frmMain.DGE.GetW4)
End Function

Public Function GetAxisSystemFromBoneInModel(Bone As Long) As Matrix3
    'The X axis is not stored in bones but can easily be calculated using a cross product
    frmMain.DGE.Model_Bone_GetYAxis_OutV3 Model_Main, Bone: GetAxisSystemFromBoneInModel.YAxis = GetVector3FromMatrixBuffer: RE
    frmMain.DGE.Model_Bone_GetZAxis_OutV3 Model_Main, Bone: GetAxisSystemFromBoneInModel.ZAxis = GetVector3FromMatrixBuffer: RE
    GetAxisSystemFromBoneInModel.XAxis = NormalVector3(CrossProduct(GetAxisSystemFromBoneInModel.YAxis, GetAxisSystemFromBoneInModel.ZAxis))
End Function

Public Function GetAxisSystemFromBoneInFrame(Bone As Long) As Matrix3
    'The X axis is not stored in bones but can easily be calculated using a cross product
    frmMain.DGE.BoneFrame_GetYAxis_OutV3 BoneFrame_Main, Bone: GetAxisSystemFromBoneInFrame.YAxis = GetVector3FromMatrixBuffer: RE
    frmMain.DGE.BoneFrame_GetZAxis_OutV3 BoneFrame_Main, Bone: GetAxisSystemFromBoneInFrame.ZAxis = GetVector3FromMatrixBuffer: RE
    GetAxisSystemFromBoneInFrame.XAxis = NormalVector3(CrossProduct(GetAxisSystemFromBoneInFrame.YAxis, GetAxisSystemFromBoneInFrame.ZAxis))
End Function

Public Sub SetVisibilityForAllChannels(Instance As Long, Visible As Boolean)
    Static ShaderChannel As Integer
    For ShaderChannel = 0 To 15
        frmMain.DGE.Instance_SetVisibility Instance, ShaderChannel, Visible: RE
    Next ShaderChannel
End Sub

Public Function GetVertexBoneIndex(Part As Long, Tri As Long, Vert As Long) As Long
    frmMain.DGE.Model_Part_Vertice_GetBoneData_OutV4 Model_Main, Part, Tri, Vert: GetVertexBoneIndex = Int(frmMain.DGE.GetW1): RE
End Function
