Beispiel #1
0
        private void ParseLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case GraphicTypes.Vertex:
                    var v = new Vertex();
                    v.ParseFromString(parts);
                    VertexList.Add(v);
                    break;

                case GraphicTypes.VertexNormal:
                    var vn = new VertexNormal();
                    vn.ParseFromString(parts);
                    NormalList.Add(vn);
                    break;

                case GraphicTypes.Face:
                    var f = new Face();
                    f.ParseFromString(parts);
                    FaceList.Add(f);
                    break;

                case GraphicTypes.TextureVertex:
                    var vt = new TextureVertex();
                    vt.ParseFromString(parts);
                    TextureList.Add(vt);
                    break;
                }
            }
        }
Beispiel #2
0
 public void calculateNormals508()
 {
     vertexNormals = null;
     if (vertexNormals == null)
     {
         vertexNormals = new VertexNormal[vertexCount];
         for (int i = 0; i < vertexCount; i++)
         {
             vertexNormals[i] = new VertexNormal();
         }
         for (int i = 0; i < triangleCount; i++)
         {
             int     triA = triangleA[i];
             int     triB = triangleB[i];
             int     triC = triangleC[i];
             Vector3 A    = vertexes[triA];
             Vector3 B    = vertexes[triB];
             Vector3 C    = vertexes[triC];
             int     Ux   = (int)(B.x - A.x) * 256;
             int     Uy   = (int)(B.y - A.y) * 256;
             int     Uz   = (int)(B.z - A.z) * 256;
             int     Vx   = (int)(C.x - A.x) * 256;
             int     Vy   = (int)(C.y - A.y) * 256;
             int     Vz   = (int)(C.z - A.z) * 256;
             int     Nx   = Uy * Vz - Vy * Uz;
             int     Ny   = Uz * Vx - Vz * Ux;
             int     Nz;
             for (Nz = Ux * Vy - Vx * Uy; (Nx > 8192 || Ny > 8192 || Nz > 8192 || Nx < -8192 || Ny < -8192 || Nz < -8192); Nz >>= 1)
             {
                 Nx >>= 1;
                 Ny >>= 1;
             }
             int i_169_ = (int)Mathf.Sqrt((float)((double)(Nx * Nx + Ny * Ny + Nz * Nz)));
             if (i_169_ <= 0)
             {
                 i_169_ = 1;
             }
             Nx = Nx * 256 / i_169_;
             Ny = Ny * 256 / i_169_;
             Nz = Nz * 256 / i_169_;
             VertexNormal vertexNormal = vertexNormals[triA];
             vertexNormal.x += Nx;
             vertexNormal.y += Ny;
             vertexNormal.z += Nz;
             vertexNormal.magnitude++;
             vertexNormal    = vertexNormals[triB];
             vertexNormal.x += Nx;
             vertexNormal.y += Ny;
             vertexNormal.z += Nz;
             vertexNormal.magnitude++;
             vertexNormal    = vertexNormals[triC];
             vertexNormal.x += Nx;
             vertexNormal.y += Ny;
             vertexNormal.z += Nz;
             vertexNormal.magnitude++;
         }
     }
 }
Beispiel #3
0
        private static void SetPolygonData(GeometryNode Polygon, Obj obj, int LodLevel)
        {
            if (Polygon.LODs.Count <= LodLevel)
            {
                for (int i = Polygon.LODs.Count - 1; i < LodLevel; ++i)
                {
                    Polygon.LODs.Add(new ServiceUtilities.Process.Geometry.LOD());
                }
            }

            ServiceUtilities.Process.Geometry.VertexNormalTangent[] VertexTangentNormals = new ServiceUtilities.Process.Geometry.VertexNormalTangent[obj.VertexList.Count];

            //Assumes triangulated faces
            for (int i = 0; i < obj.FaceList.Count; ++i)
            {
                for (int c = 0; c < 3; c++)
                {
                    Vertex       v1  = obj.VertexList[obj.FaceList[i].VertexIndexList[c] - 1];
                    VertexNormal vn1 = obj.NormalList[obj.FaceList[i].VertexNormalIndexList[c] - 1];

                    int CurrentIndex = v1.Index - 1;

                    Polygon.LODs[LodLevel].Indexes.Add((uint)CurrentIndex);

                    if (VertexTangentNormals[CurrentIndex] == null)
                    {
                        VertexTangentNormals[CurrentIndex] = new ServiceUtilities.Process.Geometry.VertexNormalTangent();
                    }

                    if (VertexTangentNormals[CurrentIndex].Vertex == null)
                    {
                        VertexTangentNormals[CurrentIndex].Vertex = new ServiceUtilities.Process.Geometry.Vector3D((float)v1.X * 100, (float)v1.Y * 100, (float)v1.Z * 100);
                    }
                    else
                    {
                        VertexTangentNormals[CurrentIndex].Vertex.X = (float)v1.X * 100;
                        VertexTangentNormals[CurrentIndex].Vertex.Y = (float)v1.Y * 100;
                        VertexTangentNormals[CurrentIndex].Vertex.Z = (float)v1.Z * 100;
                    }

                    if (VertexTangentNormals[CurrentIndex].Normal == null)
                    {
                        VertexTangentNormals[CurrentIndex].Normal = new ServiceUtilities.Process.Geometry.Vector3D((float)vn1.X, (float)vn1.Y, (float)vn1.Z);
                    }
                    else
                    {
                        VertexTangentNormals[CurrentIndex].Normal.X = (float)vn1.X;
                        VertexTangentNormals[CurrentIndex].Normal.Y = (float)vn1.Y;
                        VertexTangentNormals[CurrentIndex].Normal.Z = (float)vn1.Z;
                    }
                }
                //Index++;
            }

            Polygon.LODs[LodLevel].VertexNormalTangentList = new List <ServiceUtilities.Process.Geometry.VertexNormalTangent>(VertexTangentNormals);
            Polygon.LODs[LodLevel].Indexes.Reverse();
        }
        private void ProcessLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "usemtl":
                    UseMtl = parts[1];
                    break;

                case "mtllib":
                    Mtl = parts[1];
                    break;

                case "v":
                    Vertex v = new Vertex();
                    v.LoadFromStringArray(parts);
                    VertexList.Add(v);
                    v.Index = VertexList.Count();
                    break;

                case "vn":
                    VertexNormal vn = new VertexNormal();
                    vn.LoadFromStringArray(parts);
                    NormalList.Add(vn);
                    vn.Index = NormalList.Count();
                    break;

                case "s":
                    break;

                case "f":
                    Face f = new Face();
                    f.LoadFromStringArray(parts);
                    f.UseMtl = UseMtl;
                    FaceList.Add(f);
                    TriangleCount += f.VertexIndexList.Length - 2;
                    break;

                case "vt":
                    TextureVertex vt = new TextureVertex();
                    vt.LoadFromStringArray(parts);
                    TextureList.Add(vt);
                    vt.Index = TextureList.Count();
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine(line);
                    break;
                }
            }
        }
Beispiel #5
0
        public static VertexNormal Parse(string line)
        {
            string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            VertexNormal vertexNormal = new VertexNormal();

            vertexNormal.X = parts[0].ParseInvariantFloat();
            vertexNormal.Y = parts[1].ParseInvariantFloat();
            vertexNormal.Z = parts[2].ParseInvariantFloat();

            return(vertexNormal);
        }
