Esempio n. 1
0
    private void DoResetModeHandles(Ferr2D_Path path, Ferr2DT_PathTerrain terrain, int i, Matrix4x4 mat, Matrix4x4 invMat, Transform camTransform)
    {
        int     nextId     = i == path.Count - 1?(path.closed?i % path.Count:i - 1):i + 1;
        Vector3 pos        = mat.MultiplyPoint3x4(path.pathVerts[i]);
        Vector3 posNext    = mat.MultiplyPoint3x4(path.pathVerts[nextId]);
        Vector3 normal     = -(Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed);
        Vector3 posStart   = pos;
        bool    isSelected = false;

        if (selectedPoints != null)
        {
            isSelected = selectedPoints.Contains(i);
        }

        float       handleScale = HandleScale(posStart);
        CapFunction cap         = (isSelected || selectedPoints.Count <= 0) ? (CapFunction)CapDotMinusSelected : (CapFunction)CapDotMinus;

        if (Handles.Button(posStart, camTransform.rotation, handleScale, handleScale, cap))
        {
            EnsureVertSelected(i, ref isSelected);
            deleteSelected = true;
            GUI.changed    = true;
        }
        else if (!Ferr2DT_SceneOverlay.segmentLockMode)
        {
            handleScale = handleScale * 0.5f;

            // do scaling
            Vector3 displayPos = pos + normal * terrain.vertScales[i] * 2 * Ferr2DT_Menu.PathScale;
            if (IsVisible(displayPos) && Handles.Button(displayPos, camTransform.rotation, handleScale, handleScale, CapDotReset))
            {
                EnsureVertSelected(i, ref isSelected);

                Undo.RecordObject(terrain, "Scale Path Vert");

                for (int s = 0; s < selectedPoints.Count; s++)
                {
                    terrain.vertScales[selectedPoints[s]] = 1;
                }
                EditorUtility.SetDirty(terrain);
                GUI.changed = true;
            }

            // do edge overrides
            displayPos = GetOverridePos(i, path, mat, pos, posNext);
            if (IsVisible(displayPos) && Handles.Button(displayPos, camTransform.rotation, handleScale, handleScale, CapDotReset))
            {
                EnsureVertSelected(i, ref isSelected);

                Undo.RecordObject(terrain, "Override Vert Direction");

                for (int s = 0; s < selectedPoints.Count; s++)
                {
                    terrain.directionOverrides[selectedPoints[s]] = Ferr2DT_TerrainDirection.None;
                }
                EditorUtility.SetDirty(terrain);
                GUI.changed = true;
            }
        }
    }
