示例#1
0
        public void RefreshVertexList()
        {
            //Vertex 리스트가 Mesh의 Vert 리스트와 동기화가 되었는지 확인한다.
            //동기화되지 않았다면 ID, 순서를 모두 다시 맞춰준다.
            bool isVertChanged = false;

            if (_meshTransform_ID < 0)
            {
                _weightedVerts.Clear();
                return;
            }

            if (_meshTransform == null || _meshTransform._mesh == null)
            {
                return;
            }

            List <apVertex> srcVerts = _meshTransform._mesh._vertexData;
            int             nVerts   = srcVerts.Count;

            if (srcVerts.Count != _weightedVerts.Count)
            {
                isVertChanged = true;
            }
            else
            {
                for (int i = 0; i < nVerts; i++)
                {
                    if (srcVerts[i]._uniqueID != _weightedVerts[i]._uniqueID)
                    {
                        isVertChanged = true;
                        break;
                    }
                }
            }

            if (isVertChanged)
            {
                List <WeightedVertex> nextVerts = new List <WeightedVertex>();

                //Vertex가 동기화되지 않았다.
                //기존에 있는 값은 그대로 쓰고, 없는건 새로 만들자
                for (int i = 0; i < nVerts; i++)
                {
                    int            curUniqueID = srcVerts[i]._uniqueID;
                    WeightedVertex existVert   = GetWeightedVert(curUniqueID);
                    if (existVert != null)
                    {
                        existVert._vertIndex = i;                        //<<인덱스는 바꾸고..
                        nextVerts.Add(existVert);
                    }
                    else
                    {
                        nextVerts.Add(new WeightedVertex(curUniqueID, i));
                    }
                }

                _weightedVerts.Clear();
                for (int i = 0; i < nVerts; i++)
                {
                    _weightedVerts.Add(nextVerts[i]);
                }
            }
        }
