Ejemplo n.º 1
0
        public Tuple <DGRP3DVert[], int[]> LoadModel(string model)
        {
            OBJ obj;

            using (var str = File.Open($"Content/3D/{model}", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                obj = new OBJ(str);
            }

            var indices  = obj.FacesByObjgroup.First(x => x.Value.Count > 0).Value;
            var outVerts = new List <DGRP3DVert>();
            var outInds  = new List <int>();
            var dict     = new Dictionary <Tuple <int, int>, int>();

            foreach (var ind in indices)
            {
                var tup = new Tuple <int, int>(ind[0], ind[1]);
                int targ;
                if (!dict.TryGetValue(tup, out targ))
                {
                    //add a vertex
                    targ = outVerts.Count;
                    var vert = new DGRP3DVert(obj.Vertices[ind[0] - 1], Vector3.Zero, obj.TextureCoords[ind[1] - 1]);
                    vert.TextureCoordinate.Y = 1 - vert.TextureCoordinate.Y;
                    outVerts.Add(vert);
                    dict[tup] = targ;
                }
                outInds.Add(targ);
            }

            var triBase = new int[outInds.Count / 3][];

            for (int i = 0; i < triBase.Length; i++)
            {
                triBase[i] = new int[] { outInds[i * 3], outInds[i * 3 + 1], outInds[i * 3 + 2] }
            }
            ;

            var ordered = triBase.OrderBy(x => outVerts[x[0]].Position.Y + outVerts[x[1]].Position.Y + outVerts[x[2]].Position.Y);

            outInds.Clear();
            foreach (var item in ordered)
            {
                outInds.AddRange(item);
            }

            return(new Tuple <DGRP3DVert[], int[]>(outVerts.ToArray(), outInds.ToArray()));
        }

        Dictionary <Color, int> ForestTypes = new Dictionary <Color, int>()
        {
            { new Color(0, 0x6A, 0x28), 0 }, //heavy forest
            { new Color(0, 0xEB, 0x42), 1 }, //light forest
            { new Color(255, 0xFC, 0), 2 },  //palm
            { new Color(255, 0, 0), 3 },     //cacti
            { new Color(0, 0, 0), -1 }  //nothing; no forest
        };
Ejemplo n.º 2
0
        public DGRP3DGeometry(string[] splitName, OBJ obj, List <int[]> indices, DGRP source, GraphicsDevice gd)
        {
            if (splitName[1] == "SPR")
            {
                PixelSPR = ushort.Parse(splitName[3]);
                PixelDir = ushort.Parse(splitName[2].Substring(3));
                Pixel    = source.GetImage(1, 3, PixelDir).Sprites[PixelSPR].GetTexture(gd);
            }
            else if (splitName[1] != "MASK")
            {
                PixelSPR      = ushort.Parse(splitName[2]);
                CustomTexture = 1;
                PixelDir      = 65535;

                var name = source.ChunkParent.Filename.Replace('.', '_').Replace("spf", "iff");
                name += "_TEX_" + PixelSPR + ".png";
                Pixel = ReplTextureProvider(name);
                if (Pixel == null)
                {
                    Pixel = source.ChunkParent.Get <MTEX>(PixelSPR)?.GetTexture(gd);
                }
            }

            SVerts   = new List <DGRP3DVert>();
            SIndices = new List <int>();
            var dict = new Dictionary <Tuple <int, int>, int>();

            foreach (var ind in indices)
            {
                var tup = new Tuple <int, int>(ind[0], ind[1]);
                int targ;
                if (!dict.TryGetValue(tup, out targ))
                {
                    //add a vertex
                    targ = SVerts.Count;
                    var vert = new DGRP3DVert(obj.Vertices[ind[0] - 1], Vector3.Zero, obj.TextureCoords[ind[1] - 1]);
                    vert.TextureCoordinate.Y = 1 - vert.TextureCoordinate.Y;
                    SVerts.Add(vert);
                    dict[tup] = targ;
                }
                SIndices.Add(targ);
            }

            GenerateNormals(false);

            /*
             * var triBase = new int[SIndices.Count / 3][];
             * for (int i = 0; i < triBase.Length; i++) triBase[i] = new int[] { SIndices[i * 3], SIndices[i * 3 + 1], SIndices[i * 3 + 2] };
             *
             * var ordered = triBase.OrderBy(x => SVerts[x[0]].Position.Y + SVerts[x[1]].Position.Y + SVerts[x[2]].Position.Y);
             * SIndices.Clear();
             * foreach (var item in ordered) SIndices.AddRange(item);
             */

            SComplete(gd);
        }
Ejemplo n.º 3
0
        public void FillEdges(GraphicsDevice gd, Effect VertexShader, Effect PixelShader, CityContent content, Color color)
        {
            VertexShader.CurrentTechnique.Passes[2].Apply();

            var frontDS = FrontDepthStencil;

            var bs = NoColor;

            gd.RasterizerState   = RasterizerState.CullNone;
            gd.BlendState        = bs;
            gd.DepthStencilState = frontDS;

            PixelShader.Parameters["ObjTex"].SetValue(TextureGenerator.GetPxWhite(gd));
            PixelShader.CurrentTechnique.Passes[0].Apply();

            foreach (var cell in Cells)
            {
                gd.SetVertexBuffer(cell.Vertices);
                gd.Indices = cell.Indices;

                gd.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, cell.Indices.IndexCount / 3);
            }

            var so = StencilCompareLine;

            gd.DepthStencilState = so;
            gd.BlendState        = BlendState.AlphaBlend;

            var screen = UIScreen.Current;
            var aspect = screen.ScreenWidth / (float)(screen.ScreenHeight);
            var dat    = new DGRP3DVert[]
            {
                new DGRP3DVert(new Vector3(-1, -1, 0f), Vector3.Zero, new Vector2(0, 0)),
                new DGRP3DVert(new Vector3(1, -1, 0f), Vector3.Zero, new Vector2(20 * aspect, 0)),
                new DGRP3DVert(new Vector3(-1, 1, 0f), Vector3.Zero, new Vector2(0, 20)),
                new DGRP3DVert(new Vector3(1, 1, 0f), Vector3.Zero, new Vector2(20 * aspect, 20)),
            };

            PixelShader.Parameters["ObjTex"].SetValue(TextureGenerator.GetPxWhite(gd));// content.NeighTextures[i%3]);
            PixelShader.Parameters["HighlightColor"].SetValue(color.ToVector4());
            var bM = VertexShader.Parameters["BaseMatrix"].GetValueMatrix();

            VertexShader.Parameters["BaseMatrix"].SetValue(Matrix.CreateOrthographic(2, 2, -1, 0.0001f));
            VertexShader.CurrentTechnique.Passes[2].Apply();
            PixelShader.CurrentTechnique.Passes[0].Apply();
            gd.SamplerStates[0] = SamplerState.LinearWrap;
            gd.DrawUserPrimitives(PrimitiveType.TriangleStrip, dat, 0, 2);
            VertexShader.Parameters["BaseMatrix"].SetValue(bM);
        }
