home *** CD-ROM | disk | FTP | other *** search
/ Microsoft DirectX SDK 7.0 / Dx7.bin / DXF / samples / multimedia / vbsamples / d3dim / src / xfile / xfile.cls next >
Encoding:
Visual Basic class definition  |  1999-08-17  |  11.9 KB  |  422 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "XFileClass"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14.  
  15.  
  16. Option Explicit
  17.  
  18. Private Type XGroup
  19.     IndexList() As Integer
  20.     VertexList() As D3DVERTEX
  21.     mtVertexList() As D3DVERTEX
  22.     mat As D3DMATERIAL7
  23.     Texture As DirectDrawSurface7
  24.     TextureFileName As String
  25. End Type
  26.  
  27. Private dx As DirectX7
  28. Private RM As Direct3DRM3
  29.  
  30. Private TempMatrix As D3DMATRIX
  31. Private TranMatrix As D3DMATRIX
  32. Private RotMatrix As D3DMATRIX
  33. Private ScaleMatrix As D3DMATRIX
  34. Private GroupCount As Long
  35. Private Groups() As XGroup
  36. Private Box As D3DRMBOX
  37.  
  38. Private Active As Boolean
  39.  
  40. Public YawSpin As Single
  41. Public PitchSpin As Single
  42. Public FillMode As FillModeEnum
  43. Public ShadeMode As ShadeModeEnum
  44.  
  45. Public Enum FillModeEnum
  46.     Points = 1
  47.     Solid = 3
  48.     Wireframe = 2
  49. End Enum
  50.  
  51. Public Enum ShadeModeEnum
  52.     Gouraud = 2
  53.     Flat = 1
  54. End Enum
  55.  
  56.  
  57.  
  58.  
  59. ' Renders the group object to the backsurface
  60. Private Sub RenderGroup(groupid As Long, d3ddev As Direct3DDevice7)
  61.     On Local Error Resume Next
  62.     Dim mat As D3DMATERIAL7
  63.     Dim c As Long
  64.     With Groups(groupid)
  65.     
  66.         If (Not .Texture Is Nothing) Then
  67.             d3ddev.SetTexture 0, .Texture
  68.         Else
  69.             d3ddev.SetTexture 0, Nothing
  70.         End If
  71.         
  72.         d3ddev.SetMaterial .mat
  73.         
  74.         d3ddev.DrawIndexedPrimitive D3DPT_TRIANGLELIST, D3DFVF_VERTEX, _
  75.             .VertexList(0), UBound(.VertexList) + 1, .IndexList, _
  76.                 UBound(.IndexList), D3DDP_DEFAULT
  77.     End With
  78.                 
  79. End Sub
  80.  
  81.  
  82. Private Sub AddVertex(groupid As Long, Vertex As D3DVERTEX)
  83.     With Groups(groupid)
  84.         LSet .VertexList(UBound(.VertexList)) = Vertex
  85.         ReDim Preserve .VertexList(UBound(.VertexList) + 1)
  86.         ReDim .mtVertexList(UBound(.VertexList))
  87.     End With
  88. End Sub
  89.  
  90. Private Function VertexIndex(groupid As Long, Index As Long) As Long
  91.     With Groups(groupid)
  92.         VertexIndex = .IndexList(Index)
  93.     End With
  94. End Function
  95.  
  96. Private Sub AddVertexIndex(groupid As Long, VertexIndex As Long)
  97.     With Groups(groupid)
  98.         .IndexList(UBound(.IndexList)) = VertexIndex
  99.         ReDim Preserve .IndexList(UBound(.IndexList) + 1)
  100.     End With
  101. End Sub
  102.  
  103. Private Function IndexCount(groupid As Long) As Long
  104.     With Groups(groupid)
  105.         IndexCount = UBound(.IndexList) + 1
  106.     End With
  107. End Function
  108.  
  109.  
  110. Public Sub Rotate(rotPitch As Single, rotYaw As Single)
  111.     dx.RotateXMatrix TempMatrix, rotPitch
  112.     dx.MatrixMultiply RotMatrix, TempMatrix, RotMatrix
  113.     dx.RotateYMatrix TempMatrix, rotYaw
  114.     dx.MatrixMultiply RotMatrix, TempMatrix, RotMatrix
  115. End Sub
  116.  
  117. Public Sub SetPosition(tranX As Single, tranY As Single, tranZ As Single)
  118.     TranslateMatrix TranMatrix, MakeVector(tranX, tranY, tranZ)
  119. End Sub
  120. Public Sub AdjustScale(sx As Single, sy As Single, sz As Single)
  121.     With ScaleMatrix
  122.         .rc11 = sx
  123.         .rc22 = sy
  124.         .rc33 = sz
  125.     End With
  126. End Sub
  127.  
  128. Private Sub Class_Initialize()
  129.     ' setup the object's world matrix
  130.     Set dx = New DirectX7
  131.     ReDim Groups(0)
  132.     dx.IdentityMatrix RotMatrix
  133.     dx.IdentityMatrix ScaleMatrix
  134.     dx.IdentityMatrix TempMatrix
  135.     dx.IdentityMatrix TranMatrix
  136.     FillMode = Solid
  137.     ShadeMode = Gouraud
  138. End Sub
  139.  
  140. ' Loads an .X file into the scene.
  141. Public Sub Load(ddraw As DirectDraw7, dev As Direct3DDevice7, FileName As String)
  142.     
  143.  
  144.     Dim GIndex As Long
  145.     Dim IIndex As Long
  146.     Dim Index As Long
  147.     Dim ArraySize As Long
  148.     Dim IArray() As Long
  149.     Dim VertCount As Long
  150.     Dim FaceCount As Long
  151.     Dim FaceVertCount As Long
  152.     Dim TempVertex As D3DVERTEX
  153.     Dim TempRMVertex As D3DRMVERTEX
  154.     Dim TextureDesc As DDSURFACEDESC2
  155.     Dim frame As Direct3DRMFrame3
  156.     Dim strPath As String
  157.     Dim MeshB As Direct3DRMMeshBuilder3
  158.     Dim Mesh As Direct3DRMMesh
  159.  
  160.     strPath = StripFilenameFromPath(FileName)
  161.     
  162.     On Error GoTo XFileErr
  163.     
  164.     ' create the required retained mode objects... we're going to use
  165.     ' retained mode to do our dirty work instead of trying to parse
  166.     ' the .X file ourselves.
  167.     
  168.     Set RM = dx.Direct3DRMCreate
  169.     
  170.     Active = False
  171.     
  172.     ' try to load the .X file into a mesh
  173.     On Local Error Resume Next
  174.     Set MeshB = RM.CreateMeshBuilder
  175.     MeshB.LoadFromFile FileName, "", D3DRMLOAD_FIRST, Nothing, Nothing
  176.     
  177.     ' if that didnt work try loading it into a frame
  178.     If Err.Number <> 0 Then
  179.         Err.Clear
  180.         On Error GoTo XFileErr
  181.         Set MeshB = RM.CreateMeshBuilder
  182.         Set frame = RM.CreateFrame(Nothing)
  183.         frame.LoadFromFile FileName, "", D3DRMLOAD_FIRST, Nothing, Nothing
  184.         MeshB.AddFrame frame
  185.     End If
  186.     
  187.     MeshB.GetBox Box
  188.     
  189.     ' generate appropriate normals if they aren't already correct.
  190.     MeshB.GenerateNormals 3.14 / 4, D3DRMGENERATENORMALS_USECREASEANGLE
  191.     
  192.     ' use the meshbuilder information to create a mesh object.
  193.     ' it will be easier to parse from the mesh object than from the
  194.     ' meshbuilder.
  195.     Set Mesh = MeshB.CreateMesh
  196.     
  197.     ' resize our group object array
  198.     GroupCount = Mesh.GetGroupCount
  199.     ReDim Groups(GroupCount - 1)
  200.     
  201.     ' loop through the number of groups in the mesh
  202.     ' each group can contain a seperate texture
  203.     For GIndex = 0 To Mesh.GetGroupCount - 1
  204.         
  205.         ' get the required information for our parsing
  206.         With Groups(GIndex)
  207.             ReDim .IndexList(0)
  208.             ReDim .VertexList(0)
  209.             ReDim .mtVertexList(0)
  210.         End With
  211.  
  212.         
  213.         Mesh.GetSizes GIndex, VertCount, FaceCount, FaceVertCount, ArraySize
  214.         ReDim IArray(ArraySize)
  215.         
  216.         Mesh.GetGroupData GIndex, IArray()
  217.                        
  218.         
  219.         'setup our texture for this particular group object
  220.         If dev.GetDeviceGuid() = "IID_IDirect3DHALDevice" Then
  221.             TextureDesc.lFlags = DDSD_CAPS
  222.             TextureDesc.ddsCaps.lCaps = DDSCAPS_TEXTURE
  223.             TextureDesc.ddsCaps.lCaps2 = DDSCAPS2_TEXTUREMANAGE
  224.         Else
  225.             TextureDesc.lFlags = DDSD_CAPS
  226.             TextureDesc.ddsCaps.lCaps = DDSCAPS_TEXTURE Or DDSCAPS_SYSTEMMEMORY
  227.             TextureDesc.ddsCaps.lCaps2 = 0
  228.         End If
  229.         
  230.         
  231.         If Not Mesh.GetGroupTexture(GIndex) Is Nothing Then
  232.             On Local Error Resume Next
  233.             With Groups(GIndex)
  234.                 .TextureFileName = strPath + Mesh.GetGroupTexture(GIndex).GetName
  235.                 Set .Texture = ddraw.CreateSurfaceFromFile(.TextureFileName, TextureDesc)
  236.             End With
  237.             On Error GoTo XFileErr
  238.         End If
  239.     
  240.     
  241.         
  242.         Dim c As Long
  243.         Dim rmmat As Direct3DRMMaterial2
  244.         c = Mesh.GetGroupColor(GIndex)
  245.         Set rmmat = Mesh.GetGroupMaterial(GIndex)
  246.         
  247.         With Groups(GIndex).mat.diffuse
  248.             .a = dx.ColorGetAlpha(c)
  249.             .r = dx.ColorGetRed(c)
  250.             .g = dx.ColorGetGreen(c)
  251.             .b = dx.ColorGetBlue(c)
  252.         End With
  253.         With Groups(GIndex).mat.Ambient
  254.             rmmat.GetAmbient .r, .g, .b
  255.             .a = 1
  256.         End With
  257.         With Groups(GIndex).mat.specular
  258.             rmmat.GetSpecular .r, .g, .b
  259.             .a = 1
  260.         End With
  261.         With Groups(GIndex).mat.emissive
  262.             rmmat.GetEmissive .r, .g, .b
  263.             .a = 1
  264.         End With
  265.         Groups(GIndex).mat.power = rmmat.GetPower()
  266.  
  267.         
  268.         ' loop through the faces in the group
  269.         ' we'll need to deal with 4 verterice faces differently than
  270.         ' 3 sided.  we're adding indices to the group object here.
  271.         Dim fanIndex As Long
  272.         Dim j As Long
  273.         Dim bGetFaceCount As Boolean
  274.         
  275.         IIndex = 0
  276.         bGetFaceCount = False
  277.         If FaceVertCount = 0 Then bGetFaceCount = True
  278.         
  279.         Do While IIndex < ArraySize
  280.              If bGetFaceCount Then
  281.                 FaceVertCount = IArray(IIndex)
  282.                 IIndex = IIndex + 1
  283.              End If
  284.              
  285.  
  286.             fanIndex = IIndex
  287.                 
  288.                 
  289.             For j = 0 To FaceVertCount - 3
  290.                 'add the fan point
  291.                 AddVertexIndex GIndex, IArray(fanIndex)
  292.                 
  293.                 'add 2 other points
  294.                 AddVertexIndex GIndex, IArray(IIndex + j + 1)
  295.                 AddVertexIndex GIndex, IArray(IIndex + j + 2)
  296.             Next
  297.             IIndex = IIndex + FaceVertCount
  298.         Loop
  299.              
  300.         
  301.         ' loop through the vertices and add them to the group object.
  302.         For Index = 0 To VertCount - 1
  303.                 Mesh.GetVertex GIndex, Index, TempRMVertex
  304.                 With TempRMVertex
  305.                     TempVertex.x = .position.x
  306.                     TempVertex.y = .position.y
  307.                     TempVertex.z = .position.z
  308.                     TempVertex.nx = .Normal.x
  309.                     TempVertex.ny = .Normal.y
  310.                     TempVertex.nz = .Normal.z
  311.                     TempVertex.tu = .tu
  312.                     TempVertex.tv = .tv
  313.                 End With
  314.                 AddVertex GIndex, TempVertex
  315.         Next
  316.     Next
  317.     
  318.     Active = True
  319. Exit Sub
  320.  
  321. XFileErr:
  322.  
  323.     MsgBox "error loading xfile"
  324.     Active = False
  325. End Sub
  326.  
  327. Public Sub Render(d3ddev As Direct3DDevice7)
  328.     
  329.     On Local Error Resume Next
  330.  
  331.     Dim Index As Long
  332.  
  333.     If Not Active Then Exit Sub
  334.             
  335.     dx.RotateXMatrix TempMatrix, PitchSpin
  336.     dx.MatrixMultiply RotMatrix, TempMatrix, RotMatrix
  337.     dx.RotateYMatrix TempMatrix, YawSpin
  338.     dx.MatrixMultiply RotMatrix, TempMatrix, RotMatrix
  339.     
  340.     dx.MatrixMultiply TempMatrix, RotMatrix, TranMatrix
  341.     dx.MatrixMultiply TempMatrix, ScaleMatrix, TempMatrix
  342.     
  343.     
  344.     d3ddev.SetTransform D3DTRANSFORMSTATE_WORLD, TempMatrix
  345.     
  346.     d3ddev.SetRenderState D3DRENDERSTATE_FILLMODE, CLng(FillMode)
  347.     d3ddev.SetRenderState D3DRENDERSTATE_SHADEMODE, CLng(ShadeMode)
  348.     
  349.     
  350.     ' render each group
  351.     For Index = 0 To UBound(Groups)
  352.         RenderGroup Index, d3ddev
  353.     Next
  354.     
  355.  
  356. End Sub
  357.  
  358. Private Function StripFilenameFromPath(sPath As String) As String
  359.     Dim Q As Integer
  360.     Dim r As Integer
  361.     
  362.     'do we have a path string
  363.     r = InStr(sPath, "\")
  364.     If r = 0 Then Exit Function
  365.  
  366.     Do While r <> 0
  367.         Q = r
  368.         r = InStr(r + 1, sPath, "\")
  369.     Loop
  370.     
  371.     StripFilenameFromPath = Mid$(sPath, 1, Q)
  372. End Function
  373.  
  374. Public Function GetMinExtent(X1 As Single, Y1 As Single, z1 As Single)
  375.     X1 = Box.Min.x
  376.     Y1 = Box.Min.y
  377.     z1 = Box.Min.z
  378. End Function
  379.  
  380. Public Function GetMaxExtent(X2 As Single, Y2 As Single, z2 As Single)
  381.     X2 = Box.Max.x
  382.     Y2 = Box.Max.y
  383.     z2 = Box.Max.z
  384. End Function
  385.  
  386. Public Function ReloadTextures(ddraw As DirectDraw7, dev As Direct3DDevice7)
  387.     On Local Error Resume Next
  388.     Dim i As Long
  389.     Dim TextureDesc As DDSURFACEDESC2
  390.             
  391.     
  392.     'setup our texture for this particular group object
  393.     If dev.GetDeviceGuid() = "IID_IDirect3DHALDevice" Then
  394.         TextureDesc.lFlags = DDSD_CAPS
  395.         TextureDesc.ddsCaps.lCaps = DDSCAPS_TEXTURE
  396.         TextureDesc.ddsCaps.lCaps2 = DDSCAPS2_TEXTUREMANAGE
  397.     Else
  398.         TextureDesc.lFlags = DDSD_CAPS
  399.         TextureDesc.ddsCaps.lCaps = DDSCAPS_TEXTURE Or DDSCAPS_SYSTEMMEMORY
  400.         TextureDesc.ddsCaps.lCaps2 = 0
  401.     End If
  402.                 
  403.     For i = 0 To GroupCount - 1
  404.         With Groups(i)
  405.             Set .Texture = ddraw.CreateSurfaceFromFile(.TextureFileName, TextureDesc)
  406.         End With
  407.     Next
  408. End Function
  409.  
  410.  
  411.  
  412. Private Function MakeVector(x As Single, y As Single, z As Single) As D3DVECTOR
  413.     Dim v As D3DVECTOR
  414.     v.x = x
  415.     v.y = y
  416.     v.z = z
  417.     MakeVector = v
  418. End Function
  419.  
  420.  
  421.  
  422.