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);
        }
    }
    private void                RecreateCollider3D()
    {
        Ferr2D_DynamicMesh     colMesh = new Ferr2D_DynamicMesh();
        List <List <Vector2> > verts   = GetColliderVerts();

        // create the solid mesh for it
        for (int t = 0; t < verts.Count; t++)
        {
            for (int i = 0; i < verts[t].Count; i++)
            {
                if (Path.closed && i == verts.Count - 1)
                {
                    colMesh.AddVertex(verts[t][0]);
                }
                else
                {
                    colMesh.AddVertex(verts[t][i]);
                }
            }
        }
        colMesh.ExtrudeZ(depth, fill == Ferr2DT_FillMode.InvertedClosed);

        // remove any faces the user may not want
        if (!collidersTop)
        {
            colMesh.RemoveFaces(new Vector3(0, 1, 0), 45);
        }
        if (!collidersLeft)
        {
            colMesh.RemoveFaces(new Vector3(-1, 0, 0), 45);
        }
        if (!collidersRight)
        {
            colMesh.RemoveFaces(new Vector3(1, 0, 0), 45);
        }
        if (!collidersBottom)
        {
            colMesh.RemoveFaces(new Vector3(0, -1, 0), 45);
        }

        // make sure there's a MeshCollider component on this object
        MeshCollider collider = GetComponent <MeshCollider>();

        if (collider == null)
        {
            collider = gameObject.AddComponent <MeshCollider>();
        }
        if (physicsMaterial != null)
        {
            collider.sharedMaterial = physicsMaterial;
        }
                #if !UNITY_5
        collider.smoothSphereCollisions = smoothSphereCollisions;
                #endif
        collider.isTrigger = isTrigger;

        // compile the mesh!
        Mesh   m    = collider.sharedMesh;
        string name = "Ferr2DT_PathCollider_" + gameObject.GetInstanceID();
        if (m == null || m.name != name)
        {
            collider.sharedMesh = m = new Mesh();
            m.name = name;
        }
        collider.sharedMesh = null;
        colMesh.Build(ref m, createTangents);
        collider.sharedMesh = m;
    }
