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;
}
}
}