Collision Impact Solving(Joint physics)

Hello, I need to move nodes based on collision. How can I solve this problem? Here is my code:

foreach(ContactPoint contact in collision.contacts)
{
    Vector3 new_pos =  transform.position + (transform.position - contact.point).normalized * 0.001f ;
    Vector3 desired_pos = Vector3.zero;
    if (contact.impulse.magnitude>1f && Vector3.Distance(transform.position, contact.point) < 2f)
    {
        Vector3 inverse = Vector3.zero;
        for (int i = 0; i < 6; i++)
        {
            foreach (Bone bone in Bones)
            {
                desired_pos += bone.ConnectedTransform.TransformPoint(bone.LocalPosition);
            }
            desired_pos /= Bones.Count;
            new_pos = Vector3.Lerp(new_pos,desired_pos,0.1f); 
            desired_pos = Vector3.Lerp(desired_pos, new_pos, 0.1f);
            foreach (Bone bone in Bones)
            {
                bone.ConnectedTransform.position = Vector3.Lerp(bone.ConnectedTransform.position,transform.position-bone.LocalPosition,0.1f);
                bone.LocalPosition = Vector3.Lerp(bone.LocalPosition,bone.ConnectedTransform.InverseTransformPoint(desired_pos),0.1f );
            }
        }
        transform.position = new_pos;
    }
}

Well, you were using the foreach loop which is frame based…So it you use time based updates as they will be reliable…Additionally, I have also tried to edit the damping…perhaps its what you wanted.

 void FixedUpdate()
    {
        bool changed = false;

        foreach (Deformable deformable in Deformables)
        {
            foreach (Node node in deformable.Nodes)
            {
                foreach (ContactPoint contact in collision.contacts)
                {
                    if (Vector3.Distance(node.transform.position, contact.point) < 1f)
                    {
                        changed = true;
                        Vector3 contact_force = contact.impulse;
                        node.Velocity += contact_force * 0.0001f;
                        node.FirstContact = true;
                    }
                }
            }
        }

        if (!changed)
        {
            return;
        }

        for (int i = 0; i < 1; i++)
        {
            foreach (Deformable deformable in Deformables)
            {
                foreach (Node node in deformable.Nodes)
                {
                    if (node.Velocity.magnitude > 0)
                    {
                        node.transform.position += node.Velocity * timeStep;

                        foreach (DistanceJoint distance_joint in deformable.DistanceJoints)
                        {
                            if (distance_joint.FirstNode == node)
                            {
                                Vector3 vector = distance_joint.SecondNode.transform.position - distance_joint.FirstNode.transform.position;
                                distance_joint.SecondNode.NextVelocity += vector.normalized * Vector3.Dot(vector.normalized, node.Velocity) * distance_joint.Damping;
                            }
                            else if (distance_joint.SecondNode == node)
                            {
                                Vector3 vector = distance_joint.FirstNode.transform.position - distance_joint.SecondNode.transform.position;
                                distance_joint.FirstNode.NextVelocity += vector.normalized * Vector3.Dot(vector.normalized, node.Velocity) * distance_joint.Damping;
                            }
                        }
                    }
                    node.Velocity = Vector3.zero;
                }
            }

            foreach (Deformable deformable in Deformables)
            {
                foreach (Node node in deformable.Nodes)
                {
                    node.Velocity = node.NextVelocity;
                    node.NextVelocity = Vector3.zero;
                }
            }
        }
    }

why dont you try this…

//Code
foreach (ContactPoint contact in collision.contacts)
{
    // Calculate a new position for the object based on the collision contact.
    Vector3 new_pos = transform.position + (transform.position - contact.point).normalized * 0.001f;
    
    // Check if the collision impulse and distance meet certain conditions.
    if (contact.impulse.magnitude > 1f && Vector3.Distance(transform.position, contact.point) < 2f)
    {
        // Define a desired position.
        Vector3 desired_pos = Vector3.zero;
        
        // Iterate to refine the desired position based on connected bones.
        for (int i = 0; i < 6; i++)
        {
            // Calculate the desired position by averaging the positions of connected bones.
            foreach (Bone bone in Bones)
            {
                desired_pos += bone.ConnectedTransform.TransformPoint(bone.LocalPosition);
            }
            desired_pos /= Bones.Count;
            
            // Move the object towards the desired position using Lerp.
            new_pos = Vector3.Lerp(new_pos, desired_pos, 0.1f);
            desired_pos = Vector3.Lerp(desired_pos, new_pos, 0.1f);
            
            // Move the connected bones.
            foreach (Bone bone in Bones)
            {
                bone.ConnectedTransform.position = Vector3.Lerp(bone.ConnectedTransform.position, transform.position - bone.LocalPosition, 0.1f);
                bone.LocalPosition = Vector3.Lerp(bone.LocalPosition, bone.ConnectedTransform.InverseTransformPoint(desired_pos), 0.1f);
            }
        }
        
        // Update the position of the main object.
        transform.position = new_pos;
    }
}

