Ejemplo n.º 1
0
        public Node Import(string path, string texturePakPath = null)
        {
            // Import scene.
            var aiScene            = AssimpHelper.ImportScene(path, false);
            var materialBuildInfos = BuildProceduralMaterials(Path.GetDirectoryName(path), aiScene.Materials, texturePakPath);
            var rootNode           = ConvertNode(aiScene.RootNode, aiScene.Meshes, materialBuildInfos);

            return(rootNode);
        }
Ejemplo n.º 2
0
        private static IGeometry ConvertCollisionGeometry(Assimp.Node curAiNode, Assimp.Matrix4x4 nodeWorldTransform,
                                                          List <Assimp.Mesh> aiMeshes,
                                                          List <MaterialBuildInfo> materialBuildInfos)
        {
            var vertices  = new List <Assimp.Vector3D>();
            var triangles = new List <Basic.Triangle>();

            foreach (var aiMeshIndex in curAiNode.MeshIndices)
            {
                var aiMesh = aiMeshes[aiMeshIndex];

                for (var i = 0; i < aiMesh.Faces.Count; i++)
                {
                    var aiFace   = aiMesh.Faces[i];
                    var triangle = new Basic.Triangle();
                    var flip     = false;

                    if (!flip)
                    {
                        triangle.A = ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[0]]);
                        triangle.B = aiFace.IndexCount > 1 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[1]]) : triangle.A;
                        triangle.C = aiFace.IndexCount > 2 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[2]]) : triangle.B;
                    }
                    else
                    {
                        triangle.C = ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[0]]);
                        triangle.B = aiFace.IndexCount > 1 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[1]]) : triangle.A;
                        triangle.A = aiFace.IndexCount > 2 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[2]]) : triangle.B;
                    }

                    triangles.Add(triangle);
                }
            }

            var geometry = new Basic.Geometry
            {
                Meshes = new[]
                {
                    new Basic.Mesh
                    {
                        PrimitiveType = PrimitiveType.Triangles,
                        Primitives    = triangles.Cast <Basic.IPrimitive>().ToArray(),
                    }
                },
                VertexPositions = vertices.Select(x =>
                {
                    Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeWorldTransform);
                    return(AssimpHelper.FromAssimp(x));
                }
                                                  ).ToArray()
            };

            geometry.Bounds = BoundingSphere.Calculate(geometry.VertexPositions);

            return(geometry);
        }
        public Assimp.Scene ConvertToScene(Model model, Config config)
        {
            // Start building scene
            var aiScene = AssimpHelper.CreateDefaultScene();

            // Convert materials
            for (var i = 0; i < model.Materials.Count; i++)
            {
                var material   = model.Materials[i];
                var aiMaterial = new Assimp.Material {
                    Name = FormatMaterialName(material, i)
                };

                if (material.TextureId != null)
                {
                    aiMaterial.TextureDiffuse = new Assimp.TextureSlot
                    {
                        TextureType = Assimp.TextureType.Diffuse,
                        FilePath    = Path.Combine("textures", FormatTextureName(material.TextureId.Value))
                    };
                }

                aiScene.Materials.Add(aiMaterial);
            }

            // Convert nodes
            var aiNodeLookup = new Dictionary <Node, Assimp.Node>();

            for (var i = 0; i < model.Nodes.Count; i++)
            {
                var node   = model.Nodes[i];
                var aiNode = new Assimp.Node(FormatNodeName(node, i), node.Parent != null ? aiNodeLookup[node.Parent] : aiScene.RootNode);
                aiNodeLookup[node] = aiNode;
                aiNode.Transform   = node.Transform.ToAssimp();

                if (node.Geometry != null)
                {
                    ConvertMeshList(node.Geometry.Meshes, node, i, model.Nodes, aiScene, aiNode);

                    if (node.Geometry.TranslucentMeshes != null)
                    {
                        ConvertMeshList(node.Geometry.TranslucentMeshes, node, i, model.Nodes, aiScene, aiNode);
                    }
                }

                aiNode.Parent.Children.Add(aiNode);
            }

            return(aiScene);
        }
Ejemplo n.º 4
0
        public BoneAnimation LoadBoneAnimation(Assimp.Scene aScene, Assimp.Node aNode, BoneAnimation parent)
        {
            var boneAnimation = new BoneAnimation()
            {
                Parent    = parent,
                Children  = new List <BoneAnimation>(),
                Positions = new List <Vector3>(),
                Rotations = new List <Quaternion>(),
                Scales    = new List <Vector3>()
            };

            boneAnimation.Name = aNode.Name;

            var animationChanel = aScene.Animations[0].NodeAnimationChannels.Where(n => n.NodeName == boneAnimation.Name).FirstOrDefault();

            if (animationChanel != null)
            {
                boneAnimation.IsAnimate = true;

                foreach (var aScale in animationChanel.ScalingKeys)
                {
                    var scale = new Vector3(aScale.Value.X, aScale.Value.Y, aScale.Value.Z);
                    boneAnimation.Scales.Add(scale);
                }

                foreach (var aRotation in animationChanel.RotationKeys)
                {
                    var rotation = new Quaternion(aRotation.Value.X, aRotation.Value.Y, aRotation.Value.Z, aRotation.Value.W);
                    boneAnimation.Rotations.Add(rotation);
                }

                foreach (var aTranslate in animationChanel.PositionKeys)
                {
                    var translate = new Vector3(aTranslate.Value.X, aTranslate.Value.Y, aTranslate.Value.Z);
                    boneAnimation.Positions.Add(translate);
                }
            }
            else
            {
                boneAnimation.IsAnimate      = false;
                boneAnimation.Transformation = Matrix.Transpose(AssimpHelper.MatrixAssimpToXna(aNode.Transform));
            }

            foreach (var child in aNode.Children)
            {
                boneAnimation.Children.Add(LoadBoneAnimation(aScene, child, boneAnimation));
            }
            BoneAnimations.Add(boneAnimation);
            return(boneAnimation);
        }
