Animation (ConvertToIndexedBlendedMesh)

Started by
2 comments, last by ankhd 16 years, 1 month ago
I have been trying for weeks to get animation going and I'm going crazy. I'm using vb.net 2003 with Dec 2004 Update. I'm using the tiny.x model In the code below if I use SystemMemoryMesh I can load and display the model fine no problem, in fact I put the code to run the static model in to make sure my paths were ok. And they are. The problem I'm having now is with the ConvertToIndexedBlendedMesh function. The NumberPaletteEntries and maxFaceInfluence are coming up as 0 Now maxFaceInfluences Is showing 6841 or around there,so I'm reading something out of the model. The bottom line is that I can't get past ConvertToIndexedBlendedMesh because it's catching an exception. Maybe someone who has been through this can help. Thanks Steve

Imports System.IO
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports Direct3D = Microsoft.DirectX.Direct3D
Namespace Animation
    Public Class AnimationClass
        Implements IDisposable
        Private Device As Device = Nothing
        Public FileName As String = Nothing
        Private WorldPosition As WorldPosition
        ' Fields
        'Private camera As ModelViewerCamera = New ModelViewerCamera
        Private Const ChangeDevice As Integer = 4
        Private Shared ReadOnly Color2 As ColorValue = New ColorValue(0.25!, 0.25!, 0.25!, 1.0!)
        Private effect As effect = Nothing
        'Private hud As Dialog = Nothing
        Private isHelpShowing As Boolean = False
        Private objectCenter As Vector3
        Private objectRadius As Single = 0.0F
        Private rootFrame As AnimationRootFrame
        'Private sampleFramework As Framework = Nothing
        Private statsFont As Font = Nothing
        Private textSprite As Sprite = Nothing
        Private Const ToggleFullscreen As Integer = 1
        Private Const ToggleReference As Integer = 3
        Private Shared ReadOnly WhiteColor As ColorValue = New ColorValue(1.0!, 1.0!, 1.0!, 1.0!)
        Private SystemMemoryMesh As Mesh = Nothing ' SysMem Mesh, Lives Through Resize
        Private LocalMemoryMesh As Mesh = Nothing ' Local Mesh, Rebuilt On Resize
        Private IsUsingMeshMaterials As Boolean = True
        Private SystemMemoryVertexBuffer As VertexBuffer = Nothing
        Private LocalMemoryVertexBuffer As VertexBuffer = Nothing
        Private SystemMemoryIndexBuffer As IndexBuffer = Nothing
        Private LocalMemoryIndexBuffer As IndexBuffer = Nothing
        Private LocalBoundingSphere As Sphere
        Private Materials As Direct3D.Material() = Nothing
        Public Textures As Texture() = Nothing



        Public Property Position() As WorldPosition
            Get
                Return WorldPosition
            End Get
            Set(ByVal Value As WorldPosition)
                WorldPosition = Value
            End Set
        End Property


        Private ActualVelocity As Single

        Public Property Velocity() As Single
            Get
                Return ActualVelocity
            End Get
            Set(ByVal Value As Single)
                ActualVelocity = Value
            End Set
        End Property
        '/ <Summary>
        '/ The System Memory Mesh
        '/ </Summary>

        Public ReadOnly Property SystemMesh() As Mesh
            Get
                Return SystemMemoryMesh
            End Get
        End Property
        '/ <Summary>
        '/ The Local Memory Mesh
        '/ </Summary>

        Public ReadOnly Property LocalMesh() As Mesh
            Get
                Return LocalMemoryMesh
            End Get
        End Property
        '/ <Summary>
        '/ Should We Use The Mesh Materials
        '/ </Summary>

        Public WriteOnly Property IsUsingMaterials() As Boolean
            Set(ByVal Value As Boolean)
                IsUsingMeshMaterials = Value
            End Set
        End Property
        '/<Summary>
        '/The Bounding Sphere
        '/</Summary>

        Public ReadOnly Property BoundingSphere() As Sphere
            Get
                Return LocalBoundingSphere
            End Get
        End Property

        Public Sub New(ByVal Filename As String)
            Filename = Filename
        End Sub 'New
        Public Sub New()
            MyClass.New("AnimPositonedMesh")
        End Sub 'New

        Public Sub New(ByVal Device As Device, ByVal Filename As String)
            CreateAnim(Device, Filename)
        End Sub 'New
        Private Sub DrawFrame(ByVal frame As AnimationFrame)
            Dim container As AnimationMeshContainer = CType(frame.MeshContainer, AnimationMeshContainer)
            Do While (Not container Is Nothing)
                Me.DrawMeshContainer(container, frame)
                container = CType(container.NextContainer, AnimationMeshContainer)
            Loop
            If (Not frame.FrameSibling Is Nothing) Then
                Me.DrawFrame(CType(frame.FrameSibling, AnimationFrame))
            End If
            If (Not frame.FrameFirstChild Is Nothing) Then
                Me.DrawFrame(CType(frame.FrameFirstChild, AnimationFrame))
            End If
        End Sub
        Private Sub DrawMeshContainer(ByVal mesh As AnimationMeshContainer, ByVal parent As AnimationFrame)
            Dim device As Device = Me.Device
            If (Not mesh.SkinInformation Is Nothing) Then
                If (mesh.NumberInfluences = 1) Then
                    device.RenderState.VertexBlend = VertexBlend.ZeroWeights
                Else
                    device.RenderState.VertexBlend = CType((mesh.NumberInfluences - 1), VertexBlend)
                End If
                If (mesh.NumberInfluences > 0) Then
                    device.RenderState.IndexedVertexBlendEnable = True
                End If
                Dim bones As BoneCombination() = mesh.GetBones
                Dim i As Integer
                For i = 0 To mesh.NumberAttributes - 1
                    Dim j As Integer
                    For j = 0 To mesh.NumberPaletteEntries - 1
                        Dim index As Integer = bones(i).BoneId(j)
                        If (index <> -1) Then
                            device.Transform.SetWorldMatrixByIndex(j, Matrix.Multiply(mesh.GetOffsetMatrices(index), mesh.GetFrames(index).CombinedTransformationMatrix))
                        End If
                    Next j
                    device.Material = mesh.GetMaterials(bones(i).AttributeId).Material3D
                    device.SetTexture(0, mesh.GetTextures(bones(i).AttributeId))
                    mesh.MeshData.Mesh.DrawSubset(i)
                Next i
            Else
                device.RenderState.VertexBlend = VertexBlend.Disable
                device.Transform.World = parent.CombinedTransformationMatrix
                Dim materials As ExtendedMaterial() = mesh.GetMaterials
                Dim k As Integer
                For k = 0 To materials.Length - 1
                    device.Material = materials(k).Material3D
                    device.SetTexture(0, mesh.GetTextures(k))
                    mesh.MeshData.Mesh.DrawSubset(k)
                Next k
            End If
        End Sub


        Public Sub GenerateSkinnedMesh(ByVal mesh As AnimationMeshContainer)
            Dim maxFaceInfluences As Integer
            If (mesh.SkinInformation Is Nothing) Then
                Throw New ArgumentException
            End If
            Dim optimizeVertexCache As MeshFlags = MeshFlags.OptimizeVertexCache
            Dim deviceCaps As Caps '= Me.sampleFramework.DeviceCaps
            If deviceCaps.VertexShaderVersion.CompareTo(New Version(1, 1)) >= 0 Then
                optimizeVertexCache = (optimizeVertexCache Or MeshFlags.Managed)
            Else
                optimizeVertexCache = (optimizeVertexCache Or MeshFlags.SystemMemory)
            End If
            Dim buffer As IndexBuffer = mesh.MeshData.Mesh.IndexBuffer
            Try
                maxFaceInfluences = mesh.SkinInformation.GetMaxFaceInfluences(buffer, mesh.MeshData.Mesh.NumberFaces)
            Finally
                  CType(buffer, IDisposable).Dispose()
            End Try
           
            maxFaceInfluences = Math.Min(maxFaceInfluences, 12)
            If ((deviceCaps.MaxVertexBlendMatrixIndex + 1) >= maxFaceInfluences) Then
                mesh.NumberPaletteEntries = Math.Min(((deviceCaps.MaxVertexBlendMatrixIndex + 1) / 2), mesh.SkinInformation.NumberBones)
                optimizeVertexCache = (optimizeVertexCache Or MeshFlags.Managed)
            End If
            Dim maxFaceInfluence As Integer = 0
            Dim boneCombinationTable As BoneCombination() = Nothing
            Dim meshData As MeshData = mesh.MeshData
            meshData.Mesh = mesh.SkinInformation.ConvertToIndexedBlendedMesh(meshData.Mesh, optimizeVertexCache, mesh.GetAdjacencyStream, mesh.NumberPaletteEntries, maxFaceInfluence, boneCombinationTable)
            mesh.NumberInfluences = maxFaceInfluence
            mesh.SetBones(boneCombinationTable)
            mesh.NumberAttributes = boneCombinationTable.Length
            mesh.MeshData = meshData
        End Sub

        Public Sub CreateAnim(ByVal Device As Device, ByVal Filename As String)
            WorldPosition = New WorldPosition
            Dim AdjacencyBuffer As GraphicsStream
            Dim Mat() As ExtendedMaterial
            Me.Device = Device
            If Not (Device Is Nothing) Then
                AddHandler Device.DeviceLost, AddressOf Me.InvalidateDeviceObjects
                AddHandler Device.Disposing, AddressOf Me.InvalidateDeviceObjects
                AddHandler Device.DeviceReset, AddressOf Me.RestoreDeviceObjects
            End If
            Dim alloc As New AnimationAllocation(Me)

            Filename = MediaUtilities.FindFile(Filename)
            'SystemMemoryMesh = Mesh.FromFile(Filename, MeshFlags.SystemMemory, Device, AdjacencyBuffer, Mat)
            rootFrame = Mesh.LoadHierarchyFromFile(Filename, MeshFlags.SystemMemory, Device, alloc, Nothing)
            Dim TempMesh As Mesh = Nothing
            Dim ErrorString As String
            TempMesh = Mesh.Clean(CleanType.Optimization, SystemMemoryMesh, AdjacencyBuffer, AdjacencyBuffer, ErrorString)
            If Not TempMesh.Equals(SystemMemoryMesh) Then
                SystemMemoryMesh.Dispose()
                SystemMemoryMesh = TempMesh
            End If

            ' Optimize The Mesh For Performance
            Dim Flags As MeshFlags = MeshFlags.OptimizeCompact Or MeshFlags.OptimizeAttributeSort Or MeshFlags.OptimizeVertexCache
            SystemMemoryMesh.OptimizeInPlace(Flags, AdjacencyBuffer)
            AdjacencyBuffer.Close()
            AdjacencyBuffer = Nothing
            ' Setup Bounding Volumes
            Dim Vb As VertexBuffer = SystemMemoryMesh.VertexBuffer
            Dim VertexData As GraphicsStream = Vb.Lock(0, 0, LockFlags.ReadOnly)
            LocalBoundingSphere.Radius = Geometry.ComputeBoundingSphere(VertexData, SystemMemoryMesh.NumberVertices, SystemMemoryMesh.VertexFormat, BoundingSphere.CenterPoint)
            Vb.Unlock()
            Vb.Dispose()

            Textures = New Texture(Mat.Length) {}
            Materials = New Direct3D.Material(Mat.Length) {}

            Dim I As Integer
            For I = 0 To Mat.Length - 1
                Materials(I) = Mat(I).Material3D
                ' Set The Ambient Color For The Material (D3DX Does Not Do This)
                Materials(I).Ambient = Materials(I).Diffuse

                If Not (Mat(I).TextureFilename Is Nothing) Then
                    ' Create The Texture
                    Textures(I) = TextureLoader.FromFile(Device, MediaUtilities.FindFile(Mat(I).TextureFilename))
                End If
            Next I

            ''   rootFrame = SystemMemoryMesh.LoadHierarchyFromFile(Filename, MeshFlags.Managed, Device, alloc, Nothing)
            ' Restore the folder

            ' Calculate the center and radius of a bounding sphere
            objectRadius = Frame.CalculateBoundingSphere(rootFrame.FrameHierarchy, objectCenter)

            ' Setup the matrices for animation
            SetupBoneMatrices(CType(rootFrame.FrameHierarchy, AnimationFrame))
            RestoreDeviceObjects(Device, Nothing)
        End Sub
        Public Sub SetVertexFormat(ByVal Device As Device, ByVal Format As VertexFormats)

            Dim PTempSysMemMesh As Mesh = Nothing
            Dim PTempLocalMesh As Mesh = Nothing

            If Not (SystemMemoryMesh Is Nothing) Then
                PTempSysMemMesh = SystemMemoryMesh.Clone(MeshFlags.SystemMemory, Format, Device)
            End If
            If Not (LocalMemoryMesh Is Nothing) Then
                Try
                    PTempLocalMesh = LocalMemoryMesh.Clone(0, Format, Device)
                Catch E As Exception
                    PTempSysMemMesh.Dispose()
                    PTempSysMemMesh = Nothing
                    Throw E
                End Try
            End If

            If Not (SystemMemoryMesh Is Nothing) Then
                SystemMemoryMesh.Dispose()
            End If
            SystemMemoryMesh = Nothing

            If Not (LocalMemoryMesh Is Nothing) Then
                LocalMemoryMesh.Dispose()
            End If
            LocalMemoryMesh = Nothing

            ' Clean Up Any Vertex/Index Buffers
            DisposeLocalBuffers(True, True)

            If Not (PTempSysMemMesh Is Nothing) Then
                SystemMemoryMesh = PTempSysMemMesh
            End If
            If Not (PTempLocalMesh Is Nothing) Then
                LocalMemoryMesh = PTempLocalMesh
            End If
            ' Compute Normals In Case The Meshes Have Them
            If Not (SystemMemoryMesh Is Nothing) Then
                SystemMemoryMesh.ComputeNormals()

            End If
            If Not (LocalMemoryMesh Is Nothing) Then
                LocalMemoryMesh.ComputeNormals()
            End If
        End Sub 'SetVertexFormat
        Public Sub RestoreDeviceObjects(ByVal Sender As Object, ByVal E As EventArgs)
            If SystemMemoryMesh.Equals(Nothing) Then
                Throw New ArgumentException
            End If
            Dim Device As Device = CType(Sender, Device)
            ' Make A Local Memory Version Of The Mesh.
            LocalMemoryMesh = SystemMemoryMesh.Clone(MeshFlags.VbWriteOnly Or MeshFlags.IbWriteOnly, SystemMemoryMesh.VertexFormat, Device)
            ' Clean Up Any Vertex/Index Buffers
            DisposeLocalBuffers(False, True)
        End Sub 'RestoreDeviceObjects
        Public Sub InvalidateDeviceObjects(ByVal Sender As Object, ByVal E As EventArgs)
            If Not (LocalMemoryMesh Is Nothing) Then
                LocalMemoryMesh.Dispose()
            End If
            LocalMemoryMesh = Nothing
            ' Clean Up Any Vertex/Index Buffers
            DisposeLocalBuffers(False, True)
        End Sub 'InvalidateDeviceObjects

        Public Sub OnFrameMove(ByVal device As Device, ByVal appTime As Double, ByVal elapsedTime As Single)
            'Me.camera.FrameMove(elapsedTime)
            Dim parentMatrix As Matrix ' = (Matrix.Translation(Vector3.op_UnaryNegation(Me.objectCenter)) * Me.camera.WorldMatrix)
            device.Transform.World = parentMatrix
            If (elapsedTime > 0.0!) Then
                If (Not Me.rootFrame.AnimationController Is Nothing) Then
                    Me.rootFrame.AnimationController.AdvanceTime(CDbl(elapsedTime))
                End If
                Me.UpdateFrameMatrices(CType(Me.rootFrame.FrameHierarchy, AnimationFrame), parentMatrix)
            End If
        End Sub
        Public ReadOnly Property SystemVertexBuffer() As VertexBuffer
            Get
                If Not (SystemMemoryVertexBuffer Is Nothing) Then
                    Return SystemMemoryVertexBuffer
                End If
                If SystemMemoryMesh Is Nothing Then
                    Return Nothing
                End If
                SystemMemoryVertexBuffer = SystemMemoryMesh.VertexBuffer
                Return SystemMemoryVertexBuffer
            End Get
        End Property

        '/ <Summary>
        '/ Get The Vertex Buffer Assigned To The Local Mesh
        '/ </Summary>

        Public ReadOnly Property LocalVertexBuffer() As VertexBuffer
            Get
                If Not (LocalMemoryVertexBuffer Is Nothing) Then
                    Return LocalMemoryVertexBuffer
                End If
                If LocalMemoryMesh Is Nothing Then
                    Return Nothing
                End If
                LocalMemoryVertexBuffer = LocalMemoryMesh.VertexBuffer
                Return LocalMemoryVertexBuffer
            End Get
        End Property

        '/ <Summary>
        '/ Get The Index Buffer Assigned To The System Mesh
        '/ </Summary>

        Public ReadOnly Property SystemIndexBuffer() As IndexBuffer
            Get
                If Not (SystemMemoryIndexBuffer Is Nothing) Then
                    Return SystemMemoryIndexBuffer
                End If
                If SystemMemoryMesh Is Nothing Then
                    Return Nothing
                End If
                SystemMemoryIndexBuffer = SystemMemoryMesh.IndexBuffer
                Return SystemMemoryIndexBuffer
            End Get
        End Property

        '/ <Summary>
        '/ Get The Index Buffer Assigned To The Local Mesh
        '/ </Summary>

        Public ReadOnly Property LocalIndexBuffer() As IndexBuffer
            Get
                If Not (LocalMemoryIndexBuffer Is Nothing) Then
                    Return LocalMemoryIndexBuffer
                End If
                If LocalMemoryMesh Is Nothing Then
                    Return Nothing
                End If
                LocalMemoryIndexBuffer = LocalMemoryMesh.IndexBuffer
                Return LocalMemoryIndexBuffer
            End Get
        End Property


        '/ <Summary>
        '/ Clean Up Any Resources
        '/ </Summary>
        Public Overloads Sub Dispose() Implements IDisposable.Dispose
            If Not (Textures Is Nothing) Then
                Dim I As Integer
                For I = 0 To Textures.Length - 1
                    If Not (Textures(I) Is Nothing) Then
                        Textures(I) = Nothing
                    End If
                Next I
                Textures = Nothing
            End If

            ' Clean Up Any Vertex/Index Buffers
            DisposeLocalBuffers(True, True)

            ' Clean Up Any Memory
            If Not (SystemMemoryMesh Is Nothing) Then
                SystemMemoryMesh.Dispose()
            End If
            SystemMemoryMesh = Nothing

            ' In Case The Finalizer Hasn'T Been Called Yet.
            GC.SuppressFinalize(Me)
        End Sub 'Dispose


        Public Overloads Sub Render(ByVal CanDrawOpaque As Boolean, ByVal CanDrawAlpha As Boolean)
            If LocalMemoryMesh Is Nothing Then
                Throw New ArgumentException
            End If

            ' Set The World Transform
            Device.Transform.World = WorldPosition.WorldMatrix
            Dim Rs As RenderStateManager = Device.RenderState
            ' Frist, Draw The Subsets Without Alpha
            If CanDrawOpaque Then
                Dim I As Integer
                For I = 0 To Materials.Length - 1
                    If IsUsingMeshMaterials Then
                        If CanDrawAlpha Then
                            If Materials(I).Diffuse.A < &HFF Then
                                Exit For
                            End If
                        End If
                        Device.Material = Materials(I)
                        If Not (Textures(I) Is Nothing) Then
                            Device.SetTexture(0, Textures(I))
                        Else
                            Device.SetTexture(0, Nothing)
                        End If
                    End If
                    LocalMemoryMesh.DrawSubset(I)
                Next I
            End If

            ' Then, Draw The Subsets With Alpha
            If CanDrawAlpha And IsUsingMeshMaterials Then
                ' Enable Alpha Blending
                Rs.AlphaBlendEnable = True
                Rs.SourceBlend = Blend.SourceAlpha
                Rs.DestinationBlend = Blend.InvSourceAlpha
                Dim I As Integer
                For I = 0 To Materials.Length - 1
                    If Materials(I).Diffuse.A = &HFF Then
                        Exit For
                    End If
                    ' Set The Material And Texture
                    Device.Material = Materials(I)


                    If Not (Textures(I) Is Nothing) Then
                        Device.SetTexture(0, Textures(I))
                    Else
                        Device.SetTexture(0, Nothing)
                    End If

                    LocalMemoryMesh.DrawSubset(I)
                Next I
                ' Restore State
                Rs.AlphaBlendEnable = False
            End If
            '' DrawFrame(CType(rootFrame.FrameHierarchy, AnimationFrame))
        End Sub 'Render
        Public Overloads Sub Render()
            Render(True, True)

        End Sub 'Render
        Private Sub DisposeLocalBuffers(ByVal SystemBuffers As Boolean, ByVal LocalBuffers As Boolean)
            If SystemBuffers Then
                If Not (SystemMemoryIndexBuffer Is Nothing) Then
                    SystemMemoryIndexBuffer.Dispose()
                End If
                SystemMemoryIndexBuffer = Nothing

                If Not (SystemMemoryVertexBuffer Is Nothing) Then
                    SystemMemoryVertexBuffer.Dispose()
                End If
                SystemMemoryVertexBuffer = Nothing
            End If
            If LocalBuffers Then
                If Not (LocalMemoryIndexBuffer Is Nothing) Then
                    LocalMemoryIndexBuffer.Dispose()
                End If
                LocalMemoryIndexBuffer = Nothing

                If Not (LocalMemoryVertexBuffer Is Nothing) Then
                    LocalMemoryVertexBuffer.Dispose()
                End If
                LocalMemoryVertexBuffer = Nothing
            End If
        End Sub 'DisposeLocalBuffers
        Private Sub SetupBoneMatrices(ByVal frame As AnimationFrame)
            If (Not frame.MeshContainer Is Nothing) Then
                Me.SetupBoneMatrices(CType(frame.MeshContainer, AnimationMeshContainer))
            End If
            If (Not frame.FrameSibling Is Nothing) Then
                Me.SetupBoneMatrices(CType(frame.FrameSibling, AnimationFrame))
            End If
            If (Not frame.FrameFirstChild Is Nothing) Then
                Me.SetupBoneMatrices(CType(frame.FrameFirstChild, AnimationFrame))
            End If
        End Sub

        Private Sub SetupBoneMatrices(ByVal mesh As AnimationMeshContainer)
            If (Not mesh.SkinInformation Is Nothing) Then
                Dim numberBones As Integer = mesh.SkinInformation.NumberBones
                Dim frames As AnimationFrame() = New AnimationFrame(numberBones - 1) {}
                Dim i As Integer
                For i = 0 To numberBones - 1
                    Dim frame As AnimationFrame = CType(frame.Find(Me.rootFrame.FrameHierarchy, mesh.SkinInformation.GetBoneName(i)), AnimationFrame)
                    If (frame Is Nothing) Then
                        Throw New InvalidOperationException("Could not find valid bone.")
                    End If
                    frames(i) = frame
                Next i
                mesh.SetFrames(frames)
            End If
        End Sub
        Private Sub UpdateFrameMatrices(ByVal frame As AnimationFrame, ByVal parentMatrix As Matrix)
            frame.CombinedTransformationMatrix = Matrix.Multiply(frame.TransformationMatrix, parentMatrix)
            If (Not frame.FrameSibling Is Nothing) Then
                Me.UpdateFrameMatrices(CType(frame.FrameSibling, AnimationFrame), parentMatrix)
            End If
            If (Not frame.FrameFirstChild Is Nothing) Then
                Me.UpdateFrameMatrices(CType(frame.FrameFirstChild, AnimationFrame), frame.CombinedTransformationMatrix)
            End If
        End Sub
    End Class
    Public Class AnimationAllocation
        Inherits AllocateHierarchy
        Private parent As AnimationClass = Nothing
        ''' <summary>Create new instance of this class</summary>
        Public Sub New(ByVal p As AnimationClass)
            parent = p
        End Sub
        ''' <summary>Create a new frame</summary>
        Public Overrides Function CreateFrame(ByVal name As String) As Direct3D.Frame
            Dim frame As New AnimationFrame
            frame.Name = name
            frame.TransformationMatrix = Matrix.Identity
            frame.CombinedTransformationMatrix = Matrix.Identity

            Return frame
        End Function
        Public Overrides Function CreateMeshContainer(ByVal name As String, ByVal meshData As MeshData, ByVal materials As ExtendedMaterial(), ByVal effectInstances As EffectInstance(), ByVal adjacency As GraphicsStream, ByVal skinInfo As SkinInformation) As MeshContainer
            If (meshData.Mesh Is Nothing) Then
                Throw New ArgumentException
            End If
            If (meshData.Mesh.VertexFormat = VertexFormats.Texture0) Then
                Throw New ArgumentException
            End If
            Dim container As New AnimationMeshContainer
            container.Name = name
            Dim numberFaces As Integer = meshData.Mesh.NumberFaces
            Dim device As Device = meshData.Mesh.Device
            If ((meshData.Mesh.VertexFormat And VertexFormats.Normal) = VertexFormats.Texture0) Then
                Dim mesh As Mesh = meshData.Mesh.Clone(meshData.Mesh.Options.Value, (meshData.Mesh.VertexFormat Or VertexFormats.Normal), device)
                meshData.Mesh.Dispose()
                meshData.Mesh = mesh
                meshData.Mesh.ComputeNormals()
            End If
            container.SetMaterials(materials)
            container.SetAdjacency(adjacency)
            Dim textures As Texture() = New Texture(materials.Length - 1) {}
            Dim i As Integer
            For i = 0 To materials.Length - 1
                If (Not materials(i).TextureFilename Is Nothing) Then
                    ''textures(i) = ResourceCache.GetGlobalInstance.CreateTextureFromFile(device, materials(i).TextureFilename)
                    textures(i) = TextureLoader.FromFile(device, MediaUtilities.FindFile(materials(i).TextureFilename))
                End If
            Next i
            container.SetTextures(textures)
            container.MeshData = meshData
            If (Not skinInfo Is Nothing) Then
                container.SkinInformation = skinInfo
                Dim numberBones As Integer = skinInfo.NumberBones
                Dim matrices As Matrix() = New Matrix(numberBones - 1) {}
                Dim j As Integer
                For j = 0 To numberBones - 1
                    matrices(j) = skinInfo.GetBoneOffsetMatrix(j)
                Next j
                container.SetOffsetMatrices(matrices)
                parent.GenerateSkinnedMesh(container)
            End If
            Return container
        End Function
    End Class
    Public Class AnimationFrame
        Inherits Frame
        ' Store the combined transformation matrix
        Private combined As Matrix = Matrix.Identity
        ''' <summary>The combined transformation matrix</summary>
        Public Property CombinedTransformationMatrix() As Matrix
            Get
                Return combined
            End Get
            Set(ByVal value As Matrix)
                combined = value
            End Set
        End Property
    End Class
    Public Class AnimationMeshContainer
        Inherits MeshContainer
        ' Methods
        Public Function GetBones() As BoneCombination()
            Return Me.bones
        End Function

        Public Function GetFrames() As AnimationFrame()
            Return Me.frameMatrices
        End Function

        Public Function GetOffsetMatrices() As Matrix()
            Return Me.offsetMatrices
        End Function

        Public Function GetTextures() As Texture()
            Return Me.meshTextures
        End Function

        Public Sub SetBones(ByVal b As BoneCombination())
            Me.bones = b
        End Sub

        Public Sub SetFrames(ByVal frames As AnimationFrame())
            Me.frameMatrices = frames
        End Sub

        Public Sub SetOffsetMatrices(ByVal matrices As Matrix())
            Me.offsetMatrices = matrices
        End Sub

        Public Sub SetTextures(ByVal textures As Texture())
            Me.meshTextures = textures
        End Sub


        ' Properties
        Public Property NumberAttributes() As Integer
            Get
                Return Me.numAttributes
            End Get
            Set(ByVal value As Integer)
                Me.numAttributes = value
            End Set
        End Property

        Public Property NumberInfluences() As Integer
            Get
                Return Me.numInfluences
            End Get
            Set(ByVal value As Integer)
                Me.numInfluences = value
            End Set
        End Property

        Public Property NumberPaletteEntries() As Integer
            Get
                Return Me.numPalette
            End Get
            Set(ByVal value As Integer)
                Me.numPalette = value
            End Set
        End Property


        ' Fields
        Private bones As BoneCombination()
        Private frameMatrices As AnimationFrame()
        Private meshTextures As Texture() = Nothing
        Private numAttributes As Integer = 0
        Private numInfluences As Integer = 0
        Private numPalette As Integer = 0
        Private offsetMatrices As Matrix()
    End Class
End Namespace












Advertisement
H there, this is one way Ive done it but it's in cpp
I'll post the code you may be able to work some thing out from it

BuildSkinnedMesh(LPDIRECT3DDEVICE9 Device, ID3DXMesh* mesh){	//----------------------------------------------------------------------	// First add a normal component and 2D texture coordinates component.	D3DVERTEXELEMENT9 elements[64];	UINT numElements = 0;	VertexPNT::Decl->GetDeclaration(elements, &numElements);	ID3DXMesh* tempMesh = 0;	HRESULT hr = mesh->CloneMesh(D3DXMESH_SYSTEMMEM, elements, Device, &tempMesh);	if(FAILED(hr))	{		MessageBox(NULL,"Failed To Clone Mesh", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);	}	 	if(!HasNormals(tempMesh))	{		hr = D3DXComputeNormals(tempMesh, 0);		if(FAILED(hr))		{			MessageBox(NULL,"Failed To ComputeNormals", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);		}	}	//----------------------------------------------------------------	// Optimize the mesh; in particular, the vertex cache.	DWORD* adj = new DWORD[tempMesh->GetNumFaces()*3];	ID3DXBuffer* remap = 0;	hr = tempMesh->GenerateAdjacency(EPSILON, adj);	if(FAILED(hr))	{			MessageBox(NULL,"Failed To Generate Adjacency", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);	}	ID3DXMesh* optimizedTempMesh = 0;	hr = tempMesh->Optimize(D3DXMESH_SYSTEMMEM | D3DXMESHOPT_VERTEXCACHE | 							D3DXMESHOPT_ATTRSORT, adj, 0, 0, &remap, &optimizedTempMesh);	if(FAILED(hr))	{			MessageBox(NULL,"Failed To Optimize Mesh", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);	}	SAFE_RELEASE(tempMesh); // Done w/ this mesh.	delete[] adj;         // Done with buffer.	// In the .X file (specifically the array DWORD vertexIndices[nWeights]	// data member of the SkinWeights template) each bone has an array of	// indices which identify the vertices of the mesh that the bone influences.	// Because we have just rearranged the vertices (from optimizing), the vertex 	// indices of a bone are obviously incorrect (i.e., they index to vertices the bone	// does not influence since we moved vertices around).  In order to update a bone's 	// vertex indices to the vertices the bone _does_ influence, we simply need to specify	// where we remapped the vertices to, so that the vertex indices can be updated to 	// match.  This is done with the ID3DXSkinInfo::Remap method.	hr = m_SkinInfo->Remap(optimizedTempMesh->GetNumVertices(), 						(DWORD*)remap->GetBufferPointer());	if(FAILED(hr))		{			MessageBox(NULL,"Failed To Remap", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);		}	SAFE_RELEASE(remap); // Done with remap info.	//-----------------------------------------------------------------------------	// The vertex format of the source mesh does not include vertex weights 	// nor bone index data, which are both needed for vertex blending.	// Therefore, we must convert the source mesh to an "indexed-blended-mesh,"	// which does have the necessary data.	DWORD        numBoneComboEntries = 0;	ID3DXBuffer* boneComboTable      = 0;	hr = m_SkinInfo->ConvertToIndexedBlendedMesh(optimizedTempMesh, D3DXMESH_MANAGED | D3DXMESH_WRITEONLY,  											MAX_NUM_BONES_SUPPORTED, 0, 0, 0, 0, &m_MaxVertInfluences,											&numBoneComboEntries, &boneComboTable, &m_SkinnedMesh);	if(FAILED(hr))	{		MessageBox(NULL,"Failed To ConvertToIndexedBlendedMesh", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);	}	SAFE_RELEASE(optimizedTempMesh); // Done with tempMesh.	SAFE_RELEASE(boneComboTable); // Don't need bone table.#if defined(DEBUG) | defined(_DEBUG)	// Output to the debug output the vertex declaration of the mesh at this point.	// This is for insight only to see what exactly ConvertToIndexedBlendedMesh	// does to the vertex declaration.	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];	hr = m_SkinnedMesh->GetDeclaration(elems);	if(FAILED(hr))	{		MessageBox(NULL,"Failed To GetDeclaraction 2", "SkinnedMesh::BuildSkinnedMesh()", MB_OK);	}		OutputDebugString("\nVertex Format After ConvertToIndexedBlendedMesh\n");	int i = 0;	while( elems.Stream != 0xff ) // While not D3DDECL_END()	{		if( elems.Type == D3DDECLTYPE_FLOAT1)			OutputDebugString("Type = D3DDECLTYPE_FLOAT1; ");		if( elems.Type == D3DDECLTYPE_FLOAT2)			OutputDebugString("Type = D3DDECLTYPE_FLOAT2; ");		if( elems.Type == D3DDECLTYPE_FLOAT3)			OutputDebugString("Type = D3DDECLTYPE_FLOAT3; ");		if( elems.Type == D3DDECLTYPE_UBYTE4)			OutputDebugString("Type = D3DDECLTYPE_UBYTE4; ");			if( elems.Usage == D3DDECLUSAGE_POSITION)			OutputDebugString("Usage = D3DDECLUSAGE_POSITION\n");		if( elems.Usage == D3DDECLUSAGE_BLENDWEIGHT)			OutputDebugString("Usage = D3DDECLUSAGE_BLENDWEIGHT\n");		if( elems.Usage == D3DDECLUSAGE_BLENDINDICES)			OutputDebugString("Usage = D3DDECLUSAGE_BLENDINDICES\n");		if( elems.Usage == D3DDECLUSAGE_NORMAL)			OutputDebugString("Usage = D3DDECLUSAGE_NORMAL\n");		if( elems.Usage == D3DDECLUSAGE_TEXCOORD)			OutputDebugString("Usage = D3DDECLUSAGE_TEXCOORD\n");		++i;	} #endif}

Thanks but I not getting anything out of it.
you may need to make the mesh a system mesh first. and read this bit

// In the .X file (specifically the array DWORD vertexIndices[nWeights]
// data member of the SkinWeights template) each bone has an array of
// indices which identify the vertices of the mesh that the bone influences.

This bit looks like what is wrong in your code
// Because we have just rearranged the vertices (from optimizing), the vertex
// indices of a bone are obviously incorrect (i.e., they index to vertices the bone
// does not influence since we moved vertices around). In order to update a bone's
// vertex indices to the vertices the bone _does_ influence, we simply need to specify
// where we remapped the vertices to, so that the vertex indices can be updated to
// match. This is done with the ID3DXSkinInfo::Remap method.

This topic is closed to new replies.

Advertisement