private void LegacyCreateBody(Ferr2DT_SegmentDescription aDesc, List <Vector2> aSegment, List <float> aSegmentScale, List <CutOverrides> aCutOverrides, float aBodyWidth, int aTextureSlices, bool aClosed)
    {
        float distance    = Ferr2D_Path.GetSegmentLength(aSegment);
        int   textureCuts = Mathf.Max(1, Mathf.FloorToInt(distance / aBodyWidth + 0.5f));

        Ferr2D_DynamicMesh mesh = DMesh;

        Rect  body = LegacyPickBody(aDesc, aCutOverrides, aSegment[0], 0, 0);
        float d    = (body.height / 2) * unitsPerUV.y;
        float yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;

        int p1 = 0, p2 = 0, p3 = 0;
        int pIndex   = 0;
        int cutIndex = 0;

        // loop for each instance of the texture
        for (int t = 0; t < textureCuts; t++)
        {
            float texPercent     = (t / (float)(textureCuts));
            float texPercentStep = (1f / (float)(textureCuts));

            // slice each texture chunk a number of times
            for (int i = 0; i < aTextureSlices; i++)
            {
                float slicePercent = (i / (float)(aTextureSlices - 1));
                float totalPercent = texPercent + slicePercent * texPercentStep;

                int   ptLocal  = 0;
                float pctLocal = 0;
                Ferr2D_Path.PathGlobalPercentToLocal(aSegment, totalPercent, out ptLocal, out pctLocal, distance, aClosed);

                // if we skip over path points, we need to add slices at each path point to prevent the mesh from bypassing it.
                for (int extra = 0; extra < ptLocal - pIndex; extra++)
                {
                    float traveledDist = Ferr2D_Path.GetSegmentLengthToIndex(aSegment, pIndex + extra + 1);
                    float v            = (traveledDist / distance) * textureCuts;
                    v = v - (int)v;
                    LegacyAddVertexColumn(aDesc, aSegment, aSegmentScale, aClosed, mesh, body, d, yOff, i != 0, v, pIndex + extra + 1, 0, ref p1, ref p2, ref p3);
                    cutIndex = -1;
                }
                pIndex = ptLocal;

                LegacyAddVertexColumn(aDesc, aSegment, aSegmentScale, aClosed, mesh, body, d, yOff, i != 0, slicePercent, ptLocal, pctLocal, ref p1, ref p2, ref p3);
            }

            cutIndex += 1;
            body      = LegacyPickBody(aDesc, aCutOverrides, mesh.GetVert(p2), pIndex, cutIndex);
        }
    }
Beispiel #2
0
    private void DoCutOverrideModeHandles(Ferr2D_Path path, Ferr2DT_PathTerrain terrain, Matrix4x4 mat, Transform camTransform)
    {
        List <List <int>               > segments = new List <List <int>               >();
        List <Ferr2DT_TerrainDirection>  dirs     = new List <Ferr2DT_TerrainDirection>();
        List <Vector2> rawVerts = path.GetVertsRaw();

        // cut the terrain into segments, we need segment info to draw these points
        segments = terrain.GetSegments(rawVerts, out dirs);

        for (int s = 0; s < segments.Count; s++)
        {
            List <int>     currSeg   = segments[s];
            List <Vector2> currVerts = Ferr2D_Path.IndicesToList(rawVerts, currSeg);
            List <Ferr2DT_PathTerrain.CutOverrides> overrides = Ferr2D_Path.IndicesToList(terrain.cutOverrides, currSeg);

            // find information about this segment
            Ferr2DT_TerrainDirection   currDir = dirs[s];
            Ferr2DT_SegmentDescription desc    = default(Ferr2DT_SegmentDescription);

            if (currDir != Ferr2DT_TerrainDirection.None)
            {
                desc = terrain.TerrainMaterial.GetDescriptor(currDir);
            }
            else
            {
                desc = terrain.GetDescription(currSeg);
            }

            // if there's no body segment choices, don't bother with the rest of this
            if (desc.body.Length < 2)
            {
                continue;
            }

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

            float distance = Ferr2D_Path.GetSegmentLength(currVerts);

            // how many texture cuts are there on the segment
            float bodyWidth   = desc.body[0].width * (terrain.TerrainMaterial.edgeMaterial.mainTexture.width / terrain.pixelsPerUnit);
            int   textureCuts = Mathf.Max(1, Mathf.FloorToInt(distance / bodyWidth + 0.5f));

            // data is attached to the points still, check if we've switched to a new point
            int activePt       = -1;
            int activeLocalCut = -1;
            for (int c = 0; c < textureCuts; c++)
            {
                float pctGlobal = c / (float)textureCuts;

                int   ptLocal  = 0;
                float pctLocal = 0;
                Ferr2D_Path.PathGlobalPercentToLocal(currVerts, pctGlobal, out ptLocal, out pctLocal, distance, false);

                if (ptLocal != activePt)
                {
                    // if they size down, we need to shorten the data too
                    if (activePt != -1)
                    {
                        CapListSize <int>(ref overrides[activePt].data, activeLocalCut + 3);
                    }
                    activePt       = ptLocal;
                    activeLocalCut = 0;

                    if (overrides[activePt].data == null)
                    {
                        overrides[activePt].data = new List <int>();
                    }
                }

                while (activeLocalCut >= overrides[activePt].data.Count)
                {
                    overrides[activePt].data.Add(0);
                }

                CapFunction cap            = CapDotAuto;
                int         activeOverride = overrides[activePt].data[activeLocalCut];
                if (activeOverride != 0)
                {
                    if (activeOverride == 1)
                    {
                        cap = CapDot1;
                    }
                    else if (activeOverride == 2)
                    {
                        cap = CapDot2;
                    }
                    else if (activeOverride == 3)
                    {
                        cap = CapDot3;
                    }
                    else if (activeOverride == 4)
                    {
                        cap = CapDot4;
                    }
                    else if (activeOverride == 5)
                    {
                        cap = CapDot5;
                    }
                    else if (activeOverride >= 6)
                    {
                        cap = CapDotN;
                    }
                }
                if (Event.current.alt)
                {
                    cap = CapDotReset;
                }

                int   ptShow  = 0;
                float pctShow = 0;
                Ferr2D_Path.PathGlobalPercentToLocal(currVerts, pctGlobal + (1f / textureCuts) * 0.5f, out ptShow, out pctShow, distance, false);

                Vector2 pt  = Ferr2D_Path.LinearGetPt(currVerts, ptShow, pctShow, false);
                Vector3 pos = mat.MultiplyPoint3x4(pt);
                float   sc  = HandleScale(pos) * 0.5f;
                if (Handles.Button(pos, camTransform.rotation, sc, sc, cap))
                {
                    Undo.RecordObject(terrain, "Lock Texture Segment");

                    overrides[activePt].data[activeLocalCut] = Event.current.alt ? 0 : (activeOverride + 1) % (desc.body.Length + 1);
                    EditorUtility.SetDirty(terrain);
                    GUI.changed = true;
                }

                activeLocalCut += 1;
            }
            if (activePt != -1)
            {
                CapListSize <int>(ref overrides[activePt].data, activeLocalCut + 3);
            }
        }
    }