Ejemplo n.º 5
0
        public PropertiesView()
        {
            InitializeComponent();

            ViewModel   = Locator.Current.GetService <PropertiesViewModel>();
            DataContext = ViewModel;

            AssimpHelper.LoadAssimpNativeLibrary();

            var assimpWpfImporter      = new AssimpWpfImporter();
            var supportedImportFormats = assimpWpfImporter.SupportedImportFormats;
            var assimpWpfExporter      = new AssimpWpfExporter();
            var supportedExportFormats = assimpWpfExporter.ExportFormatDescriptions.Select(f => f.FileExtension).ToArray();

            //var themeResources = Application.LoadComponent(new Uri("Resources/Styles/ExpressionDark.xaml", UriKind.Relative)) as ResourceDictionary;
            //Resources.MergedDictionaries.Add(themeResources);

            spectrumAnalyzer.RegisterSoundPlayer(NAudioSimpleEngine.Instance);
            waveformTimeline.RegisterSoundPlayer(NAudioSimpleEngine.Instance);

            nAudioSimple = NAudioSimpleEngine.Instance;
            NAudioSimpleEngine.Instance.PropertyChanged += NAudioEngine_PropertyChanged;

            //appControl.ExeName = "binkpl64.exe";
            //appControl.Args = "test2.bk2 /J /I2 /P";
            //this.Unloaded += new RoutedEventHandler((s, e) => { appControl.Dispose(); });

            this.WhenActivated(disposables =>
            {
                ViewModel.WhenAnyValue(x => x.LoadedBitmapFrame).Subscribe(source =>
                {
                    if (source is { } frame)
                    {
                        LoadImage(frame);
                    }
                });
                ViewModel.WhenAnyValue(x => x.LoadedModelPath).Subscribe(source =>
                {
                    if (source is { } modelpath)
                    {
                        LoadModel(modelpath);
                    }
                });

                ViewModel.PreviewAudioCommand.Subscribe(path =>
                {
                    TempConvertToWemWav(path);
                });
            });
        }
Ejemplo n.º 6
0
        Bone GetBone(Mesh mesh, Assimp.Bone aBone)
        {
            var bone = mesh.Bones.FirstOrDefault(b => b.Name == aBone.Name);

            if (bone == null)
            {
                var offsetMatrix = aBone.OffsetMatrix;
                offsetMatrix.Transpose();

                bone               = new Bone();
                bone.Name          = aBone.Name;
                bone.Index         = mesh.Bones.Count;
                bone.Offset        = AssimpHelper.MatrixAssimpToXna(offsetMatrix);
                bone.OffsetInverse = Matrix.Invert(AssimpHelper.MatrixAssimpToXna(offsetMatrix));
                mesh.Bones.Add(bone);
            }
            return(bone);
        }
Ejemplo n.º 7
0
        public LandTableSA2 Import(string path, string texturePakPath = null)
        {
            var landTable = new LandTableSA2();
            var aiScene   = AssimpHelper.ImportScene(path, false);
            var meshNodes = FindMeshNodes(aiScene.RootNode);

            // Convert textures & build materials
            var convertMaterialsAndTextures = ConvertMaterialsAndTextures(Path.GetDirectoryName(path), aiScene.Materials, texturePakPath);

            landTable.TexturePakFileName = Path.GetFileNameWithoutExtension(texturePakPath);
            landTable.Textures           = convertMaterialsAndTextures.TextureReferences;

            var displayModels   = new List <LandModelSA2>();
            var collisionModels = new List <LandModelSA2>();

            foreach (var aiMeshNode in meshNodes)
            {
                if (!aiMeshNode.Name.Contains("hkRB"))
                {
                    displayModels.Add(ConvertDisplayModel(aiScene, convertMaterialsAndTextures.MaterialBuildInfos, aiMeshNode));
                }
                else
                {
                    collisionModels.Add(ConvertCollisionModel(aiScene, convertMaterialsAndTextures.MaterialBuildInfos, aiMeshNode));
                    displayModels.Add(ConvertDisplayModel(aiScene, convertMaterialsAndTextures.MaterialBuildInfos, aiMeshNode));
                    //var collisionModel = new LandModelSA2();
                    //collisionModel.Flags |= SurfaceFlags.Collidable;
                    //collisionModel.RootNode = ConvertNode( aiMeshNode, aiScene.Meshes, convertMaterialsAndTextures.MaterialBuildInfos,
                    //                                       ConvertCollisionGeometry );

                    //var collisionGeometry = ( Basic.Geometry )collisionModel.RootNode.Geometry;
                    //collisionModel.Bounds = collisionGeometry.Bounds;

                    //collisionModels.Add( collisionModel );
                }
            }

            landTable.Models.AddRange(displayModels);
            landTable.Models.AddRange(collisionModels);

            return(landTable);
        }