Ejemplo n.º 4
0
        private Tuple <DGRP3DVert[], int[]> ReadVerts(IoBuffer io)
        {
            var vertCount    = io.ReadInt32();
            var bytes        = io.ReadBytes(vertCount * Marshal.SizeOf(typeof(DGRP3DVert)));
            var readVerts    = new DGRP3DVert[vertCount];
            var pinnedHandle = GCHandle.Alloc(readVerts, GCHandleType.Pinned);

            Marshal.Copy(bytes, 0, pinnedHandle.AddrOfPinnedObject(), bytes.Length);
            pinnedHandle.Free();

            var indCount = io.ReadInt32();
            var indices  = ToTArray <int>(io.ReadBytes(indCount * 4));

            return(new Tuple <DGRP3DVert[], int[]>(readVerts, indices));
        }
Ejemplo n.º 5
0
        public DGRP3DGeometry(IoBuffer io, DGRP source, GraphicsDevice gd, int Version)
        {
            PixelSPR = io.ReadUInt16();
            PixelDir = io.ReadUInt16();
            if (PixelDir == 65535)
            {
                CustomTexture = 1;
                if (source == null)
                {
                    //temporary system for models without DGRP
                    Pixel = ReplTextureProvider("FSO_TEX_" + PixelSPR + ".png");
                }
                else
                {
                    var name = source.ChunkParent.Filename.Replace('.', '_').Replace("spf", "iff");
                    name += "_TEX_" + PixelSPR + ".png";
                    Pixel = ReplTextureProvider(name);
                    if (Pixel == null)
                    {
                        Pixel = source.ChunkParent.Get <MTEX>(PixelSPR)?.GetTexture(gd);
                    }
                }
            }
            else
            {
                Pixel = source.GetImage(1, 3, PixelDir).Sprites[PixelSPR].GetTexture(gd);
            }

            var vertCount = io.ReadInt32();

            SVerts = new List <DGRP3DVert>();

            if (Version > 1)
            {
                var bytes        = io.ReadBytes(vertCount * Marshal.SizeOf(typeof(DGRP3DVert)));
                var readVerts    = new DGRP3DVert[vertCount];
                var pinnedHandle = GCHandle.Alloc(readVerts, GCHandleType.Pinned);
                Marshal.Copy(bytes, 0, pinnedHandle.AddrOfPinnedObject(), bytes.Length);
                pinnedHandle.Free();
                SVerts = readVerts.ToList();
            }
            else
            {
                for (int i = 0; i < vertCount; i++)
                {
                    var x      = io.ReadFloat();
                    var y      = io.ReadFloat();
                    var z      = io.ReadFloat();
                    var u      = io.ReadFloat();
                    var v      = io.ReadFloat();
                    var normal = new Vector3();
                    SVerts.Add(new DGRP3DVert(new Vector3(x, y, z), normal, new Vector2(u, v)));
                }
            }
            var indexCount = io.ReadInt32();

            SIndices = ToTArray <int>(io.ReadBytes(indexCount * 4)).ToList();

            // bottom up triangle ordering. useful for trees.

            /*
             * var triBase = new int[SIndices.Count / 3][];
             * for (int i = 0; i < triBase.Length; i++) triBase[i] = new int[] { SIndices[i * 3], SIndices[i*3 + 1], SIndices[i * 3 + 2] };
             *
             * var ordered = triBase.OrderBy(x => SVerts[x[0]].Position.Y);
             * SIndices.Clear();
             * foreach (var item in ordered) SIndices.AddRange(item);
             */


            if (Version < 2)
            {
                GenerateNormals(false);
            }

            SComplete(gd);
        }