I tried to make some adjustments.

Here is new code:

foreach(ContactPoint contact in collision.contacts)
{
    Vector3 new_pos =  transform.position + (transform.position - contact.point) * 0.1f  ;

    if(Vector3.Distance(Deformable.DeformablePivot.position, transform.position) > PivotDistance / 2f)
    {
        new_pos = new_pos + (Deformable.DeformablePivot.position - transform.position) * 0.01f;

    }
    Vector3 desired_pos = Vector3.zero;
    if (contact.impulse.magnitude>1f && Vector3.Distance(transform.position, contact.point) < 2f)
    {
                        
        for (int i = 0; i < 10; i++)
        {
            desired_pos = Vector3.zero;
            foreach (Bone bone in Bones)
            {
                desired_pos += bone.ConnectedTransform.TransformPoint(bone.LocalPosition);
            }
            desired_pos /= Bones.Count;

            new_pos = Vector3.Lerp(new_pos,desired_pos,0.1f); 

            desired_pos = Vector3.Lerp(desired_pos, new_pos, 0.1f);

            foreach (Bone bone in Bones)
            {
                
                //bone.ConnectedTransform.position = Vector3.Lerp(bone.ConnectedTransform.position,new_pos-bone.LocalPosition,0.1f);
                bone.LocalPosition = Vector3.Lerp(bone.LocalPosition,bone.ConnectedTransform.InverseTransformPoint(desired_pos),0.1f );
            }
        }
        
        
       
        transform.position = new_pos;

    }
}
foreach (ContactPoint contact in collision.contacts)
{
    // Calculate new position based on collision point and pivot distance
    Vector3 new_pos = transform.position + (transform.position - contact.point) * 0.1f;
    float distanceToPivot = Vector3.Distance(Deformable.DeformablePivot.position, transform.position);

    if (distanceToPivot > PivotDistance / 2f)
    {
        new_pos += (Deformable.DeformablePivot.position - transform.position) * 0.01f;
    }

    if (contact.impulse.magnitude > 1f && distanceToPivot < 2f)
    {
        Vector3 desired_pos = Vector3.zero;

        // Calculate desired position for the bones
        foreach (Bone bone in Bones)
        {
            desired_pos += bone.ConnectedTransform.TransformPoint(bone.LocalPosition);
        }
        desired_pos /= Bones.Count;

        // Smoothly interpolate the object's position
        new_pos = Vector3.Lerp(new_pos, desired_pos, 0.1f);

        // Update bone positions
        foreach (Bone bone in Bones)
        {
            // Calculate desired bone position and apply smoothing
            Vector3 desiredBonePosition = bone.ConnectedTransform.InverseTransformPoint(desired_pos);
            bone.LocalPosition = Vector3.Lerp(bone.LocalPosition, desiredBonePosition, 0.1f);
        }

        // Update the object's position
        transform.position = new_pos;
    }
}

Perhaps this way it should work.

Do you mean like updating bone position based on desiredBonePosition ?
and then keeping “bone.ConnectedTransform” in a loop ??

Like shifting the nodes connected to another on collision?

like this?

foreach (ContactPoint contact in collision.contacts)
{
    // Calculate new position based on collision point and pivot distance
    Vector3 newObjectPosition = transform.position + (transform.position - contact.point) * 0.1f;
    float distanceToPivot = Vector3.Distance(Deformable.DeformablePivot.position, transform.position);

    if (distanceToPivot > PivotDistance / 2f)
    {
        newObjectPosition += (Deformable.DeformablePivot.position - transform.position) * 0.01f;
    }

    if (contact.impulse.magnitude > 1f && distanceToPivot < 2f)
    {
        // Calculate the desired position for the object
        Vector3 desiredObjectPosition = Vector3.zero;

        foreach (Bone bone in Bones)
        {
            desiredObjectPosition += bone.ConnectedTransform.TransformPoint(bone.LocalPosition);
        }
        desiredObjectPosition /= Bones.Count;

        // Smoothly interpolate the object's position
        newObjectPosition = Vector3.Lerp(newObjectPosition, desiredObjectPosition, 0.1f);

        // Update positions of the node and connected nodes
        foreach (Bone bone in Bones)
        {
            // Calculate desired bone position and apply smoothing
            Vector3 desiredBonePosition = bone.ConnectedTransform.InverseTransformPoint(bone.LocalPosition + desiredObjectPosition - transform.position);
            bone.LocalPosition = Vector3.Lerp(bone.LocalPosition, desiredBonePosition, 0.1f);

            // Update the bone's connected transform position
            bone.ConnectedTransform.position = transform.position - bone.LocalPosition;
        }

        // Update the object's position
        transform.position = newObjectPosition;
    }
}