Ejemplo n.º 8
0
        public void Initialize()
        {
            var vertices = new List <MeshVerticeInfo>();
            var indices  = new List <int>();

            AssimpContext importer = new AssimpContext();
            Scene         aScene   = importer.ImportFile(FilePath, PostProcessPreset.TargetRealTimeMaximumQuality);

            foreach (var aMesh in aScene.Meshes)
            {
                for (int faceIndex = 0; faceIndex < aMesh.FaceCount; faceIndex++)
                {
                    for (int vertexNum = 0; vertexNum < 3; vertexNum++)
                    {
                        int     verticeIndice   = aMesh.Faces[faceIndex].Indices[vertexNum];
                        Vector3 verticePosition = AssimpHelper.VectorAssimpToXna(aMesh.Vertices[verticeIndice]);
                        Vector3 verticeNormal   = AssimpHelper.VectorAssimpToXna(aMesh.Normals[verticeIndice]);
                        Vector3 uv        = AssimpHelper.VectorAssimpToXna(aMesh.TextureCoordinateChannels[0][verticeIndice]);
                        var     verticeUv = new Vector2(uv.X, uv.Y);

                        var vertice = new MeshVerticeInfo()
                        {
                            Position          = verticePosition,
                            Normal            = verticeNormal,
                            TextureCoordinate = verticeUv
                        };

                        indices.Add(vertices.Count);
                        vertices.Add(vertice);
                    }
                }
                FaceCount += aMesh.FaceCount;
            }

            VertexBuffer = new VertexBuffer(GraphicsDevice, typeof(SimpleModelVertex), vertices.Count, BufferUsage.WriteOnly);
            VertexBuffer.SetData <SimpleModelVertex>(vertices.Select(v => v.ToSimpleModelVertex()).ToArray());
            IndexBuffer = new IndexBuffer(GraphicsDevice, typeof(int), indices.Count, BufferUsage.WriteOnly);
            IndexBuffer.SetData(indices.ToArray());
        }
        public override Motion Import(string filepath, Config config)
        {
            var aiScene     = AssimpHelper.ImportScene(filepath);
            var aiAnimation = aiScene.Animations.FirstOrDefault();

            if (aiAnimation == null)
            {
                return(null);
            }

            var motion = new Motion {
                Duration = ConvertTime(aiAnimation.DurationInTicks, aiAnimation.TicksPerSecond)
            };

            foreach (var aiChannel in aiAnimation.NodeAnimationChannels)
            {
                var nodeName  = aiChannel.NodeName;
                var nodeIndex = ( short )(config.NodeIndexResolver?.Invoke(nodeName) ?? FindNodeIndex(aiScene.RootNode, nodeName));
                Debug.Assert(nodeIndex != -1);

                if (aiChannel.HasPositionKeys)
                {
                    var controller = new NodeController(ControllerType.Position, nodeIndex, aiChannel.NodeName);
                    foreach (var aiKey in aiChannel.PositionKeys)
                    {
                        controller.Keys.Add(new Vector3Key
                        {
                            Time  = ConvertTime(aiKey.Time, aiAnimation.TicksPerSecond),
                            Value = aiKey.Value.FromAssimp()
                        });
                    }

                    motion.Controllers.Add(controller);
                }

                if (aiChannel.HasRotationKeys)
                {
                    var controller = new NodeController(ControllerType.Rotation, nodeIndex, aiChannel.NodeName);
                    foreach (var aiKey in aiChannel.RotationKeys)
                    {
                        controller.Keys.Add(new QuaternionKey
                        {
                            Time  = ConvertTime(aiKey.Time, aiAnimation.TicksPerSecond),
                            Value = Quaternion.Inverse(aiKey.Value.FromAssimp())
                        });
                    }

                    motion.Controllers.Add(controller);
                }

                if (aiChannel.HasScalingKeys)
                {
                    var controller = new NodeController(ControllerType.Scale, nodeIndex, aiChannel.NodeName);
                    foreach (var aiKey in aiChannel.ScalingKeys)
                    {
                        controller.Keys.Add(new Vector3Key
                        {
                            Time  = ConvertTime(aiKey.Time, aiAnimation.TicksPerSecond),
                            Value = aiKey.Value.FromAssimp()
                        });
                    }

                    motion.Controllers.Add(controller);
                }
            }

            return(motion);
        }
Ejemplo n.º 10
0
        private static List <MaterialBuildInfo> BuildProceduralMaterials(string baseDirectory, List <Assimp.Material> aiMaterials, string texturePakPath)
        {
            var textureArchive       = new GvmArchive();
            var textureArchiveStream = new MemoryStream();
            var textureArchiveWriter = ( GvmArchiveWriter )textureArchive.Create(textureArchiveStream);
            var textureIdLookup      = new Dictionary <string, int>(StringComparer.InvariantCultureIgnoreCase);

            if (texturePakPath != null && File.Exists(texturePakPath))
            {
                var extension  = Path.GetExtension(texturePakPath);
                var fileStream = ( Stream )File.OpenRead(texturePakPath);
                if (extension.Equals(".prs", StringComparison.InvariantCultureIgnoreCase))
                {
                    try
                    {
                        var decompressedFileStream = new MemoryStream();
                        Prs.Decompress(fileStream, decompressedFileStream);
                        fileStream.Dispose();
                        fileStream = decompressedFileStream;
                    }
                    catch (Exception)
                    {
                        // Not compressed
                    }

                    fileStream.Position = 0;
                }

                var existingTextureArchive       = new GvmArchive();
                var existingTextureArchiveReader = ( GvmArchiveReader )existingTextureArchive.Open(fileStream);
                for (var i = 0; i < existingTextureArchiveReader.Entries.Count; i++)
                {
                    var entry = existingTextureArchiveReader.Entries[i];

                    // Make copy of entry stream
                    var entryStreamCopy = new MemoryStream();
                    entry.Open().CopyTo(entryStreamCopy);
                    entryStreamCopy.Position = 0;

                    var texture = new VrSharp.GvrTexture.GvrTexture(entryStreamCopy);
                    Console.WriteLine(texture.GlobalIndex);
                    entryStreamCopy.Position = 0;

                    // Clean entry name from the added extension
                    var entryName = Path.ChangeExtension(entry.Name, null);

                    textureArchiveWriter.CreateEntry(entryStreamCopy, entryName);
                    textureIdLookup[entryName] = i;
                }
            }

            var materials = new List <MaterialBuildInfo>();

            foreach (var aiMaterial in aiMaterials)
            {
                var textureName = Path.GetFileNameWithoutExtension(aiMaterial.TextureDiffuse.FilePath).ToLowerInvariant();
                if (!textureIdLookup.TryGetValue(textureName, out var textureId))
                {
                    textureId = textureIdLookup[textureName] = textureIdLookup.Count;
                    var texturePath = Path.GetFullPath(Path.Combine(baseDirectory, aiMaterial.TextureDiffuse.FilePath));
                    if (File.Exists(texturePath))
                    {
                        // Convert texture
                        var texture = new GvrTexture {
                            GlobalIndex = ( uint )(1 + textureId)
                        };

                        var textureStream = new MemoryStream();
                        var textureBitmap = new Bitmap(texturePath);
                        texture.Write(textureBitmap, textureStream);
                        textureStream.Position = 0;

                        // Add it
                        textureArchiveWriter.CreateEntry(textureStream, textureName);
                    }
                }

                var material = new MaterialBuildInfo
                {
                    Ambient          = AssimpHelper.FromAssimp(aiMaterial.ColorAmbient),
                    Diffuse          = AssimpHelper.FromAssimp(aiMaterial.ColorDiffuse),
                    Specular         = AssimpHelper.FromAssimp(aiMaterial.ColorSpecular),
                    ClampU           = aiMaterial.TextureDiffuse.WrapModeU == Assimp.TextureWrapMode.Clamp,
                    ClampV           = aiMaterial.TextureDiffuse.WrapModeV == Assimp.TextureWrapMode.Clamp,
                    FlipU            = aiMaterial.TextureDiffuse.WrapModeU == Assimp.TextureWrapMode.Mirror,
                    FlipV            = aiMaterial.TextureDiffuse.WrapModeV == Assimp.TextureWrapMode.Mirror,
                    DestinationAlpha = DstAlphaOp.InverseDst,
                    Exponent         = 0,
                    FilterMode       = FilterMode.Trilinear,
                    MipMapDAdjust    = MipMapDAdjust.D050,
                    SourceAlpha      = SrcAlphaOp.Src,
                    SuperSample      = false,
                    TextureId        = (short)textureId,
                };

                materials.Add(material);
            }

            // Write texture archive to file
            textureArchiveWriter.Flush();
            textureArchiveStream.Position = 0;

            if (texturePakPath != null)
            {
                // Compress it.
                var textureArchivePrsStream = new MemoryStream();
                Prs.Compress(textureArchiveStream, textureArchivePrsStream);

                // Save compressed file.
                textureArchivePrsStream.Position = 0;
                using (var outFile = File.Create(texturePakPath))
                    textureArchivePrsStream.CopyTo(outFile);
            }

            return(materials);
        }