Ejemplo n.º 6
0
 public void GenerateNormals(bool invert)
 {
     DGRP3DVert.GenerateNormals(invert, SVerts, SIndices);
 }
Ejemplo n.º 7
0
        public FSOF GetFSOF(GraphicsDevice gd, WorldRC world, Blueprint bp, Action onNight, bool compressed)
        {
            var result = new FSOF();

            RoofOnFloor = true;
            GenerateWalls(gd, world, bp, false);
            //GROUND_SUBDIV = 64;
            GenerateFloor(gd, world, bp, false);
            //SimplifyFloor();
            GenerateRoof(gd, world, bp);

            result.TexCompressionType = (compressed) ? 1 : 0;
            result.FloorWidth         = FloorTexture.Width;
            result.FloorHeight        = FloorTexture.Height;
            result.WallWidth          = WallTarget.Width;
            result.WallHeight         = WallTarget.Height;

            result.FloorTextureData = TexToData(FloorTexture, compressed);
            result.WallTextureData  = TexToData(WallTarget, compressed);

            var tVerts = new List <DGRP3DVert>();
            var tInd   = new List <int>();
            var indOff = 0;

            for (int i = 0; i < 5; i++)
            {
                var tcOffset = new Vector2((i % 3) / 3f, (i / 3) / 2f);
                //save each floor. offset the floor for each level
                var posOffset = i * 2.95f;
                var fVerts    = FloorVerts.Select(x => new DGRP3DVert(new Vector3(x.Position.X, x.Position.Y + posOffset, x.Position.Z), Vector3.Zero, x.TextureCoordinate + tcOffset));
                tVerts.AddRange(fVerts);
                tInd.AddRange(FloorIndices.Select(x => x + indOff));

                indOff = tVerts.Count;

                if (i == 0)
                {
                    tcOffset = new Vector2((5 % 3) / 3f, (5 / 3) / 2f);
                    //save each floor. offset the floor for each level
                    posOffset = 0.5f * 2.95f;
                    fVerts    = FloorVerts.Select(x => new DGRP3DVert(new Vector3(x.Position.X, x.Position.Y + posOffset, x.Position.Z), Vector3.Zero, x.TextureCoordinate + tcOffset));
                    tVerts.AddRange(fVerts);
                    tInd.AddRange(FloorIndices.Select(x => x + indOff));
                    indOff = tVerts.Count;
                }
            }

            tVerts.AddRange(RoofVerts.Select(x => new DGRP3DVert(x.Position, Vector3.Zero, x.TextureCoordinate)));
            tInd.AddRange(RoofIndices.Select(x => x + indOff));

            DGRP3DVert.GenerateNormals(false, tVerts, FloorIndices);
            result.FloorVertices = tVerts.ToArray();
            result.FloorIndices  = tInd.ToArray();

            var tempVerts = WallVerts.Select(x => new DGRP3DVert(x.Position, Vector3.Zero, x.TextureCoordinate)).ToList();

            DGRP3DVert.GenerateNormals(false, tempVerts, WallIndices);
            result.WallVertices = tempVerts.ToArray();
            result.WallIndices  = WallIndices;

            onNight();
            GenerateWalls(gd, world, bp, true);
            GenerateFloor(gd, world, bp, true);

            result.NightFloorTextureData = TexToData(FloorTexture, compressed);
            result.NightWallTextureData  = TexToData(WallTarget, compressed);
            result.NightLightColor       = world.State.OutsideColor;

            return(result);
        }
