Exemple #1
0
            private HxScene.SceneNode ConstructHelixScene(Node node, HelixInternalScene scene)
            {
                var group = new HxScene.GroupNode
                {
                    Name        = string.IsNullOrEmpty(node.Name) ? nameof(HxScene.GroupNode) : node.Name,
                    ModelMatrix = node.Transform.ToSharpDXMatrix(configuration.IsSourceMatrixColumnMajor)
                };

                if (node.HasChildren)
                {
                    foreach (var c in node.Children)
                    {
                        group.AddChildNode(ConstructHelixScene(c, scene));
                    }
                }
                if (node.HasMeshes)
                {
                    foreach (var idx in node.MeshIndices)
                    {
                        var mesh   = scene.Meshes[idx];
                        var hxNode = OnCreateHxMeshNode(mesh, scene, Matrix.Identity);
                        group.AddChildNode(hxNode);
                    }
                }
                if (node.Metadata.Count > 0)
                {
                    group.Metadata = new Metadata();
                    foreach (var metadata in node.Metadata.ToHelixMetadata())
                    {
                        group.Metadata.Add(metadata.Key, metadata.Value);
                    }
                }
                return(group);
            }
Exemple #2
0
            private HelixInternalScene ToHelixScene(Scene scene, bool parallel)
            {
                var s = new HelixInternalScene
                {
                    AssimpScene = scene,
                    Meshes      = new MeshInfo[scene.MeshCount],
                    Materials   = new KeyValuePair <global::Assimp.Material, MaterialCore> [scene.MaterialCount]
                };

                Parallel.Invoke(() =>
                {
                    if (scene.HasMeshes)
                    {
                        if (parallel)
                        {
                            Parallel.ForEach(scene.Meshes,
                                             (mesh, state, index) => { s.Meshes[index] = OnCreateHelixGeometry(mesh); });
                        }
                        else
                        {
                            for (var i = 0; i < scene.MeshCount; ++i)
                            {
                                s.Meshes[i] = OnCreateHelixGeometry(scene.Meshes[i]);
                            }
                        }
                    }
                },
                                () =>
                {
                    if (scene.HasMaterials)
                    {
                        embeddedTextures.Clear();
                        embeddedTextureDict.Clear();
                        if (scene.HasTextures)
                        {
                            embeddedTextures.AddRange(scene.Textures);
                            for (int i = 0; i < embeddedTextures.Count; ++i)
                            {
                                var key = embeddedTextures[i].Filename;
                                if (string.IsNullOrEmpty(key))
                                {
                                    key = "*" + i.ToString();
                                }
                                if (!embeddedTextureDict.ContainsKey(key))
                                {
                                    embeddedTextureDict.Add(key, embeddedTextures[i]);
                                }
                            }
                        }

                        for (var i = 0; i < scene.MaterialCount; ++i)
                        {
                            s.Materials[i] = OnCreateHelixMaterial(scene.Materials[i]);
                        }
                        embeddedTextures.Clear();
                        embeddedTextureDict.Clear();
                    }
                });
                return(s);
            }