Ejemplo n.º 11
0
        public Node Import(string path, string texturePakPath = null)
        {
            // Import scene.
            var aiScene = AssimpHelper.ImportScene(path, true);

            // Find the node root of the animated hierarchy. This assumes that only 1 hierarchy exists, and any other
            // nodes that part of the scene root are mesh nodes.
            var aiRootNode = FindHierarchyRootNode(aiScene.RootNode);

            // Convert the nodes in the animated hierarchy from Assimps format, and also keep track of additional info.
            var convertedNodes = ConvertNodes(aiRootNode);

            // Find the mesh nodes within the scene. A mesh node is a node with 1 or more meshes attached to it.
            var meshNodes = FindMeshNodes(aiScene.RootNode);

            // Map each mesh node to a target node in the animated hierarchy. This is because we can't add extra nodes
            // to the hierarchy, so we must determine the most appropriate node to add the mesh to.
            var mappedMeshes = MapMeshNodesToTargetNodes(meshNodes, aiScene.Meshes, convertedNodes);

            // Convert the materials and textures
            var materialBuildInfos =
                BuildProceduralMaterials(Path.GetDirectoryName(path), aiScene.Materials, texturePakPath);

            // Take the mapped meshes and merge them into 1 geometry per target node
            // Also builds any supplementary geometries have have to be added to store additional weighted vertex info
            var geometryBuildInfos = BuildProceduralGeometries(mappedMeshes, convertedNodes, materialBuildInfos);

            var weightedVertexIdLookup = new Dictionary <Vertex, int>();
            var nextWeightedVertexId   = 4095;

            foreach (var geometryBuildInfo in geometryBuildInfos)
            {
                // Get target node inverse world transform to transform the vertices the target node's local space
                Matrix4x4.Invert(geometryBuildInfo.TargetNodeInfo.Node.WorldTransform, out var targetNodeInvWorldTransform);

                // Start building geometry
                var geometry = new Geometry();

                if (!geometryBuildInfo.IsSupplementary && geometryBuildInfo.UnweightedVertices.Count > 0)
                {
                    // Add unweighted vertices
                    geometry.VertexList.Add(new VertexNChunk(geometryBuildInfo.UnweightedVertices.Select(x => new VertexN
                    {
                        Position = Vector3.Transform(x.Position, targetNodeInvWorldTransform),
                        Normal   = Vector3.TransformNormal(x.Normal, targetNodeInvWorldTransform)
                    }).ToArray())
                    {
                        BaseIndex = geometryBuildInfo.UnweightedVertices[0].Id
                    });
                }

                if (!sDisableWeights)
                {
                    BuildWeightedVertexChunks(geometry, geometryBuildInfo, ref targetNodeInvWorldTransform, weightedVertexIdLookup, ref nextWeightedVertexId);
                }

                if (!geometryBuildInfo.IsSupplementary)
                {
                    BuildPolygonList(geometry, geometryBuildInfo, weightedVertexIdLookup);
                }

                geometryBuildInfo.TargetNodeInfo.Node.Geometry = geometry;
            }

            foreach (var nodeInfo in convertedNodes)
            {
                nodeInfo.Node.OptimizeFlags();
            }

            var rootNode = convertedNodes[0];

            return(rootNode.Node);
        }