Ejemplo n.º 8
0
        public void Generate(GraphicsDevice gd)
        {
            Dispose();

            var pts = Data.Select(x => x.Location.ToVector2() + new Vector2(0.5f, 0.5f)).ToList();

            pts.Add(new Vector2(-256, -256));
            pts.Add(new Vector2(768, 768));
            pts.Add(new Vector2(768, -256));
            pts.Add(new Vector2(-256, 768));

            pts.Add(new Vector2(256, -256));
            pts.Add(new Vector2(256, 768));
            pts.Add(new Vector2(768, 256));
            pts.Add(new Vector2(-256, 256));

            Cells = new VoronoiCellGraph(pts).Result;
            NHoodToCell.Clear();
            var index = 0;

            foreach (var cell in Cells)
            {
                //follow cell vertices, making them into a mesh.
                var cV = new List <DGRP3DVert>();
                var cI = new List <int>();

                var i = 0;
                foreach (var vert in cell.Cycle)
                {
                    //add a part of the edge loop.
                    cV.Add(new DGRP3DVert(
                               new Vector3((float)vert.X, -1, (float)vert.Y),
                               Vector3.Zero,
                               new Vector2(0, ((-1) - City.InterpElevationAt(vert)) / 10)
                               ));

                    cV.Add(new DGRP3DVert(
                               new Vector3((float)vert.X, 100, (float)vert.Y),
                               Vector3.Zero,
                               new Vector2(0, (100 - City.InterpElevationAt(vert)) / 10)
                               ));

                    //i mod
                    //0   1
                    //_____
                    //|\  |
                    //| \ |
                    //|__\|

                    // lo, hi, lo, hi
                    if (i > 0)
                    {
                        cI.Add(i - 2);
                        cI.Add(i - 1);
                        cI.Add(i);

                        cI.Add(i - 1);
                        cI.Add(i + 1);
                        cI.Add(i);
                    }
                    i += 2;
                }

                cI.Add(i - 2);
                cI.Add(i - 1);
                cI.Add(0);

                cI.Add(i - 1);
                cI.Add(1);
                cI.Add(0);

                //add top and bottom tri fans


                i = 0;
                foreach (var vert in cell.Cycle)
                {
                    if (i > 3)
                    {
                        cI.Add(i - 2); //bottom cap
                        cI.Add(i);
                        cI.Add(0);

                        /*
                         * cI.Add(i-1); //top cap
                         * cI.Add(1);
                         * cI.Add(i+1);
                         */
                    }
                    i += 2;
                }

                DGRP3DVert.GenerateNormals(false, cV, cI);
                cV = cV.Select(x => new DGRP3DVert(x.Position + x.Normal * 0.25f, x.Normal, x.TextureCoordinate)).ToList();

                var verts = new VertexBuffer(gd, typeof(DGRP3DVert), cV.Count, BufferUsage.None);
                var inds  = new IndexBuffer(gd, IndexElementSize.ThirtyTwoBits, cI.Count, BufferUsage.None);
                verts.SetData(cV.ToArray());
                inds.SetData(cI.ToArray());

                cell.Vertices = verts;
                cell.Indices  = inds;

                NHoodToCell.Add(cell.Ind, index++);
            }
        }