示例#2
0
        public override IntermediateModel Process(IntermediateModelDef input, ContentProcessorContext context)
        {
            Scale = Scale == 0.0f ? 1.0f : Scale;

            model = new IntermediateModel();

            String prefix      = context.OutputDirectory;
            String wholeName   = context.OutputFilename;
            String partialName = wholeName.Substring(prefix.Length);
            String modelName   = partialName.Replace("\\\\", "\\");

            modelName = modelName.Replace(".xnb", "").Replace(".XNB", "");

            // Get the custom data associated with the model
            model.CustomData = ProcessCustomData(context);

            var scaleCustomData = model.CustomData["Scale"];

            if (scaleCustomData != null)
            {
                Scale = Convert.ToSingle(scaleCustomData.Value);
            }

            List <IntermediateModelMesh> imms = new List <IntermediateModelMesh>();

            for (int i = 0; i < input.ModelMeshes.Count; ++i)
            {
                var modelMesh = input.ModelMeshes[i];

                IntermediateModelMesh imm          = new IntermediateModelMesh();
                ModelMeshVertex[]     vertices     = new ModelMeshVertex[modelMesh.Vertices.Length];
                WeightedVertex[]      origVertices = new WeightedVertex[modelMesh.Vertices.Length];

                //DebugNow();

                for (int j = 0; j < modelMesh.Vertices.Length; ++j)
                {
                    if (input.HasSkinningData)
                    {
                        var intermediateWeightedVertex = input.WeightedVertices[modelMesh.Vertices[j].WeightedVertexIndex];
                        vertices[j].Position = Vector3.Transform(intermediateWeightedVertex.Position.ToVector3(), Matrix.CreateScale(Scale));

                        origVertices[j].Weight0           = new Core.Graphics.Primitives.BoneWeight();
                        origVertices[j].Weight0.BoneIndex = intermediateWeightedVertex.JointWeights[0].JointIndex;
                        origVertices[j].Weight0.Weight    = intermediateWeightedVertex.JointWeights[0].Weight;

                        origVertices[j].Weight1           = new Core.Graphics.Primitives.BoneWeight();
                        origVertices[j].Weight1.BoneIndex = intermediateWeightedVertex.JointWeights[1].JointIndex;
                        origVertices[j].Weight1.Weight    = intermediateWeightedVertex.JointWeights[1].Weight;

                        origVertices[j].Weight2           = new Core.Graphics.Primitives.BoneWeight();
                        origVertices[j].Weight2.BoneIndex = intermediateWeightedVertex.JointWeights[2].JointIndex;
                        origVertices[j].Weight2.Weight    = intermediateWeightedVertex.JointWeights[2].Weight;

                        origVertices[j].Weight3           = new Core.Graphics.Primitives.BoneWeight();
                        origVertices[j].Weight3.BoneIndex = intermediateWeightedVertex.JointWeights[3].JointIndex;
                        origVertices[j].Weight3.Weight    = intermediateWeightedVertex.JointWeights[3].Weight;
                    }
                    else
                    {
                        vertices[j].Position = Vector3.Transform(modelMesh.Vertices[j].Position.ToVector3(), Matrix.CreateScale(Scale));
                    }

                    vertices[j].Normal             = Vector3.TransformNormal(modelMesh.Vertices[j].Normal.ToVector3(), Matrix.CreateScale(Scale));
                    vertices[j].TextureCoordinate0 = modelMesh.Vertices[j].TextureCoordinate0.ToVector2();
                    vertices[j].Tangent            = modelMesh.Vertices[j].Tangent.ToVector3();
                    vertices[j].Binormal           = modelMesh.Vertices[j].Binormal.ToVector3();
                }

                OpaqueDataDictionary settings = new OpaqueDataDictionary();
                settings["GenerateMipmaps"] = true;

                IntermediateMaterial im = new IntermediateMaterial();
                im.Name          = modelMesh.Material.Name;
                im.DiffuseColor  = modelMesh.Material.DiffuseColor.ToVector3();
                im.SpecularColor = modelMesh.Material.SpecularColor.ToVector3();
                im.SpecularExp   = modelMesh.Material.CosinePower.AsSingle();
                im.Transparency  = modelMesh.Material.Transparency.AsSingle();
                im.UseAlpha      = modelMesh.Material.UseAlpha.AsBoolean();
                im.DrawBackfaces = modelMesh.Material.DrawBackfaces.AsBoolean();
                im.Reflectivity  = modelMesh.Material.Reflectivity.AsSingle();

                //DebugNow();

                im.DiffuseMapName = modelMesh.Material.DiffuseMapFilename.AsString();
                if (!String.IsNullOrEmpty(im.DiffuseMapName))
                {
                    //im.DiffuseMapReference = context.BuildAsset<TextureContent, TextureContent>(
                    //    new ExternalReference<TextureContent>(
                    //        Path.Combine(Path.GetDirectoryName(input.Path), im.DiffuseMapName)), "TextureProcessor", settings, null, null);
                }

                im.NormalMapName = modelMesh.Material.NormalMapFilename.AsString();
                if (!String.IsNullOrEmpty(im.NormalMapName))
                {
                    //im.BumpMapReference = context.BuildAsset<TextureContent, TextureContent>(
                    //    new ExternalReference<TextureContent>(
                    //        Path.Combine(Path.GetDirectoryName(input.Path), im.BumpMapName)), "TextureProcessor", settings, null, null);
                }

                im.SpecularMapName = modelMesh.Material.SpecularMapFilename.AsString();
                if (!String.IsNullOrEmpty(im.SpecularMapName))
                {
                    //im.SpecularMapReference = context.BuildAsset<TextureContent, TextureContent>(
                    //    new ExternalReference<TextureContent>(
                    //        Path.Combine(Path.GetDirectoryName(input.Path), im.SpecularMapName)), "TextureProcessor", settings, null, null);
                }

                imm.Indices = modelMesh.Indices.ToInt32Array();
                for (int k = 0; k <= imm.Indices.Length - 3; k += 3)
                {
                    var temp = imm.Indices[k];
                    imm.Indices[k]     = imm.Indices[k + 2];
                    imm.Indices[k + 2] = temp;
                }

                imm.Vertices         = vertices;
                imm.OriginalVertices = origVertices;
                imm.BoundingSphere   = BoundingSphere.CreateFromPoints(vertices.Select(v => v.Position));
                imm.BoundingBox      = BoundingBox.CreateFromPoints(vertices.Select(v => v.Position));
                imm.Material         = im;

                imms.Add(imm);
            }

            // Animation stuff
            List <Matrix>             bindPose          = new List <Matrix>();
            List <Matrix>             inverseBindPose   = new List <Matrix>();
            List <int>                skeletonHierarchy = new List <int>();
            IDictionary <string, int> boneMap           = new Dictionary <string, int>();
            IList <String>            boneNames         = new List <String>(input.BindPose.Count);

            for (int i = 0; i < input.BindPose.Count; boneNames.Add(String.Empty), ++i)
            {
                ;
            }

            //DebugNow();

            foreach (var joint in input.BindPose)
            {
                Matrix transform = Matrix.CreateFromQuaternion(joint.Rotation.ToQuaternion()) * joint.Position.ToTranslationMatrix();
                transform.Translation *= Scale;

                Matrix absoluteTransform = Matrix.CreateFromQuaternion(joint.AbsoluteRotation.ToQuaternion()) *
                                           joint.AbsolutePosition.ToTranslationMatrix();
                absoluteTransform.Translation *= Scale;

                bindPose.Add(transform);
                inverseBindPose.Add(Matrix.Invert(absoluteTransform));
                skeletonHierarchy.Add(joint.ParentIndex);
                boneNames[joint.Index] = joint.Name;
                boneMap.Add(joint.Name, joint.Index);
            }

            var animationClips = ProcessAnimations(input.AnimationKeyframes, input.BindPose, boneNames);
            var skinningData   = new SkinningData(bindPose, inverseBindPose, skeletonHierarchy, boneMap, boneNames, modelName);
            var animations     = PrepareAnimations(animationClips, skinningData, context);

            model.ModelMeshes    = imms.ToArray();
            model.AnimationMap   = animations;
            model.SkinningData   = skinningData;
            model.BoundingSphere = BoundingSphere.CreateFromPoints(imms.SelectMany(m => m.Vertices.Select(v => v.Position)));
            model.BoundingBox    = BoundingBox.CreateFromPoints(imms.SelectMany(m => m.Vertices.Select(v => v.Position)));

            return(model);
        }
 public void CopyFrom(WeightedVertex vertex)
 {
     Weight      = vertex.Weight;
     VertexIndex = vertex.VertexIndex;
 }
示例#4
0
        /// <summary>
        /// Imports an FBX file.
        /// </summary>
        /// <param name="stream">The FBX stream.</param>
        /// <param name="settings">An import settings object.</param>
        /// <param name="format">The filetype of the mesh.</param>
        /// <param name="filePath">The path to the file.</param>
        /// <returns>An <see cref="ImportResult" /> object.</returns>
        public static ImportResult Import(Stream stream, ImportSettings settings, string format, string filePath)
        {
            var sceneName = Path.GetFileNameWithoutExtension(filePath);

            Debug.Assert(sceneName != null, "sceneName != null");

            var steps = PostProcessSteps.ValidateDataStructure
                        | PostProcessSteps.GenerateUVCoords
                        | PostProcessSteps.Triangulate
                        | PostProcessSteps.SortByPrimitiveType
                        | PostProcessSteps.FlipUVs
                        | PostProcessSteps.FlipWindingOrder
                        | PostProcessSteps.LimitBoneWeights
                        | PostProcessSteps.ImproveCacheLocality
                        | PostProcessSteps.RemoveComponent
                        | PostProcessSteps.RemoveRedundantMaterials;

            if (!settings.KeepOverlappingVertices)
            {
                steps |= PostProcessSteps.JoinIdenticalVertices;
            }
            if (!settings.ImportAsSkeletal)
            {
                steps |= PostProcessSteps.Debone;
            }
            if (settings.MergeMeshes)
            {
                steps |= PostProcessSteps.OptimizeMeshes;
            }

            switch (settings.NormalImportMethod)
            {
            case NormalImportMethod.ComputeNormals:
                steps |= PostProcessSteps.GenerateNormals;
                steps |= PostProcessSteps.CalculateTangentSpace;
                break;

            case NormalImportMethod.ComputeNormalsSmooth:
                steps |= PostProcessSteps.GenerateSmoothNormals;
                steps |= PostProcessSteps.CalculateTangentSpace;
                break;

            case NormalImportMethod.ImportNormals:
                steps |= PostProcessSteps.CalculateTangentSpace;
                break;

            case NormalImportMethod.ImportNormalsAndTangents:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var      scene             = ContentProvider.AssimpContext.ImportFileFromStream(stream, steps, format);
            Skeleton skeleton          = null;
            var      importedSkeleton  = false;
            var      importedAnimation = false;
            var      importedMesh      = false;
            var      importedMaterials = false;
            var      geometries        = new Dictionary <string, Geometry>(scene.MeshCount);
            var      animations        = new AnimationData[scene.AnimationCount];
            var      materials         = new Material[scene.MaterialCount];
            var      textures          = new Data.Texture[scene.TextureCount];

            if (settings.ImportAsSkeletal)
            {
                if (settings.Skeleton == null)
                {
                    SkeletonNodeData nodeData;

                    if (!FindSkeleton(ref scene, out nodeData))
                    {
                        throw new InvalidOperationException("Could not import skeleton.");
                    }

                    skeleton         = ImportSkeleton(ref nodeData);
                    importedSkeleton = true;
                }
                else
                {
                    skeleton = settings.Skeleton;
                }
            }

            if (scene.HasMaterials)
            {
                importedMaterials = true;

                if (filePath != null)
                {
                    var fileFolder = Path.GetDirectoryName(filePath);
                    for (var i = 0; i < scene.MaterialCount; i++)
                    {
                        var mat = scene.Materials[i];

                        var material = new Material();



                        materials[i] = material;
                    }
                }
            }

            for (var i = 0; i < scene.MeshCount; i++)
            {
                var mesh     = scene.Meshes[i];
                var meshName = string.IsNullOrWhiteSpace(mesh.Name) ? $"{sceneName} ({i})" : mesh.Name;

                var vertices             = new Vertex[mesh.VertexCount];
                WeightedVertex[] weights = null;

                if (mesh.HasBones && settings.ImportAsSkeletal)
                {
                    weights = new WeightedVertex[mesh.VertexCount];
                }

                for (var j = 0; j < mesh.VertexCount; j++)
                {
                    var texCoordChannel = mesh.HasTextureCoords(0)
                        ? mesh.TextureCoordinateChannels[0][j]
                        : new Vector3D(0, 0, 0);
                    var vertexColourChannel = mesh.HasVertexColors(0)
                        ? mesh.VertexColorChannels[0][j]
                        : new Color4D(0, 0, 0, 1);

                    var tangent   = mesh.HasTangentBasis ? mesh.Tangents[j] : new Vector3D(0, 0, 0);
                    var bitangent = mesh.HasTangentBasis ? mesh.Tangents[j] : new Vector3D(0, 0, 0);

                    vertices[j] = new Vertex
                    {
                        Position  = (Vector3)mesh.Vertices[j],
                        Normal    = (Vector3)mesh.Normals[j],
                        Colour    = vertexColourChannel,
                        TexCoord  = new Vector2(texCoordChannel.X, texCoordChannel.Y),
                        Tangent   = (Vector3)tangent,
                        BiTangent = (Vector3)bitangent
                    };

                    // TODO: add bone data
                }

                importedMesh          = true;
                geometries[mesh.Name] = new Geometry(meshName, vertices.ToArray(), mesh.GetIndices(), weights?.ToArray(),
                                                     PrimitiveTopology.TriangleList)
                {
                    MaterialIndex = mesh.MaterialIndex
                };
            }

            if (settings.MergeMeshes && !settings.ImportAsSkeletal)
            {
                var vertices = new Vertex[0];
                var weights  = new WeightedVertex[0];
                var indices  = new int[0];

                foreach (var mesh in geometries.Values)
                {
                    var lastVertices = vertices;
                    vertices = new Vertex[lastVertices.Length + mesh.Vertices.Length];
                    lastVertices.CopyTo(vertices, 0);
                    mesh.Vertices.CopyTo(vertices, lastVertices.Length);

                    var lastWeights = weights;
                    weights = new WeightedVertex[lastWeights.Length + (mesh.Weights?.Length ?? 0)];
                    lastWeights.CopyTo(weights, 0);
                    mesh.Weights?.CopyTo(weights, lastWeights.Length);

                    var lastIndices = indices;
                    indices = new int[indices.Length + mesh.Indices.Length];
                    lastIndices.CopyTo(indices, 0);
                    mesh.Indices.Select(i => i + lastVertices.Length).ToArray().CopyTo(indices, lastIndices.Length);

                    mesh.Dispose();
                }

                geometries.Clear();
                geometries[sceneName] = new Geometry(sceneName, vertices, indices, weights);
            }

            for (var i = 0; i < scene.AnimationCount; i++)
            {
                var animation = scene.Animations[i];

                animations[i]     = new AnimationData();
                importedAnimation = true;

                // TODO: import animations
            }

            string path;

            if (settings.ContentPath == null)
            {
                path = Path.Combine(Engine.TempPath, Guid.NewGuid().ToString("N"));
                Directory.CreateDirectory(path);
            }
            else
            {
                path = settings.ContentPath;
            }

            #region File Creation

            foreach (var material in materials)
            {
                var materialPath = Path.Combine(path, $"{material.Name}.material");
                if (materialPath == null)
                {
                    continue;
                }
                using (var file = File.Create(materialPath))
                {
                    Inst.Serialize(material, file);
                }
            }

            foreach (var geo in geometries.Values)
            {
                var meshPath = GetFilePath(sceneName, path, settings);
                if (meshPath == null)
                {
                    continue;
                }
                using (var file = File.Create(meshPath))
                {
                    geo.Material = materials[geo.MaterialIndex];
                    geo.Save(file);
                }
            }

            if (importedSkeleton)
            {
                var skeletonPath = GetFilePath(sceneName, path, settings);
                if (skeletonPath != null)
                {
                    using (var file = File.Create(skeletonPath))
                    {
                        Inst.Serialize(skeleton, file);
                    }
                }
            }

            foreach (var animation in animations)
            {
                var animPath = GetFilePath(sceneName, path, settings);
                if (animPath == null)
                {
                    continue;
                }
                using (var file = File.Create(animPath))
                {
                    animation.Save(file);
                }
            }

            #endregion

            if (settings.ContentPath != null)
            {
                foreach (var file in Directory.GetFiles(path))
                {
                    File.Move(file, Path.Combine(settings.ContentPath, Path.GetFileName(file)));
                }
            }

            return(new ImportResult(geometries, animations, materials, skeleton, importedSkeleton, importedAnimation,
                                    importedMesh, importedMaterials));
        }