Esempio n. 2
0
    private void AddSegment(List <Vector2> aSegment, bool aClosed, Ferr2DT_TerrainDirection aDir = Ferr2DT_TerrainDirection.None)
    {
        Ferr2DT_SegmentDescription desc = GetDescription(aSegment);

        if (aDir != Ferr2DT_TerrainDirection.None)
        {
            desc = terrainMaterial.GetDescriptor(aDir);
        }
        int   bodyID    = UnityEngine.Random.Range(0, desc.body.Length);
        Rect  body      = terrainMaterial.ToUV(desc.body[bodyID]);
        float bodyWidth = body.width * unitsPerUV.x;

        int tSeed = UnityEngine.Random.seed;

        Vector2 capLeftSlideDir  = (aSegment[1] - aSegment[0]);
        Vector2 capRightSlideDir = (aSegment[aSegment.Count - 2] - aSegment[aSegment.Count - 1]);

        capLeftSlideDir.Normalize();
        capRightSlideDir.Normalize();
        aSegment[0] -= capLeftSlideDir * desc.capOffset;
        aSegment[aSegment.Count - 1] -= capRightSlideDir * desc.capOffset;

        for (int i = 0; i < aSegment.Count - 1; i++)
        {
            Vector2 norm1   = Vector2.zero;
            Vector2 norm2   = Vector2.zero;
            float   length  = Vector2.Distance(aSegment[i + 1], aSegment[i]);
            int     repeats = Mathf.Max(1, Mathf.FloorToInt(length / bodyWidth + stretchThreshold));

            norm1 = Ferr2D_Path.GetNormal(aSegment, i, aClosed);
            norm2 = Ferr2D_Path.GetNormal(aSegment, i + 1, aClosed);

            for (int t = 1; t < repeats + 1; t++)
            {
                UnityEngine.Random.seed = (int)(transform.position.x * 100000 + transform.position.y * 10000 + i * 100 + t);
                body = terrainMaterial.ToUV(desc.body[UnityEngine.Random.Range(0, desc.body.Length)]);
                Vector2 pos1, pos2, n1, n2;

                pos1 = Vector2.Lerp(aSegment[i], aSegment[i + 1], (float)(t - 1) / repeats);
                pos2 = Vector2.Lerp(aSegment[i], aSegment[i + 1], (float)t / repeats);
                n1   = Vector2.Lerp(norm1, norm2, (float)(t - 1) / repeats);
                n2   = Vector2.Lerp(norm1, norm2, (float)t / repeats);

                float d    = (body.height / 2) * unitsPerUV.y;
                float yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -desc.yOffset : desc.yOffset;
                int   v1   = dMesh.AddVertex(pos1.x + n1.x * (d + yOff), pos1.y + n1.y * (d + yOff), desc.zOffset, body.x, fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
                int   v2   = dMesh.AddVertex(pos1.x - n1.x * (d - yOff), pos1.y - n1.y * (d - yOff), desc.zOffset, body.x, fill == Ferr2DT_FillMode.InvertedClosed ? body.y    : body.yMax);
                int   v3   = dMesh.AddVertex(pos2.x + n2.x * (d + yOff), pos2.y + n2.y * (d + yOff), desc.zOffset, body.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
                int   v4   = dMesh.AddVertex(pos2.x - n2.x * (d - yOff), pos2.y - n2.y * (d - yOff), desc.zOffset, body.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? body.y    : body.yMax);
                dMesh.AddFace(v1, v3, v4, v2);
            }
        }
        if (!aClosed)
        {
            AddCap(aSegment, desc, -1);
            AddCap(aSegment, desc, 1);
        }
        UnityEngine.Random.seed = tSeed;
    }
Esempio n. 3
0
    private List <Vector2> ExpandColliderPath(List <Vector2> aList, float aAmount)
    {
        int count = aList.Count;

        for (int i = count - 1; i >= 0; i--)
        {
            Vector2 norm = Ferr2D_Path.GetNormal(aList, i, false);
            aList.Add(aList [i] + new Vector2(norm.x * aAmount, norm.y * aAmount));
        }
        return(aList);
    }
Esempio n. 4
0
    private void AddCap(List <Vector2> aSegment, Ferr2DT_SegmentDescription aDesc, float aDir)
    {
        int     index = 0;
        Vector2 dir   = Vector2.zero;

        if (aDir < 0)
        {
            index = 0;
            dir   = aSegment[0] - aSegment[1];
        }
        else
        {
            index = aSegment.Count - 1;
            dir   = aSegment[aSegment.Count - 1] - aSegment[aSegment.Count - 2];
        }
        dir.Normalize();
        Vector2 norm = Ferr2D_Path.GetNormal(aSegment, index, false);
        Vector2 pos  = aSegment[index];
        Rect    lCap = fill == Ferr2DT_FillMode.InvertedClosed ? terrainMaterial.ToUV(aDesc.rightCap) : terrainMaterial.ToUV(aDesc.leftCap);
        Rect    rCap = fill == Ferr2DT_FillMode.InvertedClosed ? terrainMaterial.ToUV(aDesc.leftCap) : terrainMaterial.ToUV(aDesc.rightCap);
        float   yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;

        if (aDir < 0)
        {
            float width = lCap.width * unitsPerUV.x;
            float scale = (lCap.height / 2) * unitsPerUV.y;

            int v1 = dMesh.AddVertex(pos + dir * width + norm * (scale + yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed? lCap.xMax : lCap.x, fill == Ferr2DT_FillMode.InvertedClosed ? lCap.yMax : lCap.y));
            int v2 = dMesh.AddVertex(pos + norm * (scale + yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? lCap.x : lCap.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? lCap.yMax : lCap.y));

            int v3 = dMesh.AddVertex(pos - norm * (scale - yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? lCap.x : lCap.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? lCap.y : lCap.yMax));
            int v4 = dMesh.AddVertex(pos + dir * width - norm * (scale - yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? lCap.xMax : lCap.x, fill == Ferr2DT_FillMode.InvertedClosed ? lCap.y : lCap.yMax));
            dMesh.AddFace(v1, v2, v3, v4);
        }
        else
        {
            float width = rCap.width * unitsPerUV.x;
            float scale = (rCap.height / 2) * unitsPerUV.y;

            int v1 = dMesh.AddVertex(pos + dir * width + norm * (scale + yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? rCap.x : rCap.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? rCap.yMax : rCap.y));
            int v2 = dMesh.AddVertex(pos + norm * (scale + yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? rCap.xMax : rCap.x, fill == Ferr2DT_FillMode.InvertedClosed ? rCap.yMax : rCap.y));

            int v3 = dMesh.AddVertex(pos - norm * (scale - yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? rCap.xMax : rCap.x, fill == Ferr2DT_FillMode.InvertedClosed ? rCap.y : rCap.yMax));
            int v4 = dMesh.AddVertex(pos + dir * width - norm * (scale - yOff), aDesc.zOffset, new Vector2(fill == Ferr2DT_FillMode.InvertedClosed ? rCap.x : rCap.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? rCap.y : rCap.yMax));
            dMesh.AddFace(v4, v3, v2, v1);
        }
    }
Esempio n. 5
0
    private List <Vector2> GetColliderVerts()
    {
        Ferr2D_Path    path  = GetComponent <Ferr2D_Path> ();
        List <Vector2> verts = path.GetVerts(smoothPath, splitDist, splitCorners);

        if (path.closed && smoothPath == false)
        {
            verts.Add(verts [0]);
        }
        List <Vector2> raw = new List <Vector2> (verts);

        MatchOverrides();

        // consider the offset values for the collider. Also, if it's not filled, make sure we add in
        // extra path verts for the underside of the path
        int count = raw.Count;

        for (int i = count - 1; i >= 0; i--)
        {
            Vector2 norm = Ferr2D_Path.GetNormal(raw, i, path.closed);
            if (fill == Ferr2DT_FillMode.None)
            {
                verts.Add(raw [i] + new Vector2(norm.x * surfaceOffset [(int)Ferr2DT_TerrainDirection.Top], norm.y * surfaceOffset [(int)Ferr2DT_TerrainDirection.Top]));
                verts [i] += new Vector2(norm.x * -surfaceOffset [(int)Ferr2DT_TerrainDirection.Bottom], norm.y * -surfaceOffset [(int)Ferr2DT_TerrainDirection.Bottom]);
            }
            else
            {
                Vector2 offset = GetOffset(raw, i, path.closed);
                verts [i] += new Vector2(norm.x * -offset.x, norm.y * -offset.y);
            }
        }

        if (fill == Ferr2DT_FillMode.Skirt || fill == Ferr2DT_FillMode.FillOnlySkirt)
        {
            Vector2 start = verts [0];
            Vector2 end   = verts [verts.Count - 1];
            verts.Add(new Vector2(end.x, fillY));
            verts.Add(new Vector2(Mathf.Lerp(end.x, start.x, 0.33f), fillY));
            verts.Add(new Vector2(Mathf.Lerp(end.x, start.x, 0.66f), fillY));
            verts.Add(new Vector2(start.x, fillY));
        }
        else if (fill == Ferr2DT_FillMode.None)
        {
        }
        return(verts);
    }
Esempio n. 6
0
    private void DoNormalModeHandles(Ferr2D_Path path, Ferr2DT_PathTerrain terrain, int i, Matrix4x4 mat, Matrix4x4 invMat, Transform camTransform)
    {
        int     nextId     = i == path.Count - 1?(path.closed?0:i - 1):i + 1;
        Vector3 pos        = mat.MultiplyPoint3x4(path.pathVerts[i]);
        Vector3 posNext    = mat.MultiplyPoint3x4(path.pathVerts[nextId]);
        Vector3 normal     = -(Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed);
        bool    isSelected = false;

        if (selectedPoints != null)
        {
            isSelected = selectedPoints.Contains(i);
        }

        // check for moving the point
        CapFunction cap = CapDot;

        if (Event.current.control)
        {
            cap = isSelected ? (CapFunction)CapDotSelectedSnap : (CapFunction)CapDotSnap;
        }
        else
        {
            cap = isSelected ? (CapFunction)CapDotSelected     : (CapFunction)CapDot;
        }

        Vector3 result = Handles.FreeMoveHandle(pos, camTransform.rotation, HandleScale(pos), snap, cap);

        if (result != pos)
        {
            EnsureVertSelected(i, ref isSelected);

            Vector2 relative = GetRelativeMovementWithSnap(result, invMat, i, path);

            for (int s = 0; s < selectedPoints.Count; s++)
            {
                path.pathVerts[selectedPoints[s]] += relative;
            }
        }

        if (Ferr2DT_SceneOverlay.showIndices)
        {
            Vector3 labelPos = pos + normal;
            Handles.color = Color.white;
            Handles.Label(labelPos, "" + i);
        }

        if (!Ferr2DT_SceneOverlay.segmentLockMode)
        {
            float   scale      = HandleScale(pos) * 0.5f;
            Vector3 displayPos = pos;

            if (path.closed || i + 1 < path.pathVerts.Count)
            {
                displayPos = GetOverridePos(i, path, mat, pos, posNext);

                if (IsVisible(displayPos) && terrain.directionOverrides != null)
                {
                    cap = Event.current.alt ? (CapFunction)CapDotReset : GetDirIcon(terrain.directionOverrides[i]);
                    if (Handles.Button(displayPos, camTransform.rotation, scale, scale, cap))
                    {
                        EnsureVertSelected(i, ref isSelected);

                        Undo.RecordObject(terrain, "Override Vert Direction");

                        Ferr2DT_TerrainDirection dir = NextDir(terrain.directionOverrides[i]);
                        for (int s = 0; s < selectedPoints.Count; s++)
                        {
                            terrain.directionOverrides[selectedPoints[s]] = dir;
                        }
                        EditorUtility.SetDirty(terrain);
                        GUI.changed = true;
                    }
                }
            }

            displayPos = pos + normal * terrain.vertScales[i] * 2 * Ferr2DT_Menu.PathScale;
            if (IsVisible(displayPos))
            {
                cap = Event.current.alt ? (CapFunction)CapDotReset : (CapFunction)CapDotScale;

                Vector3 scaleMove = Handles.FreeMoveHandle(displayPos, camTransform.rotation, scale, Vector3.zero, cap);
                float   scaleAmt  = Vector3.Distance(displayPos, scaleMove);
                if (Mathf.Abs(scaleAmt) > 0.01f)
                {
                    EnsureVertSelected(i, ref isSelected);

                    Undo.RecordObject(terrain, "Scale Path Vert");

                    float vertScale = Vector3.Distance(scaleMove, pos) / 2 / Ferr2DT_Menu.PathScale;
                    vertScale = Mathf.Clamp(vertScale, 0.2f, 3f);
                    for (int s = 0; s < selectedPoints.Count; s++)
                    {
                        terrain.vertScales[selectedPoints[s]] = vertScale;
                    }
                    EditorUtility.SetDirty(terrain);
                    GUI.changed = true;
                }
            }

            // make sure we can add new point at the midpoints!
            if (i + 1 < path.pathVerts.Count || path.closed == true)
            {
                Vector3 mid         = (pos + posNext) / 2;
                float   handleScale = HandleScale(mid);

                if (Handles.Button(mid, camTransform.rotation, handleScale, handleScale, CapDotPlus))
                {
                    Vector2 pt = invMat.MultiplyPoint3x4(mid);

                    terrain.AddPoint(pt, nextId);
                    EditorUtility.SetDirty(terrain);
                    GUI.changed = true;
                }
            }
        }
    }
Esempio n. 7
0
    private void DoHandles(Ferr2D_Path path, GUIStyle iconStyle)
    {
        Ferr2DT_PathTerrain terrain = path.gameObject.GetComponent <Ferr2DT_PathTerrain>();

        if (terrain)
        {
            terrain.MatchOverrides();
        }
        Quaternion inv = Quaternion.Inverse(path.transform.rotation);

        Handles.color = new Color(1, 1, 1, 0);
        for (int i = 0; i < path.pathVerts.Count; i++)
        {
            Vector3 pos        = path.transform.position + path.transform.rotation * Vector3.Scale(new Vector3(path.pathVerts[i].x, path.pathVerts[i].y, 0), path.transform.localScale);
            Vector3 posOff     = pos + offset;
            bool    isSelected = false;
            if (selectedPoints != null)
            {
                isSelected = selectedPoints.Contains(i);
            }

            // check if we want to remove points
            if (Event.current.alt)
            {
                float handleScale = HandleScale(posOff);
                if (IsVisible(posOff))
                {
                    SetScale(posOff, texMinus, ref iconStyle);
                    //Handles.Label(posOff, new GUIContent((isSelected || selectedPoints.Count <= 0) ? texMinusSelected : texMinus), iconStyle);
                }

                if (Handles.Button(posOff, SceneView.lastActiveSceneView.camera.transform.rotation, handleScale, handleScale, Handles.CircleCap))
                {
                    if (!isSelected && selectedPoints != null)
                    {
                        selectedPoints.Clear();
                        selectedPoints.Add(i);
                    }
                    if (selectedPoints != null)
                    {
                        for (int s = 0; s < selectedPoints.Count; s++)
                        {
                            if (terrain)
                            {
                                terrain.RemovePoint(selectedPoints[s]);
                            }
                            else
                            {
                                path.pathVerts.RemoveAt(selectedPoints[s]);
                            }
                            if (selectedPoints[s] <= i)
                            {
                                i--;
                            }

                            for (int u = 0; u < selectedPoints.Count; u++)
                            {
                                if (selectedPoints[u] > selectedPoints[s])
                                {
                                    selectedPoints[u] -= 1;
                                }
                            }
                        }
                    }
                    if (selectedPoints != null)
                    {
                        selectedPoints.Clear();
                    }
                    GUI.changed = true;
                }
                else if (Ferr2DT_SceneOverlay.editMode != Ferr2DT_EditMode.None)
                {
                    if (terrain && i + 1 < path.pathVerts.Count)
                    {
                        float   scale     = handleScale * 0.5f;
                        Vector3 dirOff    = GetTickerOffset(path, pos, i);
                        Vector3 posDirOff = posOff + dirOff;

                        if (IsVisible(posDirOff))
                        {
                            Texture2D icon = null;
                            if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override)
                            {
                                icon = GetDirIcon(terrain.directionOverrides[i]);
                            }
                            else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale)
                            {
                                icon = texScale;
                            }
                            if (Event.current.alt)
                            {
                                icon = texReset;
                            }

                            SetScale(posDirOff, icon, ref iconStyle, 0.5f);
                            Handles.Label(posDirOff, new GUIContent(icon), iconStyle);

                            if (Handles.Button(posDirOff, SceneView.lastActiveSceneView.camera.transform.rotation, scale, scale, Handles.CircleCap) && selectedPoints != null)
                            {
                                if (selectedPoints.Count < 2 || isSelected == false)
                                {
                                    selectedPoints.Clear();
                                    selectedPoints.Add(i);
                                    isSelected = true;
                                }

                                for (int s = 0; s < selectedPoints.Count; s++)
                                {
                                    if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override)
                                    {
                                        terrain.directionOverrides[selectedPoints[s]] = Ferr2DT_TerrainDirection.None;
                                    }
                                    else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale)
                                    {
                                        terrain.vertScales[selectedPoints[s]] = 1;
                                    }
                                }
                                GUI.changed = true;
                            }
                        }
                    }
                }
            }
            else
            {
                // check for moving the point
                Texture2D tex = null;
                if (Event.current.control)
                {
                    tex = isSelected ? texDotSelectedSnap : texDotSnap;
                }
                else
                {
                    tex = isSelected ? texDotSelected : texDot;
                }

                if (IsVisible(posOff))
                {
                    SetScale(posOff, texMinus, ref iconStyle);
                    Handles.Label(posOff, new GUIContent(tex), iconStyle);
                }
                Vector3 snap   = Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapRelative ? new Vector3(EditorPrefs.GetFloat("MoveSnapX"), EditorPrefs.GetFloat("MoveSnapY"), EditorPrefs.GetFloat("MoveSnapZ")) : Vector3.zero;
                Vector3 result = Handles.FreeMoveHandle(
                    posOff,
                    SceneView.lastActiveSceneView.camera.transform.rotation,
                    HandleScale(pos + offset),
                    snap,
                    Handles.CircleCap);

                if (result != posOff)
                {
                    if (selectedPoints != null)
                    {
                        if (selectedPoints.Count < 2 || isSelected == false)
                        {
                            selectedPoints.Clear();
                            selectedPoints.Add(i);
                            isSelected = true;
                        }
                    }

                    if (!(Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapRelative))
                    {
                        result = GetRealPoint(result, path.transform.position.z);
                    }
                    Vector3 global = (result - offset);
                    if (Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapGlobal)
                    {
                        global = SnapVector(global);
                    }
                    Vector3 local = inv * (global - path.transform.position);
                    if (Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapLocal)
                    {
                        local = SnapVector(local);
                    }
                    if (!Event.current.control && Ferr2DT_SceneOverlay.smartSnap && selectedPoints != null)
                    {
                        local = SmartSnap(local, path.pathVerts, selectedPoints, Ferr_Menu.SmartSnapDist);
                    }

                    Vector2 relative = new Vector2(
                        local.x / path.transform.localScale.x,
                        local.y / path.transform.localScale.y) - path.pathVerts[i];
                    if (selectedPoints != null)
                    {
                        for (int s = 0; s < selectedPoints.Count; s++)
                        {
                            path.pathVerts[selectedPoints[s]] += relative;
                        }
                    }
                }

                // if using terrain, check to see for any edge overrides
                if (Ferr2DT_SceneOverlay.showIndices)
                {
                    Vector3 labelPos = posOff + (Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed);
                    Handles.color = Color.white;
                    Handles.Label(labelPos, "" + i);
                    Handles.color = new Color(1, 1, 1, 0);
                }

                if (terrain)
                {// && i+1 < path.pathVerts.Count) {
                    float   scale     = HandleScale(pos + offset) * 0.5f;
                    Vector3 dirOff    = GetTickerOffset(path, pos, i);
                    Vector3 posDirOff = posOff + dirOff;

                    if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override && i + 1 < path.pathVerts.Count)
                    {
                        if (IsVisible(posDirOff))
                        {
                            SetScale(posDirOff, texMinus, ref iconStyle, 0.5f);
                            Handles.Label(posDirOff, new GUIContent(Event.current.alt ? texReset : GetDirIcon(terrain.directionOverrides[i])), iconStyle);

                            if (Handles.Button(posDirOff, SceneView.lastActiveSceneView.camera.transform.rotation, scale, scale, Handles.CircleCap) && selectedPoints != null)
                            {
                                if (selectedPoints.Count < 2 || isSelected == false)
                                {
                                    selectedPoints.Clear();
                                    selectedPoints.Add(i);
                                    isSelected = true;
                                }

                                Ferr2DT_TerrainDirection dir = NextDir(terrain.directionOverrides[i]);
                                for (int s = 0; s < selectedPoints.Count; s++)
                                {
                                    terrain.directionOverrides[selectedPoints[s]] = dir;
                                }
                                GUI.changed = true;
                            }
                        }
                    }
                    else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale)
                    {
                        if (IsVisible(posDirOff))
                        {
                            SetScale(posDirOff, texMinus, ref iconStyle, 0.5f);
                            Handles.Label(posDirOff, new GUIContent(Event.current.alt ? texReset : texScale), iconStyle);

                            Vector3 scaleMove = Handles.FreeMoveHandle(posDirOff, SceneView.lastActiveSceneView.camera.transform.rotation, scale, Vector3.zero, Handles.CircleCap);
                            float   scaleAmt  = scaleMove.y - posDirOff.y;
                            if (Mathf.Abs(scaleAmt) > 0.01f)
                            {
                                if (selectedPoints != null && selectedPoints.Count < 2 || isSelected == false)
                                {
                                    selectedPoints.Clear();
                                    selectedPoints.Add(i);
                                    isSelected = true;
                                }

                                float vertScale = terrain.vertScales[i] - Event.current.delta.y / 100f;
                                vertScale = Mathf.Clamp(vertScale, 0.2f, 3f);
                                if (selectedPoints != null)
                                {
                                    for (int s = 0; s < selectedPoints.Count; s++)
                                    {
                                        terrain.vertScales[selectedPoints[s]] = vertScale;
                                    }
                                }
                                GUI.changed = true;
                            }
                        }
                    }
                }

                // make sure we can add new point at the midpoints!
                if (i + 1 < path.pathVerts.Count || path.closed == true)
                {
                    int     index       = path.closed && i + 1 == path.pathVerts.Count ? 0 : i + 1;
                    Vector3 pos2        = path.transform.position + path.transform.rotation * Vector3.Scale(new Vector3(path.pathVerts[index].x, path.pathVerts[index].y, 0), path.transform.localScale);
                    Vector3 mid         = (pos + pos2) / 2;
                    float   handleScale = HandleScale(mid + offset);

                    if (Handles.Button(mid + offset, SceneView.lastActiveSceneView.camera.transform.rotation, handleScale, handleScale, Handles.CircleCap))
                    {
                        Vector2 pt = inv * new Vector2((mid.x - path.transform.position.x) / path.transform.localScale.x, (mid.y - path.transform.position.y) / path.transform.localScale.y);
                        if (terrain)
                        {
                            terrain.AddPoint(pt, index);
                        }
                        else
                        {
                            path.pathVerts.Insert(index, pt);
                        }
                    }
                    if (IsVisible(mid + offset))
                    {
                        SetScale(mid + offset, texDotPlus, ref iconStyle);
                        Handles.Label(mid + offset, new GUIContent(texDotPlus), iconStyle);
                    }
                }
            }
        }

        if (selectedPoints != null && Event.current.type == EventType.keyDown && Event.current.keyCode == KeyCode.Delete && selectedPoints.Count > 0)
        {
            for (int s = 0; s < selectedPoints.Count; s++)
            {
                if (terrain)
                {
                    terrain.RemovePoint(selectedPoints[s]);
                }
                else
                {
                    path.pathVerts.RemoveAt(selectedPoints[s]);
                }

                for (int u = 0; u < selectedPoints.Count; u++)
                {
                    if (selectedPoints[u] > selectedPoints[s])
                    {
                        selectedPoints[u] -= 1;
                    }
                }
            }
            selectedPoints.Clear();
            GUI.changed = true;
            Event.current.Use();
        }
    }
    private void    DoHandles(Ferr2D_Path path, GUIStyle iconStyle)
    {
        Vector3             snap         = Event.current.control ? new Vector3(EditorPrefs.GetFloat("MoveSnapX"), EditorPrefs.GetFloat("MoveSnapY"), EditorPrefs.GetFloat("MoveSnapZ")) : Vector3.zero;
        Transform           transform    = path.transform;
        Matrix4x4           mat          = transform.localToWorldMatrix;
        Matrix4x4           invMat       = transform.worldToLocalMatrix;
        Transform           camTransform = SceneView.lastActiveSceneView.camera.transform;
        Ferr2DT_PathTerrain terrain      = path.GetComponent <Ferr2DT_PathTerrain>();

        if (terrain)
        {
            terrain.MatchOverrides();
        }

        Handles.color = new Color(1, 1, 1, 1);
        for (int i = 0; i < path.pathVerts.Count; i++)
        {
            Vector3 pos        = mat.MultiplyPoint3x4(path.pathVerts[i]);
            Vector3 posStart   = pos;
            bool    isSelected = false;
            if (selectedPoints != null)
            {
                isSelected = selectedPoints.Contains(i);
            }

            // check if we want to remove points
            if (Event.current.alt)
            {
                float handleScale           = HandleScale(posStart);
                Handles.DrawCapFunction cap = (isSelected || selectedPoints.Count <= 0) ? (Handles.DrawCapFunction)CapDotMinusSelected : (Handles.DrawCapFunction)CapDotMinus;
                if (Handles.Button(posStart, camTransform.rotation, handleScale, handleScale, cap))
                {
                    if (!isSelected)
                    {
                        selectedPoints.Clear();
                        selectedPoints.Add(i);
                    }
                    for (int s = 0; s < selectedPoints.Count; s++)
                    {
                        if (terrain)
                        {
                            terrain.RemovePoint(selectedPoints[s]);
                        }
                        else
                        {
                            path.pathVerts.RemoveAt(selectedPoints[s]);
                        }
                        if (selectedPoints[s] <= i)
                        {
                            i--;
                        }

                        for (int u = 0; u < selectedPoints.Count; u++)
                        {
                            if (selectedPoints[u] > selectedPoints[s])
                            {
                                selectedPoints[u] -= 1;
                            }
                        }
                    }
                    selectedPoints.Clear();
                    GUI.changed = true;
                }
                else if (Ferr2DT_SceneOverlay.editMode != Ferr2DT_EditMode.None)
                {
                    if (terrain && i + 1 < path.pathVerts.Count)
                    {
                        float   scale     = handleScale * 0.5f;
                        Vector3 dirOff    = GetTickerOffset(path, pos, i);
                        Vector3 posDirOff = posStart + dirOff;

                        if (IsVisible(posDirOff))
                        {
                            cap = null;
                            if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override)
                            {
                                cap = GetDirIcon(terrain.directionOverrides[i]);
                            }
                            else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale)
                            {
                                cap = CapDotScale;
                            }
                            if (Event.current.alt)
                            {
                                cap = CapDotReset;
                            }

                            if (Handles.Button(posDirOff, camTransform.rotation, scale, scale, cap))
                            {
                                if (selectedPoints.Count < 2 || isSelected == false)
                                {
                                    selectedPoints.Clear();
                                    selectedPoints.Add(i);
                                    isSelected = true;
                                }

                                for (int s = 0; s < selectedPoints.Count; s++)
                                {
                                    if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override)
                                    {
                                        terrain.directionOverrides[selectedPoints[s]] = Ferr2DT_TerrainDirection.None;
                                    }
                                    else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale)
                                    {
                                        terrain.vertScales        [selectedPoints[s]] = 1;
                                    }
                                }
                                GUI.changed = true;
                            }
                        }
                    }
                }
            }
            else
            {
                // check for moving the point
                Handles.DrawCapFunction cap = CapDot;
                if (Event.current.control)
                {
                    cap = isSelected ? (Handles.DrawCapFunction)CapDotSelectedSnap : (Handles.DrawCapFunction)CapDotSnap;
                }
                else
                {
                    cap = isSelected ? (Handles.DrawCapFunction)CapDotSelected     : (Handles.DrawCapFunction)CapDot;
                }

                Vector3 result = Handles.FreeMoveHandle(
                    posStart,
                    camTransform.rotation,
                    HandleScale(pos),
                    snap,
                    cap);

                if (result != posStart)
                {
                    if (selectedPoints.Count < 2 || isSelected == false)
                    {
                        selectedPoints.Clear();
                        selectedPoints.Add(i);
                        isSelected = true;
                    }

                    if (!(Event.current.control && Ferr2DT_Menu.SnapMode == Ferr2DT_Menu.SnapType.SnapRelative))
                    {
                        result = GetRealPoint(result, transform);
                    }

                    Vector3 global = result;
                    if (Event.current.control && Ferr2DT_Menu.SnapMode == Ferr2DT_Menu.SnapType.SnapGlobal)
                    {
                        global = SnapVector(global, snap);
                    }
                    Vector3 local = invMat.MultiplyPoint3x4(global);
                    if (Event.current.control && Ferr2DT_Menu.SnapMode == Ferr2DT_Menu.SnapType.SnapLocal)
                    {
                        local = SnapVector(local, snap);
                    }
                    if (!Event.current.control && Ferr2DT_SceneOverlay.smartSnap)
                    {
                        local = SmartSnap(local, path.pathVerts, selectedPoints, Ferr2DT_Menu.SmartSnapDist);
                    }

                    Vector2 relative = new Vector2(local.x, local.y) - path.pathVerts[i];

                    for (int s = 0; s < selectedPoints.Count; s++)
                    {
                        path.pathVerts[selectedPoints[s]] += relative;
                    }
                }

                // if using terrain, check to see for any edge overrides
                if (Ferr2DT_SceneOverlay.showIndices)
                {
                    Vector3 labelPos = posStart + (Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed);
                    Handles.color = Color.white;
                    Handles.Label(labelPos, "" + i);
                    Handles.color = new Color(1, 1, 1, 0);
                }

                if (terrain)
                {
                    float   scale     = HandleScale(pos) * 0.5f;
                    Vector3 dirOff    = GetTickerOffset(path, pos, i);
                    Vector3 posDirOff = posStart + dirOff;

                    if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override && i + 1 < path.pathVerts.Count)
                    {
                        if (IsVisible(posDirOff) && terrain.directionOverrides != null)
                        {
                            cap = Event.current.alt ? (Handles.DrawCapFunction)CapDotReset : GetDirIcon(terrain.directionOverrides[i]);
                            if (Handles.Button(posDirOff, camTransform.rotation, scale, scale, cap))
                            {
                                if (selectedPoints.Count < 2 || isSelected == false)
                                {
                                    selectedPoints.Clear();
                                    selectedPoints.Add(i);
                                    isSelected = true;
                                }

                                Ferr2DT_TerrainDirection dir = NextDir(terrain.directionOverrides[i]);
                                for (int s = 0; s < selectedPoints.Count; s++)
                                {
                                    terrain.directionOverrides[selectedPoints[s]] = dir;
                                }
                                GUI.changed = true;
                            }
                        }
                    }
                    else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale)
                    {
                        if (IsVisible(posDirOff))
                        {
                            cap = Event.current.alt ? (Handles.DrawCapFunction)CapDotReset : (Handles.DrawCapFunction)CapDotScale;

                            Vector3 scaleMove = Handles.FreeMoveHandle(posDirOff, camTransform.rotation, scale, Vector3.zero, cap);
                            float   scaleAmt  = scaleMove.y - posDirOff.y;
                            if (Mathf.Abs(scaleAmt) > 0.01f)
                            {
                                if (selectedPoints.Count < 2 || isSelected == false)
                                {
                                    selectedPoints.Clear();
                                    selectedPoints.Add(i);
                                    isSelected = true;
                                }

                                float vertScale = terrain.vertScales[i] - Event.current.delta.y / 100f;
                                vertScale = Mathf.Clamp(vertScale, 0.2f, 3f);
                                for (int s = 0; s < selectedPoints.Count; s++)
                                {
                                    terrain.vertScales[selectedPoints[s]] = vertScale;
                                }
                                GUI.changed = true;
                            }
                        }
                    }
                }

                // make sure we can add new point at the midpoints!
                if (i + 1 < path.pathVerts.Count || path.closed == true)
                {
                    int     index       = path.closed && i + 1 == path.pathVerts.Count ? 0 : i + 1;
                    Vector3 pos2        = mat.MultiplyPoint3x4(path.pathVerts[index]);
                    Vector3 mid         = (pos + pos2) / 2;
                    float   handleScale = HandleScale(mid);

                    if (Handles.Button(mid, camTransform.rotation, handleScale, handleScale, CapDotPlus))
                    {
                        Vector2 pt = invMat.MultiplyPoint3x4(mid);
                        if (terrain)
                        {
                            terrain.AddPoint(pt, index);
                        }
                        else
                        {
                            path.pathVerts.Insert(index, pt);
                        }
                    }
                }
            }
        }

        if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Delete && selectedPoints.Count > 0)
        {
            for (int s = 0; s < selectedPoints.Count; s++)
            {
                if (terrain)
                {
                    terrain.RemovePoint(selectedPoints[s]);
                }
                else
                {
                    path.pathVerts.RemoveAt(selectedPoints[s]);
                }

                for (int u = 0; u < selectedPoints.Count; u++)
                {
                    if (selectedPoints[u] > selectedPoints[s])
                    {
                        selectedPoints[u] -= 1;
                    }
                }
            }
            selectedPoints.Clear();
            GUI.changed = true;
            Event.current.Use();
        }
    }
