void Calc() { //if ( from > 0.0f) from = 0.0f; //if ( to < 0.0f ) to = 0.0f; tm = transform.worldToLocalMatrix; invtm = tm.inverse; mat = Matrix4x4.identity; switch (axis) { case MegaAxis.X: MegaMatrix.RotateZ(ref mat, Mathf.PI * 0.5f); break; case MegaAxis.Y: MegaMatrix.RotateX(ref mat, -Mathf.PI * 0.5f); break; case MegaAxis.Z: break; } MegaMatrix.RotateY(ref mat, Mathf.Deg2Rad * dir); SetAxis(mat); CalcR(axis, Mathf.Deg2Rad * -angle); if (doRegion) { doRegion = false; float len = to - from; float rat1, rat2; if (len == 0.0f) { rat1 = rat2 = 1.0f; } else { rat1 = to / len; rat2 = from / len; } Vector3 pt; tmAbove = Matrix4x4.identity; MegaMatrix.Translate(ref tmAbove, 0.0f, -to, 0.0f); MegaMatrix.RotateZ(ref tmAbove, -Mathf.Deg2Rad * angle * rat1); MegaMatrix.Translate(ref tmAbove, 0.0f, to, 0.0f); pt = new Vector3(0.0f, to, 0.0f); MegaMatrix.Translate(ref tmAbove, tm.MultiplyPoint3x4(Map(0, invtm.MultiplyPoint3x4(pt))) - pt); tmBelow = Matrix4x4.identity; MegaMatrix.Translate(ref tmBelow, 0.0f, -from, 0.0f); MegaMatrix.RotateZ(ref tmBelow, -Mathf.Deg2Rad * angle * rat2); MegaMatrix.Translate(ref tmBelow, 0.0f, from, 0.0f); pt = new Vector3(0.0f, from, 0.0f); MegaMatrix.Translate(ref tmBelow, tm.MultiplyPoint3x4(Map(0, invtm.MultiplyPoint3x4(pt))) - pt); doRegion = true; } }
// TODO: If we draw like warps do we know if we are the current edited script? public virtual void DrawGizmo(MegaModContext context) { tm = Matrix4x4.identity; MegaMatrix.Translate(ref tm, context.Offset); invtm = tm.inverse; if ( !Prepare(context) ) return; Vector3 min = context.bbox.min; Vector3 max = context.bbox.max; Matrix4x4 gtm = Matrix4x4.identity; Vector3 pos = gizmoPos; pos.x = -pos.x; pos.y = -pos.y; pos.z = -pos.z; Vector3 scl = gizmoScale; scl.x = 1.0f - (scl.x - 1.0f); scl.y = 1.0f - (scl.y - 1.0f); gtm.SetTRS(pos, Quaternion.Euler(gizmoRot), scl); // put sourceObj into context if ( context.mod.sourceObj != null ) Gizmos.matrix = context.mod.sourceObj.transform.localToWorldMatrix * gtm; else Gizmos.matrix = context.go.transform.localToWorldMatrix * gtm; //Gizmos.color = ModCol(); //Color.yellow; corners[0] = new Vector3(min.x, min.y, min.z); corners[1] = new Vector3(min.x, max.y, min.z); corners[2] = new Vector3(max.x, max.y, min.z); corners[3] = new Vector3(max.x, min.y, min.z); corners[4] = new Vector3(min.x, min.y, max.z); corners[5] = new Vector3(min.x, max.y, max.z); corners[6] = new Vector3(max.x, max.y, max.z); corners[7] = new Vector3(max.x, min.y, max.z); DrawEdge(corners[0], corners[1]); DrawEdge(corners[1], corners[2]); DrawEdge(corners[2], corners[3]); DrawEdge(corners[3], corners[0]); DrawEdge(corners[4], corners[5]); DrawEdge(corners[5], corners[6]); DrawEdge(corners[6], corners[7]); DrawEdge(corners[7], corners[4]); DrawEdge(corners[0], corners[4]); DrawEdge(corners[1], corners[5]); DrawEdge(corners[2], corners[6]); DrawEdge(corners[3], corners[7]); ExtraGizmo(context); }
Vector3 GetCross(int csect, float ca, Vector3 off) { MegaLoftSection lsection = loftsections[csect]; int curve = lsection.curve; int k = -1; Matrix4x4 tm1 = Matrix4x4.identity; float start = crossStart; float len = crossEnd; if (lsection.uselen) { start = lsection.start; len = lsection.length; } MegaShape shape = lsection.shape; MegaMatrix.Translate(ref tm1, pivot); Vector3 rot = crossRot + lsection.rot; MegaMatrix.Rotate(ref tm1, new Vector3(Mathf.Deg2Rad * rot.x, Mathf.Deg2Rad * rot.y, Mathf.Deg2Rad * rot.z)); float alpha = start + (ca * len); //float alpha = start + ca; if (shape.splines[curve].closed) { alpha = Mathf.Repeat(alpha, 1.0f); } Vector3 pos = tm1.MultiplyPoint3x4(shape.splines[curve].InterpCurve3D(alpha, shape.normalizedInterp, ref k) + off + lsection.offset); pos.x *= lsection.scale.x; pos.y *= lsection.scale.y; pos.z *= lsection.scale.z; return(pos); }
Vector3 GetCross(MegaShapeLoft loft, float ca) { MegaShape section = layerSection; Matrix4x4 tm1 = Matrix4x4.identity; MegaMatrix.Translate(ref tm1, pivot); MegaMatrix.Rotate(ref tm1, new Vector3(Mathf.Deg2Rad * crossRot.x, Mathf.Deg2Rad * crossRot.y, Mathf.Deg2Rad * crossRot.z)); int lk = -1; float alpha = crossStart + ca; MegaSpline cspl = section.splines[crosscurve]; if (cspl.closed) { if (alpha < 0.0f) { alpha += 1.0f; } } Vector3 off = Vector3.zero; if (snap) { off = section.splines[0].knots[0].p - cspl.knots[0].p; } if (cspl.closed) { alpha = Mathf.Repeat(alpha, 1.0f); } return(tm1.MultiplyPoint3x4(section.splines[crosscurve].InterpCurve3D(alpha, section.normalizedInterp, ref lk) + off)); }
// Have cdist per material // Best way is to treat each material section like a layer public override bool PrepareLoft(MegaShapeLoft loft, int sc) { MegaShape section = layerSection; // Look at section and find out how many changes in material there are, ie matid // That will be the number of materials // Each change will have its own cdist, uv mapping, material // We seem to do this below as well FindSections(section.splines[crosscurve]); Matrix4x4 tm1 = Matrix4x4.identity; MegaMatrix.Translate(ref tm1, pivot); MegaMatrix.Rotate(ref tm1, new Vector3(Mathf.Deg2Rad * crossRot.x, Mathf.Deg2Rad * crossRot.y, Mathf.Deg2Rad * crossRot.z)); // Build the cross for each section if (enabled) { float dst = crossDist; if (dst < 0.01f) { dst = 0.01f; } int k = -1; int lk = -1; svert = verts.Count; Vector2 uv = Vector2.zero; float alpha = crossStart; float cend = crossStart + crossEnd; if (alpha < 0.0f) { alpha = 0.0f; } if (cend > 1.0f) { cend = 1.0f; } MegaSpline cspl = section.splines[crosscurve]; if (cspl.closed) { if (alpha < 0.0f) { alpha += 1.0f; } } Vector3 off = Vector3.zero; if (snap) { off = cspl.knots[0].p - cspl.knots[0].p; } if (cspl.closed) { alpha = Mathf.Repeat(alpha, 1.0f); } meshsections.Clear(); Vector3 pos = tm1.MultiplyPoint3x4(cspl.InterpCurve3D(alpha, section.normalizedInterp, ref lk) + off); int currentid = cspl.knots[lk].id; MegaMeshSection msect = new MegaMeshSection(); msect.castart = 0.0f; float uvalpha = crossStart; uv.y = uvalpha; //crossStart; msect.vertstart = 0; msect.mat = FindMaterial(currentid); meshsections.Add(msect); // Method to get cdist MegaMaterialSection ms = sections[msect.mat]; msect.cverts.Add(pos); bool loop = true; //float lastalpha = alpha; while (alpha <= cend) { if (loop) { alpha += ms.cdist; loop = false; } if (alpha > cend) { alpha = cend; } pos = tm1.MultiplyPoint3x4(cspl.InterpCurve3D(alpha, section.normalizedInterp, ref k) + off); if (k != lk) { while (lk != k) { //bool looped = false; lk++; int lk1 = lk % cspl.knots.Count; lk = lk1; if (cspl.knots[lk].id != currentid) { msect.cverts.Add(tm1.MultiplyPoint3x4(cspl.knots[lk].p + off)); float caend = ((cspl.knots[lk].length / cspl.length) - crossStart) / (crossEnd - crossStart); msect.caend = caend; // New material msect = new MegaMeshSection(); msect.castart = caend; pos = tm1.MultiplyPoint3x4(cspl.knots[lk].p + off); msect.vertstart = 0; currentid = cspl.knots[lk].id; msect.mat = FindMaterial(currentid); meshsections.Add(msect); ms = sections[msect.mat]; msect.cverts.Add(pos); lk1 = lk - 1; if (lk1 < 0) { lk1 = cspl.knots.Count - 1; } alpha = (cspl.knots[lk1].length / cspl.length); // + crossStart; break; } else { if (ms.includeknots) { msect.cverts.Add(tm1.MultiplyPoint3x4(cspl.knots[lk].p + off)); } else { if (cspl.knots[k].id != currentid) { int kk = lk; while (cspl.knots[kk].id == currentid && kk < cspl.knots.Count) { kk++; } if (kk >= cspl.knots.Count) { kk = cspl.knots.Count - 1; } msect.cverts.Add(tm1.MultiplyPoint3x4(cspl.knots[kk].p + off)); break; } else { msect.cverts.Add(pos); } } } } } else { msect.cverts.Add(pos); } if (alpha == cend) { if (msect.cverts[msect.cverts.Count - 1] != pos) { msect.cverts.Add(pos); } break; } alpha += ms.cdist; if (alpha > cend) { alpha = cend; } } msect.caend = 1.0f; // Do uv and col now for (int i = 0; i < meshsections.Count; i++) { MegaMeshSection ms1 = meshsections[i]; Vector2 uv1 = Vector2.zero; ms1.cuvs.Add(uv1); ms1.ccols.Add(Color.white); for (int v = 1; v < ms1.cverts.Count; v++) { uv1.y += Vector3.Distance(ms1.cverts[v], ms1.cverts[v - 1]); ms1.cuvs.Add(uv1); ms1.ccols.Add(Color.white); } } // Add end point if (section.splines[crosscurve].closed) { alpha = Mathf.Repeat(cend, 1.0f); } } // Calc normals Vector3 up = Vector3.zero; Vector3 n1 = Vector3.zero; for (int i = 0; i < meshsections.Count; i++) { MegaMeshSection ms1 = meshsections[i]; if (ms1.cverts.Count > 1) { for (int v = 0; v < ms1.cverts.Count; v++) { if (v < ms1.cverts.Count - 1) { n1 = (ms1.cverts[v + 1] - ms1.cverts[v]); } else { n1 = (ms1.cverts[v] - ms1.cverts[v - 1]); } up.x = -n1.y; up.y = n1.x; up.z = 0.0f; ms1.cnorms.Add(up); } } } Prepare(loft); return(true); }
void BuildPolyShape(MegaLoftSection lsection, int steps, Vector3 off1, float width) { int curve = lsection.curve; int lk = -1; Matrix4x4 tm1 = Matrix4x4.identity; MegaShape shape = lsection.shape; //verts.Clear(); //uvs.Clear(); //norms.Clear(); MegaMatrix.Translate(ref tm1, pivot); Vector3 rot = crossRot + lsection.rot; MegaMatrix.Rotate(ref tm1, new Vector3(Mathf.Deg2Rad * rot.x, Mathf.Deg2Rad * rot.y, Mathf.Deg2Rad * rot.z)); svert = verts.Count; { float dst = crossDist; if (dst < 0.01f) { dst = 0.01f; } svert = verts.Count; float alpha = crossStart; float cend = crossStart + crossEnd; if (alpha < 0.0f) { alpha = 0.0f; } if (cend > 1.0f) { cend = 1.0f; } MegaSpline cspl = shape.splines[curve]; if (cspl.closed) { if (alpha < 0.0f) { alpha += 1.0f; } } Vector3 off = off1; //Vector3.zero; if (snap) { off = cspl.knots[0].p - cspl.knots[0].p; } if (cspl.closed) { alpha = Mathf.Repeat(alpha, 1.0f); } lsection.meshsections.Clear(); FindSections(lsection, cspl); Vector3 pos = tm1.MultiplyPoint3x4(cspl.InterpCurve3D(alpha, shape.normalizedInterp, ref lk) + off); //Debug.Log("MeshSections " + lsection.meshsections.Count); for (int i = 0; i < lsection.meshsections.Count; i++) { MegaMeshSection ms = lsection.meshsections[i]; //new MegaMeshSection(); MegaMaterialSection s = sections[ms.mat]; int k1 = ms.firstknot; int k2 = ms.lastknot; float l1 = 0.0f; float l2 = 0.0f; //Debug.Log("k1 " + k1 + " k2 " + k2); if (k1 > 0) { l1 = cspl.knots[k1 - 1].length; } else { l1 = 0.0f; } if (k2 < cspl.knots.Count - 1) { l2 = cspl.knots[k2 - 1].length; } else { l2 = cspl.length; } //float slen = l2 - l1; //Debug.Log("l1 " + l1 + " l2 " + l2); float a1 = l1 / cspl.length; float a2 = l2 / cspl.length; ms.castart = a1; ms.caend = a2; for (int kn = k1; kn < k2; kn++) { pos = cspl.knots[kn].Interpolate(0.0f, cspl.knots[kn + 1]) + lsection.offset; pos.x *= lsection.scale.x; pos.y *= lsection.scale.y; pos.z *= lsection.scale.z; pos = tm1.MultiplyPoint3x4(pos + off); ms.cverts.Add(pos); for (int j = 1; j < s.steps; j++) { float ka = (float)j / (float)s.steps; pos = cspl.knots[kn].Interpolate(ka, cspl.knots[kn + 1]) + lsection.offset; pos.x *= lsection.scale.x; pos.y *= lsection.scale.y; pos.z *= lsection.scale.z; pos = tm1.MultiplyPoint3x4(pos + off); ms.cverts.Add(pos); } } pos = cspl.knots[k2 - 1].Interpolate(1.0f, cspl.knots[k2]) + lsection.offset; pos.x *= lsection.scale.x; pos.y *= lsection.scale.y; pos.z *= lsection.scale.z; pos = tm1.MultiplyPoint3x4(pos + off); ms.cverts.Add(pos); //pos = tm1.MultiplyPoint3x4(cspl.knots[k2].p + off); //ms.cverts.Add(pos); } // Do uv and col now for (int i = 0; i < lsection.meshsections.Count; i++) { MegaMeshSection ms1 = lsection.meshsections[i]; ms1.len = 0.0f; //int k1 = ms1.firstknot; //int k2 = ms1.lastknot; //Debug.Log("k1 " + k1 + " k2 " + k2); //float l1 = cspl.knots[k2].length - cspl.knots[k1].length; Vector2 uv1 = Vector2.zero; ms1.cuvs.Add(uv1); ms1.ccols.Add(Color.white); for (int v = 1; v < ms1.cverts.Count; v++) { ms1.len += Vector3.Distance(ms1.cverts[v], ms1.cverts[v - 1]); } for (int v = 1; v < ms1.cverts.Count; v++) { uv1.y += Vector3.Distance(ms1.cverts[v], ms1.cverts[v - 1]) / ms1.len; //uv1.y /= len; //Vector3.Distance(ms1.cverts[v], ms1.cverts[v - 1]); ms1.cuvs.Add(uv1); ms1.ccols.Add(Color.white); } } // Add end point if (cspl.closed) { alpha = Mathf.Repeat(cend, 1.0f); } } // Calc normals Vector3 up = Vector3.zero; Vector3 n1 = Vector3.zero; for (int i = 0; i < lsection.meshsections.Count; i++) { MegaMeshSection ms1 = lsection.meshsections[i]; if (ms1.cverts.Count > 1) { for (int v = 0; v < ms1.cverts.Count; v++) { if (v < ms1.cverts.Count - 1) { n1 = (ms1.cverts[v + 1] - ms1.cverts[v]); } else { n1 = (ms1.cverts[v] - ms1.cverts[v - 1]); } up.x = -n1.y; up.y = n1.x; up.z = 0.0f; ms1.cnorms.Add(up); } } } }
void BuildPolyShape(MegaLoftSection lsection, int steps, Vector3 off, float width) { int curve = lsection.curve; int k = -1; Matrix4x4 tm1 = Matrix4x4.identity; Vector2 uv = Vector2.zero; float start = crossStart; float len = crossEnd; if (lsection.uselen) { start = lsection.start; len = lsection.length; } MegaShape shape = lsection.shape; verts.Clear(); uvs.Clear(); norms.Clear(); MegaMatrix.Translate(ref tm1, pivot); Vector3 rot = crossRot + lsection.rot; MegaMatrix.Rotate(ref tm1, new Vector3(Mathf.Deg2Rad * rot.x, Mathf.Deg2Rad * rot.y, Mathf.Deg2Rad * rot.z)); svert = verts.Count; float alpha = start; if (shape.splines[curve].closed) { alpha = Mathf.Repeat(alpha, 1.0f); } uv.y = start; float dist = 0.0f; Vector3 last = Vector3.zero; for (int i = 0; i <= steps; i++) { alpha = start + (((float)i / (float)steps) * len); if (shape.splines[curve].closed) { alpha = Mathf.Repeat(alpha, 1.0f); } Vector3 pos = tm1.MultiplyPoint3x4(shape.splines[curve].InterpCurve3D(alpha, shape.normalizedInterp, ref k) + off + lsection.offset); pos.x *= lsection.scale.x; pos.y *= lsection.scale.y; pos.z *= lsection.scale.z; verts.Add(pos); if (physuv) { if (i > 0) { dist += Vector3.Distance(pos, last); } last = pos; uv.x = (dist / width); } else { uv.x = alpha; } uvs.Add(uv); } evert = verts.Count - 1; uv.y = start + len; lsection.crossverts = verts.ToArray(); lsection.crossuvs = uvs.ToArray(); lsection.crosssize = MegaUtils.Extents(lsection.crossverts, out lsection.crossmin, out lsection.crossmax); }