Ejemplo n.º 1
0
 static void AddTextureIfExists(bool Exists, ref FoamMaterial FoamMat, TextureSlot Texture, FoamTextureType TexType)
 {
     if (Exists)
     {
         FoamMat.AddTexture(new FoamTexture(Texture.FilePath, TexType));
     }
 }
Ejemplo n.º 2
0
        static void ApplyEmissive(Vector4[] Pixels, int W, int H, List <FoamVertex3> ModelVerts, List <FoamMesh> Meshes, FoamModel Model)
        {
            Vector4 ClrR = new Vector4(1, 0, 0, 1);
            Vector4 ClrG = new Vector4(0, 1, 0, 1);
            Vector4 ClrB = new Vector4(0, 0, 1, 1);
            Vector4 ClrW = new Vector4(1, 1, 1, 1);

            Vector2 Size = new Vector2(W, H);

            for (int i = 0; i < ModelVerts.Count; i += 3)
            {
                FoamMaterial Mat = Model.Materials[Meshes[i].MaterialIndex];

                // TODO: Move somewhere else
                switch (Mat.MaterialName)
                {
                case "base/emissive_red":
                    DrawTriangle(Pixels, W, H, ClrR, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                case "base/emissive_green":
                    DrawTriangle(Pixels, W, H, ClrG, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                case "base/emissive_blue":
                    DrawTriangle(Pixels, W, H, ClrB, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                //case "base/emissive_sky":
                case "base/emissive_white":
                    DrawTriangle(Pixels, W, H, ClrW, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                default:
                    break;
                }
            }
        }
Ejemplo n.º 3
0
 public static FoamModel Load(string ObjFile, string MtlFile)
 {
     FoamMaterial[]   Materials = new FoamMaterial[] { new FoamMaterial("default") };
     ref FoamMaterial CurMat    = ref Materials[0];
Ejemplo n.º 4
0
        static FoamModel Load(string FileName, int MD3Frame = 0)
        {
            string Ext = Path.GetExtension(FileName).ToLower();

            using (AssimpContext Importer = new AssimpContext()) {
                Importer.SetConfig(new MD3HandleMultiPartConfig(false));
                //Importer.SetConfig(new MD5NoAnimationAutoLoadConfig(true));
                Importer.SetConfig(new VertexBoneWeightLimitConfig(4));
                Importer.SetConfig(new MD3KeyFrameImportConfig(MD3Frame));

                PostProcessSteps ProcessSteps = PostProcessSteps.Triangulate;
                ProcessSteps |= PostProcessSteps.SplitLargeMeshes;
                ProcessSteps |= PostProcessSteps.OptimizeMeshes;
                ProcessSteps |= PostProcessSteps.LimitBoneWeights;
                ProcessSteps |= PostProcessSteps.JoinIdenticalVertices;
                ProcessSteps |= PostProcessSteps.ImproveCacheLocality;
                ProcessSteps |= PostProcessSteps.GenerateNormals;
                ProcessSteps |= PostProcessSteps.GenerateUVCoords;

                //if (Ext != ".md3")
                ProcessSteps |= PostProcessPreset.ConvertToLeftHanded;

                Scene Sc = Importer.ImportFile(FileName, ProcessSteps);

                List <FoamMaterial> MaterialList = new List <FoamMaterial>();
                foreach (var Mat in Sc.Materials)
                {
                    FoamMaterial FoamMat = new FoamMaterial(Mat.Name);

                    AddTextureIfExists(Mat.HasTextureDiffuse, ref FoamMat, Mat.TextureDiffuse, FoamTextureType.Diffuse);
                    AddTextureIfExists(Mat.HasTextureEmissive, ref FoamMat, Mat.TextureEmissive, FoamTextureType.Glow);
                    AddTextureIfExists(Mat.HasTextureNormal, ref FoamMat, Mat.TextureNormal, FoamTextureType.Normal);
                    AddTextureIfExists(Mat.HasTextureSpecular, ref FoamMat, Mat.TextureSpecular, FoamTextureType.Specular);
                    AddTextureIfExists(Mat.HasTextureReflection, ref FoamMat, Mat.TextureReflection, FoamTextureType.Reflection);
                    AddTextureIfExists(Mat.HasTextureHeight, ref FoamMat, Mat.TextureHeight, FoamTextureType.Height);
                    AddTextureIfExists(Mat.HasTextureLightMap, ref FoamMat, Mat.TextureLightMap, FoamTextureType.LightMap);
                    AddTextureIfExists(Mat.HasTextureDisplacement, ref FoamMat, Mat.TextureDisplacement, FoamTextureType.Displacement);
                    AddTextureIfExists(Mat.HasTextureAmbient, ref FoamMat, Mat.TextureAmbient, FoamTextureType.Ambient);
                    AddTextureIfExists(Mat.HasTextureOpacity, ref FoamMat, Mat.TextureOpacity, FoamTextureType.Opacity);

                    MaterialList.Add(FoamMat);
                }

                FoamBone[]      Bones    = new FoamBone[0];
                List <FoamMesh> MeshList = new List <FoamMesh>();

                foreach (var Msh in Sc.Meshes)
                {
                    Vector3D[] Verts    = Msh.Vertices.ToArray();
                    Vector3D[] UVs1     = Msh.TextureCoordinateChannels[0].ToArray();
                    Vector3D[] UVs2     = Msh.TextureCoordinateChannels[1].ToArray();
                    Vector3D[] Normals  = Msh.Normals.ToArray();
                    Vector3D[] Tangents = Msh.Tangents.ToArray();
                    Color4D[]  Colors   = Msh.VertexColorChannels[0].ToArray();

                    string MeshName      = Msh.Name;
                    int    MaterialIndex = Msh.MaterialIndex;

                    FoamVertex3[] FoamVertices = new FoamVertex3[Verts.Length];
                    for (int i = 0; i < FoamVertices.Length; i++)
                    {
                        Vector2   UV1     = UVs1.Length != 0 ? new Vector2(UVs1[i].X, UVs1[i].Y) : Vector2.Zero;
                        Vector2   UV2     = UVs2.Length != 0 ? new Vector2(UVs2[i].X, UVs2[i].Y) : Vector2.Zero;
                        Vector3   Normal  = Normals.Length != 0 ? new Vector3(Normals[i].X, Normals[i].Y, Normals[i].Z) : Vector3.Zero;
                        Vector3   Tangent = Tangents.Length != 0 ? new Vector3(Tangents[i].X, Tangents[i].Y, Tangents[i].Z) : Vector3.Zero;
                        FoamColor Color   = Colors.Length != 0 ? new FoamColor(Colors[i].R, Colors[i].G, Colors[i].B, Colors[i].A) : FoamColor.White;

                        FoamVertex3 V = new FoamVertex3(new Vector3(Verts[i].X, Verts[i].Y, Verts[i].Z), UV1, UV2, Normal, Tangent, Color);
                        FoamVertices[i] = V;
                    }

                    bool CalculateTangents = Tangents.Length == 0 && UVs1.Length != 0;
                    //bool CalculateNormals = Normals.Length == 0;

                    List <ushort> FoamIndices = new List <ushort>();
                    foreach (var F in Msh.Faces)
                    {
                        ushort IndexA = (ushort)F.Indices[0];
                        ushort IndexB = (ushort)F.Indices[1];
                        ushort IndexC = (ushort)F.Indices[2];

                        if (CalculateTangents)
                        {
                            FoamVertex3 V0 = FoamVertices[IndexA];
                            FoamVertex3 V1 = FoamVertices[IndexB];
                            FoamVertex3 V2 = FoamVertices[IndexC];

                            Vector3 DeltaPos1 = V1.Position - V0.Position;
                            Vector3 DeltaPos2 = V2.Position - V0.Position;

                            //if (CalculateTangents) {
                            Vector2 DeltaUV1 = V1.UV - V0.UV;
                            Vector2 DeltaUV2 = V2.UV - V0.UV;

                            Vector3 Tangent = (DeltaPos1 * DeltaUV2.Y - DeltaPos2 * DeltaUV1.Y) * (1.0f / (DeltaUV1.X * DeltaUV2.Y - DeltaUV1.Y * DeltaUV2.X));
                            FoamVertices[IndexA].Tangent = FoamVertices[IndexB].Tangent = FoamVertices[IndexC].Tangent = Tangent;

                            /*}
                             *
                             * if (CalculateNormals)
                             *      FoamVertices[IndexA].Normal = FoamVertices[IndexB].Normal = FoamVertices[IndexC].Normal = Vector3.Normalize(Vector3.Cross(DeltaPos1, DeltaPos2));*/
                        }

                        FoamIndices.AddRange(F.Indices.Select(I => (ushort)I));
                    }

                    FoamBoneInfo[] BoneInfo = null;

                    if (Msh.BoneCount != 0)
                    {
                        BoneInfo = new FoamBoneInfo[FoamVertices.Length];
                        Bone[] OrigBones = Msh.Bones.ToArray();

                        // Convert bones
                        for (int i = 0; i < OrigBones.Length; i++)
                        {
                            if (!ContainsBoneNamed(Bones, OrigBones[i].Name))
                            {
                                Utils.Append(ref Bones, new FoamBone(OrigBones[i].Name, -1, ConvertMatrix(OrigBones[i].OffsetMatrix)));
                            }
                        }

                        // Convert vertex bone information
                        for (int i = 0; i < FoamVertices.Length; i++)
                        {
                            BoneInfo[i] = FindWeightsFor(OrigBones, Bones, i);
                        }
                    }

                    MeshList.Add(new FoamMesh(FoamVertices, FoamIndices?.ToArray() ?? null, BoneInfo, MeshName, MaterialIndex));
                }

                if (Bones.Length > 0)
                {
                    Node[] NodeHierarchy = Flatten(Sc.RootNode);
                    //Node SceneRootNode = Sc.RootNode;
                    Node RootNode = FindRoot(FindNode(NodeHierarchy, Bones[0].Name), Bones);
                    Utils.Prepend(ref Bones, new FoamBone(RootNode.Name, -1, ConvertMatrix(RootNode.Transform)));

                    /*Node RootNodeTest = RootNode;
                     * while (RootNodeTest.Parent != null) {
                     *      Bones[0].BindMatrix = Bones[0].BindMatrix * ConvertMatrix(RootNodeTest.Transform);
                     *      RootNodeTest = RootNodeTest.Parent;
                     * }*/


                    /*while (RootNode.Parent != null) {
                     *      Utils.Prepend(ref Bones, new FoamBone(RootNode.Name, -1, NumMatrix4x4.Identity));
                     *      RootNode = RootNode.Parent;
                     * }*/


                    for (int i = 0; i < Bones.Length; i++)
                    {
                        Node BoneNode        = FindNode(NodeHierarchy, Bones[i].Name);
                        int  BoneParentIndex = FindBoneIndex(Bones, BoneNode.Parent.Name);

                        if (BoneNode != RootNode)
                        {
                            if (BoneParentIndex == -1)
                            {
                                throw new Exception("Could not find a bone");
                            }
                        }

                        Bones[i].ParentBoneIndex = BoneParentIndex;
                    }
                }
                else
                {
                    Bones = null;
                }

                // Animations
                FoamAnimation[] Animations = null;

                foreach (var Anim in Sc.Animations)
                {
                    string[]             BoneNames  = Anim.NodeAnimationChannels.Select(C => C.NodeName).ToArray();
                    int                  FrameCount = Anim.NodeAnimationChannels[0].PositionKeyCount;
                    FoamAnimationFrame[] Frames     = new FoamAnimationFrame[FrameCount];

                    for (int i = 0; i < FrameCount; i++)
                    {
                        Frames[i] = ReadFrame(Anim.NodeAnimationChannels, BoneNames, i);
                    }

                    FoamAnimation Animation = new FoamAnimation(Anim.Name, Frames, BoneNames, (float)Anim.DurationInTicks, (float)Anim.TicksPerSecond);
                    Utils.Append(ref Animations, Animation);
                }

                return(new FoamModel(Path.GetFileNameWithoutExtension(FileName), FoamFlags.Model, MeshList.ToArray(), Bones, Animations, MaterialList.ToArray()));
            }
        }
Ejemplo n.º 5
0
        static void Run()
        {
            string ObjInput      = ArgumentParser.GetSingle("obj");
            string MtlInput      = ArgumentParser.GetSingle("mtl");
            string MapOutput     = ArgumentParser.GetSingle("out");
            bool   EmbedTextures = ArgumentParser.Defined("e");
            bool   ComputeLights = !ArgumentParser.Defined("l");

            string ObjName = "test";

            if (ObjInput == null)
            {
                ObjInput  = "sample/" + ObjName + ".obj";
                MtlInput  = "sample/" + ObjName + ".mtl";
                MapOutput = "sample/" + ObjName + ".mapfoam";
            }

            if (!File.Exists(ObjInput))
            {
                throw new Exception("Obj input file not found");
            }

            if (!File.Exists(MtlInput))
            {
                throw new Exception("Mtl input file not found");
            }

            string OutDir = Path.GetDirectoryName(Path.GetFullPath(MapOutput));

            Console.WriteLine("obj = '{0}'", ObjInput);
            Console.WriteLine("mtl = '{0}'", MtlInput);
            Console.WriteLine("out = '{0}'", MapOutput);
            Console.WriteLine("Embed textures? {0}", EmbedTextures);
            Console.WriteLine("Compute lights? {0}", ComputeLights);

            FoamModel LevelModel = ObjLoader.Load(ObjInput, MtlInput);


            MeshAtlasMap AtlasMap;

            LevelModel.CalcBounds(out Vector3 Min, out Vector3 Max);
            Console.WriteLine("Level min = {0}; max = {1}", Min, Max);

            // Generate atlas
            {
                Console.WriteLine("Generating lightmap");
                GenAtlas(OutDir, LevelModel, out AtlasMap);
            }

            if (ComputeLights)
            {
                Light[] Lights = new Light[] {
                    new Light(new Vector3(-32, 104, 368), new Vector3(1, 0, 0), 10000),
                    new Light(new Vector3(-80, 104, 704), new Vector3(0, 1, 0), 10000),
                    new Light(new Vector3(0, 312, 304), new Vector3(0, 0, 1), 20000)
                };

                //LightMapping.Compute(LevelModel, AtlasMap, Lights);

                //Vector4[] Pixels = new Vector4[1024 * 1024];
                //RayLightmapper.raylight_render_scene(1024, 1024, 512, new Vector3(1, 1, 1), 0, null, 0, null, null, null, ref Pixels);

                {
                    string TexName = "lightmap.png";

                    FoamMaterial LightmapMat = new FoamMaterial(Path.GetFileNameWithoutExtension(TexName), new[] { new FoamTexture(TexName, FoamTextureType.LightMap) });
                    Utils.Append(ref LevelModel.Materials, LightmapMat);

                    foreach (var M in LevelModel.Meshes)
                    {
                        M.MaterialIndex = LevelModel.Materials.Length - 1;
                    }

                    //AtlasMap.Atlas.Resize(4);
                    AtlasMap.Atlas.FlipY();
                    AtlasMap.Atlas.Save(Path.Combine(OutDir, TexName));

                    Utils.Append(ref LevelModel.Extensions, FoamExtension.CreateEmbeddedPng(TexName, AtlasMap.Atlas.GetImage()));
                }
            }

            //ObjLoader.Save(LevelModel, "sample/EXPORTED.obj");
            LevelModel.SaveToFile(MapOutput);

            //Console.WriteLine("Done!");
            //Console.ReadLine();
        }