Ejemplo n.º 1
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");
                }
            }