Ejemplo n.º 12
0
        public void Initialize()
        {
            var importer = new AssimpContext();
            var aScene   = importer.ImportFile(FilePath, PostProcessPreset.TargetRealTimeMaximumQuality);

            Meshes = new List <Mesh>();

            foreach (var aMesh in aScene.Meshes)
            {
                var verticesResult = new List <MeshSkinnedVerticeInfo>();
                var indicesResult  = new List <int>();

                var mesh = new Mesh();
                mesh.Bones = new List <Bone>();

                mesh.Name = aMesh.Name;

                Dictionary <int, List <VerticeWeight> > VerticeWeights = new Dictionary <int, List <VerticeWeight> >();
                foreach (var aBone in aMesh.Bones)
                {
                    Bone bone = GetBone(mesh, aBone);

                    foreach (var vw in aBone.VertexWeights)
                    {
                        if (!VerticeWeights.ContainsKey(vw.VertexID))
                        {
                            VerticeWeights.Add(vw.VertexID, new List <VerticeWeight>());
                        }
                        VerticeWeights[vw.VertexID].Add(new VerticeWeight()
                        {
                            Bone = bone, Weight = vw.Weight
                        });
                    }
                }

                var c = aScene.Materials[aMesh.MaterialIndex].ColorDiffuse;

                for (int faceIndex = 0; faceIndex < aMesh.Faces.Count(); faceIndex++)
                {
                    for (int vertexNum = 0; vertexNum < 3; vertexNum++)
                    {
                        int verticeIndice = 0;

                        if (vertexNum < aMesh.Faces[faceIndex].Indices.Count())
                        {
                            verticeIndice = aMesh.Faces[faceIndex].Indices[vertexNum];
                        }

                        Vector3 verticePosition = AssimpHelper.VectorAssimpToXna(aMesh.Vertices[verticeIndice]);
                        Vector3 verticeNormal   = AssimpHelper.VectorAssimpToXna(aMesh.Normals[verticeIndice]);

                        var uv        = AssimpHelper.VectorAssimpToXna(aMesh.TextureCoordinateChannels[0][verticeIndice]);
                        var verticeUv = new Vector2(uv.X, uv.Y);

                        BlendInfo blendInfo = GetBlendInfo(VerticeWeights, verticeIndice);

                        var vertice = new MeshSkinnedVerticeInfo()
                        {
                            Position          = verticePosition,
                            Normal            = verticeNormal,
                            TextureCoordinate = verticeUv,
                            BoneID            = blendInfo.BoneId,
                            BoneWeight        = blendInfo.Weight
                        };

                        indicesResult.Add(verticesResult.Count);
                        verticesResult.Add(vertice);
                    }
                }

                mesh.TextureFilePath = aScene.Materials[aMesh.MaterialIndex].TextureDiffuse.FilePath;

                mesh.VertexBuffer = new VertexBuffer(GraphicsDevice, typeof(SkinnedModelVertex), verticesResult.Count, BufferUsage.WriteOnly);
                mesh.VertexBuffer.SetData <SkinnedModelVertex>(verticesResult.Select(v => v.ToVertexPositionNormalTextureBones()).ToArray());

                mesh.IndexBuffer = new IndexBuffer(GraphicsDevice, typeof(int), indicesResult.Count, BufferUsage.WriteOnly);
                mesh.IndexBuffer.SetData(indicesResult.ToArray());

                mesh.FaceCount = aMesh.FaceCount;

                Meshes.Add(mesh);
            }
        }
Ejemplo n.º 13
0
        private static Node ConvertNode(Assimp.Node aiNode, List <Assimp.Mesh> aiMeshes, List <MaterialBuildInfo> materialBuildInfos)
        {
            Node ConvertHierarchyNodeRecursively(Assimp.Node curAiNode, ref Node previousSibling, Node parent, ref Assimp.Matrix4x4 parentNodeWorldTransform)
            {
                var nodeWorldTransform        = curAiNode.Transform * parentNodeWorldTransform;
                var nodeInverseWorldTransform = nodeWorldTransform;

                nodeInverseWorldTransform.Inverse();

                curAiNode.Transform.Decompose(out var scale, out var rotation, out var translation);

                // Create node
                var node = new Node(AssimpHelper.FromAssimp(translation), AngleVector.FromQuaternion(AssimpHelper.FromAssimp(rotation)),
                                    AssimpHelper.FromAssimp(scale), parent);

                if (curAiNode.HasMeshes)
                {
                    var geometry = new Geometry();

                    // Convert meshes
                    var vertexPositions = new List <Assimp.Vector3D>();
                    var vertexNormals   = new List <Assimp.Vector3D>();
                    var vertexUVs       = new List <Assimp.Vector3D>();
                    var vertexColors    = new List <Assimp.Color4D>();
                    var lastRenderState = new MeshRenderState();

                    foreach (var aiMeshIndex in curAiNode.MeshIndices)
                    {
                        var aiMesh      = aiMeshes[aiMeshIndex];
                        var material    = materialBuildInfos[aiMesh.MaterialIndex];
                        var mesh        = new Mesh();
                        var renderState = new MeshRenderState();

                        renderState.IndexFlags = IndexAttributeFlags.HasPosition | IndexAttributeFlags.Position16BitIndex;
                        var useColors  = false;
                        var hasColors  = aiMesh.HasVertexColors(0);
                        var hasUVs     = aiMesh.HasTextureCoords(0);
                        var hasNormals = aiMesh.HasNormals;

                        if (hasColors || !hasNormals)
                        {
                            renderState.IndexFlags |= IndexAttributeFlags.HasColor | IndexAttributeFlags.Color16BitIndex;
                            useColors = true;
                        }
                        else
                        {
                            renderState.IndexFlags |= IndexAttributeFlags.HasNormal | IndexAttributeFlags.Normal16BitIndex;
                        }

                        if (hasUVs)
                        {
                            renderState.IndexFlags |= IndexAttributeFlags.HasUV | IndexAttributeFlags.UV16BitIndex;
                        }

                        // Convert faces
                        var triangleIndices = new Index[aiMesh.FaceCount * 3];
                        for (var i = 0; i < aiMesh.Faces.Count; i++)
                        {
                            var aiFace = aiMesh.Faces[i];
                            Debug.Assert(aiFace.IndexCount == 3);

                            for (var j = 0; j < aiFace.Indices.Count; j++)
                            {
                                int aiFaceIndex = aiFace.Indices[j];

                                var position      = aiMesh.Vertices[aiFaceIndex];
                                var positionIndex = vertexPositions.IndexOf(position);
                                if (positionIndex == -1)
                                {
                                    positionIndex = vertexPositions.Count;
                                    vertexPositions.Add(position);
                                }

                                var normalIndex = 0;
                                var colorIndex  = 0;
                                var uvIndex     = 0;

                                if (useColors)
                                {
                                    var color = hasColors ? aiMesh.VertexColorChannels[0][aiFaceIndex] : new Assimp.Color4D();
                                    colorIndex = vertexColors.IndexOf(color);
                                    if (colorIndex == -1)
                                    {
                                        colorIndex = vertexColors.Count;
                                        vertexColors.Add(color);
                                    }
                                }
                                else
                                {
                                    var normal = aiMesh.Normals[aiFaceIndex];
                                    normalIndex = vertexNormals.IndexOf(normal);
                                    if (normalIndex == -1)
                                    {
                                        normalIndex = vertexNormals.Count;
                                        vertexNormals.Add(normal);
                                    }
                                }

                                if (hasUVs)
                                {
                                    var uv = aiMesh.TextureCoordinateChannels[0][aiFaceIndex];
                                    uvIndex = vertexUVs.IndexOf(uv);
                                    if (uvIndex == -1)
                                    {
                                        uvIndex = vertexUVs.Count;
                                        vertexUVs.Add(uv);
                                    }
                                }

                                triangleIndices[(i * 3) + j] = new Index
                                {
                                    PositionIndex = ( ushort )positionIndex,
                                    NormalIndex   = ( ushort )normalIndex,
                                    ColorIndex    = ( ushort )colorIndex,
                                    UVIndex       = ( ushort )uvIndex
                                };
                            }
                        }

                        // Build display list
                        var displayList = new GXDisplayList(GXPrimitive.Triangles, triangleIndices);
                        mesh.DisplayLists.Add(displayList);

                        // Set up render params
                        var indexFlagsParam = new IndexAttributeFlagsParam(renderState.IndexFlags);
                        mesh.Parameters.Add(indexFlagsParam);

                        if (useColors)
                        {
                            mesh.Parameters.Add(new LightingParams(LightingParams.Preset.Colors));
                        }
                        else
                        {
                            mesh.Parameters.Add(new LightingParams(LightingParams.Preset.Normals));
                        }

                        mesh.Parameters.Add(new TextureParams(( ushort )(material.TextureId)));
                        mesh.Parameters.Add(new MipMapParams());
                        geometry.OpaqueMeshes.Add(mesh);
                    }

                    // Build vertex buffers
                    if (vertexPositions.Count > 0)
                    {
                        geometry.VertexBuffers.Add(new VertexPositionBuffer(vertexPositions.Select(x =>
                        {
                            Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeInverseWorldTransform);
                            return(AssimpHelper.FromAssimp(x));
                        }).ToArray()));
                    }

                    if (vertexNormals.Count > 0)
                    {
                        nodeInverseWorldTransform.Transpose();

                        geometry.VertexBuffers.Add(new VertexNormalBuffer(vertexNormals.Select(x =>
                        {
                            Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeInverseWorldTransform);
                            return(AssimpHelper.FromAssimp(x));
                        }).ToArray()));
                    }

                    if (vertexColors.Count > 0)
                    {
                        geometry.VertexBuffers.Add(new VertexColorBuffer(vertexColors.Select(AssimpHelper.FromAssimp).ToArray()));
                    }

                    if (vertexUVs.Count > 0)
                    {
                        geometry.VertexBuffers.Add(new VertexUVBuffer(vertexUVs.Select(x =>
                                                                                       UVCodec.Encode1023(AssimpHelper
                                                                                                          .FromAssimpAsVector2(x)))
                                                                      .ToArray()));
                    }
                }

                // Set sibling (next) reference of previous
                if (previousSibling != null)
                {
                    previousSibling.Sibling = node;
                }

                previousSibling = node;

                if (curAiNode.HasChildren)
                {
                    Node childPreviousSibling = null;
                    foreach (var aiChildNode in curAiNode.Children)
                    {
                        var childNode = ConvertHierarchyNodeRecursively(aiChildNode, ref childPreviousSibling, node, ref nodeWorldTransform);

                        // Make sure to set the 'first child' reference if we haven't already
                        if (node.Child == null)
                        {
                            node.Child = childNode;
                        }
                    }
                }

                return(node);
            }

            // Dummy!
            Node dummy    = null;
            var  identity = Assimp.Matrix4x4.Identity;

            return(ConvertHierarchyNodeRecursively(aiNode, ref dummy, null, ref identity));
        }
