Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ObiParticlePicker for any object [might be helpful for everyone]
#1
Hello everyone, can anyone help me convert a custom interaction?
I'm experimenting to use a cube as an interaction other than the Input.mousePosition of ObiParticlePicker.cs, but i'm having trouble customizing it.

My idea is, by using a boolean variable as a trigger for grabbing the closest particle of the obi cloth if true and release the grabbing if false, a cube must have its own forward raycasting, than using the input.mousePosition.

I'm currently experimenting how for 3-days, but it seems I'm stuck.

These line of code are the one I am currently having trouble with.
Code:
// Drag:
Vector3 mouseDelta = Input.mousePosition - lastMousePos;
if (mouseDelta.magnitude > 0.01f && OnParticleDragged != null)
{
    Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
    OnParticleDragged.Invoke(new ParticlePickEventArgs(pickedParticleIndex,worldPosition));
    
}
else if (OnParticleHeld != null)
{
    
    Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
    OnParticleHeld.Invoke(new ParticlePickEventArgs(pickedParticleIndex,worldPosition));
}
    
// Release:                
if (Input.GetMouseButtonUp(0))
{                    
    if (OnParticleReleased != null)
       {
        Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
        OnParticleReleased.Invoke(new ParticlePickEventArgs(pickedParticleIndex,worldPosition));
    }
    
    pickedParticleIndex = -1;
        
}
Reply
#2
Update: this is a sample and it somehow works, but not precise yet as there is a spring thing happening. It would be great if we can make the springing thing disappear. 
Code:
void FixedUpdate()
    {
        Ray ray = new Ray(this.transform.position, transform.forward);

        if (triggerOnce)
        {
            Debug.Log("Tigger once");
            triggerOnce = false;
            RenderOnce();
        }
        else if (pickedParticleIndex >= 0)
        {
            float invmass = solver.invMasses[pickedParticleIndex];
            Vector4 position = solver.transform.TransformPoint(solver.positions[pickedParticleIndex]);
            Vector4 velocity = solver.velocities[pickedParticleIndex];
            Vector4 targetposition = this.transform.position;

            //// calculate picking position in solver space:
            solver.externalForces[pickedParticleIndex] = ((targetposition - position) * springStiffness - velocity * springDamping) / invmass;

        }

    }

    void RenderOnce()
    {
        Ray ray = new Ray(transform.position, transform.forward);

        float closestMu = float.MaxValue;
        float closestDistance = float.MaxValue;

        for (int i = 0; i < solver.renderablePositions.count; ++i)
        {
            float mu;
            Vector3 projected = ObiUtils.ProjectPointLine(solver.transform.TransformPoint(solver.renderablePositions[i]), ray.origin, ray.origin + ray.direction, out mu, false);
            float distanceToRay = Vector3.SqrMagnitude((Vector3)solver.transform.TransformPoint(solver.renderablePositions[i]) - projected);
            
            mu = Mathf.Max(0, mu);

            float radius = solver.principalRadii[i][0] * radiusScale;

            if (distanceToRay <= radius * radius && distanceToRay < closestDistance && mu < closestMu)
            {
                closestMu = mu;
                closestDistance = distanceToRay;
                pickedParticleIndex = i;
            }
        }
    }
Reply
#3
(30-01-2020, 03:36 AM)jbvobling Wrote: Update: this is a sample and it somehow works, but not precise yet as there is a spring thing happening. It would be great if we can make the springing thing disappear. 
Code:
void FixedUpdate()
    {
        Ray ray = new Ray(this.transform.position, transform.forward);

        if (triggerOnce)
        {
            Debug.Log("Tigger once");
            triggerOnce = false;
            RenderOnce();
        }
        else if (pickedParticleIndex >= 0)
        {
            float invmass = solver.invMasses[pickedParticleIndex];
            Vector4 position = solver.transform.TransformPoint(solver.positions[pickedParticleIndex]);
            Vector4 velocity = solver.velocities[pickedParticleIndex];
            Vector4 targetposition = this.transform.position;

            //// calculate picking position in solver space:
            solver.externalForces[pickedParticleIndex] = ((targetposition - position) * springStiffness - velocity * springDamping) / invmass;

        }

    }

    void RenderOnce()
    {
        Ray ray = new Ray(transform.position, transform.forward);

        float closestMu = float.MaxValue;
        float closestDistance = float.MaxValue;

        for (int i = 0; i < solver.renderablePositions.count; ++i)
        {
            float mu;
            Vector3 projected = ObiUtils.ProjectPointLine(solver.transform.TransformPoint(solver.renderablePositions[i]), ray.origin, ray.origin + ray.direction, out mu, false);
            float distanceToRay = Vector3.SqrMagnitude((Vector3)solver.transform.TransformPoint(solver.renderablePositions[i]) - projected);
            
            mu = Mathf.Max(0, mu);

            float radius = solver.principalRadii[i][0] * radiusScale;

            if (distanceToRay <= radius * radius && distanceToRay < closestDistance && mu < closestMu)
            {
                closestMu = mu;
                closestDistance = distanceToRay;
                pickedParticleIndex = i;
            }
        }
    }

Hi,

Instead of calculating a spring force, fix the particle (by setting its inverse mass and velocity to zero) and set the particle position directly. That will completely get rid of the "spring thing":

Quote:solver.velocities[pickedParticleIndex] = Vector4.zero;
solver.invMasses[pickedParticleIndex] = 0;
solver.positions[pickedParticleIndex] = solver.transform.InverseTransformPoint(this.transform.position);

Note that you should revert the inverse mass to whatever it was when you want the particle to start behaving normally again.
Reply
#4
(30-01-2020, 08:24 AM)josemendez Wrote: Hi,

Instead of calculating a spring force, fix the particle (by setting its inverse mass and velocity to zero) and set the particle position directly. That will completely get rid of the "spring thing":


Note that you should revert the inverse mass to whatever it was when you want the particle to start behaving normally again.

Thank you, it works.
Reply