Beispiel #3
0
    private void                RecreateCollider3D()
    {
		Ferr2D_DynamicMesh colMesh = new Ferr2D_DynamicMesh();
        List<List<Vector2>> verts = GetColliderVerts();

        // create the solid mesh for it
        for (int t = 0; t < verts.Count; t++) {
            for (int i = 0; i < verts[t].Count; i++) {
                if (Path.closed && i == verts.Count - 1) colMesh.AddVertex(verts[t][0]);
                else colMesh.AddVertex(verts[t][i]);
            }
        }
        colMesh.ExtrudeZ(depth, fill == Ferr2DT_FillMode.InvertedClosed);

        // remove any faces the user may not want
        if (!collidersTop   ) colMesh.RemoveFaces(new Vector3( 0, 1,0), 45);
        if (!collidersLeft  ) colMesh.RemoveFaces(new Vector3(-1, 0,0), 45);
        if (!collidersRight ) colMesh.RemoveFaces(new Vector3( 1, 0,0), 45);
        if (!collidersBottom) colMesh.RemoveFaces(new Vector3( 0,-1,0), 45);

        // make sure there's a MeshCollider component on this object
		MeshCollider collider = GetComponent<MeshCollider>();
        if (collider == null) {
            collider = gameObject.AddComponent<MeshCollider>();
        }
        if (physicsMaterial != null) collider.sharedMaterial = physicsMaterial;
		#if !UNITY_5
        collider.smoothSphereCollisions = smoothSphereCollisions;
		#endif
        collider.isTrigger              = isTrigger;

        // compile the mesh!
        Mesh   m    = collider.sharedMesh;
        string name = "Ferr2DT_PathCollider_" + gameObject.GetInstanceID();
        if (m == null || m.name != name) {
            collider.sharedMesh = m = new Mesh();
            m.name = name;
        }
        collider.sharedMesh = null;
        colMesh.Build(ref m, createTangents);
        collider.sharedMesh = m;
    }
    private void LegacyAddCap(List <Vector2> aSegment, Ferr2DT_SegmentDescription aDesc, bool aInner, float aDir, float aScale, bool aSmooth)
    {
        IFerr2DTMaterial   mat  = TerrainMaterial;
        Ferr2D_DynamicMesh mesh = DMesh;
        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) ? mat.ToUV(aDesc.innerRightCap) : mat.ToUV(aDesc.rightCap);
            }
            else
            {
                cap = (aInner && aDesc.innerLeftCap.width > 0) ? mat.ToUV(aDesc.innerLeftCap) : mat.ToUV(aDesc.leftCap);
            }
        }
        else
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerLeftCap.width > 0) ? mat.ToUV(aDesc.innerLeftCap) : mat.ToUV(aDesc.leftCap);
            }
            else
            {
                cap = (aInner && aDesc.innerRightCap.width > 0) ? mat.ToUV(aDesc.innerRightCap) : mat.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 = mesh.AddVertex(pos + dir * width + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(minU, minV));
        int v2 = mesh.AddVertex(pos + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(maxU, minV));

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

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

        if (splitMiddle && aDir < 0)
        {
            mesh.AddFace(v1, v2, v25, v15);
            mesh.AddFace(v15, v25, v3, v4);
        }
        else if (splitMiddle && aDir >= 0)
        {
            mesh.AddFace(v2, v1, v15, v25);
            mesh.AddFace(v25, v15, v4, v3);
        }
        else if (aDir < 0)
        {
            mesh.AddFace(v1, v2, v3, v4);
        }
        else
        {
            mesh.AddFace(v2, v1, v4, v3);
        }
    }
    private void LegacyAddVertexColumn(Ferr2DT_SegmentDescription aDesc, List <Vector2> aSegment, List <float> aSegmentScale, bool aClosed, Ferr2D_DynamicMesh mesh, Rect body, float d, float yOff, bool aConnectFace, float slicePercent, int ptLocal, float pctLocal, ref int p1, ref int p2, ref int p3)
    {
        Vector2 pos1 = smoothPath ? Ferr2D_Path.HermiteGetPt(aSegment, ptLocal, pctLocal, aClosed) : Ferr2D_Path.LinearGetPt(aSegment, ptLocal, pctLocal, aClosed);
        Vector2 n1   = smoothPath ? Ferr2D_Path.HermiteGetNormal(aSegment, ptLocal, pctLocal, aClosed) : Ferr2D_Path.LinearGetNormal(aSegment, ptLocal, pctLocal, aClosed);
        float   s    = aClosed    ? Mathf.Lerp(aSegmentScale[ptLocal], aSegmentScale[(ptLocal + 1) % aSegmentScale.Count], pctLocal) : Mathf.Lerp(aSegmentScale[ptLocal], aSegmentScale[Mathf.Min(ptLocal + 1, aSegmentScale.Count - 1)], pctLocal);

        // this compensates for scale distortion when corners are very sharp, but the normals are not long enough to keep the edge the appropriate width
        // not actually a problem for smooth paths
        if (!smoothPath)
        {
            n1.Normalize();
            float rootScale = 1f / Mathf.Abs(Mathf.Cos(Vector2.Angle(Ferr2D_Path.GetSegmentNormal(ptLocal, aSegment, aClosed), n1) * Mathf.Deg2Rad));
            s = s * rootScale;
        }

        int v1 = mesh.AddVertex(pos1.x + n1.x * (d * s + yOff), pos1.y + n1.y * (d * s + yOff), -slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, slicePercent), fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
        int v2 = mesh.AddVertex(pos1.x - n1.x * (d * s - yOff), pos1.y - n1.y * (d * s - yOff), slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, slicePercent), fill == Ferr2DT_FillMode.InvertedClosed ? body.y : body.yMax);
        int v3 = splitMiddle ? mesh.AddVertex(pos1.x + n1.x * yOff, pos1.y + n1.y * yOff, aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, slicePercent), Mathf.Lerp(body.y, body.yMax, 0.5f)) : -1;

        if (aConnectFace)
        {
            if (!splitMiddle)
            {
                mesh.AddFace(v2, p2, p1, v1);
            }
            else
            {
                mesh.AddFace(v2, p2, p3, v3);
                mesh.AddFace(v3, p3, p1, v1);
            }
        }

        p1 = v1;
        p2 = v2;
        p3 = v3;
    }