// we only need to build the savevertex and uvs if mesh def changes, else we can keep the uvs void BuildMesh() { if (!mesh) { mesh = GetComponent <MeshFilter>().sharedMesh; if (mesh == null) { updatemesh = true; return; } } if (hosespline.knots.Count == 0) { hosespline.AddKnot(Vector3.zero, Vector3.zero, Vector3.zero); hosespline.AddKnot(Vector3.zero, Vector3.zero, Vector3.zero); } FixHoseFillet(); bool createfree = freecreate; if ((!createfree) && ((!custnode) || (!custnode2))) { createfree = true; } if (custnode && custnode2) { createfree = false; } Matrix4x4 mat1, mat2; float Lf = 0.0f; Tlocal = Matrix4x4.identity; Vector3 startvec, endvec, startpoint, endpoint, endy; starty = Vector3.zero; roty = Vector3.zero; yangle = 0.0f; Vector3 RV = Vector3.zero; if (createfree) { Lf = noreflength; } else { RV = up; //new Vector3(xtmp, ytmp, ztmp); mat1 = custnode.transform.localToWorldMatrix; mat2 = custnode2.transform.localToWorldMatrix; Matrix4x4 mato1 = Matrix4x4.identity; Matrix4x4 mato2 = Matrix4x4.identity; mato1 = Matrix4x4.TRS(offset, Quaternion.Euler(rotate), scale); mato1 = mato1.inverse; mato2 = Matrix4x4.TRS(offset1, Quaternion.Euler(rotate1), scale1); mato2 = mato2.inverse; S = transform.localToWorldMatrix; Matrix4x4 mat1NT, mat2NT; mat1NT = mat1; mat2NT = mat2; MegaMatrix.NoTrans(ref mat1NT); MegaMatrix.NoTrans(ref mat2NT); Vector3 P1 = mat1.MultiplyPoint(mato1.GetColumn(3)); Vector3 P2 = mat2.MultiplyPoint(mato2.GetColumn(3)); startvec = mat1NT.MultiplyPoint(mato1.GetColumn(2)); endvec = mat2NT.MultiplyPoint(mato2.GetColumn(2)); starty = mat1NT.MultiplyPoint(mato1.GetColumn(1)); endy = mat2NT.MultiplyPoint(mato2.GetColumn(1)); Matrix4x4 SI = S.inverse; Vector3 P0 = SI.MultiplyPoint(P1); Matrix4x4 T1 = mat1; MegaMatrix.NoTrans(ref T1); Vector3 RVw = T1.MultiplyPoint(RV); Lf = (P2 - P1).magnitude; Vector3 Zw; if (Lf < 0.01f) { Zw = P1.normalized; } else { Zw = (P2 - P1).normalized; } Vector3 Xw = Vector3.Cross(RVw, Zw).normalized; Vector3 Yw = Vector3.Cross(Zw, Xw).normalized; MegaMatrix.NoTrans(ref SI); Vector3 Xs = SI.MultiplyPoint(Xw); Vector3 Ys = SI.MultiplyPoint(Yw); Vector3 Zs = SI.MultiplyPoint(Zw); Tlocal.SetColumn(0, Xs); Tlocal.SetColumn(1, Ys); Tlocal.SetColumn(2, Zs); MegaMatrix.SetTrans(ref Tlocal, P0); // move z-axes of end transforms into local frame Matrix4x4 TlocalInvNT = Tlocal; MegaMatrix.NoTrans(ref TlocalInvNT); TlocalInvNT = TlocalInvNT.inverse; float tenstop = tension1; // * 0.01f; float tensbot = tension2; // * 0.01f; startvec = tensbot * (TlocalInvNT.MultiplyPoint(startvec)); endvec = tenstop * (TlocalInvNT.MultiplyPoint(endvec)); starty = TlocalInvNT.MultiplyPoint(starty); endy = TlocalInvNT.MultiplyPoint(endy); yangle = Mathf.Acos(Vector3.Dot(starty, endy)); if (yangle > EPSILON) { roty = Vector3.Cross(starty, endy).normalized; } else { roty = Vector3.zero; } startpoint = Vector3.zero; endpoint = new Vector3(0.0f, 0.0f, Lf); hosespline.knots[0].p = startpoint; hosespline.knots[0].invec = startpoint - startvec; hosespline.knots[0].outvec = startpoint + startvec; hosespline.knots[1].p = endpoint; hosespline.knots[1].invec = endpoint + endvec; hosespline.knots[1].outvec = endpoint - endvec; hosespline.CalcLength(); //10); } MegaHoseType wtype = wiretype; int Segs = segments; if (Segs < 3) { Segs = 3; } if (rebuildcross) { rebuildcross = false; int nfillets = 0; int nsides = 0; if (wtype == MegaHoseType.Round) { NvertsPerRing = rndsides; if (NvertsPerRing < 3) { NvertsPerRing = 3; } } else { if (wtype == MegaHoseType.Rectangle) { nfillets = rectfilletsides; if (nfillets < 0) { nfillets = 0; } if (smooth == MegaHoseSmooth.SMOOTHNONE) { NvertsPerRing = (nfillets > 0 ? 8 + 4 * (nfillets - 1) : 8); } else { NvertsPerRing = (nfillets > 0 ? 8 + 4 * (nfillets - 1) : 4); //4); } } else { nfillets = dsecfilletsides; if (nfillets < 0) { nfillets = 0; } nsides = dsecrndsides; if (nsides < 2) { nsides = 2; } int nsm1 = nsides - 1; NvertsPerRing = (nfillets > 0 ? 6 + nsm1 + 2 * (nfillets - 1): 4 + nsm1); } } NvertsPerRing++; int NfacesPerEnd, NfacesPerRing, Nfaces = 0; //MegaHoseSmooth SMOOTH = smooth; Nverts = (Segs + 1) * (NvertsPerRing + 1); // + 2; if (capends) { Nverts += 2; } NfacesPerEnd = NvertsPerRing; NfacesPerRing = 6 * NvertsPerRing; Nfaces = Segs * NfacesPerRing; // + 2 * NfacesPerEnd; if (capends) { Nfaces += 2 * NfacesPerEnd; } if (SaveVertex == null || SaveVertex.Length != NvertsPerRing) { SaveVertex = new Vector3[NvertsPerRing]; SaveUV = new Vector2[NvertsPerRing]; } if (calcnormals) { if (SaveNormals == null || SaveNormals.Length != NvertsPerRing) { SaveNormals = new Vector3[NvertsPerRing]; } } MakeSaveVertex(NvertsPerRing, nfillets, nsides, wtype); if (verts == null || verts.Length != Nverts) { verts = new Vector3[Nverts]; uvs = new Vector2[Nverts]; faces = new int[Nfaces * 3]; } if (calcnormals && (normals == null || normals.Length != Nverts)) { normals = new Vector3[Nverts]; } } if (Nverts == 0) { return; } bool mapmenow = mapmemapme; int thisvert = 0; int last = Nverts - 1; int last2 = last - 1; int lastvpr = NvertsPerRing; // - 1; int maxseg = Segs + 1; float flexhere; float dadjust; float flexlen; float flex1 = flexstart; float flex2 = flexstop; int flexn = flexcycles; float flexd = flexdiameter; Vector3 ThisPosition; Vector3 ThisXAxis, ThisYAxis, ThisZAxis; Vector2 uv = Vector2.zero; Matrix4x4 RingTM = Matrix4x4.identity; Matrix4x4 invRingTM = Matrix4x4.identity; for (int i = 0; i < maxseg; i++) { float incr = (float)i / (float)Segs; if (createfree) { ThisPosition = new Vector3(0.0f, 0.0f, Lf * incr); ThisXAxis = new Vector3(1.0f, 0.0f, 0.0f); ThisYAxis = new Vector3(0.0f, 1.0f, 0.0f); ThisZAxis = new Vector3(0.0f, 0.0f, 1.0f); } else { int k = 0; ThisPosition = hosespline.InterpCurve3D(incr, true, ref k); ThisZAxis = (hosespline.InterpCurve3D(incr + 0.001f, true, ref k) - ThisPosition).normalized; ThisYAxis = starty; if (yangle > EPSILON) { RotateOnePoint(ref ThisYAxis, Vector3.zero, roty, incr * yangle); } ThisXAxis = Vector3.Cross(ThisYAxis, ThisZAxis).normalized; ThisYAxis = Vector3.Cross(ThisZAxis, ThisXAxis); } RingTM.SetColumn(0, ThisXAxis); RingTM.SetColumn(1, ThisYAxis); RingTM.SetColumn(2, ThisZAxis); MegaMatrix.SetTrans(ref RingTM, ThisPosition); if (!createfree) { RingTM = Tlocal * RingTM; } if (calcnormals) { invRingTM = RingTM; MegaMatrix.NoTrans(ref invRingTM); //invRingTM = invRingTM.inverse.transpose; } if ((incr > flex1) && (incr < flex2) && flexon) { flexlen = flex2 - flex1; if (flexlen < 0.01f) { flexlen = 0.01f; } flexhere = (incr - flex1) / flexlen; float ang = (float)flexn * flexhere * (Mathf.PI * 2.0f) + PIover2; dadjust = 1.0f + flexd * (1.0f - Mathf.Sin(ang)); //(float)flexn * flexhere * (Mathf.PI * 2.0f) + PIover2)); } else { dadjust = 0.0f; } if (usebulgecurve) { if (dadjust == 0.0f) { dadjust = 1.0f + (bulge.Evaluate(incr + bulgeoffset) * bulgeamount); } else { dadjust += bulge.Evaluate(incr + bulgeoffset) * bulgeamount; } } uv.x = 0.999999f * incr * uvscale.x; for (int j = 0; j < NvertsPerRing; j++) { int jj = j; // % NvertsPerRing; if (mapmenow) { uv.y = SaveUV[jj].y; uvs[thisvert] = uv; //new Vector2(0.999999f * incr * uvscale.x, SaveUV[jj].y); } if (dadjust != 0.0f) { verts[thisvert] = RingTM.MultiplyPoint(dadjust * SaveVertex[jj]); } else { verts[thisvert] = RingTM.MultiplyPoint(SaveVertex[jj]); } if (calcnormals) { normals[thisvert] = invRingTM.MultiplyPoint(SaveNormals[jj]).normalized; //.MultiplyPoint(-SaveNormals[jj]); } //if ( j == 0 ) //{ // Debug.Log("norm " + normals[thisvert].ToString("0.000") + " save " + SaveNormals[jj].ToString("0.000")); //} thisvert++; } if (mapmenow) { //uvs[Nverts + i] = new Vector2(0.999999f * incr, 0.999f); } if (capends) { if (i == 0) { verts[last2] = (createfree ? ThisPosition : Tlocal.MultiplyPoint(ThisPosition)); if (mapmenow) { uvs[last2] = Vector3.zero; } } else { if (i == Segs) { verts[last] = createfree ? ThisPosition : Tlocal.MultiplyPoint(ThisPosition); if (mapmenow) { uvs[last] = Vector3.zero; } } } } } // Now, set up the faces int thisface = 0, v1, v2, v3, v4; v3 = last2; if (capends) { for (int i = 0; i < NvertsPerRing - 1; i++) { v1 = i; v2 = (i < lastvpr ? v1 + 1 : v1 - lastvpr); //v5 = (i < lastvpr ? v2 : Nverts); faces[thisface++] = v2; faces[thisface++] = v1; faces[thisface++] = v3; } } int ringnum = NvertsPerRing; // + 1; for (int i = 0; i < Segs; i++) { for (int j = 0; j < NvertsPerRing - 1; j++) { v1 = i * ringnum + j; v2 = v1 + 1; //(j < lastvpr? v1 + 1 : v1 - lastvpr); v4 = v1 + ringnum; v3 = v2 + ringnum; faces[thisface++] = v1; faces[thisface++] = v2; faces[thisface++] = v3; faces[thisface++] = v1; faces[thisface++] = v3; faces[thisface++] = v4; } } int basevert = Segs * ringnum; //NvertsPerRing; v3 = Nverts - 1; if (capends) { for (int i = 0; i < NvertsPerRing - 1; i++) { v1 = i + basevert; v2 = (i < lastvpr? v1 + 1 : v1 - lastvpr); //v5 = (i < lastvpr? v2 : Nverts + Segs); faces[thisface++] = v1; faces[thisface++] = v2; faces[thisface++] = v3; } } mesh.Clear(); mesh.subMeshCount = 1; mesh.vertices = verts; mesh.uv = uvs; mesh.triangles = faces; if (calcnormals) { mesh.normals = normals; } else { mesh.RecalculateNormals(); } mesh.RecalculateBounds(); #if UNITY_5_5 || UNITY_5_6 || UNITY_2017 #else if (optimize) { ; } #endif if (calctangents) { MegaUtils.BuildTangents(mesh); } if (recalcCollider) { if (meshCol == null) { meshCol = GetComponent <MeshCollider>(); } if (meshCol != null) { meshCol.sharedMesh = null; meshCol.sharedMesh = mesh; //bool con = meshCol.convex; //meshCol.convex = con; } } }
// we only need to build the savevertex and uvs if mesh def changes, else we can keep the uvs void BuildMesh() { if (!mesh) { mesh = GetComponent <MeshFilter>().sharedMesh; if (mesh == null) { updatemesh = true; return; } } if (hosespline.knots.Count == 0) { hosespline.AddKnot(Vector3.zero, Vector3.zero, Vector3.zero); hosespline.AddKnot(Vector3.zero, Vector3.zero, Vector3.zero); } FixHoseFillet(); bool createfree = freecreate; if ((!createfree) && ((!custnode) || (!custnode2))) { createfree = true; } if (custnode && custnode2) { createfree = false; } float Lf = 0.0f; Tlocal = Matrix4x4.identity; starty = Vector3.zero; if (createfree) { Lf = noreflength; } else { starty = custnode.transform.up; //Vector3.up; CalcSpline(); Lf = Vector3.Distance(custnode.transform.position, custnode2.transform.position); } MegaHoseType wtype = wiretype; int Segs = segments; if (Segs < 3) { Segs = 3; } if (rebuildcross) { rebuildcross = false; int nfillets = 0; int nsides = 0; if (wtype == MegaHoseType.Round) { NvertsPerRing = rndsides; if (NvertsPerRing < 3) { NvertsPerRing = 3; } } else { if (wtype == MegaHoseType.Rectangle) { nfillets = rectfilletsides; if (nfillets < 0) { nfillets = 0; } if (smooth == MegaHoseSmooth.SMOOTHNONE) { NvertsPerRing = (nfillets > 0 ? 8 + 4 * (nfillets - 1) : 8); } else { NvertsPerRing = (nfillets > 0 ? 8 + 4 * (nfillets - 1) : 4); //4); } } else { nfillets = dsecfilletsides; if (nfillets < 0) { nfillets = 0; } nsides = dsecrndsides; if (nsides < 2) { nsides = 2; } int nsm1 = nsides - 1; NvertsPerRing = (nfillets > 0 ? 6 + nsm1 + 2 * (nfillets - 1): 4 + nsm1); } } NvertsPerRing++; int NfacesPerEnd, NfacesPerRing, Nfaces = 0; //MegaHoseSmooth SMOOTH = smooth; Nverts = (Segs + 1) * (NvertsPerRing + 1); // + 2; if (capends) { Nverts += 2; } NfacesPerEnd = NvertsPerRing; NfacesPerRing = 6 * NvertsPerRing; Nfaces = Segs * NfacesPerRing; // + 2 * NfacesPerEnd; if (capends) { Nfaces += 2 * NfacesPerEnd; } if (SaveVertex == null || SaveVertex.Length != NvertsPerRing) { SaveVertex = new Vector3[NvertsPerRing]; SaveUV = new Vector2[NvertsPerRing]; } if (calcnormals) { if (SaveNormals == null || SaveNormals.Length != NvertsPerRing) { SaveNormals = new Vector3[NvertsPerRing]; } } MakeSaveVertex(NvertsPerRing, nfillets, nsides, wtype); if (verts == null || verts.Length != Nverts) { verts = new Vector3[Nverts]; uvs = new Vector2[Nverts]; faces = new int[Nfaces * 3]; } if (calcnormals && (normals == null || normals.Length != Nverts)) { normals = new Vector3[Nverts]; } } if (Nverts == 0) { return; } bool mapmenow = mapmemapme; int thisvert = 0; int last = Nverts - 1; int last2 = last - 1; int lastvpr = NvertsPerRing; // - 1; int maxseg = Segs + 1; float flexhere; float dadjust; float flexlen; float flex1 = flexstart; float flex2 = flexstop; int flexn = flexcycles; float flexd = flexdiameter; Vector3 ThisPosition; Vector2 uv = Vector2.zero; Matrix4x4 RingTM = Matrix4x4.identity; Matrix4x4 invRingTM = Matrix4x4.identity; Vector3 lastup = starty; float sizeadj = 1.0f; for (int i = 0; i < maxseg; i++) { float incr = (float)i / (float)Segs; if (createfree) { ThisPosition = new Vector3(0.0f, 0.0f, Lf * incr); } else { int k = 0; ThisPosition = hosespline.InterpCurve3D(incr, true, ref k); } RingTM = GetSplineMat(hosespline, incr, true, ref lastup); if (!createfree) { RingTM = Tlocal * RingTM; } if (calcnormals) { invRingTM = RingTM; MegaMatrix.NoTrans(ref invRingTM); } if ((incr > flex1) && (incr < flex2) && flexon) { flexlen = flex2 - flex1; if (flexlen < 0.01f) { flexlen = 0.01f; } flexhere = (incr - flex1) / flexlen; float ang = (float)flexn * flexhere * (Mathf.PI * 2.0f) + PIover2; dadjust = 1.0f + flexd * (1.0f - Mathf.Sin(ang)); //(float)flexn * flexhere * (Mathf.PI * 2.0f) + PIover2)); } else { dadjust = 0.0f; } if (usebulgecurve) { if (dadjust == 0.0f) { dadjust = 1.0f + (bulge.Evaluate(incr + bulgeoffset) * bulgeamount); } else { dadjust += bulge.Evaluate(incr + bulgeoffset) * bulgeamount; } } if (usesizecurve) { sizeadj = size.Evaluate(incr); } uv.x = 0.999999f * incr * uvscale.x; for (int j = 0; j < NvertsPerRing; j++) { int jj = j; // % NvertsPerRing; if (mapmenow) { uv.y = SaveUV[jj].y; uvs[thisvert] = uv; //new Vector2(0.999999f * incr * uvscale.x, SaveUV[jj].y); } if (dadjust != 0.0f) { verts[thisvert] = RingTM.MultiplyPoint(sizeadj * dadjust * SaveVertex[jj]); } else { verts[thisvert] = RingTM.MultiplyPoint(sizeadj * SaveVertex[jj]); } if (calcnormals) { normals[thisvert] = invRingTM.MultiplyPoint(SaveNormals[jj]).normalized; //.MultiplyPoint(-SaveNormals[jj]); } thisvert++; } if (mapmenow) { //uvs[Nverts + i] = new Vector2(0.999999f * incr, 0.999f); } if (capends) { if (i == 0) { verts[last2] = (createfree ? ThisPosition : Tlocal.MultiplyPoint(ThisPosition)); if (mapmenow) { uvs[last2] = Vector3.zero; } } else { if (i == Segs) { verts[last] = createfree ? ThisPosition : Tlocal.MultiplyPoint(ThisPosition); if (mapmenow) { uvs[last] = Vector3.zero; } } } } } // Now, set up the faces int thisface = 0, v1, v2, v3, v4; v3 = last2; if (capends) { for (int i = 0; i < NvertsPerRing - 1; i++) { v1 = i; v2 = (i < lastvpr ? v1 + 1 : v1 - lastvpr); //v5 = (i < lastvpr ? v2 : Nverts); faces[thisface++] = v2; faces[thisface++] = v1; faces[thisface++] = v3; } } int ringnum = NvertsPerRing; // + 1; for (int i = 0; i < Segs; i++) { for (int j = 0; j < NvertsPerRing - 1; j++) { v1 = i * ringnum + j; v2 = v1 + 1; //(j < lastvpr? v1 + 1 : v1 - lastvpr); v4 = v1 + ringnum; v3 = v2 + ringnum; faces[thisface++] = v1; faces[thisface++] = v2; faces[thisface++] = v3; faces[thisface++] = v1; faces[thisface++] = v3; faces[thisface++] = v4; } } int basevert = Segs * ringnum; //NvertsPerRing; v3 = Nverts - 1; if (capends) { for (int i = 0; i < NvertsPerRing - 1; i++) { v1 = i + basevert; v2 = (i < lastvpr? v1 + 1 : v1 - lastvpr); //v5 = (i < lastvpr? v2 : Nverts + Segs); faces[thisface++] = v1; faces[thisface++] = v2; faces[thisface++] = v3; } } mesh.Clear(); mesh.subMeshCount = 1; mesh.vertices = verts; mesh.uv = uvs; mesh.triangles = faces; if (calcnormals) { mesh.normals = normals; } else { mesh.RecalculateNormals(); } mesh.RecalculateBounds(); #if UNITY_5_5 || UNITY_5_6 || UNITY_2017 #else if (optimize) { ; } #endif if (calctangents) { MegaUtils.BuildTangents(mesh); } if (recalcCollider) { if (meshCol == null) { meshCol = GetComponent <MeshCollider>(); } if (meshCol != null) { meshCol.sharedMesh = null; meshCol.sharedMesh = mesh; //bool con = meshCol.convex; //meshCol.convex = con; } } }