Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Rope reacting weird
#5
Code:
using UnityEngine;
using System.Collections.Generic;
using Obi;

//Sample component that makes a collider "grab" any particle it touches (regardless of which Actor it belongs to).
[RequireComponent(typeof(ObiCollider))]
public class ObiContactGrabber : MonoBehaviour
{

    public ObiSolver solver;

    //Helper class that stores the index of a particle in the solver, its position in the grabber's local space, and its inverse mass previous to being grabbed.
    //This makes it easy to tell if a particle has been grabbed, update its position while grabbing, and restore its mass after being released.
    private class GrabbedParticle : IEqualityComparer<GrabbedParticle>
    {
        public int index;
        public float invMass;
        public Vector3 localPosition;

        public GrabbedParticle(int index, float invMass)
        {
            this.index = index;
            this.invMass = invMass;
        }

        public bool Equals(GrabbedParticle x, GrabbedParticle y)
        {
            return x.index == y.index;
        }

        public int GetHashCode(GrabbedParticle obj)
        {
            return index;
        }
    }

    private ObiSolver.ObiCollisionEventArgs collisionEvent;                                     //Store the current collision event
    private ObiCollider localCollider;                                                          //the collider on this gameObject.
    private HashSet<GrabbedParticle> grabbedParticles = new HashSet<GrabbedParticle>();         //Set to store all currently grabbed particles.
    private HashSet<ObiActor> grabbedActors = new HashSet<ObiActor>();                          //Set of softbodies grabbed during this step.

    private Matrix4x4 grabber2Solver;
    private Matrix4x4 solver2Grabber;

    private void Awake()
    {
        localCollider = GetComponent<ObiCollider>();
    }

    private void OnEnable()
    {
        if (solver != null)
            solver.OnCollision += Solver_OnCollision;
    }

    private void OnDisable()
    {
        if (solver != null)
            solver.OnCollision -= Solver_OnCollision;
    }

    private void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
    {
        // Calculate transform matrix from grabber to world space (Note: if using local space simulation, postmultiply with solver.transform.localToWorldMatrix)
        solver2Grabber = transform.worldToLocalMatrix * solver.transform.localToWorldMatrix;
        // and its inverse:
        grabber2Solver = solver2Grabber.inverse;
        collisionEvent = e;
    }

    private void UpdateParticleProperties()
    {
        // Update rest shape matching of all grabbed softbodies:
        foreach (ObiActor actor in grabbedActors)
        {
            actor.UpdateParticleProperties();
        }
    }

    //Creates and stores a GrabbedParticle from the particle at the given index.
    //Returns true if we sucessfully grabbed a particle, false if the particle was already grabbed.
    private bool GrabParticle(int index)
    {
        GrabbedParticle p = new GrabbedParticle(index, solver.invMasses[index]);
        // in case this particle has not been grabbed yet:
        if (!grabbedParticles.Contains(p))
        {
            // record the particle's position relative to the grabber, and store it.
            p.localPosition = solver2Grabber.MultiplyPoint3x4(solver.positions[index]);
            grabbedParticles.Add(p);

            // Set inv mass and velocity to zero:
            solver.invMasses[index] = 0;
            solver.velocities[index] = Vector4.zero;

            return true;
        }
        return false;
    }

    // Grabs all particles currently touching the grabber.
    public bool Grab()
    {
        grabbedActors.Clear();
        var world = ObiColliderWorld.GetInstance();

        if (solver != null && collisionEvent != null)
        {
            foreach (Oni.Contact contact in collisionEvent.contacts)
            {
                // this one is an actual collision:
                if (contact.distance < 0.01f)
                {
                    var contactCollider = world.colliderHandles[contact.other].owner;
                    // if the current contact references our collider, proceed to grab the particle.
                    if (contactCollider == localCollider)
                    {
                        // try to grab the particle, if not already grabbed.
                        if (GrabParticle(contact.particle))
                        {
                            grabbedActors.Add(solver.particleToActor[contact.particle].actor);
                            return true;
                        }
                    }
                }
            }
        }

        UpdateParticleProperties();
        return false;
    }

    // Releases all currently grabbed particles. This boils down to simply resetting their invMass.
    public void Release()
    {
        // Restore the inverse mass of all grabbed particles, so dynamics affect them.
        foreach (GrabbedParticle p in grabbedParticles)
            solver.invMasses[p.index] = p.invMass;

        UpdateParticleProperties();
        grabbedActors.Clear();
        grabbedParticles.Clear();
    }

    // Updates the position of the grabbed particles.
    private void FixedUpdate()
    {
        foreach (GrabbedParticle p in grabbedParticles)
            solver.positions[p.index] = grabber2Solver.MultiplyPoint3x4(p.localPosition);
    }

    public bool RightControl = false;

    private void Update()
    {
        if (!RightControl)
        {
            if (Input.GetKeyDown(KeyCode.Joystick1Button14))
                Grab();
            if (Input.GetKeyUp(KeyCode.Joystick1Button14))
                Release();
        }
        else
        {
            if (Input.GetKeyDown(KeyCode.Joystick2Button15))
                Grab();
            if (Input.GetKeyUp(KeyCode.Joystick2Button15))
                Release();
        }
    }
}

This is what I have.

Regards,
Stanley
Reply


Messages In This Thread
Rope reacting weird - by SilverStanley - 14-12-2020, 03:07 PM
RE: Rope reacting weird - by josemendez - 14-12-2020, 03:21 PM
RE: Rope reacting weird - by SilverStanley - 14-12-2020, 04:57 PM
RE: Rope reacting weird - by josemendez - 15-12-2020, 09:22 AM
RE: Rope reacting weird - by SilverStanley - 15-12-2020, 11:32 AM
RE: Rope reacting weird - by josemendez - 15-12-2020, 02:00 PM
RE: Rope reacting weird - by SilverStanley - 17-12-2020, 07:23 PM
RE: Rope reacting weird - by josemendez - 17-12-2020, 08:08 PM
RE: Rope reacting weird - by SilverStanley - 29-12-2020, 02:22 PM
RE: Rope reacting weird - by SilverStanley - 08-01-2021, 01:39 PM
RE: Rope reacting weird - by josemendez - 08-01-2021, 01:52 PM
RE: Rope reacting weird - by SilverStanley - 09-01-2021, 03:39 PM