Esempio n. 9
0
    private void AddCap(List <Vector2> aSegment, Ferr2DT_SegmentDescription aDesc, bool aInner, float aDir, float aScale, bool aSmooth)
    {
        int     index = 0;
        Vector2 dir   = Vector2.zero;

        if (aDir < 0)
        {
            index = 0;
            dir   = aSegment[0] - aSegment[1];
        }
        else
        {
            index = aSegment.Count - 1;
            dir   = aSegment[aSegment.Count - 1] - aSegment[aSegment.Count - 2];
        }
        dir.Normalize();
        Vector2 norm = aSmooth ? Ferr2D_Path.HermiteGetNormal(aSegment, index, 0, false): Ferr2D_Path.GetNormal(aSegment, index, false);
        Vector2 pos  = aSegment[index];
        float   yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;
        Rect    cap;

        if (aDir < 0)
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerRightCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerRightCap) : terrainMaterial.ToUV(aDesc.rightCap);
            }
            else
            {
                cap = (aInner && aDesc.innerLeftCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerLeftCap) : terrainMaterial.ToUV(aDesc.leftCap);
            }
        }
        else
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerLeftCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerLeftCap) : terrainMaterial.ToUV(aDesc.leftCap);
            }
            else
            {
                cap = (aInner && aDesc.innerRightCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerRightCap) : terrainMaterial.ToUV(aDesc.rightCap);
            }
        }

        float width = cap.width * unitsPerUV.x;
        float scale = (cap.height / 2) * unitsPerUV.y * aScale;

        float minU = fill == Ferr2DT_FillMode.InvertedClosed ? cap.xMax : cap.x;
        float maxU = fill == Ferr2DT_FillMode.InvertedClosed ? cap.x    : cap.xMax;
        float minV = fill == Ferr2DT_FillMode.InvertedClosed ? cap.yMax : cap.y;
        float maxV = fill == Ferr2DT_FillMode.InvertedClosed ? cap.y    : cap.yMax;

        if (aDir >= 0)
        {
            float t = minU;
            minU = maxU;
            maxU = t;
        }

        int v1 = DMesh.AddVertex(pos + dir * width + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(minU, minV));
        int v2 = DMesh.AddVertex(pos + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(maxU, minV));

        int v15 = splitMiddle ? DMesh.AddVertex(pos + dir * width + (norm * yOff), aDesc.zOffset, new Vector2(minU, cap.y + (cap.height / 2))) : -1;
        int v25 = splitMiddle ? DMesh.AddVertex(pos + (norm * yOff), aDesc.zOffset, new Vector2(maxU, cap.y + (cap.height / 2))) : -1;

        int v3 = DMesh.AddVertex(pos - norm * (scale - yOff), slantAmount + aDesc.zOffset, new Vector2(maxU, maxV));
        int v4 = DMesh.AddVertex(pos + dir * width - norm * (scale - yOff), slantAmount + aDesc.zOffset, new Vector2(minU, maxV));

        if (splitMiddle && aDir < 0)
        {
            DMesh.AddFace(v1, v2, v25, v15);
            DMesh.AddFace(v15, v25, v3, v4);
        }
        else if (splitMiddle && aDir >= 0)
        {
            DMesh.AddFace(v2, v1, v15, v25);
            DMesh.AddFace(v25, v15, v4, v3);
        }
        else if (aDir < 0)
        {
            DMesh.AddFace(v1, v2, v3, v4);
        }
        else
        {
            DMesh.AddFace(v2, v1, v4, v3);
        }
    }