Ejemplo n.º 14
0
        public void ExportCollada(string filepath)
        {
            var aiScene = AssimpHelper.CreateDefaultScene();

            foreach (var geometry in Geometries)
            {
                for (var meshIndex = 0; meshIndex < geometry.Meshes.Count; meshIndex++)
                {
                    var aiMeshNode = new Assimp.Node(geometry.Meshes.Count > 1 ? $"{geometry.Name}_mesh_{meshIndex}" : geometry.Name,
                                                     aiScene.RootNode);
                    aiScene.RootNode.Children.Add(aiMeshNode);

                    var mesh   = geometry.Meshes[meshIndex];
                    var aiMesh = new Assimp.Mesh();

                    var aiMaterial = new Assimp.Material
                    {
                        Name = mesh.Material.Name,
                        //ColorDiffuse      = AssimpHelper.ToAssimp( mesh.Material.Diffuse ),
                        //ColorSpecular     = AssimpHelper.ToAssimp( mesh.Material.Specular ),
                        //ColorAmbient      = AssimpHelper.ToAssimp( mesh.Material.Ambient ),
                        Shininess         = 0,
                        ShininessStrength = 0,
                        Reflectivity      = 0,
                        TextureDiffuse    = new Assimp.TextureSlot
                        {
                            TextureType = Assimp.TextureType.Diffuse,
                            FilePath    = mesh.Material.TextureName,
                            WrapModeU   = Assimp.TextureWrapMode.Wrap,
                            WrapModeV   = Assimp.TextureWrapMode.Wrap,
                        }
                    };

                    aiMesh.MaterialIndex = aiScene.MaterialCount;
                    aiScene.Materials.Add(aiMaterial);

                    foreach (var vertex in mesh.Vertices)
                    {
                        aiMesh.Vertices.Add(AssimpHelper.ToAssimp(vertex.Position));
                        aiMesh.Normals.Add(AssimpHelper.ToAssimp(vertex.Normal));
                        aiMesh.VertexColorChannels[0].Add(AssimpHelper.ToAssimp(vertex.Color));
                        aiMesh.TextureCoordinateChannels[0].Add(AssimpHelper.ToAssimp(vertex.UV));
                    }

                    for (int i = 0; i < mesh.Indices.Length; i += 3)
                    {
                        var aiFace = new Assimp.Face();
                        for (int j = 0; j < 3; j++)
                        {
                            aiFace.Indices.Add(mesh.Indices[i + j]);
                        }

                        aiMesh.Faces.Add(aiFace);
                    }

                    aiMeshNode.MeshIndices.Add(aiScene.MeshCount);
                    aiScene.Meshes.Add(aiMesh);
                }
            }

            AssimpHelper.ExportCollada(aiScene, filepath);
        }
Ejemplo n.º 15
0
        public static Model Import(string filepath, bool conformanceMode = true)
        {
            var      model    = new Model();
            Geometry geometry = null;

            if (conformanceMode)
            {
                geometry = new Geometry {
                    Name = "polySurfaceShape6"
                };
                model.Geometries.Add(geometry);
            }

            var aiScene = AssimpHelper.ImportScene(filepath, false);

            void ConvertNode(Assimp.Node aiNode)
            {
                if (aiNode.HasMeshes)
                {
                    var nodeWorldTransform = AssimpHelper.CalculateWorldTransform(aiNode);

                    if (!conformanceMode)
                    {
                        geometry = new Geometry {
                            Name = aiNode.Name
                        }
                    }
                    ;

                    foreach (var aiMeshIndex in aiNode.MeshIndices)
                    {
                        var aiMesh     = aiScene.Meshes[aiMeshIndex];
                        var aiMaterial = aiScene.Materials[aiMesh.MaterialIndex];

                        var mesh = new Mesh();

                        mesh.Material.Name = aiMaterial.Name;
                        //mesh.Material.Ambient = new Vector4( aiMaterial.ColorAmbient.R, aiMaterial.ColorAmbient.G, aiMaterial.ColorAmbient.B, aiMaterial.ColorAmbient.A );
                        //mesh.Material.Diffuse = new Vector4( aiMaterial.ColorDiffuse.R, aiMaterial.ColorDiffuse.G, aiMaterial.ColorDiffuse.B,aiMaterial.ColorDiffuse.A );
                        //mesh.Material.Specular = new Vector4( aiMaterial.ColorSpecular.R, aiMaterial.ColorSpecular.G, aiMaterial.ColorSpecular.B, aiMaterial.ColorSpecular.A );
                        mesh.Material.TextureName =
                            Path.ChangeExtension(Path.GetFileNameWithoutExtension(aiMaterial.TextureDiffuse.FilePath), "dds");

                        mesh.Vertices = new Vertex[aiMesh.VertexCount];
                        for (int i = 0; i < mesh.Vertices.Length; i++)
                        {
                            ref var vertex = ref mesh.Vertices[i];
                            vertex.Position = Vector3.Transform(AssimpHelper.FromAssimp(aiMesh.Vertices[i]), nodeWorldTransform);
                            vertex.Normal   = aiMesh.HasNormals ? Vector3.TransformNormal(AssimpHelper.FromAssimp(aiMesh.Normals[i]), nodeWorldTransform) : new Vector3();
                            vertex.Color    = aiMesh.HasVertexColors(0)
                                ? AssimpHelper.FromAssimp(aiMesh.VertexColorChannels[0][i])
                                : Color.White;
                            vertex.UV = aiMesh.HasTextureCoords(0)
                                ? AssimpHelper.FromAssimpAsVector2(aiMesh.TextureCoordinateChannels[0][i])
                                : new Vector2();
                        }

                        mesh.Indices = aiMesh.GetIndices();
                        geometry.Meshes.Add(mesh);
                    }

                    if (!conformanceMode)
                    {
                        model.Geometries.Add(geometry);
                    }
                }

                foreach (var aiChildNode in aiNode.Children)
                {
                    ConvertNode(aiChildNode);
                }
            }

            ConvertNode(aiScene.RootNode);

            if (conformanceMode)
            {
                var meshes = new List <Mesh>(geometry.Meshes);

                var meshMap = new List <int>();
                var nextUniqueNewMeshIndex = sOriginalMaterialNames.Length;
                for (int i = 0; i < meshes.Count; i++)
                {
                    var newMeshIndex = Array.IndexOf(sOriginalMaterialNames, meshes[i].Material.Name);
                    if (newMeshIndex == -1)
                    {
                        newMeshIndex = nextUniqueNewMeshIndex++;
                    }

                    meshMap.Add(newMeshIndex);
                }

                geometry.Meshes.Clear();
                for (int i = 0; i < nextUniqueNewMeshIndex; i++)
                {
                    if (!meshMap.Contains(i))
                    {
                        geometry.Meshes.Add(new Mesh
                        {
                            Indices  = new int[0],
                            Vertices = new Vertex[0],
                            Material = new Material
                            {
                                Name        = sOriginalMaterialNames[i % sOriginalMaterialNames.Length],
                                TextureName = sOriginalTextureNames[i % sOriginalTextureNames.Length]
                            }
                        });
                    }
                    else
                    {
                        geometry.Meshes.Add(null);
                    }
                }

                for (int i = 0; i < meshMap.Count; i++)
                {
                    geometry.Meshes[meshMap[i]] = meshes[i];
                }
            }

            return(model);
        }