Beispiel #6
0
        public override void Parse(string line)
        {
            var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            var x = parts[0].ParseInvariantFloat();
            var y = parts[1].ParseInvariantFloat();
            var z = parts[2].ParseInvariantFloat();

            var normal = new VertexNormal(x, y, z);

            _normalDataStore.AddNormal(normal);
        }
Beispiel #7
0
        async Task <bool> DrawMiniatureByMatrix(Matrix4x4 result, Matrix4x4 viewport)
        {
            List <Pixel> pixels = new List <Pixel>();
            //double scale = 400;
            GraphObject graphObject_copy = (GraphObject)globalMiniature.Clone();

            foreach (Group group in globalMiniature.Groups)
            {
                //result = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY(0), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale, (float)scale, (float)scale));
                WriteableBitmap source = new WriteableBitmap(miniatureWidth, miniatureHeight, 96, 96, PixelFormats.Bgra32, null);
                Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                bitmap.Source.Lock();
                graphObject_copy = (GraphObject)globalMiniature.Clone();
                for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                {
                    Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                    Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                    Vector4 vectorResult = Vector4.Transform(vector, result);
                    vectorResult /= vertex.W;
                    //vectorResult = Vector4.Transform(vectorResult, viewport);
                    vertex.X = vectorResult.X;
                    vertex.Y = vectorResult.Y;
                    vertex.Z = vectorResult.Z;
                    vertex.W = vectorResult.W;
                }
                for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                {
                    VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                    Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                    Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                    vertexNormal.X = vectorResult.X;
                    vertexNormal.Y = vectorResult.Y;
                    vertexNormal.Z = vectorResult.Z;
                }
                //VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                pixels = await GetListAsync(graphObject_copy.Groups[0], minDx, minDy, -1, miniatureWidth, miniatureHeight, bitmap);

                MiniatureModel.Source = bitmap.Source;
                bitmap.Source.Unlock();
                //MiniatureModel.Source = PixelDrawing.GetBitmap(miniatureWidth, miniatureHeight, pixels);
            }
            return(true);
        }
Beispiel #8
0
        async void DrawModel(GraphObject graphObject, Image targetPlace, int dx, int dy, double scale)
        {
            List <Pixel> pixels           = new List <Pixel>();
            GraphObject  graphObject_copy = (GraphObject)graphObject.Clone();

            Matrix4x4 result;

            foreach (Group group in graphObject.Groups)
            {
                WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null);
                Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                bitmap.Source.Lock();
                result           = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY(0), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale, (float)scale, (float)scale));
                graphObject_copy = (GraphObject)graphObject.Clone();
                for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                {
                    Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                    Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                    Vector4 vectorResult = Vector4.Transform(vector, result);
                    vertex.X = vectorResult.X;
                    vertex.Y = vectorResult.Y;
                    vertex.Z = vectorResult.Z;
                    vertex.W = vectorResult.W;
                }
                for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                {
                    VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                    Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                    Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                    vertexNormal.X = vectorResult.X;
                    vertexNormal.Y = vectorResult.Y;
                    vertexNormal.Z = vectorResult.Z;
                }
                pixels = await GetListAsync(graphObject_copy.Groups[0], dx, dy, -1, windowWidth, windowHeight, bitmap);

                targetPlace.Source = bitmap.Source;
                bitmap.Source.Unlock();
                //targetPlace.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels);
            }
        }
