Пример #1
0
    public static void Silhouette(SplineSys spline, MatrixWorld matrix, bool strokePrepared = false)
    /// Fills all pixels within closed spline with 1, and all outer pixels with 0
    /// Pixels directly in the spline are filled with 0.5
    /// Requires an empty matrix (can use matrix with the stroke, in this case strokePrepared should be set to true)
    {
        if (!strokePrepared)
        {
            Stroke(spline, matrix, white: true, intensity: 0.5f, antialiased: false, padOnePixel: false);
        }

        CoordRect rect = matrix.rect;
        Coord     min = rect.Min; Coord max = rect.Max;

        for (int x = min.x; x < max.x; x++)
        {
            for (int z = min.z; z < max.z; z++)
            {
                int pos = (z - rect.offset.z) * rect.size.x + x - rect.offset.x;

                if (matrix.arr[pos] < 0.01f)                 //free from stroke and fill
                {
                    Vector3 pixelPos = matrix.PixelToWorld(x, z, center: true);
                    bool    handness = spline.Handness(pixelPos) >= 0;

                    matrix.PaintBucket(new Coord(x, z), handness ? 0.75f : 0.25f);
                }
            }
        }
    }
Пример #2
0
    public static void Silhouette(SplineSys spline, MatrixWorld strokeMatrix, MatrixWorld dstMatrix)
    /// Fills all pixels within closed spline with 1, and all outer pixels with 0
    /// Pixels directly in the spline are filled with 0.5
    /// Requires the matrix with line stroked. StrokeMatrix and DstMatrix could be the same
    {
        if (strokeMatrix != dstMatrix)
        {
            dstMatrix.Fill(strokeMatrix);
        }
        //and then using dst matrix only

        CoordRect rect = dstMatrix.rect;
        Coord     min = rect.Min; Coord max = rect.Max;

        for (int x = min.x; x < max.x; x++)
        {
            for (int z = min.z; z < max.z; z++)
            {
                int pos = (z - rect.offset.z) * rect.size.x + x - rect.offset.x;

                if (dstMatrix.arr[pos] < 0.01f)                 //free from stroke and fill
                {
                    Vector3 pixelPos = dstMatrix.PixelToWorld(x, z, center: true);
                    bool    handness = spline.Handness(pixelPos) >= 0;

                    dstMatrix.PaintBucket(new Coord(x, z), handness ? 0.75f : 0.25f);
                }
            }
        }
    }
Пример #3
0
            public void ProcessToFloor(Inlet <SplineSys> splineIn, Outlet <SplineSys> splineOut, TileData data, StopToken stop)
            {
                SplineSys   src     = data.ReadInletProduct(splineIn);
                MatrixWorld heights = data.ReadInletProduct(heightIn);

                if (src == null)
                {
                    return;
                }
                if (!enabled || heights == null)
                {
                    data.StoreProduct(splineOut, src); return;
                }

                if (stop != null && stop.stop)
                {
                    return;
                }
                SplineSys dst = new SplineSys(src);

                FloorSplines(dst, heights);
                dst.Update();

                if (stop != null && stop.stop)
                {
                    return;
                }
                data.StoreProduct(splineOut, dst);

                DebugGizmos.Clear("Spline");
                foreach (Segment segment in dst.lines[0].segments)
                {
                    DebugGizmos.DrawLine("Spline", segment.start.pos, segment.end.pos, Color.white, additive: true);
                }
            }
Пример #4
0
 public static void Silhouette(SplineSys spline, MatrixWorld matrix)
 /// Fills all pixels within closed spline with 1, and all outer pixels with 0
 /// Pixels directly in the spline are filled with 0.5
 /// Internally strokes matrix first
 {
     Stroke(spline, matrix, white: true, intensity: 0.5f, antialiased: false, padOnePixel: false);
     Silhouette(spline, matrix, matrix);
 }