Ejemplo n.º 9
0
        public DGRP3DMesh(DGRP dgrp, OBJD obj, GraphicsDevice gd, string saveDirectory)
        {
            ReconstructVersion = CURRENT_RECONSTRUCT;
            SaveDirectory      = saveDirectory;
            Geoms = new List <Dictionary <Texture2D, DGRP3DGeometry> >();
            if (dgrp == null)
            {
                return;
            }
            Name = obj.ChunkParent.Filename.Replace('.', '_') + "_" + dgrp.ChunkID;
            var lower  = obj.ChunkParent.Filename.ToLowerInvariant();
            var config = obj.ChunkParent.List <FSOR>()?.FirstOrDefault()?.Params;

            if (config == null)
            {
                if (!ParamsByIff.TryGetValue(lower, out config))
                {
                    config = DefaultParams;
                }
            }
            if (!config.InRange(dgrp.ChunkID))
            {
                config = DefaultParams;
            }

            int totalSpr = 0;

            for (uint rotation = 0; rotation < 4; rotation++)
            {
                if (config.DoorFix)
                {
                    if ((obj.SubIndex & 0xFF) == 1)
                    {
                        if ((rotation + 1) % 4 > 1)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if ((rotation + 1) % 4 < 2)
                        {
                            continue;
                        }
                    }
                }
                else if (!config.Rotations[rotation])
                {
                    continue;
                }
                var img = dgrp.GetImage(1, 3, rotation);

                var zOff = (config.BlenderTweak) ? -57.5f : -55f;

                var mat = Matrix.CreateTranslation(new Vector3(-72, -344, zOff));
                mat *= Matrix.CreateScale((1f / (128)) * 1.43f);//1.4142135623730f);
                mat *= Matrix.CreateScale(1, -1, 1);

                mat *= Matrix.CreateRotationX((float)Math.PI / -6);
                mat *= Matrix.CreateRotationY(((float)Math.PI / 4) * (1 + rotation * 2));

                var factor = (config.BlenderTweak) ? 0.40f : 0.39f;

                int curSpr = 0;
                foreach (var sprite in img.Sprites)
                {
                    var sprMat = mat * Matrix.CreateTranslation(new Vector3(sprite.ObjectOffset.X, sprite.ObjectOffset.Z, sprite.ObjectOffset.Y) * new Vector3(1f / 16f, 1f / 5f, 1f / 16f));
                    var inv    = Matrix.Invert(sprMat);
                    var tex    = sprite.GetTexture(gd);

                    if (tex == null)
                    {
                        curSpr++;
                        continue;
                    }
                    var isDynamic = sprite.SpriteID >= obj.DynamicSpriteBaseId && sprite.SpriteID < (obj.DynamicSpriteBaseId + obj.NumDynamicSprites);
                    var dynid     = (isDynamic) ? (int)(1 + sprite.SpriteID - obj.DynamicSpriteBaseId) : 0;

                    while (Geoms.Count <= dynid)
                    {
                        Geoms.Add(new Dictionary <Texture2D, DGRP3DGeometry>());
                    }

                    DGRP3DGeometry geom = null;
                    if (!Geoms[dynid].TryGetValue(tex, out geom))
                    {
                        geom = new DGRP3DGeometry()
                        {
                            Pixel = tex
                        };
                        Geoms[dynid][geom.Pixel] = geom;
                    }
                    geom.PixelDir = (ushort)rotation;
                    geom.PixelSPR = (ushort)(curSpr++);
                    totalSpr++;

                    var depthB = sprite.GetDepth();

                    var     useDequantize  = false;
                    float[] depth          = null;
                    int     iterations     = 125;
                    int     triDivisor     = 100;
                    float   aggressiveness = 3.5f;
                    if (useDequantize)
                    {
                        var dtex = new Texture2D(gd, ((TextureInfo)tex.Tag).Size.X, ((TextureInfo)tex.Tag).Size.Y, false, SurfaceFormat.Color);
                        dtex.SetData(depthB.Select(x => new Color(x, x, x, x)).ToArray());
                        depth = DepthTreatment.DequantizeDepth(gd, dtex);
                        dtex.Dispose();

                        iterations     = 500;
                        aggressiveness = 2.5f;
                        MaxAllowedSq   = 0.05f * 0.05f;
                    }
                    else if (depthB != null)
                    {
                        depth          = depthB.Select(x => x / 255f).ToArray();
                        iterations     = 125;
                        aggressiveness = 3.5f;
                    }

                    if (depth == null)
                    {
                        continue;
                    }

                    QueueWork(() =>
                    {
                        var boundPts = new List <Vector3>();
                        //begin async part
                        var w = ((TextureInfo)tex.Tag).Size.X;
                        var h = ((TextureInfo)tex.Tag).Size.Y;

                        var pos     = sprite.SpriteOffset + new Vector2(72, 348 - h);
                        var tl      = Vector3.Transform(new Vector3(pos, 0), sprMat);
                        var tr      = Vector3.Transform(new Vector3(pos + new Vector2(w, 0), 0), sprMat);
                        var bl      = Vector3.Transform(new Vector3(pos + new Vector2(0, h), 0), sprMat);
                        var tlFront = Vector3.Transform(new Vector3(pos, 110.851251f), sprMat);

                        var xInc    = (tr - tl) / w;
                        var yInc    = (bl - tl) / h;
                        var dFactor = (tlFront - tl) / (factor);

                        if (sprite.Flip)
                        {
                            tl    = tr;
                            xInc *= -1;
                        }

                        var dict    = new Dictionary <int, int>();
                        var verts   = new List <VertexPositionTexture>();
                        var indices = new List <int>();

                        var lastPt = new Vector3();
                        var i      = 0;
                        var verti  = 0;
                        for (int y = 0; y < h; y++)
                        {
                            if (y > 0)
                            {
                                boundPts.Add(lastPt);
                            }
                            bool first = true;
                            var vpos   = tl;
                            for (int x = 0; x < w; x++)
                            {
                                var d = depth[i++];
                                if (d < 0.999f)
                                {
                                    lastPt = vpos + (1f - d) * dFactor;
                                    if (first)
                                    {
                                        boundPts.Add(lastPt); first = false;
                                    }
                                    var vert = new VertexPositionTexture(lastPt, new Vector2((float)x / w, (float)y / h));
                                    verts.Add(vert);
                                    dict.Add(y * w + x, verti++);
                                }
                                vpos += xInc;
                            }
                            tl += yInc;
                        }

                        for (int y = 0; y < h - 1; y++)
                        {
                            for (int x = 0; x < w - 1; x++)
                            {
                                //try make a triangle or two
                                var quad = new int?[] {
                                    QuickTryGet(dict, x + y * w),
                                    QuickTryGet(dict, x + 1 + y * w),
                                    QuickTryGet(dict, x + 1 + (y + 1) * w),
                                    QuickTryGet(dict, x + (y + 1) * w)
                                };
                                var total = quad.Sum(v => (v == null) ? 0 : 1);
                                if (total == 4)
                                {
                                    var d1 = Vector3.DistanceSquared(verts[quad[0].Value].Position, verts[quad[2].Value].Position);
                                    var d2 = Vector3.DistanceSquared(verts[quad[1].Value].Position, verts[quad[3].Value].Position);

                                    if (d1 > MaxAllowedSq || d2 > MaxAllowedSq)
                                    {
                                        continue;
                                    }

                                    indices.Add(quad[0].Value);
                                    indices.Add(quad[1].Value);
                                    indices.Add(quad[2].Value);

                                    indices.Add(quad[0].Value);
                                    indices.Add(quad[2].Value);
                                    indices.Add(quad[3].Value);
                                }
                                else if (total == 3)
                                {
                                    //clockwise anyways. we can only make one
                                    int?last  = null;
                                    int?first = null;
                                    bool exit = false;
                                    foreach (var v in quad)
                                    {
                                        if (v != null)
                                        {
                                            if (last != null && Vector3.DistanceSquared(verts[last.Value].Position, verts[v.Value].Position) > MaxAllowedSq)
                                            {
                                                exit = true;
                                                break;
                                            }
                                            last = v.Value;
                                            if (first == null)
                                            {
                                                first = last;
                                            }
                                        }
                                    }

                                    if (!exit && Vector3.DistanceSquared(verts[last.Value].Position, verts[first.Value].Position) > MaxAllowedSq)
                                    {
                                        exit = true;
                                    }
                                    if (exit)
                                    {
                                        continue;
                                    }

                                    foreach (var v in quad)
                                    {
                                        if (v != null)
                                        {
                                            indices.Add(v.Value);
                                        }
                                    }
                                }
                            }
                        }

                        if (config.CounterFix)
                        {
                            //x axis extrapolation
                            //clip: -0.4 to 0.4

                            //identify vertices very close to clipping range(border)
                            //! for each vertex outwith clipping range
                            //- idendify closest border pixel bp in image space
                            //- result.zy = bp.zy
                            //- result.x = (resultIMAGE.x - bpIMAGE.x) / 64;
                            //- clip x to -0.5, 0.5f.

                            var clip     = 0.4;
                            var bWidth   = 0.02;
                            var border1  = new List <Tuple <Vector2, Vector3> >();
                            var invalid1 = new List <KeyValuePair <int, int> >();
                            var border2  = new List <Tuple <Vector2, Vector3> >();
                            var invalid2 = new List <KeyValuePair <int, int> >();
                            foreach (var vert in dict)
                            {
                                var vpos = verts[vert.Value].Position;
                                var dist = Math.Abs(vpos.X);
                                if (dist > clip)
                                {
                                    if (vpos.X > 0)
                                    {
                                        invalid1.Add(vert);
                                    }
                                    else
                                    {
                                        invalid2.Add(vert);
                                    }
                                }
                                else if (dist > (clip - bWidth))
                                {
                                    if (vpos.X > 0)
                                    {
                                        border1.Add(new Tuple <Vector2, Vector3>(new Vector2(vert.Key % w, vert.Key / w), vpos));
                                    }
                                    else
                                    {
                                        border2.Add(new Tuple <Vector2, Vector3>(new Vector2(vert.Key % w, vert.Key / w), vpos));
                                    }
                                }
                            }

                            var edge = 0.498f + 0.001f * (rotation % 2);

                            if (border1.Count > 0)
                            {
                                foreach (var vert in invalid1)
                                {
                                    var vstr    = verts[vert.Value];
                                    var pos2d   = new Vector2(vert.Key % w, vert.Key / w);
                                    var vpos    = vstr.Position;
                                    var closest = border1.OrderBy(x => Vector2.DistanceSquared(x.Item1, pos2d)).First();

                                    vpos.X = closest.Item2.X + Vector2.Distance(closest.Item1, pos2d) / 71.55f;
                                    if (vpos.X > 0.5f)
                                    {
                                        vpos.X = edge;
                                    }
                                    else
                                    {
                                        vpos.Y = closest.Item2.Y;
                                        vpos.Z = closest.Item2.Z;
                                    }

                                    vstr.Position     = vpos;
                                    verts[vert.Value] = vstr;
                                }
                            }

                            if (border2.Count > 0)
                            {
                                foreach (var vert in invalid2)
                                {
                                    var vstr    = verts[vert.Value];
                                    var pos2d   = new Vector2(vert.Key % w, vert.Key / w);
                                    var vpos    = vstr.Position;
                                    var closest = border2.OrderBy(x => Vector2.DistanceSquared(x.Item1, pos2d)).First();

                                    vpos.X = closest.Item2.X - Vector2.Distance(closest.Item1, pos2d) / 71.55f;
                                    if (vpos.X < -0.5f)
                                    {
                                        vpos.X = -edge;
                                    }
                                    else
                                    {
                                        vpos.Y = closest.Item2.Y;
                                        vpos.Z = closest.Item2.Z;
                                    }

                                    vstr.Position     = vpos;
                                    verts[vert.Value] = vstr;
                                }
                            }
                        }


                        lock (BoundPts) BoundPts.AddRange(boundPts);
                        var useSimplification = config.Simplify;

                        if (useSimplification)
                        {
                            var simple      = new Simplify();
                            simple.vertices = verts.Select(x => new MSVertex()
                            {
                                p = x.Position, t = x.TextureCoordinate
                            }).ToList();
                            for (int t = 0; t < indices.Count; t += 3)
                            {
                                simple.triangles.Add(new MSTriangle()
                                {
                                    v = new int[] { indices[t], indices[t + 1], indices[t + 2] }
                                });
                            }
                            simple.simplify_mesh(simple.triangles.Count / triDivisor, agressiveness: aggressiveness, iterations: iterations);

                            verts = simple.vertices.Select(x =>
                            {
                                var iv = Vector3.Transform(x.p, inv);
                                //DGRP3DVert
                                return(new VertexPositionTexture(x.p,
                                                                 new Vector2(
                                                                     (sprite.Flip) ? (1 - ((iv.X - pos.X + 0.5f) / w)) : ((iv.X - pos.X + 0.5f) / w),
                                                                     (iv.Y - pos.Y + 0.5f) / h)));
                            }
                                                           ).ToList();
                            indices.Clear();
                            foreach (var t in simple.triangles)
                            {
                                indices.Add(t.v[0]);
                                indices.Add(t.v[1]);
                                indices.Add(t.v[2]);
                            }

                            GameThread.NextUpdate(x =>
                            {
                                if (geom.SVerts == null)
                                {
                                    geom.SVerts   = new List <DGRP3DVert>();
                                    geom.SIndices = new List <int>();
                                }

                                var bID = geom.SVerts.Count;
                                foreach (var id in indices)
                                {
                                    geom.SIndices.Add(id + bID);
                                }
                                var verts2 = verts.Select(v => new DGRP3DVert(v.Position, Vector3.Zero, v.TextureCoordinate)).ToList();
                                DGRP3DVert.GenerateNormals(!sprite.Flip, verts2, indices);
                                geom.SVerts.AddRange(verts2);

                                lock (this)
                                {
                                    if (++CompletedCount == TotalSprites)
                                    {
                                        Complete(gd);
                                    }
                                }
                            });
                        }
                        else
                        {
                            GameThread.NextUpdate(x =>
                            {
                                if (geom.SVerts == null)
                                {
                                    geom.SVerts   = new List <DGRP3DVert>();
                                    geom.SIndices = new List <int>();
                                }

                                var baseID = geom.SVerts.Count;
                                foreach (var id in indices)
                                {
                                    geom.SIndices.Add(id + baseID);
                                }
                                var verts2 = verts.Select(v => new DGRP3DVert(v.Position, Vector3.Zero, v.TextureCoordinate)).ToList();
                                DGRP3DVert.GenerateNormals(!sprite.Flip, verts2, indices);
                                geom.SVerts.AddRange(verts2);
                                lock (this)
                                {
                                    if (++CompletedCount == TotalSprites)
                                    {
                                        Complete(gd);
                                    }
                                }
                            });
                        }
                    });
                }
            }
            TotalSprites = totalSpr;
        }