Beispiel #9
0
        static void Main(string[] args)
        {
            bool sketchupMode = false;
            bool nuf = false, fe = true, doNotOptimize = false;

            Console.WriteLine($"EasyExporter V{version} (C) 2020-2021 iProgramInCpp");
            Console.WriteLine("[!!BETA!!] This tool is beta-ware, so some stuff might not work correctly. If some faces aren't drawing properly, use \"-nop\".");
            if (args.Length < 1)
            {
                Console.WriteLine("usage: convert <your obj file> [output name] [-sum] [-noscale] [-nuf] [-nop] [-fe]");
                Console.WriteLine("   -sum: swaps the y and z axes (sketchup + lipid obj mode)");
                Console.WriteLine("   -noscale: sets the scaling factor to 1");
                Console.WriteLine("   -verbose: actively shows the progress of the app");
                Console.WriteLine("   -nuf:  disables fixing UV overflow (experimental). Use this if you're sure you don't have UV overflow in your model, or if the UV overflow fix fails.");
                Console.WriteLine("   -nofe: disables the UV fixing automatically done by program, not recommended unless you know what you're doing!");
                Console.WriteLine("   -nop:  do not optimize the model (loads 3 vertices per triangle, is slower but more reliable)");
                Console.WriteLine("   -f64s: sets the scale to 212.77, the default Fast64 scaling. Useful for using Fast64 scaled models.");
                return;
            }
            if (args.Contains("-verbose"))
            {
                Console.WriteLine("Verbose log enabled.");
                g_isVerbose = true;
            }
            if (args.Contains("-nofe"))
            {
                Console.WriteLine("UV Fix Extreme disabled.");
                fe = false;
            }
            if (args.Contains("-nop"))
            {
                Console.WriteLine("Model is not being optimized.");
                doNotOptimize = true;
            }
            if (args.Contains("-sum"))
            {
                Console.WriteLine("Activated Sketchup exporter mode.");

                LogVerbose("Adding default Layer_Layer0 material, sometimes it's used and not implemented in the mtl file itself!!");

                //add a new material named Layer_Layer0
                Material curMatA = new Material()
                {
                    name         = "Layer_Layer0",
                    alphaChannel = false,
                };
                curMatA.image = new Bitmap(8, 8);
                for (int i = 0; i < 8 * 8; i++)
                {
                    curMatA.image.SetPixel(i % 8, i / 8, Color.White);
                }
                materials["Layer_Layer0"] = curMatA;

                sketchupMode = true;
            }
            if (args.Contains("-noscale"))
            {
                Console.WriteLine("Scaling factor set to 1.");
                scale = 1;
            }
            if (args.Contains("-f64s"))
            {
                Console.WriteLine("Scaling factor set to 212.77f. (default fast64 scale)");
                scale = 212.77f;
            }
            if (args.Contains("-nuf"))
            {
                Console.WriteLine("Disabled UV overflow fixing.");
                if (fe)
                {
                    fe = false;
                    Console.WriteLine("Warning: -fe and -nuf switches both running at the same time, -nuf takes priority over -fe");
                }
                nuf = true;
            }
            string[] lines  = File.ReadAllLines(args[0]);
            string   curMat = "";

            Console.WriteLine("Parsing obj file...");
            foreach (string line in lines)
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line.StartsWith("#"))
                {
                    continue;
                }
                string[] tokens = line.Split(' ');
                if (tokens.Length < 1)
                {
                    continue;                    // safety
                }
                switch (tokens[0])
                {
                case "mtllib": {
                    LogVerbose($"Importing material library from \"{tokens[1]}\"");
                    ImportMaterial(tokens[1]);
                    break;
                }

                case "v":
                {
                    // Add Vertex
                    Vertex vtx = new Vertex()
                    {
                        x = float.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                        y = float.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                        z = float.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                    };
                    if (sketchupMode)
                    {
                        vtx.y = -vtx.y;
                        float f = vtx.z;
                        vtx.z = vtx.y;
                        vtx.y = f;
                    }
                    vertices.Add(vtx);
                    break;
                }

                case "vt":
                {
                    // Add Vertex Texture Coordinate
                    VertexTexCoord vtx = new VertexTexCoord()
                    {
                        u = float.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                        v = 1 - float.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture),     // N64 requires this :)
                    };
                    texCoordVertices.Add(vtx);
                    break;
                }

                case "vn":
                {
                    // Add Vertex Normal Coordinate
                    VertexNormal vtx = new VertexNormal()
                    {
                        n1 = float.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                        n2 = float.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                        n3 = float.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture),         // always a dot, never comma
                    };
                    if (sketchupMode)
                    {
                        vtx.n2 = -vtx.n2;
                        float f = vtx.n3;
                        vtx.n3 = vtx.n2;
                        vtx.n2 = f;
                    }
                    normalVertices.Add(vtx);
                    break;
                }

                case "usemtl":
                {
                    LogVerbose("Switching material to " + tokens[1]);
                    curMat = tokens[1];
                    break;
                }

                case "f":
                {
                    // face - always a triangle, quads not supported
                    int[]   v      = new int[3];
                    int[]   vt     = new int[3];
                    int[]   vn     = new int[3];
                    float[] localU = new float[3], localV = new float[3];
                    for (int i = 0; i < 3; i++)
                    {
                        string[] subTokens = tokens[i + 1].Split('/');
                        if (subTokens.Length < 1)
                        {
                            Console.WriteLine($"Error: Face with no coordinate {i}");
                            return;
                        }
                        switch (subTokens.Length)
                        {
                        case 1:
                            // vertex coord
                            v[i] = int.Parse(subTokens[0]) - 1;             // apparently indexes start with 1 here :/
                            break;

                        case 2:
                            // vertex tex coord
                            v[i] = int.Parse(subTokens[0]) - 1;
                            if (subTokens[1] == "")
                            {
                                vt[i] = -1; localU[i] = 0; localV[i] = 0;
                            }
                            else
                            {
                                vt[i] = int.Parse(subTokens[1]) - 1; localU[i] = texCoordVertices[vt[i]].u; localV[i] = texCoordVertices[vt[i]].v;
                            }


                            break;

                        case 3:
                            // vertex coord
                            v[i] = int.Parse(subTokens[0]) - 1;
                            if (subTokens[1] == "")
                            {
                                vt[i] = -1; localU[i] = 0; localV[i] = 0;
                            }
                            else
                            {
                                vt[i] = int.Parse(subTokens[1]) - 1; localU[i] = texCoordVertices[vt[i]].u; localV[i] = texCoordVertices[vt[i]].v;
                            }
                            vn[i] = int.Parse(subTokens[2]) - 1;
                            break;
                        }
                    }
                    Face f;
                    try
                    {
                        f = new Face()
                        {
                            v      = v,
                            vn     = vn,
                            vt     = vt,
                            localU = localU,
                            localV = localV,
                            mat    = materials[curMat]
                        };
                        faces.Add(f);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error while creating display lists: {curMat} material does not exist or is bad.");
                        Environment.Exit(1);
                    }
                    break;
                }

                default:
                {
                    Console.WriteLine($"Warning: Unrecognized instruction {tokens[0]}, this may go downhill quick!");
                    break;
                }
                }
            }
            ;

            // Loaded in everything, let's write it!
            Console.WriteLine("Loaded obj file, writing collision...");
            string outName = "output";

            if (args.Length > 1)
            {
                outName = StringToGoodCName(args[1]);
            }

            // Sort faces by material name
            //faces.Sort(new Comparison<Face>(FaceCompareShit)); // makes it easier to clump things together

            //string curMatName = "";

            string unlitMaterialNameShouldContain = "fence";
            bool   evenMakeUnlitMatls             = true;

            string s = $"// Written by EasyExporter V{version} (C) 2020-2021 iProgramInCpp.\n\nconst Collision {outName}_collision[] = {{";

            s += $"\n\tCOL_INIT(),\n\tCOL_VERTEX_INIT({vertices.Count}),\n";
            foreach (Vertex v in vertices)
            {
                s += $"\tCOL_VERTEX({(int)(v.x * scale)},{(int)(v.y * scale)},{(int)(v.z * scale)}),\n";
            }

            foreach (var v in materials)
            {
                LogVerbose("Writing collision for " + v.Value.name + ".");
                string s2 = ""; int mtlCnt = 0;
                foreach (Face f in faces)
                {
                    if (f.mat == v.Value)
                    {
                        s2 += $"\tCOL_TRI({f.v[0]},{f.v[1]},{f.v[2]}),\n";
                        mtlCnt++;
                    }
                }
                s += $"\t// {v.Value.name} Material...\n\tCOL_TRI_INIT(SURFACE_DEFAULT, {mtlCnt}),\n" + s2;
            }

            s += "\tCOL_TRI_STOP(),\n\tCOL_END(),\n};";
            File.WriteAllText(args[0] + "_outputCollision.inc.c", s);
            s = "";


            Console.WriteLine("Wrote collision of {0} verts and {1} tris, writing display list data...", vertices.Count, faces.Count);
            s += $"// Written by EasyExporter V{version} (C) 2020-2021 iProgramInCpp.\n\nstatic const Lights1 {outName}_lights = gdSPDefLights1(0x3f,0x3f,0x3f,0xff,0xff,0xff,0x28,0x28,0x28);\n";
            s += $"static const Vtx {outName}_vertices[] = {{\n";
            int vtxIndex = 0;

            LogVerbose("Writing vertex data...");
            for (int i = 0; i < faces.Count; i++)
            {
                // Write each face as its own 3 vertexes
                // This will make the model disjointed, but it's fine for now,
                // as normals and UV mapping requires it

                // get the 3 verts
                Face                f  = faces[i];
                Vertex[]            v  = new Vertex[3];
                VertexTexCoord16b[] vt = new VertexTexCoord16b[3];
                byte[]              vn = new byte[9];
                for (int j = 0; j < 3; j++)
                {
                    v[j] = vertices[f.v[j]];
                    //vt[j] = ConvertUVToFixed16b(f.vt[j] == -1 ? new VertexTexCoord() : texCoordVertices[f.vt[j]], f.mat.image.Width, f.mat.image.Height);
                    vn[j * 3 + 0] = (byte)(127 * (normalVertices[f.vn[j]]).n1);
                    vn[j * 3 + 1] = (byte)(127 * (normalVertices[f.vn[j]]).n2);
                    vn[j * 3 + 2] = (byte)(127 * (normalVertices[f.vn[j]]).n3);
                    //Console.WriteLine(curMat);
                    if (f.mat.name.ToLower().Contains(unlitMaterialNameShouldContain) && evenMakeUnlitMatls) //! hardcoded for now
                    {
                        vn[j * 3 + 0] = 255;
                        vn[j * 3 + 1] = 255;
                        vn[j * 3 + 2] = 255;
                    }
                }

                // This is code that's designed to fix UV overflow on certain exporters.
                int iterCount = 100000;
                if (f.vt[0] == -1) // no texture?
                {
                    vt[0] = new VertexTexCoord16b();
                    vt[1] = new VertexTexCoord16b();
                    vt[2] = new VertexTexCoord16b();
                    goto skipOverflowFix;
                }
                //disabled UV overflow fix?
                if (nuf)
                {
                    goto skipOverflowFix;
                }

                if (fe)
                {
                    // UV Fix Extreme
                    float[] ue = new float[3], ve = new float[3];
                    float   avgU = 0, avgV = 0;
                    for (int q = 0; q < 3; q++)
                    {
                        ue[q] = f.localU[q];
                        ve[q] = f.localV[q];
                        avgU += f.localU[q];
                        avgV += f.localV[q];
                        //f.localU[q] = (float)(f.localU[q] - Math.Floor(f.localU[q]));
                        //f.localV[q] = (float)(f.localV[q] - Math.Floor(f.localV[q]));
                    }
                    avgU /= 3; avgV /= 3;
                    float nAvgU = (float)(avgU - Math.Floor(avgU));
                    float nAvgV = (float)(avgV - Math.Floor(avgV));
                    //calculate delta
                    float deltaU = nAvgU - avgU;
                    float deltaV = nAvgV - avgV;
                    for (int q = 0; q < 3; q++)
                    {
                        f.localU[q] += deltaU;
                        f.localV[q] += deltaV;
                    }
                }
                else
                {
                    float minu = 999999, maxu = -999999, minv = 999999, maxv = -999999;
                    for (int j = 0; j < 3; j++)
                    {
                        //if (IsInBound(f.localU[j], f.localV[j], minx, miny, maxx, maxy) {
                        minu = Math.Min(minu, f.localU[j]);
                        minv = Math.Min(minv, f.localV[j]);
                        maxu = Math.Max(maxu, f.localU[j]);
                        maxv = Math.Max(maxv, f.localV[j]);
                        //}
                    }
                    float dx = Math.Abs(maxu - minu);
                    float dy = Math.Abs(maxv - minv);
                    if (dx + 4 >= f.mat.image.Width || dy + 4 >= f.mat.image.Height)
                    {
                        Console.WriteLine("Error: uv overflow so big that it can't be fixed automatically. Please fix it yourself. Some faces might look weird.");
                        goto skipOverflowFix;
                    }

                    float minx = -16 / (f.mat.image.Width / 32f), miny = -16 / (f.mat.image.Height / 32f);
                    float maxx = 15 / (f.mat.image.Width / 32f), maxy = 15 / (f.mat.image.Height / 32f);

                    bool firstIter = true;

                    int coordsThatNeedFixing = 0;//bitflag
                    do
                    {
                        coordsThatNeedFixing = 0;
                        for (int j = 0; j < 3; j++)
                        {
                            if (!IsInBound(f.localU[j], f.localV[j], minx, miny, maxx, maxy))
                            {
                                if (firstIter)
                                {
                                    Console.WriteLine("Warning: UV overflow present in your model. Fixed the face automatically. You might see this when working with LIPID OBJ exporter for sketchup, this is only because of the way the addon works.");
                                }
                                coordsThatNeedFixing |= (1 << i);
                                firstIter             = false;
                                //! check what this vert has done wrong. Moving by integers has no real effect on what the model looks like.
                                if (f.localU[j] < minx)
                                {
                                    float badu = f.localU[j];
                                    for (int r = 0; r < 3; r++)
                                    {
                                        f.localU[r] -= (float)Math.Floor(badu - minx);
                                    }
                                    iterCount--;
                                }
                                if (f.localU[j] > maxx)
                                {
                                    float badu = f.localU[j];
                                    for (int r = 0; r < 3; r++)
                                    {
                                        f.localU[r] -= (float)Math.Ceiling(badu - maxx);
                                    }
                                    iterCount--;
                                }
                                if (f.localV[j] < miny)
                                {
                                    float badv = f.localV[j];
                                    for (int r = 0; r < 3; r++)
                                    {
                                        f.localV[r] -= (float)Math.Floor(badv - miny);
                                    }
                                    iterCount--;
                                }
                                if (f.localV[j] > maxy)
                                {
                                    float badv = f.localV[j];
                                    for (int r = 0; r < 3; r++)
                                    {
                                        f.localV[r] -= (float)Math.Ceiling(badv - maxy);
                                    }
                                    iterCount--;
                                }
                            }
                        }
                    } while (coordsThatNeedFixing != 0 && iterCount > 0);
                    //goto fixedOverflowAlready;
                }
skipOverflowFix:

                if (iterCount <= 0)
                {
                    Console.WriteLine("Severe warning: trying to fix UV overflow resulted in an infinite loop. Please fix your model.");
                }

                //fixedOverflowAlready:
                for (int j = 0; j < 3; j++)
                {
                    VertexTexCoord vtc = new VertexTexCoord();
                    if (f.vt[j] != -1)
                    {
                        vtc.u = f.localU[j];
                        vtc.v = f.localV[j];
                    }
                    vt[j] = ConvertUVToFixed16b(vtc /*f.vt[j] == -1 ? new VertexTexCoord() : texCoordVertices[f.vt[j]]*/, f.mat.image.Width, f.mat.image.Height);
                    s    += $"\t{{{{{{ {v[j].x * scale},\t{v[j].y * scale},\t{v[j].z * scale}\t }}, 0, {{\t {vt[j].u},\t{vt[j].v} }}, {{ \t{vn[j * 3 + 0]},\t{vn[j * 3 + 1]},\t{vn[j * 3 + 2]},\t{0xff} }} }} }},\n";
                }

                f.cachedVInsideCode = vtxIndex;
                vtxIndex           += 3;

                // support for 32x texs only for now

                /*
                 * Vertex v = vertices[i]; VertexTexCoord16b vt = ConvertUVToFixed16b(texCoordVertices[i],32,32);
                 * byte vtn1, vtn2, vtn3;
                 * vtn1 = 0xff;// TODO : (byte)(127 * normalVertices[i].n1);
                 * vtn2 = 0xff;// TODO : (byte)(127 * normalVertices[i].n2);
                 * vtn3 = 0xff;// TODO : (byte)(127 * normalVertices[i].n3);
                 */
                //s += $"\t{{{{{{ {v.x * scale},{v.y * scale},{v.z * scale} }}, 0, {{ {vt.u},{vt.v} }}, {{ {vtn1},{vtn2},{vtn3},{0xff} }} }} }},\n";
            }

            //!TODO: move to using StringBuilder, makes it faster and abuses GC less
            s += "};\n\n";

            LogVerbose("Separating each material used in the mesh into its own display list...");

            //List<string> displayListsToDraw = new List<string>();
            foreach (var materialKvp in materials)
            {
                if (materialKvp.Value.image == null)
                {
                    continue;                                  // color only isnt supported!
                }
                LogVerbose("Writing texture " + materialKvp.Value.name);
                string goodMatName = StringToGoodCName(materialKvp.Key); // name
                // export texture

                int pixels_written = 0, total_pixels = materialKvp.Value.image.Height * materialKvp.Value.image.Width;

                StringBuilder stringBuilder = new StringBuilder(8192);
                s += "ALIGNED8 const u16 " + goodMatName + "_txt[] = {\n\t";
                for (int j = 0; j < materialKvp.Value.image.Height; j++)
                {
                    for (int e = 0; e < materialKvp.Value.image.Width; e++)
                    {
                        stringBuilder.Append($"{ColorToRGBA16(materialKvp.Value.image.GetPixel(e,j))}, ");
                        pixels_written++;
                    }
                    if (g_isVerbose)
                    {
                        Console.Write($"\rWrote {pixels_written} pixels out of {total_pixels}.");
                    }
                }
                s += stringBuilder.ToString();
                s += "\n};\n\n";
                if (g_isVerbose)
                {
                    Console.WriteLine();
                }

                LogVerbose("Writing display list for the material...");

                s += $"static const Gfx {outName}_draw_{goodMatName}_txt[] = {{\n";
                s += $"\tgsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, {goodMatName}_txt),\n";
                s += $"\tgsDPLoadSync(),\n";
                s += $"\tgsDPLoadBlock(G_TX_LOADTILE, 0, 0, {materialKvp.Value.image.Width} * {materialKvp.Value.image.Height} - 1, CALC_DXT({materialKvp.Value.image.Width}, G_IM_SIZ_16b_BYTES)),\n";
                s += $"\tgsSPLight(&{outName}_lights.l, 1),\n";
                s += $"\tgsSPLight(&{outName}_lights.a, 2),\n";
                s += $"\t\n";
                if (materialKvp.Key.ToLower().Contains(unlitMaterialNameShouldContain) && evenMakeUnlitMatls) //! hardcoded for now
                {
                    s += $"\tgsSPClearGeometryMode(G_CULL_BACK),\n";
                    s += $"\tgsSPClearGeometryMode(G_LIGHTING),\n";
                }
                s += $"\t\n";

                /*
                 * s += $"\tgsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, {goodMatName}_txt),\n";
                 * s += $"\tgsDPLoadSync(),\n";
                 * s += $"\tgsDPLoadBlock(G_TX_LOADTILE, 0, 0, {materialKvp.Value.image.Width} * {materialKvp.Value.image.Height} - 1, CALC_DXT({materialKvp.Value.image.Width}, G_IM_SIZ_16b_BYTES)),\n";*/
                int faceCount = 0;
                int faceStart = -1, eeai = 0;
                foreach (Face f in faces)
                {
                    if (f.mat.name == materialKvp.Value.name)
                    {
                        if (doNotOptimize)
                        {
                            s += $"\tgsSPVertex(&{outName}_vertices[{f.cachedVInsideCode}], 3, 0),\n";
                            s += $"\tgsSP1Triangle(0,1,2,0x0),\n";
                        }
                        else
                        {
                            faceCount++;
                            if (faceStart == -1)
                            {
                                faceStart = eeai;
                            }
                        }
                    }
                    eeai++;
                }

                if (!doNotOptimize)
                {
                    if (faceStart != -1)
                    {
                        int amountsOf5s = faceCount / 5;
                        int leftover = faceCount % 5, i;
                        for (i = 0; i < amountsOf5s; i++)
                        {
                            Face first_face = faces[i * 5 + faceStart];
                            s += $"\tgsSPVertex(&{outName}_vertices[{first_face.cachedVInsideCode}], 15, 0),\n";
                            for (int j = 0; j < 5; j++)
                            {
                                Face f = faces[i * 5 + j + faceStart];
                                s += $"\tgsSP1Triangle({0 + j * 3},{1 + j * 3},{2 + j * 3},0x0),\n";
                            }
                        }
                        Face first_face2 = faces[i * 5 + faceStart];
                        s += $"\tgsSPVertex(&{outName}_vertices[{first_face2.cachedVInsideCode}], 15, 0),\n";
                        for (int j = 0; j < leftover; j++)
                        {
                            Face f = faces[i * 5 + j + faceStart];
                            s += $"\tgsSP1Triangle({0 + j * 3},{1 + j * 3},{2 + j * 3},0x0),\n";
                        }
                    }
                    else
                    {
                        s += $"//! This is not drawing anything, please remove!!\t\n";
                    }
                }
                s += $"\t\n";
                if (materialKvp.Key.ToLower().Contains(unlitMaterialNameShouldContain) && evenMakeUnlitMatls) //! hardcoded for now
                {
                    s += $"\tgsSPSetGeometryMode(G_CULL_BACK),\n";
                    s += $"\tgsSPSetGeometryMode(G_LIGHTING),\n";
                }
                s += $"\t\n";
                s += $"\tgsSPEndDisplayList(),\n}};\n\n";
                //displayListsToDraw.Add(outName + "_draw_" + goodMatName + "_txt");
            }

            /*
             * s += $"const Gfx {outName}_main_display_list[] = {{\n";
             * s += $"\tgsDPPipeSync(),\n";
             * s += $"\tgsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),\n";
             * s += $"\tgsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),\n";
             * s += $"\tgsSPTexture(0xffff,0xffff,0,G_TX_RENDERTILE,G_ON),\n";
             * s += $"\tgsDPTileSync(),\n";
             * // todo: change width/height
             * foreach (string dl in displayListsToDraw)
             * {
             *  / *
             *  s += $"\tgsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 5, G_TX_NOLOD),\n";
             *  s += $"\tgsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),\n";
             *  s += $"\tgsSPDisplayList({dl}),\n";
             *  s += $"\tgsDPTileSync(),\n";
             * /
             *  s += $"\tgsSPDisplayList({dl}),\n";
             * }
             * s += $"\tgsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),\n";
             * s += $"\tgsDPPipeSync(),\n";
             * s += $"\tgsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),\n";
             * s += $"\tgsSPEndDisplayList(),\n";
             * s += "};";*/
            // using Fast 64 method

            LogVerbose("Done writing material DLs, writing main DL that unites them all together");

            s += $"const Gfx {outName}_main_display_list_opaque[] = {{\n";
            s += $"\tgsDPPipeSync(),\n";
            s += $"\tgsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),\n";
            s += $"\tgsSPClearGeometryMode(G_SHADING_SMOOTH),\n";
            s += $"\tgsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),\n";
            s += $"\tgsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),\n";
            foreach (var materialKvp in materials)
            {
                if (materialKvp.Value.alphaChannel)
                {
                    continue;                                 // This is for no alpha channel textures.
                }
                if (materialKvp.Value.image == null)
                {
                    continue;                                            // color only isnt supported!
                }
                string goodMatName = StringToGoodCName(materialKvp.Key); // name
                s += $"\tgsDPTileSync(),\n";
                s += $"\tgsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, {materialKvp.Value.image.Width / 4}, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, {GetPO2(materialKvp.Value.image.Height)}, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, {GetPO2(materialKvp.Value.image.Width)}, G_TX_NOLOD),\n";
                s += $"\tgsDPSetTileSize(0, 0, 0, ({materialKvp.Value.image.Width} - 1) << G_TEXTURE_IMAGE_FRAC, ({materialKvp.Value.image.Height} - 1) << G_TEXTURE_IMAGE_FRAC),\n"; // todo image width-height
                //s += $"\t\n";
                s += $"\tgsSPDisplayList({outName}_draw_{goodMatName}_txt),\n";
            }
            s += $"\tgsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),\n";
            s += $"\tgsDPPipeSync(),\n";
            s += $"\tgsSPSetGeometryMode(G_LIGHTING),\n";
            s += $"\tgsSPSetGeometryMode(G_SHADING_SMOOTH),\n";
            s += $"\tgsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),\n";
            s += $"\tgsSPEndDisplayList(),\n";
            s += $"}};";
            s += $"\n\n";
            s += $"const Gfx {outName}_main_display_list_alpha[] = {{\n";
            s += $"\tgsDPPipeSync(),\n";
            s += $"\tgsDPSetCombineMode(G_CC_MODULATERGBA, G_CC_MODULATERGBA),\n";
            s += $"\tgsSPClearGeometryMode(G_SHADING_SMOOTH),\n";
            s += $"\tgsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),\n";
            s += $"\tgsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),\n";
            foreach (var materialKvp in materials)
            {
                if (!materialKvp.Value.alphaChannel)
                {
                    continue;                                  // This is for alpha channel textures.
                }
                if (materialKvp.Value.image == null)
                {
                    continue;                                            // color only isnt supported!
                }
                string goodMatName = StringToGoodCName(materialKvp.Key); // name
                s += $"\tgsDPTileSync(),\n";
                s += $"\tgsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, {materialKvp.Value.image.Width / 4}, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, {GetPO2(materialKvp.Value.image.Height)}, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, {GetPO2(materialKvp.Value.image.Width)}, G_TX_NOLOD),\n";
                s += $"\tgsDPSetTileSize(0, 0, 0, ({materialKvp.Value.image.Width} - 1) << G_TEXTURE_IMAGE_FRAC, ({materialKvp.Value.image.Height} - 1) << G_TEXTURE_IMAGE_FRAC),\n"; // todo image width-height
                //s += $"\t\n";
                s += $"\tgsSPDisplayList({outName}_draw_{goodMatName}_txt),\n";
            }
            s += $"\tgsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),\n";
            s += $"\tgsDPPipeSync(),\n";
            s += $"\tgsSPSetGeometryMode(G_LIGHTING),\n";
            s += $"\tgsSPSetGeometryMode(G_SHADING_SMOOTH),\n";
            s += $"\tgsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),\n";
            s += $"\tgsSPEndDisplayList(),\n";
            s += $"}};";
            File.WriteAllText(args[0] + "_outputModel.inc.c", s);
            Console.WriteLine("Done!");
        }
 public VertexNormal(int index) : base(dataSize, index)
 {
     inst = this;
 }
