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);
    }
Beispiel #2
0
    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;
    }
Beispiel #3
0
    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;
    }
Beispiel #5
0
    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);
    }
Beispiel #7
0
    // 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;
            }
        }
    }
Beispiel #8
0
    // 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);
    }