Quaternion GetLinkQuat(float alpha, float last, out Vector3 ps, MegaRope rope) { ps = rope.Interp(last); Vector3 ps1 = rope.Interp(alpha); //ps + Velocity(alpha); Vector3 relativePos = ps1 - ps; // This is Vel? Quaternion rotation = Quaternion.LookRotation(relativePos, rope.ropeup); //vertices[p + 1].point - vertices[p].point); return(rotation); //wtm; }
Matrix4x4 GetLinkMat(float alpha, float last, MegaRope rope) { Vector3 ps = rope.Interp(last); Vector3 ps1 = rope.Interp(alpha); //ps + Velocity(alpha); Vector3 relativePos = ps1 - ps; // This is Vel? Quaternion rotation = Quaternion.LookRotation(relativePos, rope.ropeup); //vertices[p + 1].point - vertices[p].point); wtm.SetTRS(ps, rotation, Vector3.one); wtm = mat * wtm; // * roll; return(wtm); }
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); }
// 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); } }
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; }
// 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); } }
Matrix4x4 GetLinkMat(float alpha, float last, MegaRope rope) { Vector3 ps = rope.Interp(last); Vector3 ps1 = rope.Interp(alpha); //ps + Velocity(alpha); Vector3 relativePos = ps1 - ps; // This is Vel? Quaternion rotation = Quaternion.LookRotation(relativePos, rope.ropeup); //vertices[p + 1].point - vertices[p].point); wtm.SetTRS(ps, rotation, Vector3.one); wtm = mat * wtm; // * roll; return wtm; }
Quaternion GetLinkQuat(float alpha, float last, out Vector3 ps, MegaRope rope) { ps = rope.Interp(last); Vector3 ps1 = rope.Interp(alpha); //ps + Velocity(alpha); Vector3 relativePos = ps1 - ps; // This is Vel? Quaternion rotation = Quaternion.LookRotation(relativePos, rope.ropeup); //vertices[p + 1].point - vertices[p].point); return rotation; //wtm; }
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); }
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); }