Beispiel #11
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        EntityCommandBuffer.ParallelWriter commandBufferPR = EndSimulationCBS.CreateCommandBuffer().AsParallelWriter();


        NativeArray <int> Triangles            = this.Triangles;
        NativeArray <int> CornerIndexAFromEdge = this.CornerIndexAFromEdge;
        NativeArray <int> CornerIndexBFromEdge = this.CornerIndexBFromEdge;
        //, ref DynamicBuffer<Normals> normalsBuf, ref DynamicBuffer<Index> trianglesBuf
        JobHandle job = Entities.WithAll <BuffersPresentTag>().WithNone <NoiseBufferTag>().ForEach((Entity thisEntity, int entityInQueryIndex, ref NoiseOrderComponent noiseOrder
                                                                                                    , ref DynamicBuffer <Vertices> verticesBuf, ref DynamicBuffer <Normals> normalsBuf, ref DynamicBuffer <Index> trianglesBuf) =>
        {
            commandBufferPR.AddComponent(entityInQueryIndex, thisEntity, new NoiseBufferTag());

            DynamicBuffer <float3> vertices = verticesBuf.Reinterpret <float3>();
            DynamicBuffer <float3> normals  = normalsBuf.Reinterpret <float3>();
            DynamicBuffer <int> triangles   = trianglesBuf.Reinterpret <int>();

            float3 sampleDist = noiseOrder.size / noiseOrder.sampleCount;
            int3 samples      = (int3)(noiseOrder.size / sampleDist) + 1;
            int numOfSamples  = samples.x * samples.y * samples.z;
            NativeArray <NoiseVal> noiseValues = new NativeArray <NoiseVal>(numOfSamples, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            float3 maxPoint = noiseOrder.minPoint + noiseOrder.size;



            for (int3 iter = default; iter.z < samples.z; iter.z++)
            {
                for (iter.y = 0; iter.y < samples.y; iter.y++)
                {
                    for (iter.x = 0; iter.x < samples.x; iter.x++)
                    {
                        int index          = GetIndex(samples, iter);
                        float3 pos         = noiseOrder.minPoint + iter * sampleDist;
                        float4 noise       = Noise.snoise_grad(pos * noiseOrder.noiseFactor);
                        noiseValues[index] = new NoiseVal(pos, noise);// new float4(pos, (noise.w+1f)*0.5f);
                    }
                }
            }

            NativeHashMap <float3, int> newLayerPosIdDict = new NativeHashMap <float3, int>(noiseOrder.sampleCount.x * noiseOrder.sampleCount.y * 2, Allocator.Temp);
            NativeHashMap <float3, int> oldLayerPosIdDict = new NativeHashMap <float3, int>(noiseOrder.sampleCount.x * noiseOrder.sampleCount.y * 2, Allocator.Temp);
            for (int3 id = default; id.z < samples.z - 1; id.z++)
            {
                NativeHashMap <float3, int> temp = oldLayerPosIdDict;
                oldLayerPosIdDict = newLayerPosIdDict;
                newLayerPosIdDict = temp;
                newLayerPosIdDict.Clear();
                for (id.y = 0; id.y < samples.y - 1; id.y++)
                {
                    for (id.x = 0; id.x < samples.x - 1; id.x++)
                    {
                        // 8 corners of the current cube
                        NativeArray <NoiseVal> cubeCorners = new NativeArray <NoiseVal>(8, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

                        cubeCorners[0] = noiseValues[GetIndex(samples, new int3(id.x, id.y, id.z))];
                        cubeCorners[1] = noiseValues[GetIndex(samples, new int3(id.x + 1, id.y, id.z))];
                        cubeCorners[2] = noiseValues[GetIndex(samples, new int3(id.x + 1, id.y, id.z + 1))];
                        cubeCorners[3] = noiseValues[GetIndex(samples, new int3(id.x, id.y, id.z + 1))];
                        cubeCorners[4] = noiseValues[GetIndex(samples, new int3(id.x, id.y + 1, id.z))];
                        cubeCorners[5] = noiseValues[GetIndex(samples, new int3(id.x + 1, id.y + 1, id.z))];
                        cubeCorners[6] = noiseValues[GetIndex(samples, new int3(id.x + 1, id.y + 1, id.z + 1))];
                        cubeCorners[7] = noiseValues[GetIndex(samples, new int3(id.x, id.y + 1, id.z + 1))];

                        float3 topPoint = noiseValues[GetIndex(samples, new int3(id.x + 1, id.y + 1, id.z + 1))].Pos;


                        // Calculate unique index for each cube configuration.
                        // There are 256 possible values
                        // A value of 0 means cube is entirely inside surface; 255 entirely outside.
                        // The value is used to look up the edge table, which indicates which edges of the cube are cut by the isosurface.
                        int cubeIndex = 0;
                        if (cubeCorners[0].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 1;
                        }
                        if (cubeCorners[1].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 2;
                        }
                        if (cubeCorners[2].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 4;
                        }
                        if (cubeCorners[3].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 8;
                        }
                        if (cubeCorners[4].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 16;
                        }
                        if (cubeCorners[5].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 32;
                        }
                        if (cubeCorners[6].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 64;
                        }
                        if (cubeCorners[7].Noise < noiseOrder.isoSurfaceLevel)
                        {
                            cubeIndex |= 128;
                        }

                        // Create triangles for current cube configuration
                        for (int i = 0; Triangles[16 * cubeIndex + i] != -1; i += 3)
                        {
                            // Get indices of corner points A and B for each of the three edges
                            // of the cube that need to be joined to form the triangle.
                            int a0 = CornerIndexAFromEdge[Triangles[16 * cubeIndex + i]];
                            int b0 = CornerIndexBFromEdge[Triangles[16 * cubeIndex + i]];

                            int a1 = CornerIndexAFromEdge[Triangles[16 * cubeIndex + i + 1]];
                            int b1 = CornerIndexBFromEdge[Triangles[16 * cubeIndex + i + 1]];

                            int a2 = CornerIndexAFromEdge[Triangles[16 * cubeIndex + i + 2]];
                            int b2 = CornerIndexBFromEdge[Triangles[16 * cubeIndex + i + 2]];

                            VertexNormal vertexA = interpolateVerts(noiseOrder.isoSurfaceLevel, cubeCorners[a0], cubeCorners[b0]);
                            VertexNormal vertexB = interpolateVerts(noiseOrder.isoSurfaceLevel, cubeCorners[a1], cubeCorners[b1]);
                            VertexNormal vertexC = interpolateVerts(noiseOrder.isoSurfaceLevel, cubeCorners[a2], cubeCorners[b2]);

                            int len = vertices.Length;

                            int vertCId = GetVertId(ref vertices, ref normals, oldLayerPosIdDict, newLayerPosIdDict, vertexC, topPoint, ref len);

                            int vertBId = GetVertId(ref vertices, ref normals, oldLayerPosIdDict, newLayerPosIdDict, vertexB, topPoint, ref len);

                            int vertAId = GetVertId(ref vertices, ref normals, oldLayerPosIdDict, newLayerPosIdDict, vertexA, topPoint, ref len);

                            //vertices.Add(vertexC.position);
                            //vertices.Add(vertexB.position);
                            //vertices.Add(vertexA.position);

                            //normals.Add(vertexC.normal);
                            //normals.Add(vertexB.normal);
                            //normals.Add(vertexA.normal);

                            triangles.Add(vertCId);
                            triangles.Add(vertBId);
                            triangles.Add(vertAId);
                        }
                    }
                }
            }
        }).Schedule(inputDeps);

        EndSimulationCBS.AddJobHandleForProducer(job);
        return(job);
    }
Beispiel #12
0
    private static int GetVertId(ref DynamicBuffer <float3> vertices, ref DynamicBuffer <float3> normals, NativeHashMap <float3, int> oldLayerPosIdDict, NativeHashMap <float3, int> newLayerPosIdDict, VertexNormal vertex, float3 topPoint, ref int len)
    {
        int vertId;

        if (oldLayerPosIdDict.TryGetValue(vertex.position, out vertId))
        {
            //vertId = positionIdDict.TryGetValue;
        }
        else
        {
            vertices.Add(vertex.position);
            normals.Add(vertex.normal);
            vertId = len;
            if (math.any(vertex.position == topPoint))
            {
                oldLayerPosIdDict.Add(vertex.position, vertId);
            }
            if (vertex.position.z == topPoint.z)
            {
                newLayerPosIdDict.Add(vertex.position, vertId);
            }
            len++;
        }

        return(vertId);
    }
Beispiel #13
0
 public void AddNormal(VertexNormal normal)
 {
     _normals.Add(normal);
 }
Beispiel #14
0
        public async void ImageButton_Click(object sender, RoutedEventArgs e)
        {
            Parser       parser      = new Parser();
            GraphObject  graphObject = parser.ParseFile(filePath);
            List <Pixel> pixels      = new List <Pixel>();

            if (!isApplyOptions)
            {
                double      value            = 5 * Math.PI / 180;
                GraphObject graphObject_copy = (GraphObject)graphObject.Clone();

                Matrix4x4 result;
                foreach (Group group in graphObject.Groups)
                {
                    while (value < 10000)
                    {
                        WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null);
                        Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                        bitmap.Source.Lock();
                        result           = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY((float)(value)), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale * 2, (float)scale * 2, (float)scale * 2));
                        graphObject_copy = (GraphObject)graphObject.Clone();
                        for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                        {
                            Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                            Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                            Vector4 vectorResult = Vector4.Transform(vector, result);
                            vertex.X = vectorResult.X;
                            vertex.Y = vectorResult.Y;
                            vertex.Z = vectorResult.Z;
                            vertex.W = vectorResult.W;
                        }
                        for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                        {
                            VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                            Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                            Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                            vertexNormal.X = vectorResult.X;
                            vertexNormal.Y = vectorResult.Y;
                            vertexNormal.Z = vectorResult.Z;
                        }
                        pixels = await GetListAsync(graphObject_copy.Groups[0], maxDx, maxDy, -1, windowWidth, windowHeight, bitmap);

                        //GraphicModel.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels);
                        value += 1 * Math.PI / 180;
                        GraphicModel.Source = bitmap.Source;
                        bitmap.Source.Unlock();
                    }
                }
            }
            else
            {
                TransformOptions options          = GetUserOptions(scale * 2);
                GraphObject      graphObject_copy = (GraphObject)graphObject.Clone();

                Matrix4x4 result, viewport;
                foreach (Group group in graphObject.Groups)
                {
                    WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null);
                    Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                    bitmap.Source.Lock();
                    result           = GetOptionsMatrix(options, windowWidth, windowHeight);
                    viewport         = GetViewPort(0, 0, windowWidth, windowHeight);
                    graphObject_copy = (GraphObject)graphObject.Clone();
                    for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                    {
                        Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                        Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                        Vector4 vectorResult = Vector4.Transform(vector, result);
                        vectorResult /= vertex.W;
                        //vectorResult = Vector4.Transform(vectorResult, viewport);
                        vertex.X = vectorResult.X;
                        vertex.Y = vectorResult.Y;
                        vertex.Z = vectorResult.Z;
                        vertex.W = vectorResult.W;
                    }
                    for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                    {
                        VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                        Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                        Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                        vertexNormal.X = vectorResult.X;
                        vertexNormal.Y = vectorResult.Y;
                        vertexNormal.Z = vectorResult.Z;
                    }
                    pixels = await GetListAsync(graphObject_copy.Groups[0], maxDx, maxDy, -1, windowWidth, windowHeight, bitmap);

                    GraphicModel.Source = bitmap.Source;
                    bitmap.Source.Unlock();

                    //if (pixels != null) { GraphicModel.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels); }
                }
            }
        }
