public override bool Prepare(MegaModContext mc) { Vector3 s = LatticeSize(); for (int i = 0; i < 3; i++) { if (s[i] == 0.0f) { s[i] = 1.0f; } else { s[i] = 1.0f / s[i]; } } Vector3 c = MegaMatrix.GetTrans(ref tm); MegaMatrix.SetTrans(ref tm, c - bbox.min - Offset); MegaMatrix.Scale(ref tm, s, false); invtm = tm.inverse; return(true); }
public void CalcMatrix(ref Matrix4x4 mat, float incr) { #if false Matrix4x4 RingTM = Matrix4x4.identity; Matrix4x4 invRingTM = Matrix4x4.identity; int k = 0; Vector3 ThisPosition = hosespline.InterpCurve3D(incr, true, ref k); Vector3 ThisZAxis = (hosespline.InterpCurve3D(incr + 0.001f, true, ref k) - ThisPosition).normalized; Vector3 ThisYAxis = starty; if (yangle > EPSILON) { RotateOnePoint(ref ThisYAxis, Vector3.zero, roty, incr * yangle); } Vector3 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); #endif mat = Tlocal; // * RingTM; }
Vector3 Deform(Vector3 p, float off, MegaRope rope, float alpha) { Vector3 np = rope.Interp(alpha); //tm.MultiplyPoint3x4(rope.Interp(alpha)); T = rope.Velocity(alpha).normalized; wtm = rope.CalcFrame(T, ref N, ref B); //wtm.SetRow(3, np); MegaMatrix.SetTrans(ref wtm, np); return(p); }
public void SetTM1() { tm = Matrix4x4.identity; MegaMatrix.RotateZ(ref tm, -gizmoRot.z * Mathf.Deg2Rad); MegaMatrix.RotateY(ref tm, -gizmoRot.y * Mathf.Deg2Rad); MegaMatrix.RotateX(ref tm, -gizmoRot.x * Mathf.Deg2Rad); MegaMatrix.SetTrans(ref tm, gizmoPos + Offset); invtm = tm.inverse; }
public void SetTM1() { tm = Matrix4x4.identity; //Quaternion rot = Quaternion.Euler(-gizmoRot); MegaMatrix.RotateZ(ref tm, -gizmoRot.z * Mathf.Deg2Rad); MegaMatrix.RotateY(ref tm, -gizmoRot.y * Mathf.Deg2Rad); MegaMatrix.RotateX(ref tm, -gizmoRot.x * Mathf.Deg2Rad); MegaMatrix.SetTrans(ref tm, gizmoPos + Offset); //tm.SetTRS(gizmoPos + Offset, rot, gizmoScale); invtm = tm.inverse; }
//Matrix4x4 tmm = Matrix4x4.identity; public override bool Prepare(float decay) { if (bsize.x != Width || bsize.y != Height || bsize.z != Length) { Init(); } Vector3 s = LatticeSize(); for (int i = 0; i < 3; i++) { if (s[i] == 0.0f) { s[i] = 1.0f; } else { s[i] = 1.0f / s[i]; } } tm = transform.worldToLocalMatrix; //Matrix4x4 tmm = Matrix4x4.TRS(bsize * 0.5f, Quaternion.identity, Vector3.one); Vector3 c = MegaMatrix.GetTrans(ref tm); MegaMatrix.SetTrans(ref tm, c - (-bsize * 0.5f)); //Vector3.zero); //c - bbox.min - Offset); MegaMatrix.Scale(ref tm, s, false); invtm = tm.inverse; //tm = tmm * transform.worldToLocalMatrix; //invtm = tm.inverse; totaldecay = Decay + decay; if (totaldecay < 0.0f) { totaldecay = 0.0f; } hw = Width * 0.5f; hh = Height * 0.5f; hl = Length * 0.5f; return(true); }
// 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; } } }
// This will take a selected object and deform that along the spline public override void BuildMesh(MegaRope rope) { // Option to stretch the mesh to fit, and end to start from if (source) { if (overts == null) { Rebuild(rope); //Mesh smesh = MegaUtils.GetMesh(source); //bounds = smesh.bounds; //sverts = smesh.vertices; //verts = new Vector3[smesh.vertexCount]; } // Calc frames if (frames == null || frames.Length != numframes + 1) { frames = new Matrix4x4[numframes + 1]; } wtm = rope.GetDeformMat(0.0f); T = wtm.MultiplyPoint3x4(rope.Velocity(0.0f).normalized); // Calc vector to use for cp based on velocity of first point Vector3 cp = wtm.MultiplyPoint3x4(tm.MultiplyPoint3x4(Vector3.right)); N = (cp - wtm.MultiplyPoint3x4(rope.Interp(0.0f))).normalized; B = Vector3.Cross(T, N); frames[0] = wtm; for (int i = 0; i <= numframes; i++) { float alpha = (float)i / (float)numframes; if (i == 0) { alpha = 0.001f; } T = rope.Velocity(alpha).normalized; frames[i] = rope.CalcFrame(T, ref N, ref B); } int ax = (int)meshaxis; Vector3 sscl = scale; //StartScale * GlobalScale; //Vector3 soff = Vector3.Scale(offset, sscl); tm = Matrix4x4.identity; //wtm = rope.GetDeformMat(0.0f); //T = wtm.MultiplyPoint3x4(rope.Velocity(0.0f).normalized); // Calc vector to use for cp based on velocity of first point //Vector3 cp = wtm.MultiplyPoint3x4(tm.MultiplyPoint3x4(Vector3.right)); //N = (cp - wtm.MultiplyPoint3x4(rope.Interp(0.0f))).normalized; //B = Vector3.Cross(T, N); float off = 0.0f; float min = bounds.min[ax]; float sz = bounds.size[ax]; //float alpha = 0.0f; //Debug.Log("min " + min + "sz " + sz); off -= bounds.min[(int)meshaxis] * sscl[ax]; if (!stretchtofit) { sz = rope.RopeLength; } for (int i = 0; i < sverts.Length; i++) { Vector3 p = sverts[i]; float alpha = Mathf.Clamp01((p[ax] - min) / sz); // can pre calc //if ( alpha > 1.0f || alpha < 0.0f ) //{ // Debug.Log("Alpha " + alpha + " val " + p[ax]); //} MegaMatrix.SetTrans(ref frames[(int)(alpha * numframes)], rope.Interp(alpha)); p[ax] = 0.0f; p.x *= scale.x; p.y *= scale.y; p.z *= scale.z; //p = Deform(p, off, rope, alpha); overts[i] = frames[(int)(alpha * numframes)].MultiplyPoint3x4(p); } // Going to need Mega Normal calculator here potentially rope.mesh.vertices = overts; rope.mesh.RecalculateBounds(); //rope.mesh.RecalculateNormals(); RecalcNormals(rope.mesh, overts); } }
public override void BuildMesh(MegaRope rope) { float lengthuvtile = uvtiley * rope.RopeLength; Twist = TwistPerUnit * rope.RopeLength; segments = (int)(rope.RopeLength * SegsPerUnit); float off = (rope.radius * 0.5f) + offset; float sradius = 0.0f; if (strands == 1) { off = offset; sradius = rope.radius; } else { sradius = (rope.radius * 0.5f) + strandRadius; } BuildCrossSection(sradius); int vcount = ((segments + 1) * (sides + 1)) * strands; int tcount = ((sides * 2) * segments) * strands; if (cap) { vcount += ((sides + 1) * 2) * strands; tcount += (sides * 2) * strands; } if (verts == null || verts.Length != vcount) { verts = new Vector3[vcount]; } bool builduvs = false; if (uvs == null || uvs.Length != vcount) { uvs = new Vector2[vcount]; tris = new int[tcount * 3]; builduvs = true; } //mat = Matrix4x4.identity; tm = Matrix4x4.identity; switch (rope.axis) { case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break; case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break; case MegaAxis.Z: break; } //switch ( rope.RopeUp ) //{ // case MegaAxis.X: ropeup = Vector3.right; break; // case MegaAxis.Y: ropeup = Vector3.up; break; // case MegaAxis.Z: ropeup = Vector3.forward; break; //} // We only need to refresh the verts, tris and uvs are done once int vi = 0; int ti = 0; Vector2 uv = Vector2.zero; Vector3 soff = Vector3.zero; //Vector3 up = Vector3.up; Vector3 T = Vector3.zero; Vector3 N = Vector3.zero; Vector3 B = Vector3.zero; for (int s = 0; s < strands; s++) { //rollingquat = Quaternion.identity; float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f; soff.x = Mathf.Sin(ang) * off; soff.z = Mathf.Cos(ang) * off; //Matrix.SetTrans(ref tm, soff); int vo = vi; // Cap maybe needs to be submesh, at least needs seperate verts if (cap) { // Add slice at 0 float alpha = 0.0f; wtm = rope.GetDeformMat(alpha); //wtm = rope.GetDeformMat(alpha, up); //float uvt = alpha * uvtwist; float tst = alpha * Twist * Mathf.PI * 2.0f; soff.x = Mathf.Sin(ang + tst) * off; soff.z = Mathf.Cos(ang + tst) * off; //int ovi = vi; for (int v = 0; v <= cross.Length; v++) { Vector3 p = tm.MultiplyPoint3x4(cross[v % cross.Length] + soff); verts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]); if (builduvs) { uv.y = 0.0f; //alpha * uvtiley; uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt; uvs[vi++] = uv; } else { vi++; } } //up = wtm.MultiplyPoint3x4(tm.MultiplyPoint3x4(cross[0])).normalized; if (builduvs) { for (int sd = 1; sd < sides; sd++) { tris[ti++] = vo; tris[ti++] = vo + sd + 1; tris[ti++] = vo + sd; } } vo = vi; // Other end alpha = 1.0f; wtm = rope.GetDeformMat(alpha); //wtm = rope.CalcFrame(T, ref N, ref B); //uvt = alpha * uvtwist; tst = alpha * Twist * Mathf.PI * 2.0f; soff.x = Mathf.Sin(ang + tst) * off; soff.z = Mathf.Cos(ang + tst) * off; for (int v = 0; v <= cross.Length; v++) { Vector3 p = tm.MultiplyPoint3x4(cross[v % cross.Length] + soff); verts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]); if (builduvs) { uv.y = 0.0f; //alpha * uvtiley; uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt; uvs[vi++] = uv; } else { vi++; } } if (builduvs) { for (int sd = 1; sd < sides; sd++) { tris[ti++] = vo; tris[ti++] = vo + sd; tris[ti++] = vo + sd + 1; } } } vo = vi; //wtm = rope.GetDeformMat(0.0f); for (int i = 0; i <= segments; i++) { float alpha = ((float)i / (float)segments); float uvt = alpha * uvtwist; float tst = (alpha * Twist * Mathf.PI * 2.0f); // + rollang; soff.x = Mathf.Sin(ang + tst) * off; soff.z = Mathf.Cos(ang + tst) * off; if (i == 0) { wtm = rope.GetDeformMat(alpha); T = wtm.MultiplyPoint3x4(rope.Velocity(0.0f).normalized); Vector3 cp = wtm.MultiplyPoint3x4(tm.MultiplyPoint3x4(cross[0])); N = (cp - wtm.MultiplyPoint3x4(rope.Interp(0.0f))).normalized; B = Vector3.Cross(T, N); } else { Vector3 np = rope.Interp(alpha); //tm.MultiplyPoint3x4(rope.Interp(alpha)); T = rope.Velocity(alpha).normalized; wtm = rope.CalcFrame(T, ref N, ref B); //wtm.SetRow(3, np); MegaMatrix.SetTrans(ref wtm, np); } //wtm = rope.GetDeformMat(alpha); for (int v = 0; v <= cross.Length; v++) { Vector3 p = tm.MultiplyPoint3x4(cross[v % cross.Length] + soff); verts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]); //if ( true ) //builduvs ) { uv.y = alpha * lengthuvtile; //uvtiley; uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt; uvs[vi++] = uv; } //else // vi++; } // Uv is - to 1 around and alpha along } if (builduvs) { int sc = sides + 1; for (int i = 0; i < segments; i++) { for (int v = 0; v < cross.Length; v++) { tris[ti++] = (i * sc) + v + vo; tris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo; tris[ti++] = ((i + 1) * sc) + v + vo; tris[ti++] = (i * sc) + v + vo; tris[ti++] = (i * sc) + ((v + 1) % sc) + vo; tris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo; } } } } //Mesh mesh = MegaUtils.GetMesh(rope.gameObject); if (builduvs) { rope.mesh.Clear(); rope.mesh.vertices = verts; rope.mesh.uv = uvs; rope.mesh.triangles = tris; } else { rope.mesh.vertices = verts; rope.mesh.uv = uvs; } rope.mesh.RecalculateBounds(); rope.mesh.RecalculateNormals(); //MeshConstructor.BuildTangents(mesh); }