예제 #1
0
        private Ai.Node ConvertNode(Model model, Node node, Ai.Node aiParent)
        {
            var aiNode = new Ai.Node(AssimpConverterCommon.EscapeName(node.Name), aiParent)
            {
                Transform = new Ai.Matrix4x4(node.LocalTransform.M11, node.LocalTransform.M21, node.LocalTransform.M31, node.LocalTransform.M41,
                                             node.LocalTransform.M12, node.LocalTransform.M22, node.LocalTransform.M32, node.LocalTransform.M42,
                                             node.LocalTransform.M13, node.LocalTransform.M23, node.LocalTransform.M33, node.LocalTransform.M43,
                                             node.LocalTransform.M14, node.LocalTransform.M24, node.LocalTransform.M34, node.LocalTransform.M44)
            };

            if (node.HasProperties)
            {
                ConvertNodeProperties(node.Properties, aiNode);
            }

            if (node.HasAttachments)
            {
                ConvertNodeAttachments(model, node, aiNode);
            }

            if (node.HasChildren)
            {
                foreach (var childNode in node.Children)
                {
                    aiNode.Children.Add(ConvertNode(model, childNode, aiNode));
                }
            }

            return(aiNode);
        }
예제 #2
0
        private void ConvertNodeAttachments(Model model, Node node, Ai.Node aiNode)
        {
            for (int i = 0; i < node.Attachments.Count; i++)
            {
                var attachment = node.Attachments[i];

                switch (attachment.Type)
                {
                case NodeAttachmentType.Mesh:
                {
                    var mesh = ConvertGeometry(model, node, attachment.GetValue <Mesh>());

                    mesh.Name = $"{AssimpConverterCommon.EscapeName(node.Name)}_Attachment{i}_Mesh";
                    aiNode.MeshIndices.Add(mAiScene.Meshes.Count);
                    mAiScene.Meshes.Add(mesh);
                }
                break;

                case NodeAttachmentType.Camera:
                {
                    var camera = attachment.GetValue <Camera>();
                    mAiScene.Cameras.Add(new Ai.Camera
                        {
                            Name          = node.Name,
                            Position      = camera.Position.ToAssimp(),
                            Up            = camera.Up.ToAssimp(),
                            Direction     = -camera.Direction.ToAssimp(),
                            FieldOfview   = MathHelper.DegreesToRadians(camera.FieldOfView),
                            ClipPlaneNear = camera.ClipPlaneNear,
                            ClipPlaneFar  = camera.ClipPlaneFar,
                            AspectRatio   = camera.AspectRatio
                        });
                }
                break;

                case NodeAttachmentType.Light:
                {
                    var light = attachment.GetValue <Light>();
                    mAiScene.Lights.Add(new Ai.Light
                        {
                            Name           = node.Name,
                            AngleInnerCone = light.AngleInnerCone,
                            AngleOuterCone = light.AngleOuterCone,
                            ColorAmbient   = light.AmbientColor.ToAssimpAsColor3D(),
                            ColorDiffuse   = light.DiffuseColor.ToAssimpAsColor3D(),
                            ColorSpecular  = light.SpecularColor.ToAssimpAsColor3D(),
                            LightType      = light.Type == LightType.Point ? Ai.LightSourceType.Point : light.Type == LightType.Spot ? Ai.LightSourceType.Spot : Ai.LightSourceType.Directional,
                        });
                }
                break;

                default:
                    //throw new NotImplementedException();
                    break;
                }
            }
        }
예제 #3
0
        private void ConvertTextures(TextureDictionary textureDictionary)
        {
            Directory.CreateDirectory(mTextureBaseDirectoryPath);

            foreach (var texture in textureDictionary.Textures)
            {
                var texturePath = Path.Combine(mTextureBaseDirectoryPath, AssimpConverterCommon.EscapeName(texture.Name));

                File.WriteAllBytes(texturePath, texture.Data);
            }
        }
예제 #4
0
        private Ai.Material ConvertMaterial(Material material)
        {
            var aiMaterial = new Ai.Material
            {
                Name          = AssimpConverterCommon.EscapeName(material.Name),
                ColorAmbient  = new Ai.Color4D(material.AmbientColor.X, material.AmbientColor.Y, material.AmbientColor.Z, material.AmbientColor.W),
                ColorDiffuse  = new Ai.Color4D(material.DiffuseColor.X, material.DiffuseColor.Y, material.DiffuseColor.Z, material.DiffuseColor.W),
                ColorSpecular = new Ai.Color4D(material.SpecularColor.X, material.SpecularColor.Y, material.SpecularColor.Z, material.SpecularColor.W),
                ColorEmissive = new Ai.Color4D(material.EmissiveColor.X, material.EmissiveColor.Y, material.EmissiveColor.Z, material.EmissiveColor.W)
            };

            if (material.Flags.HasFlag(MaterialFlags.HasDiffuseMap))
            {
                aiMaterial.TextureDiffuse = new Ai.TextureSlot(
                    Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.DiffuseMap.Name)),
                    Ai.TextureType.Diffuse, 0, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0);
            }

            if (material.Flags.HasFlag(MaterialFlags.HasNormalMap))
            {
                aiMaterial.TextureNormal = new Ai.TextureSlot(
                    Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.NormalMap.Name)),
                    Ai.TextureType.Normals, 1, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0);
            }

            if (material.Flags.HasFlag(MaterialFlags.HasSpecularMap))
            {
                aiMaterial.TextureSpecular = new Ai.TextureSlot(
                    Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.SpecularMap.Name)),
                    Ai.TextureType.Specular, 2, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0);
            }

            if (material.Flags.HasFlag(MaterialFlags.HasReflectionMap))
            {
                aiMaterial.TextureReflection = new Ai.TextureSlot(
                    Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.ReflectionMap.Name)),
                    Ai.TextureType.Reflection, 3, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0);
            }

            // todo: add more textures

            return(aiMaterial);
        }
