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; }
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; }