This commit is contained in:
2019-08-11 18:39:28 +02:00

View File

@@ -3,6 +3,40 @@ Imports Assimp
Imports Assimp.Unmanaged Imports Assimp.Unmanaged
Namespace AssimpModule Namespace AssimpModule
Structure ConversionContext
Public Sub New(daeMdlP As Scene, upAxis As UpAxis)
daeMdl = daeMdlP
upAxis = upAxis
newMesh = New Mesh
newObj = New Object3D
newObj.Meshes.Add(newMesh)
channelIndicies = New Dictionary(Of Material, Integer)
End Sub
Dim daeMdl As Scene
Dim UpAxis As UpAxis
Dim newMesh As Mesh
Dim newObj As Object3D
Dim channelIndicies As Dictionary(Of Material, Integer)
End Structure
Structure ParsingContext
Public Sub New(ctx As ConversionContext)
cc = ctx
dicVertices = New Dictionary(Of Vector3D, Vertex)
dicNormals = New Dictionary(Of Vector3D, Normal)
dicUVs = New Dictionary(Of Vector3D, UV)
dicVertexColors = New Dictionary(Of Color4D, VertexColor)
End Sub
ReadOnly cc As ConversionContext
Dim dicVertices As Dictionary(Of Vector3D, Vertex)
Dim dicNormals As Dictionary(Of Vector3D, Normal)
Dim dicUVs As Dictionary(Of Vector3D, UV)
Dim dicVertexColors As Dictionary(Of Color4D, VertexColor)
End Structure
Public Class AssimpLoader Public Class AssimpLoader
@@ -15,14 +49,163 @@ Namespace AssimpModule
End If End If
End Sub End Sub
Private Shared Sub ComputeNewObj(cc As ConversionContext)
Dim identity As Matrix4x4 = Matrix4x4.Identity
ComputeNode(cc.daeMdl.RootNode, identity, New ParsingContext(cc))
End Sub
Private Shared Sub ComputeNode(node As Node, trafo As Matrix4x4, ByRef pc As ParsingContext)
Dim newObj = pc.cc.newObj
Dim newMesh = pc.cc.newMesh
Dim daeMdl = pc.cc.daeMdl
Dim channelIndicies = pc.cc.channelIndicies
Dim UpAxis = pc.cc.UpAxis
Dim dicVertices = pc.dicVertices
Dim dicNormals = pc.dicNormals
Dim dicUVs = pc.dicUVs
Dim dicVertexColors = pc.dicVertexColors
trafo = trafo * node.Transform
If node.HasMeshes Then
For Each meshIndex In node.MeshIndices
Dim m As Assimp.Mesh = daeMdl.Meshes(meshIndex)
Dim curMat As Material
If m.MaterialIndex > -1 AndAlso newObj.Materials.Count > m.MaterialIndex Then
curMat = newObj.Materials.ElementAt(m.MaterialIndex).Value
Else
curMat = Nothing
End If
For Each untransformedN As Vector3D In m.Normals
Dim n = trafo * untransformedN
If Not dicNormals.ContainsKey(n) Then
Dim newNormal As New Normal
Select Case UpAxis
Case UpAxis.Y
newNormal.X = n.X
newNormal.Y = n.Y
newNormal.Z = n.Z
Case UpAxis.Z
newNormal.X = n.Y
newNormal.Y = n.Z
newNormal.Z = n.X
End Select
newMesh.Normals.Add(newNormal)
dicNormals.Add(n, newNormal)
End If
Next
For Each untranformedV As Vector3D In m.Vertices
Dim v = trafo * untranformedV
If Not dicVertices.ContainsKey(v) Then
Dim newVert As New Vertex
Select Case UpAxis
Case UpAxis.Y
newVert.X = v.X
newVert.Y = v.Y
newVert.Z = v.Z
Case UpAxis.Z
newVert.X = v.Y
newVert.Y = v.Z
newVert.Z = v.X
End Select
newMesh.Vertices.Add(newVert)
dicVertices.Add(v, newVert)
End If
Next
For Each uvList As List(Of Vector3D) In m.TextureCoordinateChannels
For Each uv As Vector3D In uvList
If Not dicUVs.ContainsKey(uv) Then
Dim newUV As New UV
newUV.U = uv.X
newUV.V = uv.Y
newMesh.UVs.Add(newUV)
dicUVs.Add(uv, newUV)
End If
Next
Next
For Each vcList As List(Of Color4D) In m.VertexColorChannels
For Each vc As Color4D In vcList
If Not dicVertexColors.ContainsKey(vc) Then
Dim newVC As New VertexColor
newVC.R = vc.R
newVC.G = vc.G
newVC.B = vc.B
newVC.A = vc.A
newMesh.VertexColors.Add(newVC)
dicVertexColors.Add(vc, newVC)
End If
Next
Next
For Each f As Assimp.Face In m.Faces
If f.HasIndices Then
Dim newFace As New Face With {.Material = curMat}
For Each index As Integer In f.Indices
If index > -1 Then
Dim newPoint As New Point
If m.HasVertices Then
Dim v = trafo * m.Vertices(index)
newPoint.Vertex = dicVertices(v)
End If
If m.HasNormals Then
Dim n = trafo * m.Normals(index)
newPoint.Normal = dicNormals(n)
End If
If curMat IsNot Nothing AndAlso channelIndicies.ContainsKey(curMat) Then
Dim tkey As Integer = channelIndicies(curMat)
If m.HasTextureCoords(tkey) Then
newPoint.UV = dicUVs(m.TextureCoordinateChannels(tkey)(index))
End If
If m.HasVertexColors(tkey) Then
newPoint.VertexColor = dicVertexColors(m.VertexColorChannels(tkey)(index))
End If
End If
newFace.Points.Add(newPoint)
End If
Next
If newFace.Points.Count = 3 Then
newMesh.Faces.Add(newFace)
End If
End If
Next
Next
End If
For Each n In node.Children
ComputeNode(n, trafo, pc)
Next
End Sub
Public Shared Function FromFile(fileName As String, LoadMaterials As Boolean, UpAxis As UpAxis) As Object3D Public Shared Function FromFile(fileName As String, LoadMaterials As Boolean, UpAxis As UpAxis) As Object3D
Dim LoadedImages As New Dictionary(Of String, Image) Dim LoadedImages As New Dictionary(Of String, Image)
Dim newObj As New Object3D
Dim daeMdl As Scene = Nothing
Dim ac As New AssimpContext Dim ac As New AssimpContext
Dim channelIndicies As New Dictionary(Of Material, Integer)
daeMdl = ac.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality Or PostProcessSteps.Triangulate) Dim cc As New ConversionContext(ac.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality Or PostProcessSteps.Triangulate), UpAxis)
Dim newObj = cc.newObj
Dim daeMdl = cc.daeMdl
Dim channelIndicies = cc.channelIndicies
For Each et As EmbeddedTexture In daeMdl.Textures For Each et As EmbeddedTexture In daeMdl.Textures
If et.HasCompressedData Then If et.HasCompressedData Then
@@ -94,130 +277,7 @@ Namespace AssimpModule
newObj.Materials.Add(mat.Name, newMat) newObj.Materials.Add(mat.Name, newMat)
Next Next
Dim newMesh As New Mesh ComputeNewObj(cc)
newObj.Meshes.Add(newMesh)
Dim dicVertices As New Dictionary(Of Vector3D, Vertex)
Dim dicNormals As New Dictionary(Of Vector3D, Normal)
Dim dicUVs As New Dictionary(Of Vector3D, UV)
Dim dicVertexColors As New Dictionary(Of Color4D, VertexColor)
For Each m As Assimp.Mesh In daeMdl.Meshes
Dim curMat As Material
If m.MaterialIndex > -1 AndAlso newObj.Materials.Count > m.MaterialIndex Then
curMat = newObj.Materials.ElementAt(m.MaterialIndex).Value
Else
curMat = Nothing
End If
For Each n As Vector3D In m.Normals
If Not dicNormals.ContainsKey(n) Then
Dim newNormal As New Normal
Select Case UpAxis
Case UpAxis.Y
newNormal.X = n.X
newNormal.Y = n.Y
newNormal.Z = n.Z
Case UpAxis.Z
newNormal.X = n.Y
newNormal.Y = n.Z
newNormal.Z = n.X
End Select
newMesh.Normals.Add(newNormal)
dicNormals.Add(n, newNormal)
End If
Next
For Each v As Vector3D In m.Vertices
If Not dicVertices.ContainsKey(v) Then
Dim newVert As New Vertex
Select Case UpAxis
Case UpAxis.Y
newVert.X = v.X
newVert.Y = v.Y
newVert.Z = v.Z
Case UpAxis.Z
newVert.X = v.Y
newVert.Y = v.Z
newVert.Z = v.X
End Select
newMesh.Vertices.Add(newVert)
dicVertices.Add(v, newVert)
End If
Next
For Each uvList As List(Of Vector3D) In m.TextureCoordinateChannels
For Each uv As Vector3D In uvList
If Not dicUVs.ContainsKey(uv) Then
Dim newUV As New UV
newUV.U = uv.X
newUV.V = uv.Y
newMesh.UVs.Add(newUV)
dicUVs.Add(uv, newUV)
End If
Next
Next
For Each vcList As List(Of Color4D) In m.VertexColorChannels
For Each vc As Color4D In vcList
If Not dicVertexColors.ContainsKey(vc) Then
Dim newVC As New VertexColor
newVC.R = vc.R
newVC.G = vc.G
newVC.B = vc.B
newVC.A = vc.A
newMesh.VertexColors.Add(newVC)
dicVertexColors.Add(vc, newVC)
End If
Next
Next
For Each f As Assimp.Face In m.Faces
If f.HasIndices Then
Dim newFace As New Face With {.Material = curMat}
For Each index As Integer In f.Indices
If index > -1 Then
Dim newPoint As New Point
If m.HasVertices Then
newPoint.Vertex = dicVertices(m.Vertices(index))
End If
If m.HasNormals Then
newPoint.Normal = dicNormals(m.Normals(index))
End If
If curMat IsNot Nothing AndAlso channelIndicies.ContainsKey(curMat) Then
Dim tkey As Integer = channelIndicies(curMat)
If m.HasTextureCoords(tkey) Then
newPoint.UV = dicUVs(m.TextureCoordinateChannels(tkey)(index))
End If
If m.HasVertexColors(tkey) Then
newPoint.VertexColor = dicVertexColors(m.VertexColorChannels(tkey)(index))
End If
End If
newFace.Points.Add(newPoint)
End If
Next
If newFace.Points.Count = 3 Then
newMesh.Faces.Add(newFace)
End If
End If
Next
Next
Return newObj Return newObj
End Function End Function