Пример #5
0
            public static void FloorSplines(SplineSys dst, MatrixWorld heights)
            {
                foreach (Line line in dst.lines)
                {
                    for (int s = 0; s < line.segments.Length; s++)
                    {
                        line.segments[s].start.pos.y = FloorPoint(line.segments[s].start.pos, heights);
                    }

                    line.segments[line.segments.Length - 1].end.pos.y = FloorPoint(line.segments[line.segments.Length - 1].end.pos, heights);
                }
            }
Пример #6
0
        public SplineSysWithPrefab(SplineSys src)
        {
            CopyLinesFrom(src.lines);

            scale   = 1f;
            spacing = 1f;

            guiDrawNodes    = src.guiDrawNodes;
            guiDrawSegments = src.guiDrawSegments;
            guiDrawDots     = src.guiDrawDots;
            guiDotsCount    = src.guiDotsCount;
            guiDotsEquidist = src.guiDotsEquidist;
        }
Пример #7
0
        public void SetObject(IOutlet <object> outlet, TileData data)
        {
            if (data == null)
            {
                return;
            }

            this.splineSys   = (SplineSys)data.products[outlet];
            this.worldPos    = data.area.active.worldPos;
            this.worldSize   = data.area.active.worldSize;
            this.worldHeight = data.globals.height;

            Stage = PreviewStage.Generating;
            ThreadManager.Enqueue(ExecuteInThread, priority: -1000);
        }
Пример #8
0
    public static void Stroke(SplineSys spline, MatrixWorld matrix,
                              bool white       = false, float intensity  = 1,
                              bool antialiased = false, bool padOnePixel = false)
    /// Draws a line on matrix
    /// White will fill the line with 1, when disabled it will use spline height
    /// PaddedOnePixel works similarly to AA, but fills border pixels with full value (to create main tex for the mask)
    {
        foreach (Line line in spline.lines)
        {
            for (int s = 0; s < line.segments.Length; s++)
            {
                int numSteps = (int)(line.segments[s].length / matrix.PixelSize.x * 0.1f + 1);

                Vector3 startPos   = line.segments[s].start.pos;
                Vector3 prevCoord  = matrix.WorldToPixelInterpolated(startPos.x, startPos.z);
                float   prevHeight = white ? intensity : (startPos.y / matrix.worldSize.y);

                for (int i = 0; i < numSteps; i++)
                {
                    float   percent   = numSteps != 1 ? 1f * i / (numSteps - 1) : 1;
                    Vector3 pos       = line.segments[s].GetPoint(percent);
                    float   posHeight = white ? intensity : (pos.y / matrix.worldSize.y);
                    pos = matrix.WorldToPixelInterpolated(pos.x, pos.z);

                    matrix.Line(
                        new Vector2(prevCoord.x, prevCoord.z),
                        new Vector2(pos.x, pos.z),
                        prevHeight,
                        posHeight,
                        antialised: antialiased,
                        paddedOnePixel: padOnePixel,
                        endInclusive: i == numSteps - 1);

                    prevCoord  = pos;
                    prevHeight = posHeight;
                }
            }
        }
    }
