📄 clsmd3loader.cls
字号:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "Cls_MD3Loader"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
'*********************************************************************'
'*** ***'
'*** Diese Klasse decodiert und rendert Quake3 (MD3) models. ***'
'*** ***'
'*** Original autor: ***'
'*** Russel Taylor (www.solarsplace.com) ***'
'*** Animation, Bounding boxes & *viele* Optimierungen: ***'
'*** Marius Schmidt (www.matrixvb.da.ru) ***'
'*** ***'
'*********************************************************************'
Option Explicit
Option Compare Text
Private MD3HeadOffSet(2) As Long
'Our MD3 Model structures
Private ModelUpper As udtMD3Model
Private ModelLower As udtMD3Model
Private ModelHead As udtMD3Model
Private ModelWeapon As udtMD3Model
Private MeshResult() As MDLVERTEX
Private nMaxVerts As Long
'''Matrizen und Quaternions
Private matTorsoResult As D3DMATRIX
Private matHeadResult As D3DMATRIX
Private matWeapon As D3DMATRIX
Private MatTemp As D3DMATRIX
Private ModelWorld As D3DMATRIX
Private ModelWorld2 As D3DMATRIX
Private MatX As D3DMATRIX
Private MatY As D3DMATRIX
Private IdentMat As D3DMATRIX
'Diese Variablen werden f黵 die Animation der Bones genutzt
Private PosFrom As D3DVECTOR
Private PosTo As D3DVECTOR
Private PosFinal As D3DVECTOR
Private MatrixFrom As D3DMATRIX
Private MatrixTo As D3DMATRIX
Private MatrixFinal As D3DMATRIX
Private quatFrom As D3DQUATERNION
Private quatTo As D3DQUATERNION
Private quatFinal As D3DQUATERNION
Private tmpVect1 As D3DVECTOR
Private tmpVect2 As D3DVECTOR
'Viele n黷zliche Variablen
Public MD3Path As String
Public bLoaded As Boolean
Public bDbgRenderHitBoxes As Boolean
Public bDbgRenderBoundingBox As Boolean
Public bSmoothBoneAnim As Boolean
Public bLinearKeyFrames As Boolean
Public bUseTextures As Boolean
Public bWeaponLoaded As Boolean
Public AnimSpeed As Single '1 = original
Public NumVertices As Long
Public NumWeaponVertices As Long
' For keeping track of model frame animations, looping frames, number of frames
Private Type AN
FirstFrame As Long
NumFrames As Long
LoopingFrames As Long
AnFPS As Currency
End Type
Private Anim(25) As AN
Private Type udtAnimations
FPS As Currency
StartFrame As Long
EndFrame As Long
NextFrame As Long
tLastFrame As Currency
tElapsed As Currency
tFactor As Currency
Frame As Long
End Type
Private mUpper As udtAnimations
Private mLower As udtAnimations
Private m As Long, x As Long, y As Long, s As Long, h As Long, i As Long
Private BBoxMin As D3DVECTOR
Private BBoxMax As D3DVECTOR
Private Type BBoxVert
pos As D3DVECTOR
col As Long
End Type
Private Const BBoxVert_FVF As Long = (D3DFVF_XYZ Or D3DFVF_DIFFUSE)
Private Const BBoxVert_SIZE As Long = 16
Private BoundingBox(35) As BBoxVert
Public Property Get BoxMin() As D3DVECTOR
BoxMin = BBoxMin
End Property
Public Property Get BoxMax() As D3DVECTOR
BoxMax = BBoxMax
End Property
Public Sub LoadMD3(ByVal sFileName As String)
' Get the pathonly
MD3Path = GetPathOnly(sFileName)
NumVertices = 0
' Load the animation.cfg file
ReadAnimationFile MD3Path + "animation.cfg"
' Load the various MD3 files for a player
LoadModels ModelLower, MD3Path + "lower.md3"
LoadModels ModelUpper, MD3Path + "upper.md3"
LoadModels ModelHead, MD3Path + "head.md3"
mUpper.tLastFrame = QPTimer
mLower.tLastFrame = QPTimer
For m = 0 To ModelLower.MD3Header.NumOfMeshes - 1
NumVertices = NumVertices + ModelLower.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
If ModelLower.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3 > nMaxVerts Then
nMaxVerts = ModelLower.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
End If
Next m
For m = 0 To ModelUpper.MD3Header.NumOfMeshes - 1
NumVertices = NumVertices + ModelUpper.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
If ModelUpper.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3 > nMaxVerts Then
nMaxVerts = ModelUpper.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
End If
Next m
For m = 0 To ModelHead.MD3Header.NumOfMeshes - 1
NumVertices = NumVertices + ModelHead.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
If ModelHead.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3 > nMaxVerts Then
nMaxVerts = ModelHead.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
End If
Next m
ReDim MeshResult(nMaxVerts)
MD3Path = sFileName
bLoaded = True
End Sub
Public Sub LoadMD3Weapon(ByVal sFileName As String)
LoadModels ModelWeapon, sFileName
NumWeaponVertices = 0
For m = 0 To ModelWeapon.MD3Header.NumOfMeshes - 1
NumWeaponVertices = NumWeaponVertices + ModelWeapon.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
If ModelWeapon.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3 > nMaxVerts Then
nMaxVerts = ModelWeapon.MD3Meshes(m).MD3MeshHeader.NumOfTriangle * 3
End If
Next m
ReDim MeshResult(nMaxVerts)
bWeaponLoaded = True
End Sub
Private Sub ReadAnimationFile(ByVal sFileName As String)
Dim FN As Integer
FN = FreeFile()
Dim MyCount As Long
MyCount = 0
' Set the head offsets to a default value
For x = 0 To 2
MD3HeadOffSet(x) = 0
Next x
Dim sData As String
Dim RefPos As Long
Dim sLen As Long
Dim sChr As Long
Dim sKeep(3) As String
Open sFileName For Input As #FN
Do While Not EOF(FN)
Line Input #FN, sData
If InStr(1, sData, "//", vbTextCompare) = 1 Then
'This is a comment. Ignor
GoTo DoNextLine
ElseIf InStr(1, sData, "sex", vbTextCompare) = 1 Then
'This is not dealt with at present.
GoTo DoNextLine
ElseIf InStr(1, sData, "footsteps", vbTextCompare) = 1 Then
'This is not dealt with at present.
GoTo DoNextLine
ElseIf InStr(1, sData, "headoffset", vbTextCompare) = 1 Then
Dim sOffSets As String
Dim Pos1 As Long
Pos1 = 12
For x = 0 To 2
sOffSets = ""
Do While Pos1 <= Len(sData)
If Mid(sData, Pos1, 1) <> " " Then
sOffSets = sOffSets + Mid(sData, Pos1, 1)
Pos1 = Pos1 + 1
Else
Pos1 = Pos1 + 1
Exit Do
End If
Loop
MD3HeadOffSet(x) = CLng(sOffSets)
Next x
' Reverse the sign of the z component
MD3HeadOffSet(2) = MD3HeadOffSet(2)
GoTo DoNextLine
ElseIf sData = "" Then
'A blank line. Not really very important
GoTo DoNextLine
End If
sData = Trim(Mid(sData, 1, InStr(1, sData, "//", vbTextCompare) - 1))
For s = 0 To 3
sKeep(s) = ""
Next s
RefPos = 0
For h = 1 To Len(sData)
sChr = Asc(Mid(sData, h, 1))
If sChr >= 48 And sChr <= 57 Then
sKeep(RefPos) = sKeep(RefPos) + Mid(sData, h, 1)
Else
RefPos = RefPos + 1
End If
Next h
Anim(MyCount).FirstFrame = CLng(sKeep(0))
Anim(MyCount).NumFrames = CLng(sKeep(1))
Anim(MyCount).LoopingFrames = CLng(sKeep(2))
Anim(MyCount).AnFPS = CCur(sKeep(3)) / Takt
MyCount = MyCount + 1
DoNextLine:
Loop
Dim Skip As Long
Skip = Anim(LEGS_WALKCR).FirstFrame - Anim(TORSO_GESTURE).FirstFrame
For i = LEGS_WALKCR To MAX_ANIMATIONS - 1
Anim(i).FirstFrame = Anim(i).FirstFrame - Skip
Next i
End Sub
Private Sub UpdateFrames(ByRef MD3 As udtAnimations)
With MD3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -