Esempio n. 1
0
        void Draw(SplineResult[] points, ref float[,] drawLayer, ref float[,] alphaLayer)
        {
            List <SplineResult> selectedPoints = new List <SplineResult>();
            Point last = new Point();

            //Filter out points that are too close to each other
            for (int i = 0; i < points.Length; i++)
            {
                Point current = ToHeightmapCoords(points[i].position + points[i].normal * offset);
                if (i == 0 || i == points.Length - 1)
                {
                    last = new Point(current.x, current.y);
                    selectedPoints.Add(points[i]);
                }
                else if (Vector2.Distance(new Vector2(current.x, current.y), new Vector2(last.x, last.y)) >= 1.5f)
                {
                    selectedPoints.Add(points[i]);
                    last = new Point(current.x, current.y);
                }
            }
            if (selectedPoints.Count <= 1)
            {
                return;
            }
            TerrainPaintPoint[] paintPoints = new TerrainPaintPoint[selectedPoints.Count];
            for (int i = 0; i < selectedPoints.Count; i++)
            {
                ConvertToPaintPoint(selectedPoints[i], ref paintPoints[i]);
            }
            //Paint the points
            for (int i = 0; i < paintPoints.Length - 1; i++)
            {
                hasChanges = true;
                PaintSegment(paintPoints[i], paintPoints[i + 1], ref drawLayer, ref alphaLayer);
            }

            SplineResult exResult = selectedPoints[0];

            exResult.position += exResult.position - selectedPoints[1].position;
            TerrainPaintPoint exPoint = null;

            ConvertToPaintPoint(exResult, ref exPoint);
            PaintSegment(paintPoints[0], exPoint, ref drawLayer, ref alphaLayer, false, false);

            exResult           = selectedPoints[selectedPoints.Count - 1];
            exResult.position += exResult.position - selectedPoints[selectedPoints.Count - 2].position;
            ConvertToPaintPoint(exResult, ref exPoint);
            PaintSegment(paintPoints[paintPoints.Length - 1], exPoint, ref drawLayer, ref alphaLayer, false, false);
            //Extrapolate the ending and the begining
        }
Esempio n. 2
0
        TerrainPaintPoint ConvertToPaintPoint(SplineResult result, ref TerrainPaintPoint paintPoint)
        {
            paintPoint = new TerrainPaintPoint();
            Vector3 right      = -Vector3.Cross(result.direction, result.normal).normalized *size * 0.5f * result.size;
            Vector3 leftPoint  = result.position - right + result.normal * offset;
            Vector3 rightPoint = result.position + right + result.normal * offset;

            paintPoint.center        = ToHeightmapCoords(result.position + result.normal * offset);
            paintPoint.leftPoint     = ToHeightmapCoords(leftPoint);
            paintPoint.rightPoint    = ToHeightmapCoords(rightPoint);
            paintPoint.leftHeight    = ToHeightmapValue(leftPoint.y);
            paintPoint.rightHeight   = ToHeightmapValue(rightPoint.y);
            paintPoint.floatDiameter = Vector2.Distance(new Vector2(leftPoint.x, leftPoint.z), new Vector2(rightPoint.x, rightPoint.z));
            if (paintPoint.leftHeight > maxDrawHeight)
            {
                maxDrawHeight = paintPoint.leftHeight;
            }
            if (paintPoint.rightHeight > maxDrawHeight)
            {
                maxDrawHeight = paintPoint.rightHeight;
            }
            return(paintPoint);
        }
Esempio n. 3
0
        void PaintSegment(TerrainPaintPoint fromPoint, TerrainPaintPoint toPoint, ref float[,] layer, ref float[,] alphaLayer, bool writeAlpha = true, bool overWriteHeight = true)
        {
            //Flip the points if the forward one has a bigger radius so the lerp can work well
            if (Vector2.Distance(fromPoint.leftPoint.vector, fromPoint.rightPoint.vector) < Vector2.Distance(toPoint.leftPoint.vector, toPoint.rightPoint.vector))
            {
                TerrainPaintPoint temp = fromPoint;
                fromPoint = toPoint;
                toPoint   = temp;
            }

            List <Point> drawn           = new List <Point>();
            Vector2      currentPosition = fromPoint.leftPoint.vector;
            Vector2      fromRight       = fromPoint.rightPoint.vector;

            float alphaStartPercent = 0f;
            float alphaEndPercent   = 1f;

            if (feather > 0)
            {
                currentPosition += (fromPoint.leftPoint.vector - fromPoint.center.vector).normalized * feather * 4f;
                fromRight       += (fromPoint.rightPoint.vector - fromPoint.center.vector).normalized * feather * 4f;
                float span = (fromPoint.leftPoint.vector - fromPoint.rightPoint.vector).magnitude / (fromRight - currentPosition).magnitude;
                float rest = (1f - span) / 2f;
                alphaStartPercent = rest;
                alphaEndPercent   = 1f - rest;
            }
            float armLength = Vector2.Distance(currentPosition, fromRight);

            if (armLength < 1f)
            {
                return;
            }
            while (true)
            {
                float armDistance = Vector2.Distance(currentPosition, fromRight);
                float armPercent  = 1f - armDistance / armLength;
                //This can be optimized, take it outside of the cycle
                Point   fromPos     = new Point(currentPosition);
                Vector2 leftvector  = toPoint.leftPoint.vector;
                Vector2 rightVector = toPoint.rightPoint.vector;
                if (feather > 0)
                {
                    leftvector  += (toPoint.leftPoint.vector - toPoint.center.vector).normalized * feather * 4f;
                    rightVector += (toPoint.rightPoint.vector - toPoint.center.vector).normalized * feather * 4f;
                }
                Vector2 toArm = Vector2.Lerp(leftvector, rightVector, armPercent);

                Point   toPos = new Point(toArm);
                int     dx = Mathf.Abs(toPos.x - fromPos.x), sx = fromPos.x < toPos.x ? 1 : -1;
                int     dy = -Mathf.Abs(toPos.y - fromPos.y), sy = fromPos.y < toPos.y ? 1 : -1;
                int     err = dx + dy, e2;
                Point   current = fromPos;
                Vector2 target  = new Vector2(toPos.x - fromPos.x, toPos.y - fromPos.y);

                float fromHeight = fromPoint.GetHeight(armPercent);
                float toHeight   = toPoint.GetHeight(armPercent);
                while (true)
                {
                    if (current.x >= 0 && current.x < layer.GetLength(0) && current.y >= 0 && current.y < layer.GetLength(1))
                    {
                        if (overWriteHeight || layer[current.x, current.y] == 0f)
                        {
                            if (!ContainsPoint(ref drawn, current))
                            {
                                Vector2 currentDist     = new Vector2(current.x - fromPos.x, current.y - fromPos.y);
                                float   positionPercent = Mathf.Clamp01(currentDist.magnitude / target.magnitude);
                                float   height          = Mathf.Lerp(fromHeight, toHeight, positionPercent);
                                float   alphaValue      = 0f;
                                if (armPercent >= alphaStartPercent && armPercent <= alphaEndPercent)
                                {
                                    alphaValue = 1f;
                                }
                                if (writeAlpha)
                                {
                                    plot(current.x, current.y, height, alphaValue, ref alphaLayer, ref layer);
                                }
                                else
                                {
                                    plot(current.x, current.y, height, alphaLayer[current.x, current.y], ref alphaLayer, ref layer);
                                }
                                drawn.Add(current);
                            }
                        }
                    }
                    if (current.x == toPos.x && current.y == toPos.y)
                    {
                        break;
                    }
                    e2 = 2 * err;
                    if (e2 > dy)
                    {
                        err       += dy;
                        current.x += sx;
                    }
                    else if (e2 < dx)
                    {
                        err       += dx;
                        current.y += sy;
                    }
                }
                if (currentPosition == fromRight)
                {
                    break;
                }
                currentPosition = Vector2.MoveTowards(currentPosition, fromRight, 1f);
            }
        }