예제 #5
0
        private Ai.Mesh ConvertGeometry(Model model, Node geometryNode, Mesh mesh)
        {
            var aiMesh = new Ai.Mesh(Ai.PrimitiveType.Triangle);

            if (mesh.Flags.HasFlag(GeometryFlags.HasMaterial))
            {
                aiMesh.MaterialIndex = mAiScene.Materials.FindIndex(x => x.Name == AssimpConverterCommon.EscapeName(mesh.MaterialName));
            }

            if (mesh.Flags.HasFlag(GeometryFlags.HasTriangles))
            {
                foreach (var triangle in mesh.Triangles)
                {
                    var aiFace = new Ai.Face();
                    aiFace.Indices.Add(( int )triangle.A);
                    aiFace.Indices.Add(( int )triangle.B);
                    aiFace.Indices.Add(( int )triangle.C);
                    aiMesh.Faces.Add(aiFace);
                }
            }

            var vertices = mesh.Vertices;
            var normals  = mesh.Normals;

            if (mesh.VertexWeights != null)
            {
                (vertices, normals) = mesh.Transform(geometryNode, model.Nodes.ToList(), model.Bones);
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Position))
            {
                foreach (var vertex in vertices)
                {
                    aiMesh.Vertices.Add(new Ai.Vector3D(vertex.X, vertex.Y, vertex.Z));
                }
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Normal))
            {
                foreach (var normal in normals)
                {
                    aiMesh.Normals.Add(new Ai.Vector3D(normal.X, normal.Y, normal.Z));
                }
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Tangent))
            {
                foreach (var tangent in mesh.Tangents)
                {
                    aiMesh.Tangents.Add(new Ai.Vector3D(tangent.X, tangent.Y, tangent.Z));
                }
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Binormal))
            {
                foreach (var binormal in mesh.Binormals)
                {
                    aiMesh.BiTangents.Add(new Ai.Vector3D(binormal.X, binormal.Y, binormal.Z));
                }
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.TexCoord0))
            {
                foreach (var vertex in mesh.TexCoordsChannel0)
                {
                    aiMesh.TextureCoordinateChannels[0].Add(new Ai.Vector3D(vertex.X, vertex.Y, 0));
                }
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.TexCoord1))
            {
                foreach (var vertex in mesh.TexCoordsChannel1)
                {
                    aiMesh.TextureCoordinateChannels[1].Add(new Ai.Vector3D(vertex.X, vertex.Y, 0));
                }
            }

            if (mesh.VertexAttributeFlags.HasFlag(VertexAttributeFlags.TexCoord2))
            {
                foreach (var vertex in mesh.TexCoordsChannel2)
                {
                    aiMesh.TextureCoordinateChannels[2].Add(new Ai.Vector3D(vertex.X, vertex.Y, 0));
                }
            }

            /* todo: colors
             * if ( mesh.VertexAttributeFlags.HasFlag( VertexAttributeFlags.Color0 ) )
             * {
             *  foreach ( var color in mesh.ColorChannel0 )
             *  {
             *      aiMesh.VertexColorChannels[0].Add( new Ai.Color4D( color. ))
             *  }
             * }
             */

            if (mesh.Flags.HasFlag(GeometryFlags.HasVertexWeights))
            {
                var boneMap = new Dictionary <int, Ai.Bone>();

                for (int i = 0; i < mesh.VertexWeights.Length; i++)
                {
                    var vertexWeight = mesh.VertexWeights[i];

                    for (int j = 0; j < 4; j++)
                    {
                        var boneWeight = vertexWeight.Weights[j];
                        if (boneWeight == 0f)
                        {
                            continue;
                        }

                        var boneIndex = vertexWeight.Indices[j];
                        var nodeIndex = model.Bones[boneIndex].NodeIndex;

                        if (!boneMap.ContainsKey(nodeIndex))
                        {
                            var aiBone   = new Ai.Bone();
                            var boneNode = model.GetNode(nodeIndex);

                            aiBone.Name = AssimpConverterCommon.EscapeName(boneNode.Name);
                            aiBone.VertexWeights.Add(new Ai.VertexWeight(i, boneWeight));

                            Matrix4x4.Invert(geometryNode.WorldTransform, out Matrix4x4 invGeometryNodeWorldTransform);
                            Matrix4x4.Invert(boneNode.WorldTransform * invGeometryNodeWorldTransform, out Matrix4x4 offsetMatrix);
                            aiBone.OffsetMatrix = new Ai.Matrix4x4(offsetMatrix.M11, offsetMatrix.M21, offsetMatrix.M31, offsetMatrix.M41,
                                                                   offsetMatrix.M12, offsetMatrix.M22, offsetMatrix.M32, offsetMatrix.M42,
                                                                   offsetMatrix.M13, offsetMatrix.M23, offsetMatrix.M33, offsetMatrix.M43,
                                                                   offsetMatrix.M14, offsetMatrix.M24, offsetMatrix.M34, offsetMatrix.M44);
                            boneMap[nodeIndex] = aiBone;
                        }
                        else
                        {
                            boneMap[nodeIndex].VertexWeights.Add(new Ai.VertexWeight(i, boneWeight));
                        }
                    }
                }

                aiMesh.Bones.AddRange(boneMap.Values);
            }

            return(aiMesh);
        }