Exemple #3
0
            private ErrorCode LoadAnimations(HelixInternalScene scene)
            {
                var dict = new Dictionary <string, HxScene.SceneNode>(SceneNodes.Count);

                foreach (var node in SceneNodes)
                {
                    if (node is HxScene.GroupNode && !dict.ContainsKey(node.Name))
                    {
                        dict.Add(node.Name, node);
                    }
                }

                foreach (var node in SceneNodes.Where(x => x is Animations.IBoneMatricesNode)
                         .Select(x => x as Animations.IBoneMatricesNode))
                {
                    if (node.Bones != null)
                    {
                        for (var i = 0; i < node.Bones.Length; ++i)
                        {
                            if (dict.TryGetValue(node.Bones[i].Name, out var s))
                            {
                                ref var b = ref node.Bones[i];
                                b.ParentNode      = s.Parent;
                                b.Node            = s;
                                s.IsAnimationNode = true; // Make sure to set this to true
                            }
                        }
                    }
                }
            private ErrorCode LoadAnimations(HelixInternalScene scene)
            {
                var dict = new Dictionary <string, HxScene.SceneNode>(SceneNodes.Count);

                foreach (var node in SceneNodes)
                {
                    if (node is HxScene.GroupNode && !dict.ContainsKey(node.Name))
                    {
                        dict.Add(node.Name, node);
                    }
                }

                var nodeIdxDict = new Dictionary <string, int>();

                foreach (var node in SceneNodes.Where(x => x is Animations.IBoneMatricesNode)
                         .Select(x => x as Animations.IBoneMatricesNode))
                {
                    if (node.Bones != null)
                    {
                        nodeIdxDict.Clear();
                        for (var i = 0; i < node.Bones.Length; ++i)
                        {
                            nodeIdxDict.Add(node.Bones[i].Name, i);
                        }
                        for (var i = 0; i < node.Bones.Length; ++i)
                        {
                            if (dict.TryGetValue(node.Bones[i].Name, out var s))
                            {
                                ref var b = ref node.Bones[i];
                                b.ParentNode         = s.Parent;
                                b.Node               = s;
                                b.BoneLocalTransform = s.ModelMatrix;
                                if (s.Parent != null && nodeIdxDict.TryGetValue(s.Parent.Name, out var idx))
                                {
                                    b.ParentIndex = idx;
                                }
                                s.IsAnimationNode = true; // Make sure to set this to true
                            }
                        }

                        if (Configuration.CreateSkeletonForBoneSkinningMesh &&
                            node is HxScene.BoneSkinMeshNode sk &&
                            sk.Parent is HxScene.GroupNodeBase group)
                        {
                            var skeleton = sk.CreateSkeletonNode(Configuration.SkeletonMaterial,
                                                                 Configuration.SkeletonEffects, Configuration.SkeletonSizeScale);
                            skeleton.Name = "HxSK_" + sk.Name;
                            group.AddChildNode(skeleton);
                        }

                        //Setup bone matrices initially if it's morphable (unable to render w/o bones)
                        if (node is HxScene.BoneSkinMeshNode sn &&
                            sn.MorphTargetWeights.Length > 0 &&
                            sn.BoneMatrices?.Length == 0)
                        {
                            sn.UpdateBoneMatrices();
                        }
                    }
                }
Exemple #5
0
            /// <summary>
            ///     To the hx mesh nodes.
            /// </summary>
            /// <param name="mesh">The mesh.</param>
            /// <param name="scene">The scene.</param>
            /// <param name="transform"></param>
            /// <returns></returns>
            /// <exception cref="System.NotSupportedException">Mesh Type {mesh.Type}</exception>
            protected virtual HxScene.SceneNode OnCreateHxMeshNode(MeshInfo mesh, HelixInternalScene scene, Matrix transform)
            {
                switch (mesh.Type)
                {
                case PrimitiveType.Triangle:
                    var material = scene.Materials[mesh.MaterialIndex];
                    var cullMode = material.Key.HasTwoSided && material.Key.IsTwoSided
                            ? CullMode.Back
                            : CullMode.None;
                    if (Configuration.ForceCullMode)
                    {
                        cullMode = Configuration.CullMode;
                    }
                    var fillMode = material.Key.HasWireFrame && material.Key.IsWireFrameEnabled
                            ? FillMode.Wireframe
                            : FillMode.Solid;

                    //Determine if has bones
                    HxScene.MeshNode mnode;
                    if (mesh.AssimpMesh.HasBones || mesh.AssimpMesh.HasMeshAnimationAttachments)
                    {
                        var mn = new HxScene.BoneSkinMeshNode();

                        //Bones
                        if (mesh.AssimpMesh.HasBones)
                        {
                            mn.Bones = mesh.AssimpMesh.Bones.Select(x => new HxAnimations.Bone()
                            {
                                Name               = x.Name,
                                BindPose           = x.OffsetMatrix.ToSharpDXMatrix(configuration.IsSourceMatrixColumnMajor).Inverted(),
                                BoneLocalTransform = Matrix.Identity,
                                InvBindPose        = x.OffsetMatrix.ToSharpDXMatrix(configuration.IsSourceMatrixColumnMajor),//Documented at https://github.com/assimp/assimp/pull/1803
                            }).ToArray();
                        }
                        else
                        {
                            mn.Geometry = mesh.Mesh;
                            mn.SetupIdentitySkeleton();
                        }

                        //Morph targets
                        if (mesh.AssimpMesh.HasMeshAnimationAttachments)
                        {
                            int attCount = mesh.AssimpMesh.MeshAnimationAttachmentCount;
                            var mtv      = new FastList <MorphTargetVertex>(attCount * mesh.AssimpMesh.VertexCount);
                            foreach (var att in mesh.AssimpMesh.MeshAnimationAttachments)
                            {
                                //NOTE: It seems some files may have invalid normal/tangent data for morph targets.
                                //May need to provide option in future to use 0 normal/tangent deltas or recalculate
                                mtv.AddRange(new MorphTargetVertex[mesh.AssimpMesh.VertexCount].Select((x, i) =>
                                                                                                       new MorphTargetVertex()
                                {
                                    deltaPosition = (att.Vertices[i] - mesh.AssimpMesh.Vertices[i]).ToSharpDXVector3(),
                                    deltaNormal   = att.HasNormals ? (att.Normals[i] - mesh.AssimpMesh.Normals[i]).ToSharpDXVector3() : Vector3.Zero,
                                    deltaTangent  = att.HasTangentBasis ? (att.Tangents[i] - mesh.AssimpMesh.Tangents[i]).ToSharpDXVector3() : Vector3.Zero
                                }));
                            }

                            mn.MorphTargetWeights = new float[attCount];
                            mn.InitializeMorphTargets(mtv.ToArray(), mesh.AssimpMesh.VertexCount);
                        }

                        mnode = mn;
                    }
                    else
                    {
                        mnode = new HxScene.MeshNode();
                    }

                    mnode.Name        = string.IsNullOrEmpty(mesh.AssimpMesh.Name) ? $"{nameof(HxScene.MeshNode)}_{Interlocked.Increment(ref MeshIndexForNoName)}" : mesh.AssimpMesh.Name;
                    mnode.Geometry    = mesh.Mesh;
                    mnode.Material    = material.Value;
                    mnode.ModelMatrix = transform;
                    mnode.CullMode    = cullMode;
                    mnode.FillMode    = fillMode;
                    return(mnode);

                case PrimitiveType.Line:
                    var lnode = new HxScene.LineNode
                    {
                        Name = string.IsNullOrEmpty(mesh.AssimpMesh.Name)
                                ? $"{nameof(HxScene.LineNode)}_{Interlocked.Increment(ref MeshIndexForNoName)}"
                                : mesh.AssimpMesh.Name,
                        Geometry    = mesh.Mesh,
                        ModelMatrix = transform
                    };
                    var lmaterial = new LineMaterialCore();     //Must create separate line material
                    lnode.Material = lmaterial;
                    var ml = scene.Materials[mesh.MaterialIndex].Value;
                    if (ml is DiffuseMaterialCore diffuse)
                    {
                        lmaterial.LineColor = diffuse.DiffuseColor;
                    }
                    return(lnode);

                case PrimitiveType.Point:
                    var pnode = new HxScene.PointNode
                    {
                        Name = string.IsNullOrEmpty(mesh.AssimpMesh.Name)
                                ? $"{nameof(HxScene.PointNode)}_{Interlocked.Increment(ref MeshIndexForNoName)}"
                                : mesh.AssimpMesh.Name,
                        Geometry    = mesh.Mesh,
                        ModelMatrix = transform
                    };
                    var pmaterial = new PointMaterialCore();     //Must create separate point material
                    pnode.Material = pmaterial;
                    var pm = scene.Materials[mesh.MaterialIndex].Value;
                    if (pm is DiffuseMaterialCore diffuse1)
                    {
                        pmaterial.PointColor = diffuse1.DiffuseColor;
                    }
                    return(pnode);

                default:
                    throw new NotSupportedException($"Mesh Type {mesh.Type} does not supported");
                }
            }
            /// <summary>
            ///     To the hx mesh nodes.
            /// </summary>
            /// <param name="mesh">The mesh.</param>
            /// <param name="scene">The scene.</param>
            /// <param name="transform"></param>
            /// <returns></returns>
            /// <exception cref="System.NotSupportedException">Mesh Type {mesh.Type}</exception>
            protected virtual HxScene.SceneNode OnCreateHxMeshNode(MeshInfo mesh, HelixInternalScene scene, Matrix transform)
            {
                switch (mesh.Type)
                {
                case PrimitiveType.Triangle:
                    var material = scene.Materials[mesh.MaterialIndex];
                    var cullMode = material.Key.HasTwoSided && material.Key.IsTwoSided
                            ? CullMode.Back
                            : CullMode.None;
                    if (Configuration.ForceCullMode)
                    {
                        cullMode = Configuration.CullMode;
                    }
                    var fillMode = material.Key.HasWireFrame && material.Key.IsWireFrameEnabled
                            ? FillMode.Wireframe
                            : FillMode.Solid;
                    //Determine if has bones
                    var mnode = mesh.AssimpMesh.HasBones ?
                                new HxScene.BoneSkinMeshNode()
                    {
                        Bones = mesh.AssimpMesh.Bones.Select(x => new HxAnimations.Bone()
                        {
                            Name               = x.Name,
                            BindPose           = x.OffsetMatrix.ToSharpDXMatrix(configuration.IsSourceMatrixColumnMajor).Inverted(),
                            BoneLocalTransform = Matrix.Identity,
                            InvBindPose        = x.OffsetMatrix.ToSharpDXMatrix(configuration.IsSourceMatrixColumnMajor), //Documented at https://github.com/assimp/assimp/pull/1803
                        }).ToArray()
                    }
                            : new HxScene.MeshNode();
                    mnode.Name        = string.IsNullOrEmpty(mesh.AssimpMesh.Name) ? $"{nameof(HxScene.MeshNode)}_{Interlocked.Increment(ref MeshIndexForNoName)}" : mesh.AssimpMesh.Name;
                    mnode.Geometry    = mesh.Mesh;
                    mnode.Material    = material.Value;
                    mnode.ModelMatrix = transform;
                    mnode.CullMode    = cullMode;
                    mnode.FillMode    = fillMode;
                    return(mnode);

                case PrimitiveType.Line:
                    var lnode = new HxScene.LineNode
                    {
                        Name = string.IsNullOrEmpty(mesh.AssimpMesh.Name)
                                ? $"{nameof(HxScene.LineNode)}_{Interlocked.Increment(ref MeshIndexForNoName)}"
                                : mesh.AssimpMesh.Name,
                        Geometry    = mesh.Mesh,
                        ModelMatrix = transform
                    };
                    var lmaterial = new LineMaterialCore();     //Must create separate line material
                    lnode.Material = lmaterial;
                    var ml = scene.Materials[mesh.MaterialIndex].Value;
                    if (ml is DiffuseMaterialCore diffuse)
                    {
                        lmaterial.LineColor = diffuse.DiffuseColor;
                    }
                    return(lnode);

                case PrimitiveType.Point:
                    var pnode = new HxScene.PointNode
                    {
                        Name = string.IsNullOrEmpty(mesh.AssimpMesh.Name)
                                ? $"{nameof(HxScene.PointNode)}_{Interlocked.Increment(ref MeshIndexForNoName)}"
                                : mesh.AssimpMesh.Name,
                        Geometry    = mesh.Mesh,
                        ModelMatrix = transform
                    };
                    var pmaterial = new PointMaterialCore();     //Must create separate point material
                    pnode.Material = pmaterial;
                    var pm = scene.Materials[mesh.MaterialIndex].Value;
                    if (pm is DiffuseMaterialCore diffuse1)
                    {
                        pmaterial.PointColor = diffuse1.DiffuseColor;
                    }
                    return(pnode);

                default:
                    throw new NotSupportedException($"Mesh Type {mesh.Type} does not supported");
                }
            }