I need to solve something like that code. But this code Break mesh completely not as expected. It looks like not solving and moving nodes too much.

 public void OnCollisionEnter(Collision collision)
 {
     foreach(ContactPoint contact in collision.contacts)
     {
         Vector3 new_pos =  transform.position + (transform.position - contact.point) * 0.00001f  ;

         /*if (Vector3.Distance(Deformable.DeformablePivot.position, transform.position) > PivotDistance / 2f)
         {
             new_pos = new_pos + (Deformable.DeformablePivot.position - transform.position) * 0.001f;

         }*/
         Vector3 desired_pos = Vector3.zero;
         if (contact.impulse.magnitude>1f && Vector3.Distance(transform.position, contact.point) < 2f)
         {
                             
             for (int i = 0; i < 10; i++)
             {
                 desired_pos = Vector3.zero;
                 foreach (Bone bone in Bones)
                 {
                     desired_pos += bone.ConnectedTransform.TransformPoint(bone.LocalPosition);
                 }
                 desired_pos /= Bones.Count;

                 desired_pos = Vector3.Lerp(desired_pos, new_pos, 0.5f);


                 new_pos = Vector3.Lerp(new_pos,desired_pos,0.5f); 


                 foreach (Bone bone in Bones)
                 {
                     bone.LocalPosition = Vector3.Lerp(bone.LocalPosition, bone.ConnectedTransform.InverseTransformPoint(desired_pos), 0.5f);

                     bone.ConnectedTransform.position = Vector3.Lerp(bone.ConnectedTransform.position,new_pos-bone.LocalPosition,0.5f);
                 }
             }
             
             
            
             transform.position = new_pos;

         }
     }
     


 }

Do you have any idea about this one? Not working properly. Move too much.

bool changed = false;
foreach (Deformable deformable in Deformables)
{
    foreach (Node node in deformable.Nodes)
    {
        foreach (ContactPoint contact in collision.contacts)
        {
            if (Vector3.Distance(node.transform.position, contact.point) < 1f)
            {
                changed = true;
                Vector3 contact_force = contact.impulse;
                node.Velocity += (contact_force) * 0.0001f;
               
                node.FirstContact = true;
            }
            
                
        }

    }
}



if (!changed)
{
    return;
}
for(int i = 0;i<1;i++)
{
    foreach (Deformable deformable in Deformables)
    {
        foreach (Node node in deformable.Nodes)
        {
            if (node.Velocity.magnitude > 0)
            {

               // node.Velocity = node.Velocity.normalized * (node.Velocity.magnitude - node.Strenght);


                node.transform.position += node.Velocity*0.01f;
                
                foreach (DistanceJoint distance_joint in deformable.DistanceJoints)
                {
                    if (distance_joint.FirstNode == node)
                    {
                        Vector3 vector = distance_joint.SecondNode.transform.position - distance_joint.FirstNode.transform.position;
                        distance_joint.SecondNode.NextVelocity += vector.normalized*Vector3.Dot(vector.normalized,node.Velocity) * distance_joint.Damping;
                    }
                    else if (distance_joint.SecondNode == node)
                    {

                        Vector3 vector = distance_joint.FirstNode.transform.position - distance_joint.SecondNode.transform.position;
                        distance_joint.FirstNode.NextVelocity += vector.normalized * Vector3.Dot(vector.normalized, node.Velocity) * distance_joint.Damping;
                    }
                }
               
               
            }
            node.Velocity = Vector3.zero;

        }


    }

    foreach (Deformable deformable in Deformables)
    {
        foreach (Node node in deformable.Nodes)
        {
            node.Velocity = node.NextVelocity;
            node.NextVelocity = Vector3.zero;

        }


    }



}