Ejemplo n.º 16
0
        private static IGeometry ConvertDisplayGeometry(Assimp.Node curAiNode, Assimp.Matrix4x4 nodeWorldTransform, List <Assimp.Mesh> aiMeshes, List <MaterialBuildInfo> materialBuildInfos)
        {
            var nodeInverseWorldTransform = nodeWorldTransform;

            nodeInverseWorldTransform.Inverse();
            var nodeInverseTransposeWorldTransform = nodeInverseWorldTransform;

            nodeInverseTransposeWorldTransform.Transpose();

            var geometry = new Geometry();

            // Convert meshes
            var vertexPositions = new List <Assimp.Vector3D>();
            var vertexNormals   = new List <Assimp.Vector3D>();
            var vertexUVs       = new List <Assimp.Vector3D>();
            var vertexColors    = new List <Assimp.Color4D>();
            var lastRenderState = new MeshRenderState();

            foreach (var aiMeshIndex in curAiNode.MeshIndices)
            {
                var aiMesh      = aiMeshes[aiMeshIndex];
                var material    = materialBuildInfos[aiMesh.MaterialIndex];
                var mesh        = new Mesh();
                var renderState = new MeshRenderState();

                renderState.IndexFlags = IndexAttributeFlags.HasPosition;
                var useColors  = false;
                var hasColors  = aiMesh.HasVertexColors(0);
                var hasUVs     = aiMesh.HasTextureCoords(0);
                var hasNormals = aiMesh.HasNormals;

                if (hasColors || !hasNormals)
                {
                    renderState.IndexFlags |= IndexAttributeFlags.HasColor;
                    useColors = true;
                }
                else
                {
                    renderState.IndexFlags |= IndexAttributeFlags.HasNormal;
                }

                if (hasUVs)
                {
                    renderState.IndexFlags |= IndexAttributeFlags.HasUV;
                }

                // Convert faces
                var triangleIndices = new Index[aiMesh.FaceCount * 3];
                for (var i = 0; i < aiMesh.Faces.Count; i++)
                {
                    var aiFace = aiMesh.Faces[i];

                    for (var j = 0; j < 3; j++)
                    {
                        var triangleIndicesIndex = (i * 3) + 2 - j;

                        if (j >= aiFace.IndexCount)
                        {
                            triangleIndices[triangleIndicesIndex] = triangleIndices[triangleIndicesIndex + 1];
                            continue;
                        }

                        int aiFaceIndex = aiFace.Indices[j];

                        var position      = aiMesh.Vertices[aiFaceIndex];
                        var positionIndex = vertexPositions.AddUnique(position);
                        if (positionIndex > byte.MaxValue)
                        {
                            renderState.IndexFlags |= IndexAttributeFlags.Position16BitIndex;
                        }

                        var normalIndex = 0;
                        var colorIndex  = 0;
                        var uvIndex     = 0;

                        if (useColors)
                        {
                            var color = hasColors ? aiMesh.VertexColorChannels[0][aiFaceIndex] : new Assimp.Color4D();
                            colorIndex = vertexColors.AddUnique(color);

                            if (colorIndex > byte.MaxValue)
                            {
                                renderState.IndexFlags |= IndexAttributeFlags.Color16BitIndex;
                            }
                        }
                        else
                        {
                            var normal = aiMesh.Normals[aiFaceIndex];
                            normalIndex = vertexNormals.AddUnique(normal);

                            if (normalIndex > byte.MaxValue)
                            {
                                renderState.IndexFlags |= IndexAttributeFlags.Normal16BitIndex;
                            }
                        }

                        if (hasUVs)
                        {
                            var uv = aiMesh.TextureCoordinateChannels[0][aiFaceIndex];
                            uvIndex = vertexUVs.AddUnique(uv);

                            if (uvIndex > byte.MaxValue)
                            {
                                renderState.IndexFlags |= IndexAttributeFlags.UV16BitIndex;
                            }
                        }

                        triangleIndices[triangleIndicesIndex] = new Index
                        {
                            PositionIndex = ( ushort )positionIndex,
                            NormalIndex   = ( ushort )normalIndex,
                            ColorIndex    = ( ushort )colorIndex,
                            UVIndex       = ( ushort )uvIndex
                        };
                    }
                }

                // Build display list
                var displayList = new GXDisplayList(GXPrimitive.Triangles, triangleIndices);
                mesh.DisplayLists.Add(displayList);

                // Set up render params
                if (renderState.IndexFlags != lastRenderState.IndexFlags)
                {
                    mesh.Parameters.Add(new IndexAttributeFlagsParam(renderState.IndexFlags));
                }

                // Set up render lighting params
                {
                    if (useColors)
                    {
                        renderState.LightingValue1 = 0x0b11;
                    }
                    else
                    {
                        renderState.LightingValue2 = 0x0011;
                    }

                    renderState.LightingValue2 = 1;

                    if (renderState.LightingValue1 != lastRenderState.LightingValue1 ||
                        renderState.LightingValue2 != lastRenderState.LightingValue2)
                    {
                        mesh.Parameters.Add(new LightingParams()
                        {
                            Value1 = renderState.LightingValue1,
                            Value2 = renderState.LightingValue2
                        });
                    }
                }

                // Set up render texture params
                {
                    renderState.TextureId = ( ushort )material.TextureId;
                    renderState.TileMode  = TileMode.WrapU | TileMode.WrapV;

                    if (renderState.TextureId != lastRenderState.TextureId ||
                        renderState.TileMode != lastRenderState.TileMode)
                    {
                        mesh.Parameters.Add(new TextureParams(renderState.TextureId, renderState.TileMode));
                    }
                }

                // Set up render mipmap params
                {
                    renderState.MipMapValue1 = 0x104a;
                    renderState.MipMapValue2 = 0;

                    if (renderState.MipMapValue1 != lastRenderState.MipMapValue1 ||
                        renderState.MipMapValue2 != lastRenderState.MipMapValue2)
                    {
                        mesh.Parameters.Add(new MipMapParams {
                            Value1 = renderState.MipMapValue1, Value2 = renderState.MipMapValue2
                        });
                    }
                }

                //if ( material.UseAlpha )
                //{
                //    mesh.Parameters.Add( new BlendAlphaParam() { Flags = BlendAlphaFlags.UseAlpha } );
                //    geometry.TranslucentMeshes.Add( mesh );
                //}
                //else
                //{
                //    geometry.OpaqueMeshes.Add( mesh );
                //}

                geometry.OpaqueMeshes.Add(mesh);
                lastRenderState = renderState;
            }

            // Build vertex buffers
            if (vertexPositions.Count > 0)
            {
                Debug.Assert(vertexPositions.Count <= ushort.MaxValue);
                var localVertexPositions = vertexPositions.Select(x =>
                {
                    Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeWorldTransform);
                    return(AssimpHelper.FromAssimp(x));
                }).ToArray();
                geometry.VertexBuffers.Add(new VertexPositionBuffer(localVertexPositions));
                geometry.Bounds = BoundingSphere.Calculate(localVertexPositions);
            }

            if (vertexNormals.Count > 0)
            {
                Debug.Assert(vertexNormals.Count <= ushort.MaxValue);
                geometry.VertexBuffers.Add(new VertexNormalBuffer(vertexNormals.Select(x =>
                {
                    Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeInverseTransposeWorldTransform);
                    return(AssimpHelper.FromAssimp(x));
                }).ToArray()));
            }

            if (vertexColors.Count > 0)
            {
                Debug.Assert(vertexColors.Count <= ushort.MaxValue);
                geometry.VertexBuffers.Add(new VertexColorBuffer(vertexColors.Select(AssimpHelper.FromAssimp).ToArray()));
            }

            if (vertexUVs.Count > 0)
            {
                Debug.Assert(vertexUVs.Count <= ushort.MaxValue);
                geometry.VertexBuffers.Add(new VertexUVBuffer(vertexUVs.Select(x =>
                                                                               UVCodec.Encode255(AssimpHelper
                                                                                                 .FromAssimpAsVector2(x)))
                                                              .ToArray()));
            }

            return(geometry);
        }