Esempio n. 10
0
    private void SlicedQuad(List <Vector2> aSegment, int aVert, float aStart, float aEnd, int aCuts, bool aSmoothed, bool aClosed, Ferr2DT_SegmentDescription aDesc, float aStartScale, float aEndScale)
    {
        Vector2[] pos    = new Vector2[aCuts];
        Vector2[] norm   = new Vector2[aCuts];
        float  [] scales = new float  [aCuts];
        Vector3   tn1    = Ferr2D_Path.GetNormal(aSegment, aVert, aClosed);
        Vector3   tn2    = Ferr2D_Path.GetNormal(aSegment, aVert + 1, aClosed);

        // get the data needed to make the quad
        for (int i = 0; i < aCuts; i++)
        {
            float percent = aStart + (i / (float)(aCuts - 1)) * (aEnd - aStart);
            if (aSmoothed)
            {
                pos [i] = Ferr2D_Path.HermiteGetPt(aSegment, aVert, percent, aClosed);
                norm[i] = Ferr2D_Path.HermiteGetNormal(aSegment, aVert, percent, aClosed);
            }
            else
            {
                pos [i] = Vector2.Lerp(aSegment[aVert], aSegment[aVert + 1], percent);
                norm[i] = Vector2.Lerp(tn1, tn2, percent);
            }
            scales[i] = Mathf.Lerp(aStartScale, aEndScale, (i / (float)(aCuts - 1)));
        }

        int tSeed = 0;

        if (randomByWorldCoordinates)
        {
            tSeed = UnityEngine.Random.seed;
            UnityEngine.Random.seed = (int)(pos[0].x * 700000 + pos[0].y * 30000);
        }

        Rect  body = terrainMaterial.ToUV(aDesc.body[UnityEngine.Random.Range(0, aDesc.body.Length)]);
        float d    = (body.height / 2) * unitsPerUV.y;
        float yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;

        if (randomByWorldCoordinates)
        {
            UnityEngine.Random.seed = tSeed;
        }

        // put the data together into a mesh
        int p1 = 0, p2 = 0, p3 = 0;

        for (int i = 0; i < aCuts; i++)
        {
            float percent = (i / (float)(aCuts - 1));

            Vector3 pos1 = pos [i];
            Vector3 n1   = norm[i];
            int     v1   = DMesh.AddVertex(pos1.x + n1.x * (d * scales[i] + yOff), pos1.y + n1.y * (d * scales[i] + yOff), -slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, percent), fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
            int     v2   = DMesh.AddVertex(pos1.x - n1.x * (d * scales[i] - yOff), pos1.y - n1.y * (d * scales[i] - yOff), slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, percent), fill == Ferr2DT_FillMode.InvertedClosed ? body.y    : body.yMax);
            int     v3   = splitMiddle ? DMesh.AddVertex(pos1.x + n1.x * yOff, pos1.y + n1.y * yOff, aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, percent), Mathf.Lerp(body.y, body.yMax, 0.5f)) : -1;

            if (i != 0)
            {
                if (!splitMiddle)
                {
                    DMesh.AddFace(v2, p2, p1, v1);
                }
                else
                {
                    DMesh.AddFace(v2, p2, p3, v3);
                    DMesh.AddFace(v3, p3, p1, v1);
                }
            }

            p1 = v1;
            p2 = v2;
            p3 = v3;
        }
    }