Beispiel #15
0
 private static void AddNormal(StringBuilder sb, VertexNormal vec)
 {
     sb.AppendFormat(CultureInfo.InvariantCulture, "vn {0:F4} {1:F4} {2:F4}\n", vec.X, vec.Y, vec.Z);
 }
Beispiel #16
0
    private static int GetVertId(List <Vector3> vertices, List <Vector3> normals, Dictionary <float3, int> oldLayerPosIdDict, Dictionary <float3, int> newLayerPosIdDict, VertexNormal vertex, float3 topPoint, ref int len)
    {
        int vertId;

        if (oldLayerPosIdDict.TryGetValue(vertex.position, out vertId))
        {
            //vertId = positionIdDict.TryGetValue;
        }
        else
        {
            vertices.Add(vertex.position);
            normals.Add(vertex.normal);
            vertId = len;
            if (math.any(vertex.position == topPoint))
            {
                oldLayerPosIdDict.Add(vertex.position, vertId);
            }
            if (vertex.position.z == topPoint.z)
            {
                newLayerPosIdDict.Add(vertex.position, vertId);
            }
            len++;
        }

        return(vertId);
    }
Beispiel #17
0
    static public GameObject CreateChunkGameObject(SpawnChunkData chunk)
    {
        GameObject gameObject   = new GameObject("meshGO", typeof(MeshFilter), typeof(MeshRenderer));
        float3     sampleDist   = chunk.size / chunk.sampleCount;
        int3       samples      = (int3)(chunk.size / sampleDist) + 1;
        int        numOfSamples = samples.x * samples.y * samples.z;

        NoiseVal[] noiseValues = new NoiseVal[numOfSamples];
        float3     maxPoint    = chunk.minPoint + chunk.size;

        List <Vector3> vertices  = new List <Vector3>();
        List <Vector3> normals   = new List <Vector3>();
        List <int>     triangles = new List <int>();

        float startTime = Time.realtimeSinceStartup * 1000;

        for (int3 iter = default; iter.z < samples.z; iter.z++)
        {
            for (iter.y = 0; iter.y < samples.y; iter.y++)
            {
                for (iter.x = 0; iter.x < samples.x; iter.x++)
                {
                    int    index = GetIndex(samples, iter);
                    float3 pos   = chunk.minPoint + iter * sampleDist;
                    float4 noise = Noise.snoise_grad(pos * chunk.noiseFactor);
                    noiseValues[index] = new NoiseVal(pos, noise);// new float4(pos, (noise.w+1f)*0.5f);
                }
            }
        }

        float timeAfterNoise = Time.realtimeSinceStartup * 1000;


        // float4[] oldPoints = new float4[8];

        Dictionary <float3, int> newLayerPosIdDict = new Dictionary <float3, int>();

        for (int3 id = default; id.z < samples.z - 1; id.z++)
        {
            Dictionary <float3, int> oldLayerPosIdDict = newLayerPosIdDict;
            newLayerPosIdDict = new Dictionary <float3, int>();
            for (id.y = 0; id.y < samples.y - 1; id.y++)
            {
                for (id.x = 0; id.x < samples.x - 1; id.x++)
                {
                    // 8 corners of the current cube
                    NoiseVal[] cubeCorners =
                    {
                        noiseValues[GetIndex(samples, new int3(id.x,     id.y,     id.z))],
                        noiseValues[GetIndex(samples, new int3(id.x + 1, id.y,     id.z))],
                        noiseValues[GetIndex(samples, new int3(id.x + 1, id.y,     id.z + 1))],
                        noiseValues[GetIndex(samples, new int3(id.x,     id.y,     id.z + 1))],
                        noiseValues[GetIndex(samples, new int3(id.x,     id.y + 1, id.z))],
                        noiseValues[GetIndex(samples, new int3(id.x + 1, id.y + 1, id.z))],
                        noiseValues[GetIndex(samples, new int3(id.x + 1, id.y + 1, id.z + 1))],
                        noiseValues[GetIndex(samples, new int3(id.x,     id.y + 1, id.z + 1))]
                    };

                    float3 topPoint = noiseValues[GetIndex(samples, new int3(id.x + 1, id.y + 1, id.z + 1))].Pos;
                    for (int i = 0; i < 8; i++)
                    {
                        bool3 cmp = (cubeCorners[i].Pos > topPoint.xyz);
                        if (cmp.x || cmp.y || cmp.z)
                        {
                            throw new Exception("Top point is not top: " + topPoint + "   " + i + "  " + cubeCorners[i]);
                        }
                    }

                    // Calculate unique index for each cube configuration.
                    // There are 256 possible values
                    // A value of 0 means cube is entirely inside surface; 255 entirely outside.
                    // The value is used to look up the edge table, which indicates which edges of the cube are cut by the isosurface.
                    int cubeIndex = 0;
                    if (cubeCorners[0].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 1;
                    }
                    if (cubeCorners[1].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 2;
                    }
                    if (cubeCorners[2].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 4;
                    }
                    if (cubeCorners[3].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 8;
                    }
                    if (cubeCorners[4].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 16;
                    }
                    if (cubeCorners[5].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 32;
                    }
                    if (cubeCorners[6].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 64;
                    }
                    if (cubeCorners[7].Noise < chunk.isoSurfaceLevel)
                    {
                        cubeIndex |= 128;
                    }

                    // Create triangles for current cube configuration
                    for (int i = 0; Table.Triangles2dArray[cubeIndex, i] != -1; i += 3)
                    {
                        // Get indices of corner points A and B for each of the three edges
                        // of the cube that need to be joined to form the triangle.
                        int a0 = Table.CornerIndexAFromEdge[Table.Triangles2dArray[cubeIndex, i]];
                        int b0 = Table.CornerIndexBFromEdge[Table.Triangles2dArray[cubeIndex, i]];

                        int a1 = Table.CornerIndexAFromEdge[Table.Triangles2dArray[cubeIndex, i + 1]];
                        int b1 = Table.CornerIndexBFromEdge[Table.Triangles2dArray[cubeIndex, i + 1]];

                        int a2 = Table.CornerIndexAFromEdge[Table.Triangles2dArray[cubeIndex, i + 2]];
                        int b2 = Table.CornerIndexBFromEdge[Table.Triangles2dArray[cubeIndex, i + 2]];

                        VertexNormal vertexA = interpolateVerts(chunk.isoSurfaceLevel, cubeCorners[a0], cubeCorners[b0]);
                        VertexNormal vertexB = interpolateVerts(chunk.isoSurfaceLevel, cubeCorners[a1], cubeCorners[b1]);
                        VertexNormal vertexC = interpolateVerts(chunk.isoSurfaceLevel, cubeCorners[a2], cubeCorners[b2]);

                        // Triangle should be C - B - A
                        //oldPoints.Clear();
                        int len = vertices.Count;
                        //oldLayerPosIdDict.Clear();
                        //newLayerPosIdDict.Clear();

                        int vertCId = GetVertId(vertices, normals, oldLayerPosIdDict, newLayerPosIdDict, vertexC, topPoint, ref len);

                        int vertBId = GetVertId(vertices, normals, oldLayerPosIdDict, newLayerPosIdDict, vertexB, topPoint, ref len);

                        int vertAId = GetVertId(vertices, normals, oldLayerPosIdDict, newLayerPosIdDict, vertexA, topPoint, ref len);

                        //normals.Add(vertexC.normal);
                        //normals.Add(vertexB.normal);
                        //normals.Add(vertexA.normal);
                        //vertices.Add(vertexA);
                        //vertices.Add(vertexB);
                        //vertices.Add(vertexC);

                        triangles.Add(vertCId);
                        triangles.Add(vertBId);
                        triangles.Add(vertAId);
                    }
                }
            }
            maxDictSize = math.max(maxDictSize, oldLayerPosIdDict.Count);
        }

        float timeAfterMesh = Time.realtimeSinceStartup * 1000;


        //Debug.Log("triangles: " + triangles.Count + " vertices: " + vertices.Count);

        Mesh mesh = new Mesh();

        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.normals   = normals.ToArray();
        //mesh.uv = uv.ToArray();
        //mesh.RecalculateNormals();
        gameObject.GetComponent <MeshFilter>().mesh = mesh;
        float timeAfterGO = Time.realtimeSinceStartup * 1000;

        Debug.Log("Time for noise: " + (timeAfterNoise - startTime) + " time for mesh: " + (timeAfterMesh - timeAfterNoise) + " GO: " + (timeAfterGO - timeAfterMesh));
        Debug.Log("maxDictSize :  " + maxDictSize);
        return(gameObject);
    }