Пример #9
0
            //  TODO we could just use this to level the final objects rather than the horror-story ray casts.
            //      public float terrainHeight; //to get relative object height (since all of the terrain data is 0-1). //TODO: maybe move it to HeightData in "Height in meters" task

            // TODO we could limit the perframe activities mid-spawn
            //    public int objsPerIteration = 500;


            public void Apply(Terrain terrain)
            {
                // unless there is no spline data

                if (splines == null || splines.Count == 0 || splines[0].lines.Length == 0)
                {
                    return;
                }

                // By this point this should absolutely exist -
                int totalNumberOfListsOfSplineMeshSplines = splines.Count;

                // There is nothing in the list
                if (totalNumberOfListsOfSplineMeshSplines == 0)
                {
                    return;
                }

                List <GameObject> thingsToActivate = new List <GameObject>();

                Coord data_area_cood = terrain.transform.parent.localPosition.ToCoord() * 0.001f;


                Coord locality = TownGlobalObject.GetIndexAtCoord(data_area_cood);


                // SplinePowerExtended

                var DynamicHolder = TownHolder.Instance.MapMagicObjectReference.transform.Find(string.Format("Tile {0},{1}", data_area_cood.x, data_area_cood.z));

                // Create splines holder

                var splineHolder = new GameObject
                {
                    name = "SPLINE_FOR_" + string.Format("Tile_{0},{1}", data_area_cood.x, data_area_cood.z)
                };


                splineHolder.transform.parent = DynamicHolder;

                splineHolder.transform.localPosition = new Vector3();


                Coord tilecoord = splineHolder.transform.parent.GetComponent <TerrainTile>().coord;


                // We walk over the nodes assuming pairs?

                for (int i = 0; i < totalNumberOfListsOfSplineMeshSplines; i++)
                {
                    SplineSys spline = splines[i];

                    var myarray = new List <SplineMesh.SplineNode>();

                    // No splines for us...
                    if (spline.NodesCount == 0)
                    {
                        continue;
                    }

                    var global = new List <SplineNode>();

                    var positionalFactor = 1f;

                    myarray = new List <SplineNode>();

                    SplineNode refnode = new SplineNode(Vector3.positiveInfinity, Vector3.positiveInfinity);

                    SplineNode startnode = refnode;
                    SplineNode endnode   = refnode;

                    Segment lastSegment = new Segment();
                    Segment thissegment = new Segment();

                    lastSegment.end.pos = thissegment.start.pos = Vector3.positiveInfinity;

                    foreach (var road in spline.lines.Reverse())
                    {
                        if (!splines[i].mergeSegments)
                        {
                            myarray = new List <SplineNode>();
                        }

                        foreach (var current in road.segments)
                        {
                            // We need to check if the last segments end connects to the next segments start or RenderOutSplinesSoFar;

                            thissegment = road.segments.Where(x => x.GetHashCode() == current.GetHashCode()).First();


                            thissegment.start.pos -= DynamicHolder.transform.localPosition;
                            thissegment.end.pos   -= DynamicHolder.transform.localPosition;

                            if (splines[i].mergeSegments)
                            {
                                //  Render out the segments if they are far apart (square root of 200) - have some data get parsed - and have been selected for merging
                                if (Vector3.SqrMagnitude(lastSegment.end.pos - thissegment.start.pos) > 200f && myarray.Count > 1)
                                {
                                    RenderOutSplinesSoFar(splineHolder, i, myarray);
                                    myarray = new List <SplineNode>();
                                }
                            }


                            lastSegment = thissegment;
                            // setup bool fence for list.
                            // add start if we didnt.

                            bool startExists = global.Exists(element => element.Position == thissegment.start.pos * positionalFactor);

                            if (!startExists)
                            {
                                startnode = new SplineMesh.SplineNode(thissegment.start.pos * positionalFactor, thissegment.start.pos * positionalFactor);

                                myarray.Add(startnode);

                                global.Add(startnode);
                            }

                            // and add end if we didnt.

                            bool endExists = global.Exists(element => element.Position == thissegment.end.pos * positionalFactor);

                            if (!endExists)
                            {
                                endnode = new SplineMesh.SplineNode(thissegment.end.pos * positionalFactor, thissegment.end.pos * positionalFactor);

                                myarray.Add(endnode);

                                global.Add(endnode);
                            }
                        }


                        if (myarray.Count == 0)
                        {
                            continue;
                        }


                        if (myarray.Count == 1)
                        {
                            // give us two by hook or crook
                            if (myarray.Contains(startnode))
                            {
                                endnode = new SplineMesh.SplineNode(lastSegment.end.pos * positionalFactor, lastSegment.end.pos * positionalFactor);
                                myarray.Add(endnode);
                            }
                            else
                            {
                                startnode = new SplineMesh.SplineNode(lastSegment.start.pos * positionalFactor, lastSegment.start.pos * positionalFactor);
                                myarray.Add(startnode);
                            }


                            continue;
                        }



                        if ((myarray[1].Position - myarray[0].Position).sqrMagnitude == 0)
                        {
                            continue;
                        }


                        // Render out as just segment node pairs
                        if (!splines[i].mergeSegments)
                        {
                            RenderOutSplinesSoFar(splineHolder, i, myarray);
                        }
                    }

                    // Attempt to merge near pairs
                    if (splines[i].mergeSegments)
                    {
                        RenderOutSplinesSoFar(splineHolder, i, myarray);
                    }
                }
            }