Esempio n. 11
0
    List <Vector2> OffsetColliderVerts(List <Vector2> aSegment, List <float> aSegmentScales, Ferr2DT_TerrainDirection aDir)
    {
        List <Vector2> result = new List <Vector2>(aSegment);
        int            count  = aSegment.Count;

        for (int v = count - 1; v >= 0; v--)
        {
            Vector2 norm  = smoothPath ? Ferr2D_Path.HermiteGetNormal(aSegment, v, 0, false) : Ferr2D_Path.GetNormal(aSegment, v, false);
            float   scale = v >= aSegmentScales.Count ? 1 : aSegmentScales[v];
            if (fill == Ferr2DT_FillMode.None)
            {
                result.Add(aSegment[v] + new Vector2(norm.x * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top], norm.y * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top]) * scale);
                result[v] += new Vector2(norm.x * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom], norm.y * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom]) * scale;
            }
            else
            {
                float   dist   = surfaceOffset[(int)aDir];
                Vector2 offset = new Vector2(dist, dist);
                result[v] += new Vector2(norm.x * -offset.x, norm.y * -offset.y) * scale;
            }
        }
        return(result);
    }
    private List <Vector2> LegacyOffsetColliderVerts(List <Vector2> aSegment, List <float> aSegmentScales, Ferr2DT_TerrainDirection aDir)
    {
        List <Vector2> result = new List <Vector2>(aSegment);
        int            count  = aSegment.Count;

        for (int v = count - 1; v >= 0; v--)
        {
            Vector2 norm      = smoothPath ? Ferr2D_Path.HermiteGetNormal(aSegment, v, 0, false) : Ferr2D_Path.GetNormal(aSegment, v, false);
            Vector2 segNormal = Ferr2D_Path.GetSegmentNormal(v, aSegment, false);
            float   scale     = v >= aSegmentScales.Count ? 1 : aSegmentScales[v];
            float   rootScale = smoothPath ? 1 : 1f / Mathf.Abs(Mathf.Cos(Vector2.Angle(-segNormal, norm) * Mathf.Deg2Rad));
            scale = scale * rootScale;

            if (fill == Ferr2DT_FillMode.None)
            {
                result.Add(aSegment[v] + new Vector2(norm.x * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top], norm.y * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top]) * scale);
                result[v] += new Vector2(norm.x * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom], norm.y * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom]) * scale;
            }
            else
            {
                float   dist   = surfaceOffset[(int)aDir];
                Vector2 offset = new Vector2(dist, dist);
                result[v] += new Vector2(norm.x * -offset.x, norm.y * -offset.y) * scale;
            }
        }
        return(result);
    }
    void OnSceneGUI()
    {
        Ferr2DT_PathTerrain collider = (Ferr2DT_PathTerrain)target;
        Ferr2D_Path         path     = collider.gameObject.GetComponent <Ferr2D_Path>();

        EditorUtility.SetSelectedWireframeHidden(collider.gameObject.renderer, Ferr_Menu.HideMeshes);

        if (collider.enabled == false || path == null || path.pathVerts.Count <= 1 || !collider.createCollider)
        {
            return;
        }

        Handles.color = new Color(0, 1, 0, 1);

        List <Vector2> verts = path.GetVerts(collider.smoothPath, collider.splitDist, collider.splitCorners);

        if (path.closed && collider.smoothPath == false)
        {
            verts.Add(verts[0]);
        }

        Vector2 norm      = Ferr2D_Path.GetNormal(verts, 0, path.closed);
        Vector2 tmp       = Vector2.zero;
        Vector2 tmpBottom = Vector2.zero;

        if (collider.fill == Ferr2DT_FillMode.None)
        {
            tmp       = verts[0] + new Vector2(norm.x * -collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Top], norm.y * -collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Top]);
            tmpBottom = verts[0] + new Vector2(norm.x * collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom], norm.y * collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom]);
        }
        else
        {
            Vector2 offset = collider.GetOffset(path.pathVerts, 0, path.closed);
            tmp = verts[0] + new Vector2(norm.x * -offset.x, norm.y * -offset.y);
        }
        Vector3 startPos   = path.gameObject.transform.position + Ferr2D_PathEditor.offset + Vector3.Scale(new Vector3(tmp.x, tmp.y, 0), path.transform.localScale);
        Vector3 currBottom = path.gameObject.transform.position + Ferr2D_PathEditor.offset + Vector3.Scale(new Vector3(tmpBottom.x, tmpBottom.y, 0), path.transform.localScale);
        Vector3 curr       = startPos;

        if (collider.fill == Ferr2DT_FillMode.None)
        {
            Handles.DrawLine(curr, currBottom);
        }
        for (int i = 0; i < verts.Count - 1; i++)
        {
            norm = Ferr2D_Path.GetNormal(verts, i + 1, path.closed);
            if (collider.fill == Ferr2DT_FillMode.None)
            {
                tmp       = verts[i + 1] + new Vector2(norm.x * -collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Top], norm.y * -collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Top]);
                tmpBottom = verts[i + 1] + new Vector2(norm.x * collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom], norm.y * collider.surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom]);
                Vector3 pos       = path.gameObject.transform.position + Ferr2D_PathEditor.offset + Vector3.Scale(new Vector3(tmp.x, tmp.y, 0), path.transform.localScale);
                Vector3 posBottom = path.gameObject.transform.position + Ferr2D_PathEditor.offset + Vector3.Scale(new Vector3(tmpBottom.x, tmpBottom.y, 0), path.transform.localScale);

                if (ColliderNormValid(collider, verts[i], verts[i + 1]))
                {
                    Handles.DrawLine(curr, pos);
                }
                if (ColliderNormValid(collider, verts[i + 1], verts[i]))
                {
                    Handles.DrawLine(currBottom, posBottom);
                }
                curr       = pos;
                currBottom = posBottom;
            }
            else
            {
                Vector2 offset = collider.GetOffset(verts, i + 1, path.closed);
                tmp = verts[i + 1] + new Vector2(norm.x * -offset.x, norm.y * -offset.y);
                Vector3 pos = path.gameObject.transform.position + Ferr2D_PathEditor.offset + Vector3.Scale(new Vector3(tmp.x, tmp.y, 0), path.transform.localScale);
                if (i + 1 == verts.Count - 1 && path.closed)
                {
                    pos = startPos;
                }
                if (ColliderNormValid(collider, verts[i], verts[i + 1]))
                {
                    Handles.DrawLine(curr, pos);
                }
                curr = pos;
            }
        }
        if (collider.fill == Ferr2DT_FillMode.None)
        {
            Handles.DrawLine(curr, currBottom);
        }

        if (collider.fill == Ferr2DT_FillMode.Skirt || collider.fill == Ferr2DT_FillMode.FillOnlySkirt)
        {
            Vector3 start      = startPos;
            Vector3 end        = curr;
            Vector3 skirtStart = new Vector3(start.x, collider.transform.position.y + collider.fillY, start.z);
            Vector3 skirtEnd   = new Vector3(end.x, collider.transform.position.y + collider.fillY, end.z);
            Handles.DrawLine(start, skirtStart);
            Handles.DrawLine(skirtStart, skirtEnd);
            Handles.DrawLine(skirtEnd, end);
        }
    }