Ejemplo n.º 10
0
        public void Generate(GraphicsDevice gd)
        {
            Dispose();
            var pts    = new List <Vector2>();
            var random = new Random();

            for (int i = 0; i < 100; i++)
            {
                pts.Add(new Vector2((float)random.NextDouble() * 512, (float)random.NextDouble() * 512));
            }

            Cells = new VoronoiCellGraph(pts).Result;
            foreach (var cell in Cells)
            {
                //follow cell vertices, making them into a mesh.
                var cV = new List <DGRP3DVert>();
                var cI = new List <int>();

                var i = 0;
                foreach (var vert in cell.Cycle)
                {
                    //add a part of the edge loop.
                    cV.Add(new DGRP3DVert(
                               new Vector3((float)vert.X, -200, (float)vert.Y),
                               Vector3.Zero,
                               Vector2.Zero
                               ));

                    cV.Add(new DGRP3DVert(
                               new Vector3((float)vert.X, 400, (float)vert.Y),
                               Vector3.Zero,
                               Vector2.Zero
                               ));

                    //i mod
                    //0   1
                    //_____
                    //|\  |
                    //| \ |
                    //|__\|

                    // lo, hi, lo, hi
                    if (i > 0)
                    {
                        cI.Add(i - 2);
                        cI.Add(i - 1);
                        cI.Add(i);

                        cI.Add(i - 1);
                        cI.Add(i + 1);
                        cI.Add(i);
                    }
                    i += 2;
                }

                cI.Add(i - 2);
                cI.Add(i - 1);
                cI.Add(0);

                cI.Add(i - 1);
                cI.Add(1);
                cI.Add(0);

                //add top and bottom tri fans


                i = 0;
                foreach (var vert in cell.Cycle)
                {
                    if (i > 3)
                    {
                        cI.Add(i - 2); //bottom cap
                        cI.Add(i);
                        cI.Add(0);

                        /*
                         * cI.Add(i-1); //top cap
                         * cI.Add(1);
                         * cI.Add(i+1);
                         */
                    }
                    i += 2;
                }


                DGRP3DVert.GenerateNormals(false, cV, cI);
                cV = cV.Select(x => new DGRP3DVert(x.Position + x.Normal * 0.25f, x.Normal, x.TextureCoordinate)).ToList();

                var verts = new VertexBuffer(gd, typeof(DGRP3DVert), cV.Count, BufferUsage.None);
                var inds  = new IndexBuffer(gd, IndexElementSize.ThirtyTwoBits, cI.Count, BufferUsage.None);
                verts.SetData(cV.ToArray());
                inds.SetData(cI.ToArray());

                cell.Vertices = verts;
                cell.Indices  = inds;
            }
        }