Пример #10
0
 public SplineSysWrapper()
 {
     this.splineSys = new SplineSys();
     // this.name = string.Empty;
 }
Пример #11
0
 public SplineSysWrapper(string name, SplineSys sys, string outletname)
 {
     this.outletName = outletname;
     this.splineSys  = new SplineSys(sys);
     this.name       = name;
 }
Пример #12
0
 public SplineSysWrapper(string name, SplineSys sys, MapMagic.Nodes.Outlet <SplineSys> outlet)
 {
     this.outlet    = outlet;
     this.splineSys = new SplineSys(sys);
     this.name      = name;
 }
Пример #13
0
 public SplineSysWrapper(string name, SplineSys sys)
 {
     this.splineSys = new SplineSys(sys);
     this.name      = name;
 }
Пример #14
0
 public SplineSysWrapper(SplineSys sys, MapMagic.Nodes.Outlet <SplineSys> outlet)
 {
     this.splineSys = new SplineSys(sys);
     this.outlet    = outlet;
 }
Пример #15
0
 public SplineSysWrapper(SplineSys sys)
 {
     this.splineSys = new SplineSys(sys);
 }
Пример #16
0
 public SplineSysWrapper(string name)
 {
     this.splineSys = new SplineSys();
     this.name      = name;
 }
Пример #17
0
        public static ITestInput CreateTestInput(GameObject go, IInlet <SplineSys> inlet, SplineSys splineSys)
        {
            SplineObject splineObj = go.AddComponent <SplineObject>();

            splineObj.splineSys = splineSys;

            SplineInout splineIn = new SplineInout()
            {
                splineObj = splineObj
            };

            return(splineIn);
        }
        public override void Generate(TileData data, StopToken stop)
        {
            if (!enabled)
            {
                return;
            }
            // if (data.isDraft) return;

            TransitionsList src = data.ReadInletProduct <TransitionsList>(this);

            TransitionsList copy = new TransitionsList(src);

            RemoveAnyBlanksInTransitionListArrayHelper(ref copy);

            // nodes for spline
            List <Vector3> markers = new List <Vector3>(copy.count);

            // setup the clamp mask
            var tileLocation   = data.area.Coord.ToVector3(1000); // x 0 z
            var tileLocationV2 = tileLocation.V2();               // x z
            var tileSize       = new Vector3(1000, 500, 1000);    // TODO: Set this to the mapmagic tile size... not assume 1k

            // now magically create perfect size slices for this tile.  Thanks Denis.
            // dst.Clamp(tileLocation, tileSize);

            //data - whatever data
            foreach (var item in copy.arr)
            {
                Vector2 offsetted = (item.pos.V2() + tileLocationV2);


                var offsettedstore = new Vector3(offsetted.x, item.pos.y, offsetted.y);

                if (!markers.Contains(offsettedstore))
                {
                    try
                    {
                        markers.Add(offsettedstore);
                    }
                    catch (Exception e)
                    {
                        Debug.LogErrorFormat(" Edge case {0} with location {1},{2},{3} and a list of Length {4}", e.Message, offsettedstore.x, offsettedstore.y, offsettedstore.z, markers.Count);
                        // ignore this weird edge case.
                    }
                }
            }


            // add the first one again, as a node. for a loop. and to ensure we have two.. which we will now test for..
            markers.Add(markers[0]);

            // there was one object ONLY...
            if (markers[0] == markers[1])
            {
                // this will just give is an N/A rather than bombing.
                Debug.LogErrorFormat(" Please add at least TWO objects");
                return;
            }

            // make some holders
            SplineSys spline = new SplineSys();
            Line      line   = new Line();

            line.SetNodes(markers.ToArray());
            spline.AddLine(line);


            // now magically create perfect size slices for this tile.  Thanks Denis.
            spline.Clamp(tileLocation, tileSize);


            //save it.
            data.StoreProduct(this, spline);
        }