Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Rope going inside the table
#1
Hi,
 Please check this video. when a shape with obicollider collides with the rope, rope goes inside the table ignoring collision.
 Shape ObiCollider rigidbody has constraints x and z rotation locked and y position locked. Attached rigidbody, collider, solver and rope config snapshots.

 Rope creation:
 
Code:
private IEnumerator CreateRope(ObiSolver solver, ObiRope rope)
{
    // Create a rope
   
    // Setup a blueprint for the rope:
    var blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
    blueprint.resolution = 0.65f;
    blueprint.thickness = 0.07f;
    blueprint.pooledParticles = 5;


    Vector3 point = Vector3.zero;
    blueprint.path.Clear();
    int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);
    float mass = 1;
    for (int i = 0; i < points.Length; i++)
    {
        if (i == 0 || i == points.Length - 1)
        {
            mass = .001f;
            filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 2);
        }
        else
        {
            mass = .002f;
            filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);
        }
        if( i == 0 )
        {
            point = rope.transform.InverseTransformPoint(points[i].position);
            blueprint.path.AddControlPoint(point, -Vector3.zero, Vector3.zero, Vector3.up, mass, 0.5f, 1, filter, Color.white, "A");
            continue;
        }

        Vector3 point2 = rope.transform.InverseTransformPoint(points[i].position);
        Vector3 direction = (point2 - points[i-1].position) * 0.25f;
       
        blueprint.path.AddControlPoint(point2, -direction, direction, Vector3.up, mass, 0.5f, 1, filter, Color.white, points[i].name);
       
        // convert both points to the rope's local space:
        /*pointA = rope.transform.InverseTransformPoint(pointA);
        pointB = rope.transform.InverseTransformPoint(pointB);

        // Procedurally generate the rope path (a simple straight line):
        Vector3 direction = (pointB - pointA) * 0.25f;
        blueprint.path.Clear();
        blueprint.path.AddControlPoint(pointA, -direction, direction, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "A");
        blueprint.path.AddControlPoint(pointB, -direction, direction, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "B");*/
    }

    blueprint.path.FlushEvents();
    yield return StartCoroutine(blueprint.Generate());

    rope.collisionMaterial = collisionMaterial;
    rope.ropeBlueprint = blueprint;

    // access the distance constraints currently simulated by the solver:
    var solverConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Distance)
                as ObiConstraints<ObiDistanceConstraintsBatch>;
    int batches = solverConstraints.batches.Count;
    for (int k = 0; k < batches; k++)
    {
        int cnt = solverConstraints.batches[k].constraintCount;
        for (int i = 0; i < cnt; i++)
        {
            solverConstraints.batches[k].restLengths[i] = length;
        }
    }
   
   

    var obiRopeExtrudeRenderer = rope.GetComponent<ObiRopeExtrudedRenderer>();
    // load the default rope section:
    obiRopeExtrudeRenderer.section = Resources.Load<ObiRopeSection>("DefaultRopeSection");
    obiRopeExtrudeRenderer.GetComponent<MeshRenderer>().material = material;
    obiRopeExtrudeRenderer.GetComponent<ObiPathSmoother>().decimation = 0.1f;
    obiRopeExtrudeRenderer.GetComponent<ObiPathSmoother>().smoothing = 3;

    cursor = rope.AddComponent<ObiRopeCursor>();
    cursor.cursorMu = 1;
    cursor.sourceMu = 1;

    rope.GetComponent<TangledRope>().cursor = cursor;

    obiRopeExtrudeRenderer.uvScale = new Vector2(2, 15);
    obiRopeExtrudeRenderer.thicknessScale = 1.1f;

    rope.distanceConstraintsEnabled = true;
    rope.stretchingScale = 1f;
    rope.stretchCompliance = 0f;
    rope.bendCompliance = 1f;
 
 



    PinRope(rope, points[0].GetComponent<ObiCollider>(), points[points.Length - 1].GetComponent<ObiCollider>(), new Vector3(0f, 0, 0), new Vector3(0f, 0, 0));

    //RopeAttachment(rope, points[0].GetComponent<ObiCollider>(), points[points.Length - 1].GetComponent<ObiCollider>());

    //AddDistanceConstrants(rope);

}
 
 https://drive.google.com/file/d/1YVsB6C8r1uQpQkQYQFSzM0K3RfHVj_f3/view?usp=sharing


Attached Files Thumbnail(s)
               
Reply
#2
Hi,

You've checked "convex" in your MeshCollider but it's clearly concave as it has 3 holes, trough which the rope is passing.

Concave (non-convex) dynamic (non-kinematic) MeshColliders aren't supported by Unity, and by extension, not supported by Obi. Obi will attempt to consider it concave despite being marked as convex for more accurate collision detection, but it can't do magic  Triste .

Quote:Concave colliders have some limitations: Concave Mesh colliders can only be static (that is, they have no physics body) or kinematic (they have a kinematic physics body).

The reason is very simple: concave colliders do not have any volume - they're paper-thin, only their surface generates collisions. Moving them around will make it extremely easy for other objects to pass trough them.

Solutions: either use a compound collider (that is, multiple primitive colliders) to approximate your shape, or use a distance field.

kind regards,
Reply
#3
Ah I see. Ok Thanks!. I will try distance field
Reply
#4
using distanceField solved all problems related to collision. Thanks!
Reply