public void MoveMasses(MegaWire wire) { for (int i = 0; i < connections.Count; i++) { connections[i].MoveMasses(wire); } }
public void UpdateSpan(MegaWire wire, float ts) { for (int i = 0; i < connections.Count; i++) { connections[i].Update(wire, ts); } }
public void OnSceneGUI() { MegaWire mod = (MegaWire)target; if ( mod.displayGizmo ) { Handles.color = mod.gizmoColor; for ( int i = 0; i < mod.spans.Count; i++ ) { MegaWireSpan span = mod.spans[i]; for ( int c = 0; c < span.connections.Count; c++ ) { MegaWireConnection con = span.connections[c]; Vector3 p = con.masspos[1]; Handles.DotCap(0, p, Quaternion.identity, con.radius); for ( int m = 2; m < con.masspos.Length - 1; m++ ) { p = con.masspos[m]; Handles.DotCap(0, con.masspos[m], Quaternion.identity, con.radius); } // Draw springs int scount = con.springs.Count; if ( mod.stiffnessSprings ) scount = con.masses.Count - 1; for ( int s = 0; s < scount; s++ ) { Vector3 p1 = con.masses[con.springs[s].p1].pos; Vector3 p2 = con.masses[con.springs[s].p2].pos; float w = ((con.springs[s].len - con.springs[s].restlen) / con.springs[s].restlen) * con.springs[s].ks; //con.springs[s].restlen; if ( w >= 0.0f ) Handles.color = Color.Lerp(Color.green, Color.red, w); else Handles.color = Color.Lerp(Color.green, Color.blue, -w); Handles.DrawLine(p1, p2); } } } if ( mod.disableOnDistance ) { Handles.color = mod.gizmoColor; for ( int s = 0; s < mod.spans.Count; s++ ) { Vector3 mp = (mod.spans[s].connections[0].masses[0].pos + mod.spans[s].connections[0].masses[mod.spans[s].connections[0].masses.Count - 1].pos) * 0.5f; Handles.SphereCap(0, mp, Quaternion.identity, mod.disableDist * 2.0f); } } } }
public void MoveMasses(MegaWire wire) { for (int i = 0; i < masses.Count; i++) { masspos[i + 1] = masses[i].pos; masses[i].forcec = Vector3.zero; } masspos[0] = masses[0].pos - (masses[1].pos - masses[0].pos); masspos[masspos.Length - 1] = masses[masses.Count - 1].pos + (masses[masses.Count - 1].pos - masses[masses.Count - 2].pos); }
public void Init(MegaWire wire) { if (start && end) { WireLength = Vector3.Distance(start.position, end.position); for (int i = 0; i < connections.Count; i++) { connections[i].Init(wire); } } }
private void CreateWire(string name, List <GameObject> objects, Material material) { if (objects.Count >= 3 && material != null) { MegaWire megaWire = MegaWire.Create(null, objects, material, "Powerline Wires", null, 1f, 0.1f); if (megaWire) { megaWire.enabled = false; megaWire.RunPhysics(megaWire.warmPhysicsTime); megaWire.gameObject.SetHierarchyGroup(name, true, false); } } }
public void Copy(MegaWire from, MegaWireConnectionHelper helper) { fudge = from.fudge; spring = from.spring; damp = from.damp; timeStep = from.timeStep; Mass = from.Mass; gravity = from.gravity; airdrag = from.airdrag; massRand = from.massRand; points = from.points; iters = from.iters; wind = from.wind; material = from.material; disableOnNotVisible = from.disableOnNotVisible; disableDist = from.disableDist; disableOnDistance = from.disableOnDistance; stretch = from.stretch; awakeTime = from.awakeTime; gizmoColor = from.gizmoColor; displayGizmo = from.displayGizmo; disableOnDistance = from.disableOnDistance; distfromcamera = from.distfromcamera; frameWait = from.frameWait; frameNum = from.frameNum; stiffnessSprings = from.stiffnessSprings; stiffrate = from.stiffrate; stiffdamp = from.stiffdamp; lengthConstraints = from.lengthConstraints; connections.Clear(); if (helper) { for (int i = 0; i < helper.connections.Count; i++) { connections.Add(new MegaWireConnectionDef(helper.connections[i])); } } else { for (int i = 0; i < from.connections.Count; i++) { connections.Add(new MegaWireConnectionDef(from.connections[i])); } } strandedMesher.Copy(from.strandedMesher); }
private void CreateWire(string name, List <GameObject> objects, Material material) { if (objects.Count < 3 || !Object.op_Inequality((Object)material, (Object)null)) { return; } MegaWire megaWire = MegaWire.Create((MegaWire)null, objects, material, "Powerline Wires", (MegaWire)null, 1f, 0.1f); if (!Object.op_Implicit((Object)megaWire)) { return; } ((Behaviour)megaWire).set_enabled(false); megaWire.RunPhysics((float)megaWire.warmPhysicsTime); ((Component)megaWire).get_gameObject().SetHierarchyGroup(name, true, false); }
public override void doIntegration1(MegaWireConnection rope, MegaWire wire, float dt) { Vector3 delta; Vector3 frc; doCalculateForces(rope, wire); // Calculate forces, only changes _f float t2 = dt * dt; float oodt = 1.0f / dt; /* Then do correction step by integration with central average (Heun) */ for (int i = 0; i < rope.masses.Count; i++) { Vector3 last = rope.masses[i].pos; //rope.masses[i].pos += wire.airdrag * (rope.masses[i].pos - rope.masses[i].last) + rope.masses[i].force * rope.masses[i].oneovermass * t2; // * t; //rope.masses[i].vel = (rope.masses[i].pos - last) / dt; delta.x = rope.masses[i].pos.x - rope.masses[i].last.x; delta.y = rope.masses[i].pos.y - rope.masses[i].last.y; delta.z = rope.masses[i].pos.z - rope.masses[i].last.z; float m2 = rope.masses[i].oneovermass * t2; frc.x = rope.masses[i].force.x * m2; frc.y = rope.masses[i].force.y * m2; frc.z = rope.masses[i].force.z * m2; //wire.masses[i].pos += wire.airdrag * (delta) + frc; //wire.masses[i].force * wire.masses[i].oneovermass * t2; // * t; rope.masses[i].pos.x += wire.airdrag * delta.x + frc.x; rope.masses[i].pos.y += wire.airdrag * delta.y + frc.y; rope.masses[i].pos.z += wire.airdrag * delta.z + frc.z; rope.masses[i].vel.x = (rope.masses[i].pos.x - last.x) * oodt; rope.masses[i].vel.y = (rope.masses[i].pos.y - last.y) * oodt; rope.masses[i].vel.z = (rope.masses[i].pos.z - last.z) * oodt; rope.masses[i].last = last; } DoConstraints(rope, wire); if (wire.doCollisions) { DoCollisions(rope, wire); } }
public override void OnInspectorGUI() { MegaWireHanger mod = (MegaWireHanger)target; undoManager.CheckUndo(); #if UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 #else EditorGUIUtility.LookLikeControls(); #endif MegaWire wire = (MegaWire)EditorGUILayout.ObjectField("Wire", mod.wire, typeof(MegaWire), true); if (wire != mod.wire) { mod.wire = wire; mod.parent = null; if (wire) { mod.parent = wire.transform.parent; } } mod.alpha = EditorGUILayout.Slider("Alpha", mod.alpha, 0.0f, 1.0f); int cons = 0; if (mod.wire) { cons = mod.wire.spans[0].connections.Count - 1; } mod.strand = EditorGUILayout.IntSlider("Strand", mod.strand, 0, cons); mod.offset = EditorGUILayout.FloatField("Offset", mod.offset); mod.align = EditorGUILayout.BeginToggleGroup("Align", mod.align); mod.rotate = EditorGUILayout.Vector3Field("Rotate", mod.rotate); EditorGUILayout.EndToggleGroup(); mod.weight = EditorGUILayout.FloatField("Weight", mod.weight); //mod.snaptomass = EditorGUILayout.Toggle("Snap To Mass", mod.snaptomass); if (GUI.changed) { EditorUtility.SetDirty(target); } undoManager.CheckDirty(); }
public override void OnInspectorGUI() { MegaWireAttach mod = (MegaWireAttach)target; undoManager.CheckUndo(); EditorGUIUtility.LookLikeControls(); MegaWire wire = (MegaWire)EditorGUILayout.ObjectField("Wire", mod.wire, typeof(MegaWire), true); if (wire != mod.wire) { mod.wire = wire; mod.parent = null; if (wire) { mod.parent = wire.transform.parent; } } mod.alpha = EditorGUILayout.Slider("Alpha", mod.alpha, 0.0f, 1.0f); int cons = 0; if (mod.wire) { cons = mod.wire.spans[0].connections.Count - 1; } mod.connection = EditorGUILayout.IntSlider("Strand", mod.connection, 0, cons); mod.offset = EditorGUILayout.Vector3Field("Offset", mod.offset); mod.align = EditorGUILayout.BeginToggleGroup("Align", mod.align); mod.rotate = EditorGUILayout.Vector3Field("Rotate", mod.rotate); EditorGUILayout.EndToggleGroup(); if (GUI.changed) { EditorUtility.SetDirty(target); } undoManager.CheckDirty(); }
void DoConstraints(MegaWireConnection rope, MegaWire wire) { for (int c = 0; c < rope.constraints.Count; c++) { rope.constraints[c].ReActivate(rope, wire.timeStep); } for (int i = 0; i < wire.iters; i++) { for (int c = 0; c < rope.lenconstraints.Count; c++) { rope.lenconstraints[c].Apply(rope); } for (int c = 0; c < rope.constraints.Count; c++) { rope.constraints[c].Apply(rope); } } }
void doCalculateForces(MegaWireConnection rope, MegaWire wire) { Vector3 frc = wire.gravity; frc.x += rope.windFrc.x; frc.y += rope.windFrc.y; frc.z += rope.windFrc.z; for (int i = 0; i < rope.masses.Count; i++) { rope.masses[i].force.x = (rope.masses[i].mass * frc.x) + rope.masses[i].forcec.x; rope.masses[i].force.y = (rope.masses[i].mass * frc.y) + rope.masses[i].forcec.y; rope.masses[i].force.z = (rope.masses[i].mass * frc.z) + rope.masses[i].forcec.z; } for (int i = 0; i < rope.springs.Count; i++) { rope.springs[i].doCalculateSpringForce1(rope); } }
void LateUpdate() { if (wire == null) { if (parent != null) { wire = parent.GetComponentInChildren <MegaWire>(); } } if (wire) { Vector3 lpos = Vector3.zero; if (alpha > 0.0f || alpha < 1.0f) { Vector3 rpos = wire.SetWeight(alpha, strand, weight, false); //snaptomass); lpos.x = rpos.x; lpos.y = rpos.y + offset; lpos.z = rpos.z; Vector3 p = wire.transform.localToWorldMatrix.MultiplyPoint(lpos); transform.position = p; if (align) { Vector3 p1 = wire.transform.localToWorldMatrix.MultiplyPoint(wire.SetWeight(alpha + 0.001f, strand, weight, false)); Vector3 relativePos = p1 - p; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); locrot = rotation; wtm.SetTRS(p, rotation, Vector3.one); Quaternion r1 = Quaternion.Euler(rotate); transform.rotation = locrot * r1; } } } }
void DoCollisions(MegaWireConnection rope, MegaWire wire) { for (int i = 0; i < rope.masses.Count; i++) { if (rope.masses[i].pos.y < wire.floor) { rope.masses[i].pos.y = wire.floor; float VdotN = Vector3.Dot(Vector3.up, rope.masses[i].vel); Vector3 Vn = Vector3.up * VdotN; // CALCULATE Vt //Vector3 Vt = (rope.masses[i].vel - Vn) * rope.floorfriction; // SCALE Vn BY COEFFICIENT OF RESTITUTION Vn *= 0.9f; //rope.bounce; // SET THE VELOCITY TO BE THE NEW IMPULSE rope.masses[i].vel = Vn; //Vt - Vn; rope.masses[i].last = rope.masses[i].pos; } } }
void LateUpdate() { if (wire == null) { if (parent != null) { wire = parent.GetComponentInChildren <MegaWire>(); } } if (wire) { float alpha1 = Mathf.Clamp(alpha, 0.0f, 0.9999f); float fa = alpha1 * (float)wire.spans.Count; int sindex = (int)fa; float aa = fa - (float)sindex; MegaWireSpan span = wire.spans[sindex]; MegaWireConnection con = span.connections[connection]; Vector3 p = con.Interp(aa); transform.position = p + offset; if (align) { Vector3 p1 = con.Interp(aa + 0.001f); Vector3 relativePos = p1 - p; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); locrot = rotation; wtm.SetTRS(p, rotation, Vector3.one); Quaternion r1 = Quaternion.Euler(rotate); transform.rotation = locrot * r1; } } }
public override void doIntegration1(MegaWireConnection rope, MegaWire wire, float dt) { doCalculateForces(rope, wire); // Calculate forces, only changes _f float t2 = dt * dt; /* Then do correction step by integration with central average (Heun) */ for (int i = 0; i < rope.masses.Count; i++) { Vector3 last = rope.masses[i].pos; rope.masses[i].pos += wire.airdrag * (rope.masses[i].pos - rope.masses[i].last) + rope.masses[i].force * rope.masses[i].oneovermass * t2; // * t; rope.masses[i].vel = (rope.masses[i].pos - last) / dt; rope.masses[i].last = last; } DoConstraints(rope, wire); if (wire.doCollisions) { DoCollisions(rope, wire); } }
public override void BuildMesh(MegaWire rope, MegaWireSpan span) { int wires = span.connections.Count; float lengthuvtile = uvtiley * span.WireLength; Twist = TwistPerUnit * span.WireLength; segments = (int)(span.WireLength * SegsPerUnit); if (segments < 1) { segments = 1; } int vcount = ((segments + 1) * (sides + 1)) * strands * wires; int tcount = ((sides * 2) * segments) * strands * wires; if (span.verts == null || span.verts.Length != vcount) { span.verts = new Vector3[vcount]; } bool buildtris = false; if ((span.uvs == null || span.uvs.Length != vcount) && genuv) { span.uvs = new Vector2[vcount]; rope.builduvs = true; } if (span.tris == null || span.tris.Length != tcount * 3) { span.tris = new int[tcount * 3]; buildtris = true; } if (span.norms == null || span.norms.Length != vcount) { span.norms = new Vector3[vcount]; } int vi = 0; int ti = 0; BuildCrossSection(1.0f); for (int c = 0; c < span.connections.Count; c++) { MegaWireConnection con = span.connections[c]; // TODO: inspector should update radius from def, then user can control per span float off = (rope.connections[c].radius * 0.5f) + offset; float sradius = 0.0f; if (strands == 1) { off = offset; sradius = rope.connections[c].radius; } else { sradius = (rope.connections[c].radius * 0.5f) + strandRadius; } Vector2 uv = Vector2.zero; Vector3 soff = Vector3.zero; int vo; for (int s = 0; s < strands; s++) { if (strands == 1) { vo = vi; if (linInterp) { for (int i = 0; i <= segments; i++) { float alpha = ((float)i / (float)segments); float uvt = alpha * uvtwist; wtm = con.GetDeformMatLin(alpha); for (int v = 0; v <= cross.Length; v++) { Vector3 p = cross[v % cross.Length]; span.verts[vi] = wtm.MultiplyPoint3x4(p * sradius); span.norms[vi] = wtm.MultiplyVector(p); if (genuv && rope.builduvs) { uv.y = alpha * lengthuvtile; uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt; span.uvs[vi] = uv; } vi++; } } } else { for (int i = 0; i <= segments; i++) { float alpha = ((float)i / (float)segments); float uvt = alpha * uvtwist; wtm = con.GetDeformMat(alpha); for (int v = 0; v <= cross.Length; v++) { Vector3 p = cross[v % cross.Length]; span.verts[vi] = wtm.MultiplyPoint3x4(p * sradius); span.norms[vi] = wtm.MultiplyVector(p); if (genuv && rope.builduvs) { uv.y = alpha * lengthuvtile; uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt; span.uvs[vi] = uv; } vi++; } } } } else { float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f; soff.x = Mathf.Sin(ang) * off; soff.z = Mathf.Cos(ang) * off; vo = vi; if (linInterp) { 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); soff.x = Mathf.Sin(ang + tst) * off; soff.z = Mathf.Cos(ang + tst) * off; wtm = con.GetDeformMatLin(alpha); for (int v = 0; v <= cross.Length; v++) { Vector3 p = cross[v % cross.Length]; span.verts[vi] = wtm.MultiplyPoint3x4((p * sradius) + soff); span.norms[vi] = wtm.MultiplyVector(p); if (genuv && rope.builduvs) { uv.y = alpha * lengthuvtile; uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt; span.uvs[vi] = uv; } vi++; } } } else { 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); soff.x = Mathf.Sin(ang + tst) * off; soff.z = Mathf.Cos(ang + tst) * off; wtm = con.GetDeformMat(alpha); for (int v = 0; v <= cross.Length; v++) { Vector3 p = cross[v % cross.Length]; span.verts[vi] = wtm.MultiplyPoint3x4((p * sradius) + soff); span.norms[vi] = wtm.MultiplyVector(p); if (genuv && rope.builduvs) { uv.y = alpha * lengthuvtile; uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt; span.uvs[vi] = uv; } vi++; } } } } if (buildtris) { int sc = sides + 1; for (int i = 0; i < segments; i++) { for (int v = 0; v < cross.Length; v++) { int v1 = ((i + 1) * sc) + v + vo; int v2 = ((i + 1) * sc) + ((v + 1) % sc) + vo; int v3 = (i * sc) + v + vo; int v4 = (i * sc) + ((v + 1) % sc) + vo; span.tris[ti++] = v1; //((i + 1) * sc) + v + vo; span.tris[ti++] = v2; //((i + 1) * sc) + ((v + 1) % sc) + vo; span.tris[ti++] = v3; //(i * sc) + v + vo; span.tris[ti++] = v2; //((i + 1) * sc) + ((v + 1) % sc) + vo; span.tris[ti++] = v4; //(i * sc) + ((v + 1) % sc) + vo; span.tris[ti++] = v3; //(i * sc) + v + vo; } } } } } if ((!genuv && rope.builduvs) || buildtris) { #if UNITY_3_5 span.mesh.Clear(); #else span.mesh.Clear(false); #endif } span.mesh.vertices = span.verts; if (genuv && rope.builduvs) { span.mesh.uv = span.uvs; } if ((!genuv && rope.builduvs) || buildtris) { span.mesh.triangles = span.tris; } if (calcBounds) { span.mesh.RecalculateBounds(); } span.mesh.normals = span.norms; if (calcTangents && genuv) { BuildTangents(span.mesh, span.verts, span.uvs, span.mesh.normals, span.tris); } span.vcount = vcount; }
// each wire length should have a very simple script attached that can do onvisible etc // to turn off the updates, other than that all updates should be done from MegaWire static public MegaWire Create(MegaWire wire, List <GameObject> objs, Material mat, string name, MegaWire copyfrom, float wiresize, float str) { //MegaWire wire = null; if (objs != null && objs.Count > 1) { GameObject newwire = null; if (wire == null) { newwire = new GameObject(); newwire.name = name; wire = newwire.AddComponent <MegaWire>(); wire.material = mat; wire.stretch = str; } else { newwire = wire.gameObject; } wire.poles.Clear(); wire.spans.Clear(); wire.connections.Clear(); wire.poles.Add(objs[0].transform); bool hide = true; if (copyfrom) { hide = copyfrom.hidespans; } // Make the connections, each connection is a new gameobject child of the wire object for (int i = 0; i < objs.Count - 1; i++) { GameObject pole = new GameObject(); if (hide) { pole.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.NotEditable; } pole.name = name + " Span Mesh " + i; pole.transform.parent = newwire.transform; MegaWireSpan span = pole.AddComponent <MegaWireSpan>(); span.start = objs[i].transform; span.end = objs[i + 1].transform; MeshFilter mf = pole.GetComponent <MeshFilter>(); mf.sharedMesh = new Mesh(); MeshRenderer mr = pole.GetComponent <MeshRenderer>(); Material[] mats = new Material[1]; mats[0] = wire.material; mr.sharedMaterials = mats; span.mesh = mf.sharedMesh; span.mesh.name = name + " Wire Mesh " + i; span.Init(wire); wire.spans.Add(span); wire.poles.Add(objs[i + 1].transform); } MegaWireConnectionHelper helper = objs[0].GetComponent <MegaWireConnectionHelper>(); if (copyfrom) { wire.Copy(copyfrom, helper); } else { // Check if any pole has a helper on it, if so use that if (helper) { wire.Copy(wire, helper); } else { // Add the first connection MegaWireConnectionDef con = new MegaWireConnectionDef(); wire.connections.Add(con); } } if (wiresize != 1.0f) { for (int i = 0; i < wire.connections.Count; i++) { wire.connections[i].radius *= wiresize; } } wire.Init(); } return(wire); }
public void BuildMesh(MegaWire wire) { wire.strandedMesher.BuildMesh(wire, this); }
public void Init(MegaWire wire) { if (start == null || end == null) { return; } Vector3 p1 = start.TransformPoint(outOffset); Vector3 p2 = end.TransformPoint(inOffset); WireLength = (p1 - p2).magnitude; if (masses == null) { masses = new List <MegaWireMass>(); } masses.Clear(); float ms = wire.Mass / (float)(wire.points + 1); for (int i = 0; i <= wire.points; i++) { float alpha = (float)i / (float)wire.points; float rn = (Random.value - 0.5f) * 2.0f * (wire.massRand * ms); float m = rn + ms; MegaWireMass rm = new MegaWireMass(m, Vector3.Lerp(p1, p2, alpha)); masses.Add(rm); } if (springs == null) { springs = new List <MegaWireSpring>(); } springs.Clear(); if (constraints == null) { constraints = new List <MegaWirePointConstraint>(); } if (lenconstraints == null) { lenconstraints = new List <MegaWireLengthConstraint>(); } constraints.Clear(); lenconstraints.Clear(); for (int i = 0; i < masses.Count - 1; i++) { MegaWireSpring spr = new MegaWireSpring(i, i + 1, wire.spring, wire.damp, this, wire.stretch); springs.Add(spr); if (wire.lengthConstraints) { MegaWireLengthConstraint lcon = new MegaWireLengthConstraint(i, i + 1, spr.restlen); lenconstraints.Add(lcon); } } if (wire.stiffnessSprings) { int gap = 2; for (int i = 0; i < masses.Count - gap; i++) { MegaWireSpring spr = new MegaWireSpring(i, i + 2, wire.stiffrate, wire.stiffdamp, this, wire.stretch); springs.Add(spr); //float alpha = (float)i / (float)masses.Count; //MegaWireSpring spr = new MegaWireSpring(i, i + gap, stiffspring * stiffnessCrv.Evaluate(alpha), stiffdamp * stiffnessCrv.Evaluate(alpha), this); //, stretch); //springs.Add(spr); //WireLengthConstraint lcon = new WireLengthConstraint(i, i + gap, spr.restlen); //constraints.Add(lcon); } } // Apply fixed end constraints MegaWirePointConstraint pcon = new MegaWirePointConstraint(0, start.transform, outOffset); constraints.Add(pcon); pcon = new MegaWirePointConstraint(masses.Count - 1, end.transform, inOffset); constraints.Add(pcon); masspos = new Vector3[masses.Count + 2]; for (int i = 0; i < masses.Count; i++) { masspos[i + 1] = masses[i].pos; } masspos[0] = masses[0].pos - (masses[1].pos - masses[0].pos); masspos[masspos.Length - 1] = masses[masses.Count - 1].pos + (masses[masses.Count - 1].pos - masses[masses.Count - 2].pos); }
public void Update(MegaWire wire, float timeStep) { wire.verletsolver.doIntegration1(this, wire, timeStep); }
public void Rebuild() { if (path && pole) { update = false; MegaWire oldwire = transform.GetComponentInChildren <MegaWire>(); // Destroy all children while (transform.childCount > 0) { GameObject go = transform.GetChild(0).gameObject; if (Application.isEditor) { DestroyImmediate(go); } else { Destroy(go); } } int polecount = (int)((path.splines[curve].length * length) / spacing); float alpha = start; float da = length / polecount; if (path.splines[curve].closed) { polecount--; } poles.Clear(); #if UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 Random.InitState(seed); #else Random.seed = seed; #endif float spacealpha = ((spacing / (path.splines[curve].length * length)) / 1.0f) * spacingVariation; // mmm need upright in here for (int i = 0; i <= polecount; i++) { float a = alpha; if (i != 0 && i != polecount - 1) { a = alpha + (Random.Range(-1.0f, 1.0f) * spacealpha); } Vector3 p = path.transform.TransformPoint(path.InterpCurve3D(curve, a, true)); Vector3 p1 = path.transform.TransformPoint(path.InterpCurve3D(curve, a + 0.001f, true)); Vector3 poff = Vector3.zero; poff.y = Random.Range(0.0f, 1.0f) * positionVariation.y; poff.z = Random.Range(-1.0f, 1.0f) * positionVariation.z; Vector3 dir = (p1 - p).normalized; Vector3 outline = Vector3.Cross(dir, Vector3.up) * (offset + poff.z); p += outline; p1 += outline; //Vector3 up = Vector3.up; //Vector3 norm = up; Quaternion hitrot = Quaternion.identity; if (conform) { Ray ray = new Ray(); Vector3 origin = p; origin.y = 1000.0f; ray.origin = origin; ray.direction = Vector3.down; RaycastHit[] hits = Physics.RaycastAll(ray); if (hits.Length > 0) { int hindex = 0; p = hits[hindex].point; for (int j = 1; j < hits.Length; j++) { if (hits[j].point.y > p.y) { hindex = j; p = hits[hindex].point; } } Vector3 norm1 = Vector3.Lerp(hits[hindex].normal, Vector3.up, upright).normalized; hitrot = Quaternion.FromToRotation(Vector3.up, norm1); } } else { } Vector3 relativePos = p1 - p; relativePos.y = 0.0f; //*= upright; Quaternion rot = Quaternion.LookRotation(relativePos, Vector3.up); Vector3 rrot = Vector3.zero; rrot.x = Random.Range(-1.0f, 1.0f) * rotateVariation.x; rrot.y = Random.Range(-1.0f, 1.0f) * rotateVariation.y; rrot.z = Random.Range(-1.0f, 1.0f) * rotateVariation.z; Quaternion erot = Quaternion.Euler(rotate + rrot); p.y -= poff.y; GameObject go = (GameObject)GameObject.Instantiate(pole, p, hitrot * rot * erot); //rot * hitrot * erot); go.name = "Pole " + i; go.transform.parent = transform; alpha += da; poles.Add(go); } if (length >= 0.99999f && path.splines[curve].closed) { poles.Add(poles[0]); } if (addwires) { if (reverseWire) { poles.Reverse(); } MegaWire wire = MegaWire.Create(oldwire, poles, material, "Wires", copyfrom, wireSizeMult, stretch); if (wire) { wire.transform.parent = transform; } } } }
void OnGUI() { scroll = EditorGUILayout.BeginScrollView(scroll); if (picking) { if (GUILayout.Button("Stop Picking")) { picking = false; } } else { if (GUILayout.Button("Start Picking")) { picking = true; lastsel = null; // Ask if clear or add if (selection.Count > 0) { bool opt = EditorUtility.DisplayDialog("Add or Replace", "Do you want to Add to or Replace selection", "Add", "Replace"); if (opt == false) { selection.Clear(); } } } } // If we have a wire object selected then replace the selection if (GUILayout.Button("Create Wire")) { picking = false; MegaWire wire = MegaWire.Create(null, selection, material, wirename, copyfrom, 1.0f, 1.0f); copyfrom = wire; selection.Clear(); } wirename = EditorGUILayout.TextField("Wire Name", wirename); material = (Material)EditorGUILayout.ObjectField("Material", material, typeof(Material), true); copyfrom = (MegaWire)EditorGUILayout.ObjectField("Copy From", copyfrom, typeof(MegaWire), true); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Current Selection"); for (int i = 0; i < selection.Count; i++) { EditorGUILayout.LabelField(i + ": " + selection[i].name); } EditorGUILayout.EndVertical(); showarrows = EditorGUILayout.Foldout(showarrows, "Arrow Params"); if (showarrows) { units = (MegaWireUnits)EditorGUILayout.EnumPopup("Units", units); unitsScale = EditorGUILayout.FloatField("Units Scale", unitsScale); arrowwidth = EditorGUILayout.FloatField("Arrow Width", arrowwidth); arrowlength = EditorGUILayout.FloatField("Arrow Length", arrowlength); arrowoff = EditorGUILayout.Slider("Arrow Offset", arrowoff, 0.0f, 1.0f); vertStart = EditorGUILayout.FloatField("Vert Start", vertStart); vertLength = EditorGUILayout.FloatField("Vert Length", vertLength); dashdist = EditorGUILayout.FloatField("Dash Dist", dashdist); lineCol = EditorGUILayout.ColorField("Line Color", lineCol); arrowCol = EditorGUILayout.ColorField("Arrow Color", arrowCol); otherCol = EditorGUILayout.ColorField("Other Color", otherCol); dashCol = EditorGUILayout.ColorField("Dash Color", dashCol); } EditorGUILayout.EndScrollView(); }
public void Rebuild() { CalcLength(); if (waypoints.Count > 1 && pole) { update = false; //GameObject oldwire = null; MegaWire oldwire = transform.GetComponentInChildren <MegaWire>(); // Destroy all children MegaWireConnectionHelper[] spans = transform.GetComponentsInChildren <MegaWireConnectionHelper>(); for (int i = 0; i < spans.Length; i++) { if (Application.isEditor) { DestroyImmediate(spans[i].gameObject); } else { Destroy(spans[i].gameObject); } } MegaWireSpan[] spans1 = transform.GetComponentsInChildren <MegaWireSpan>(); for (int i = 0; i < spans1.Length; i++) { if (Application.isEditor) { DestroyImmediate(spans1[i].gameObject); } else { Destroy(spans1[i].gameObject); } } #if false while (transform.childCount > 0) { GameObject go = transform.GetChild(0).gameObject; // Dont destroy wire object MegaWire wire = go.GetComponent <MegaWire>(); if (!wire) { if (Application.isEditor) { DestroyImmediate(go); } else { Destroy(go); } } else { oldwire = go; } } #endif int polecount = (int)((pathlength * length) / spacing); float alpha = start; float da = length / polecount; if (closed) { polecount--; } poles.Clear(); Random.seed = seed; float spacealpha = ((spacing / (pathlength * length)) / 2.0f) * spacingVariation; for (int i = 0; i <= polecount; i++) { float a = alpha; if (i != 0 && i != polecount) { a = alpha + (Random.Range(-1.0f, 1.0f) * spacealpha); } Vector3 p = InterpCurve3D(a); Vector3 p1 = InterpCurve3D(a + 0.001f); Vector3 poff = Vector3.zero; poff.y = Random.Range(0.0f, 1.0f) * positionVariation.y; poff.z = Random.Range(-1.0f, 1.0f) * positionVariation.z; Vector3 dir = (p1 - p).normalized; Vector3 outline = Vector3.Cross(dir, Vector3.up) * (offset + poff.z); p += outline; p1 += outline; Quaternion hitrot = Quaternion.identity; if (conform) { Ray ray = new Ray(); Vector3 origin = p; origin.y = 1000.0f; ray.origin = origin; ray.direction = Vector3.down; RaycastHit[] hits = Physics.RaycastAll(ray); if (hits.Length > 0) { int hindex = 0; p = hits[hindex].point; for (int j = 1; j < hits.Length; j++) { if (hits[j].point.y > p.y) { hindex = j; p = hits[hindex].point; } } Vector3 norm1 = Vector3.Lerp(hits[hindex].normal, Vector3.up, upright).normalized; hitrot = Quaternion.FromToRotation(Vector3.up, norm1); } } else { } Vector3 relativePos = p1 - p; relativePos.y = 0.0f; Quaternion rot = Quaternion.LookRotation(relativePos, Vector3.up); Vector3 rrot = Vector3.zero; rrot.x = Random.Range(-1.0f, 1.0f) * rotateVariation.x; rrot.y = Random.Range(-1.0f, 1.0f) * rotateVariation.y; rrot.z = Random.Range(-1.0f, 1.0f) * rotateVariation.z; Quaternion erot = Quaternion.Euler(rotate + rrot); p.y -= poff.y; GameObject go = (GameObject)GameObject.Instantiate(pole, p, hitrot * rot * erot); //rot * hitrot * erot); go.name = name + " Pole " + i; go.transform.parent = transform; alpha += da; poles.Add(go); } if (length >= 0.99999f && closed) { poles.Add(poles[0]); } if (addwires) { if (reverseWire) { poles.Reverse(); } MegaWire wire = MegaWire.Create(oldwire, poles, material, name + " Wires", copyfrom, wireSizeMult, stretch); if (wire) { wire.transform.parent = transform; } } } }
public virtual void doIntegration1(MegaWireConnection rope, MegaWire wire, float dt) { }
void DoCollisions(MegaWireConnection rope, MegaWire wire) { if (wire.useraycast) { int mask = wire.collisionmask.value; RaycastHit hit; float len = wire.collisiondist + wire.collisionoff; Vector3 upd = Vector3.up * wire.collisiondist; for (int i = 0; i < rope.masses.Count; i++) { Vector3 p = rope.masses[i].pos + upd; bool result = Physics.Raycast(p, -Vector3.up, out hit, len, mask); //bool result = Physics.SphereCast(p, 0.1f, -Vector3.up, out hit, len, mask); //Vector3 delta = rope.masses[i].pos - rope.masses[i].last; //bool result = Physics.Raycast(rope.masses[i].last, delta.normalized, out hit, delta.magnitude, mask); if (result) { //Debug.Log("p " + rope.masses[i].pos + " l " + rope.masses[i].last + " h " + hit.point); //Vector3 hp = hit.point + (hit.normal * wire.collisionoff); //Debug.Log("hp " + hit.point + " mhp " + hp); rope.masses[i].pos.x = hit.point.x; rope.masses[i].pos.y = hit.point.y + wire.collisionoff; rope.masses[i].pos.z = hit.point.z; //rope.masses[i].pos = hp; float VdotN = Vector3.Dot(Vector3.up, rope.masses[i].vel); Vector3 Vn = Vector3.up * VdotN; // CALCULATE Vt //Vector3 Vt = (rope.masses[i].vel - Vn) * rope.floorfriction; // SCALE Vn BY COEFFICIENT OF RESTITUTION Vn *= 0.9f; //rope.bounce; // SET THE VELOCITY TO BE THE NEW IMPULSE rope.masses[i].vel = Vn; //Vt - Vn; rope.masses[i].last = rope.masses[i].pos; } } } else { for (int i = 0; i < rope.masses.Count; i++) { if (rope.masses[i].pos.y < wire.floor) { rope.masses[i].pos.y = wire.floor; float VdotN = Vector3.Dot(Vector3.up, rope.masses[i].vel); Vector3 Vn = Vector3.up * VdotN; // CALCULATE Vt //Vector3 Vt = (rope.masses[i].vel - Vn) * rope.floorfriction; // SCALE Vn BY COEFFICIENT OF RESTITUTION Vn *= 0.9f; //rope.bounce; // SET THE VELOCITY TO BE THE NEW IMPULSE rope.masses[i].vel = Vn; //Vt - Vn; rope.masses[i].last = rope.masses[i].pos; } } } }
public override void OnInspectorGUI() { MegaWire mod = (MegaWire)target; undoManager.CheckUndo(); #if UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 #else EditorGUIUtility.LookLikeControls(); #endif MegaWire.DisableAll = EditorGUILayout.Toggle("Disable All", MegaWire.DisableAll); if (GUILayout.Button("Rebuild")) { mod.Rebuild = true; mod.RebuildWire(); } mod.warmPhysicsTime = EditorGUILayout.FloatField("Warm Physics Time", mod.warmPhysicsTime); if (GUILayout.Button("Run Physics")) { mod.RunPhysics(mod.warmPhysicsTime); } if (GUILayout.Button("Open Select Window")) { } if (GUILayout.Button("Add Wire")) { MegaWireConnectionDef last = mod.connections[mod.connections.Count - 1]; MegaWireConnectionDef cdef = new MegaWireConnectionDef(); cdef.inOffset = last.inOffset; cdef.outOffset = last.outOffset; cdef.radius = last.radius; mod.connections.Add(cdef); mod.RebuildWire(); mod.Rebuild = true; } mod.Enabled = EditorGUILayout.Toggle("Enabled", mod.Enabled); bool ShowWire = EditorGUILayout.Toggle("Show Wire", mod.ShowWire); if (ShowWire != mod.ShowWire) { mod.ShowWire = ShowWire; mod.SetWireVisible(ShowWire); } // Lod params mod.disableOnDistance = EditorGUILayout.BeginToggleGroup("Disable On Dist", mod.disableOnDistance); mod.disableDist = EditorGUILayout.FloatField("Disable Dist", mod.disableDist); EditorGUILayout.EndToggleGroup(); mod.disableOnNotVisible = EditorGUILayout.Toggle("Disable On InVisible", mod.disableOnNotVisible); // Physics data mod.showphysics = EditorGUILayout.Foldout(mod.showphysics, "Physics Params"); if (mod.showphysics) { EditorGUILayout.BeginVertical("box"); int points = EditorGUILayout.IntSlider("Masses", mod.points, 2, 20); if (points != mod.points) { mod.points = points; mod.RebuildWire(); } float Mass = EditorGUILayout.FloatField("Mass", mod.Mass); if (Mass != mod.Mass) { mod.Mass = Mass; mod.RebuildWire(); } float massrnd = EditorGUILayout.FloatField("Mass Random", mod.massRand); if (massrnd != mod.massRand) { mod.massRand = massrnd; mod.RebuildWire(); } float spring = EditorGUILayout.FloatField("Spring", mod.spring); if (spring != mod.spring) { mod.spring = spring; mod.RebuildWire(); } float damp = EditorGUILayout.FloatField("Damp", mod.damp); if (damp != mod.damp) { mod.damp = damp; mod.RebuildWire(); } float stretch = EditorGUILayout.FloatField("Stretch", mod.stretch); if (stretch != mod.stretch) { mod.stretch = stretch; mod.ChangeStretch(stretch); } mod.gravity = EditorGUILayout.Vector3Field("Gravity", mod.gravity); mod.airdrag = EditorGUILayout.Slider("Aero Drag", mod.airdrag, 0.0f, 1.0f); // These require a rebuild bool lencon = EditorGUILayout.Toggle("Length Constraints", mod.lengthConstraints); if (lencon != mod.lengthConstraints) { mod.lengthConstraints = lencon; mod.RebuildWire(); } bool stiff = EditorGUILayout.BeginToggleGroup("Stiff Springs", mod.stiffnessSprings); if (stiff != mod.stiffnessSprings) { mod.stiffnessSprings = stiff; mod.RebuildWire(); } float stiffrate = EditorGUILayout.FloatField("Stiff Rate", mod.stiffrate); if (stiffrate != mod.stiffrate) { mod.stiffrate = stiffrate; mod.RebuildWire(); } float stiffdamp = EditorGUILayout.FloatField("Stiff Damp", mod.stiffdamp); if (stiffdamp != mod.stiffdamp) { mod.stiffdamp = stiffdamp; mod.RebuildWire(); } EditorGUILayout.EndToggleGroup(); mod.doCollisions = EditorGUILayout.BeginToggleGroup("Do Collisions", mod.doCollisions); mod.useraycast = EditorGUILayout.Toggle("Use RayCast", mod.useraycast); if (mod.useraycast) { mod.collisionoff = EditorGUILayout.FloatField("Collision Offset", mod.collisionoff); mod.collisiondist = EditorGUILayout.FloatField("Collision Dist", mod.collisiondist); mod.collisionmask = LayerMaskField("Mask", mod.collisionmask); } else { mod.floor = EditorGUILayout.FloatField("Floor", mod.floor); } EditorGUILayout.EndToggleGroup(); mod.showWindParams = EditorGUILayout.Foldout(mod.showWindParams, "Wind Params"); if (mod.showWindParams) { mod.wind = (MegaWireWind)EditorGUILayout.ObjectField("Wind Src", mod.wind, typeof(MegaWireWind), true); MegaWire.windDir = EditorGUILayout.Vector3Field("Wind Dir", MegaWire.windDir); MegaWire.windFrc = EditorGUILayout.FloatField("Wind Frc", MegaWire.windFrc); mod.windEffect = EditorGUILayout.FloatField("Wind Effect", mod.windEffect); } mod.showPhysicsAdv = EditorGUILayout.Foldout(mod.showPhysicsAdv, "Advanced Params"); if (mod.showPhysicsAdv) { mod.timeStep = EditorGUILayout.FloatField("Time Step", mod.timeStep); mod.fudge = EditorGUILayout.FloatField("Time Mult", mod.fudge); mod.startTime = EditorGUILayout.FloatField("Start Time", mod.startTime); mod.awakeTime = EditorGUILayout.FloatField("Awake Time", mod.awakeTime); mod.frameWait = EditorGUILayout.IntField("Frame Wait", mod.frameWait); mod.frameNum = EditorGUILayout.IntField("Frame Num", mod.frameNum); mod.iters = EditorGUILayout.IntSlider("Constraint Iters", mod.iters, 1, 8); } EditorGUILayout.EndVertical(); } // Meshing options mod.showmeshparams = EditorGUILayout.Foldout(mod.showmeshparams, "Mesh Params"); if (mod.showmeshparams) { EditorGUILayout.BeginVertical("box"); Material mat = (Material)EditorGUILayout.ObjectField("Material", mod.material, typeof(Material), true); if (mat != mod.material) { mod.material = mat; for (int i = 0; i < mod.spans.Count; i++) { Renderer rend = mod.spans[i].GetComponent <Renderer>(); if (rend) { rend.sharedMaterial = mat; } } } mod.strandedMesher.sides = EditorGUILayout.IntSlider("Sides", mod.strandedMesher.sides, 2, 32); mod.strandedMesher.segments = EditorGUILayout.IntSlider("Segments", mod.strandedMesher.segments, 1, 64); mod.strandedMesher.SegsPerUnit = EditorGUILayout.FloatField("Segs Per Unit", mod.strandedMesher.SegsPerUnit); mod.strandedMesher.strands = EditorGUILayout.IntSlider("Strands", mod.strandedMesher.strands, 1, 8); mod.strandedMesher.offset = EditorGUILayout.FloatField("Offset", mod.strandedMesher.offset); mod.strandedMesher.strandRadius = EditorGUILayout.FloatField("Strand Radius", mod.strandedMesher.strandRadius); mod.strandedMesher.Twist = EditorGUILayout.FloatField("Twist", mod.strandedMesher.Twist); mod.strandedMesher.TwistPerUnit = EditorGUILayout.FloatField("Twist Per Unit", mod.strandedMesher.TwistPerUnit); bool genuv = EditorGUILayout.BeginToggleGroup("Gen UV", mod.strandedMesher.genuv); if (genuv != mod.strandedMesher.genuv) { mod.strandedMesher.genuv = genuv; mod.builduvs = true; } float uvtwist = EditorGUILayout.FloatField("UV Twist", mod.strandedMesher.uvtwist); if (uvtwist != mod.strandedMesher.uvtwist) { mod.strandedMesher.uvtwist = uvtwist; mod.builduvs = true; } float uvtilex = EditorGUILayout.FloatField("UV Tile X", mod.strandedMesher.uvtilex); if (uvtilex != mod.strandedMesher.uvtilex) { mod.strandedMesher.uvtilex = uvtilex; mod.builduvs = true; } float uvtiley = EditorGUILayout.FloatField("UV Tile Y", mod.strandedMesher.uvtiley); if (uvtiley != mod.strandedMesher.uvtiley) { mod.strandedMesher.uvtiley = uvtiley; mod.builduvs = true; } EditorGUILayout.EndToggleGroup(); mod.strandedMesher.linInterp = EditorGUILayout.Toggle("Linear Interp", mod.strandedMesher.linInterp); mod.strandedMesher.calcBounds = EditorGUILayout.Toggle("Calc Bounds", mod.strandedMesher.calcBounds); mod.strandedMesher.calcTangents = EditorGUILayout.Toggle("Calc Tangents", mod.strandedMesher.calcTangents); int vcount = mod.GetVertexCount(); EditorGUILayout.LabelField("Vertex Count: " + vcount); EditorGUILayout.EndVertical(); } mod.showconnections = EditorGUILayout.Foldout(mod.showconnections, "Connections"); if (mod.showconnections) { for (int i = 0; i < mod.connections.Count; i++) { MegaWireConnectionDef con = mod.connections[i]; EditorGUILayout.BeginVertical("box"); float radius = EditorGUILayout.FloatField("Radius", con.radius); if (radius != con.radius) { con.radius = radius; } Vector3 outOffset = EditorGUILayout.Vector3Field("Out Offset", con.outOffset); if (outOffset != con.outOffset) { con.outOffset = outOffset; mod.Rebuild = true; } Vector3 inOffset = EditorGUILayout.Vector3Field("In Offset", con.inOffset); if (inOffset != con.inOffset) { con.inOffset = inOffset; mod.Rebuild = true; } if (GUILayout.Button("Delete")) { if (mod.connections.Count > 1) { mod.connections.RemoveAt(i); mod.RebuildWire(); mod.Rebuild = true; } } EditorGUILayout.EndVertical(); } } bool hidespans = EditorGUILayout.Toggle("Hide Spans", mod.hidespans); if (hidespans != mod.hidespans) { mod.hidespans = hidespans; mod.SetHidden(mod.hidespans); EditorApplication.RepaintHierarchyWindow(); } mod.displayGizmo = EditorGUILayout.BeginToggleGroup("Show Gizmos", mod.displayGizmo); mod.gizmoColor = EditorGUILayout.ColorField("Gizmo Color", mod.gizmoColor); EditorGUILayout.EndToggleGroup(); mod.showAttach = EditorGUILayout.Foldout(mod.showAttach, "Span Connections"); if (mod.showAttach) { EditorGUILayout.BeginVertical("Box"); for (int i = 0; i < mod.spans.Count; i++) { if (i > 0) { EditorGUILayout.Separator(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Start", GUILayout.MaxWidth(40.0f)); for (int c = 0; c < mod.spans[i].connections.Count; c++) { bool active = EditorGUILayout.Toggle(mod.spans[i].connections[c].constraints[0].active, GUILayout.MaxWidth(10.0f)); if (active != mod.spans[i].connections[c].constraints[0].active) { mod.spans[i].connections[c].SetEndConstraintActive(0, active, 2.0f); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("End", GUILayout.MaxWidth(40.0f)); for (int c = 0; c < mod.spans[i].connections.Count; c++) { bool active = EditorGUILayout.Toggle(mod.spans[i].connections[c].constraints[1].active, GUILayout.MaxWidth(10.0f)); if (active != mod.spans[i].connections[c].constraints[1].active) { mod.spans[i].connections[c].SetEndConstraintActive(1, active, 2.0f); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); } if (GUI.changed) { EditorUtility.SetDirty(target); } undoManager.CheckDirty(); }
public virtual void BuildMesh(MegaWire rope, MegaWireSpan span) { }