Ejemplo n.º 11
0
        public void Draw(GraphicsDevice gd, Effect VertexShader, Effect PixelShader, int passIndex, CityContent content)
        {
            VertexShader.CurrentTechnique = VertexShader.Techniques[1];
            PixelShader.CurrentTechnique  = PixelShader.Techniques[4];

            VertexShader.Parameters["ObjModel"].SetValue(Matrix.Identity);
            VertexShader.Parameters["DepthBias"].SetValue(0f);

            var bM = VertexShader.Parameters["BaseMatrix"].GetValueMatrix();

            for (int i = 0; i < Cells.Count; i++)
            {
                //draw each cell
                VertexShader.CurrentTechnique.Passes[2].Apply();

                //var col = (new Vector4(m_TintColor.R / 255.0f, m_TintColor.G / 255.0f, m_TintColor.B / 255.0f, 1) * 1.25f) / fsof.NightLightColor.ToVector4();
                //PixelShader.Parameters["LightCol"].SetValue(col);

                var frontDS = FrontDepthStencil;

                var bs = NoColor;

                gd.RasterizerState   = RasterizerState.CullNone;
                gd.BlendState        = bs;
                gd.DepthStencilState = frontDS;

                PixelShader.Parameters["ObjTex"].SetValue(TextureGenerator.GetPxWhite(gd));
                PixelShader.CurrentTechnique.Passes[0].Apply();

                gd.SetVertexBuffer(Cells[i].Vertices);
                gd.Indices = Cells[i].Indices;

                gd.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, Cells[i].Indices.IndexCount / 3);

                var so = StencilCompare;

                gd.DepthStencilState = so;
                gd.BlendState        = BlendState.AlphaBlend;

                var screen = UIScreen.Current;
                var aspect = screen.ScreenWidth / (float)screen.ScreenHeight;
                var dat    = new DGRP3DVert[]
                {
                    new DGRP3DVert(new Vector3(-1, -1, 0f), Vector3.Zero, new Vector2(0, 0)),
                    new DGRP3DVert(new Vector3(1, -1, 0f), Vector3.Zero, new Vector2(20 * aspect, 0)),
                    new DGRP3DVert(new Vector3(-1, 1, 0f), Vector3.Zero, new Vector2(0, 20)),
                    new DGRP3DVert(new Vector3(1, 1, 0f), Vector3.Zero, new Vector2(20 * aspect, 20)),
                };

                PixelShader.Parameters["ObjTex"].SetValue(content.NeighTextures[i % 3]);
                PixelShader.Parameters["HighlightColor"].SetValue((Colours[i % Colours.Length] * 0.5f).ToVector4());
                VertexShader.Parameters["BaseMatrix"].SetValue(Matrix.CreateOrthographic(2, 2, -1, 1));
                VertexShader.CurrentTechnique.Passes[2].Apply();
                PixelShader.CurrentTechnique.Passes[0].Apply();
                gd.SamplerStates[0] = SamplerState.LinearWrap;
                gd.DrawUserPrimitives(PrimitiveType.TriangleStrip, dat, 0, 2);
                VertexShader.Parameters["BaseMatrix"].SetValue(bM);
            }

            VertexShader.CurrentTechnique = VertexShader.Techniques[2];
            PixelShader.CurrentTechnique  = PixelShader.Techniques[2];
        }