Home > front end >  Deform a Mesh in Unity to Align Reference Points at Runtime
Deform a Mesh in Unity to Align Reference Points at Runtime

Time:12-24

After 2 days of researching and trying different tutorials/approaches trying to grasp this issue, I've given up.

I have an explanation of what I am fully trying to achieved in this youtube video... https://youtu.be/GJ6Du0EENhc - 7min

This simplified problem: In my test scene I have a plane inside a container. There is also a sphere called "modelref" inside the container, positioned so it intersects the plane. Outside of the container is another sphere called 'realworldref'.

What i want to do, is press a button and the model ref will move to the location of the realworld ref. At the same time, it should drag verticies from the plane with it such that the vertices closest the the modelref are pulld all the way to the new location, with the effect disipating out to the radius 'influence area' (ultimately to be defined by a box collider).

What I've tried: I've made some simple steps (omitting the influence radius), but my brain is failing to grasp directions, vectors, magnitudes etc... so the vertices of the plane aren't even moving the right distance in the right direction.

Here is my current script which is on the modelref:

    public void HandleInput() //responds to mouse click
    {
    Vector3 heading = (realWorldRef.transform.position - this.transform.position);
    float distance = heading.magnitude;
    Vector3 dir = heading / distance;

    this.transform.position = realWorldRef.transform.position;
    MeshDeformer deformer = colliderOfMeshToDeform.GetComponent<MeshDeformer>();

    if (deformer)
    {
        deformer.DeformByDirectionAndDistance(heading, dir, distance);
    } 
  }

Then this is the MeshDeformer script:

public class MeshDeformer : MonoBehaviour {

Mesh deformingMesh;
Vector3[] originalVertices, displacedVertices;

void Start()
{
    deformingMesh = GetComponent<MeshFilter>().mesh;
    originalVertices = deformingMesh.vertices;
    displacedVertices = new Vector3[originalVertices.Length];
    for (int i = 0; i < originalVertices.Length; i  )
    {
        displacedVertices[i] = originalVertices[i];
    }
}

internal void DeformByDirectionAndDistance(Vector3 heading, Vector3 normalisedDir, float distance)
{
    for (int i = 0; i < displacedVertices.Length; i  )
    {
        MoveVerticesByDirectionAndDistance(i, heading, normalisedDir, distance);
    }
}

private void MoveVerticesByDirectionAndDistance(int i, Vector3 heading, Vector3 normalisedDir, float distance)
{
    displacedVertices[i]  = normalisedDir * distance; //this is the bit that is wrong...
    deformingMesh.vertices = displacedVertices;
    deformingMesh.RecalculateNormals();
}
}

At present all of the vertices of the plane move, but only by a small amount and not seemingly in the correct direction. In this first stage, I'm simply trying to move all the vertices of the plane the exact same distance and direction as the modelRef moves when it is repositioned to match realworldRef.transform.

After this, I would try to add a 'area of influence' which falls off with distance from the original modelref position., so the nearest vertices move the whole distance, with those further away moving less.

Any help most appreciated.

CodePudding user response:

The direction is in world space, so if you want to move vertices along it, you should transform it into model space first.

var dir2 = modelObject.transform.InverseTransformVector(dir.normalized * distance);

modelObject is the object that the mesh filter component is attached. distance is the distance you want to move in the world space.

Now you can move the vertices with the new direction.

displacedVertices[i]  = dir2;
  • Related