Skip to content

Instantly share code, notes, and snippets.

@PixeyeHQ
Created April 28, 2020 16:21
Show Gist options
  • Select an option

  • Save PixeyeHQ/f2d8d9c2f5a5ef777b3cf485b2f37cc7 to your computer and use it in GitHub Desktop.

Select an option

Save PixeyeHQ/f2d8d9c2f5a5ef777b3cf485b2f37cc7 to your computer and use it in GitHub Desktop.
namespace Pixeye.Source
{
sealed class ProcessorRope : Processor<ComponentRope>, ITick
{
public override void HandleEvents()
{
foreach (ent entity in source.removed)
{
var cRope = entity.componentRope();
cRope.renderer.gameObject.Release();
}
}
public void Tick(float delta)
{
const int constraints_amount = 35;
const float gravity = -3f;
foreach (ent entity in source)
{
var cRope = entity.componentRope();
// kill
if (cRope.node_end == null || cRope.node_start == null)
{
entity.Release();
continue;
}
// draw
for (int i = 0; i < cRope.segments_amount; i++)
{
ref var seg = ref cRope.segments[i];
cRope.renderer.SetPosition(i, seg.pos_new);
}
// simulate
for (var i = 0; i < cRope.segments_amount; i++)
{
ref var seg = ref cRope.segments[i];
var velocity = seg.pos_new - seg.pos_old;
seg.pos_old = seg.pos_new;
seg.pos_new += velocity;
seg.pos_new.y += gravity * delta;
}
// constraints
for (var i = 0; i < constraints_amount; i++)
{
for (var ii = 0; ii < cRope.segments_amount - 1; ii++)
{
ref var seg1 = ref cRope.segments[ii];
ref var seg2 = ref cRope.segments[ii + 1];
var distance = (seg1.pos_new - seg2.pos_new).magnitude;
var error = math.abs(distance - cRope.rope_seg_len);
var dir = Vector2.zero;
if (distance > cRope.rope_seg_len)
{
dir = (seg1.pos_new - seg2.pos_new).normalized;
}
else if (distance < cRope.rope_seg_len)
{
dir = (seg2.pos_new - seg1.pos_new).normalized;
}
var change_amount = dir * error;
if (ii != 0)
{
seg1.pos_new -= change_amount * 0.5f;
seg2.pos_new += change_amount * 0.5f;
}
else
{
seg2.pos_new += change_amount * 0.5f;
}
}
}
ref var seg_first = ref cRope.segments[0];
ref var seg_last = ref cRope.segments[cRope.segments_amount - 1];
seg_first.pos_new = cRope.node_start.transform.position;
seg_last.pos_new = cRope.node_end.transform.position;
}
}
}
public sealed partial class game
{
public partial class create
{
public static ent rope(GameObject node1, GameObject node2, int segments_amount = 48, float line_width = 0.11f, float rope_seg_len = 0.25f)
{
Vector3 ropeStartPoint = node1.transform.position;
var result = Entity.Create();
var cRope = result.Set<ComponentRope>();
cRope.rope_seg_len = rope_seg_len;
cRope.segments_amount = segments_amount;
cRope.node_start = node1.transform;
cRope.node_end = node2.transform;
cRope.renderer = Obj.Spawn<LineRenderer>(db.prefabs.obj_rope, Vector3.zero);
cRope.renderer.startWidth = line_width;
cRope.renderer.endWidth = line_width;
cRope.node_start = node1.transform;
cRope.node_end = node2.transform;
cRope.segments = new SegmentRope[segments_amount];
cRope.renderer.SetPositions(new Vector3[segments_amount]);
cRope.renderer.positionCount = segments_amount;
for (int i = 0; i < segments_amount; i++)
{
ref var seg = ref cRope.segments[i];
seg.pos_new = ropeStartPoint;
seg.pos_old = ropeStartPoint;
ropeStartPoint.y -= rope_seg_len;
}
ref var seg_first = ref cRope.segments[0];
ref var seg_last = ref cRope.segments[segments_amount - 1];
seg_first.pos_new = node1.transform.position;
seg_last.pos_new = node2.transform.position;
return result;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment