Mesh deformation help ! (VR)

Hi, the objective here is to deform the mesh (“grosMesh”) by pointing at it and pressing the trigger button of a VR controller.

Deformation objective

The deformation should work like this: the mesh stretches from the point where the Ray of the controller encounters the mesh and goes in the direction of myself.

Actual result

Actually it's not working when I push the trigger button it dig in the mesh and the initial point isn't where I point with the ray (even if i point another point on the mesh, it will keep diging from the same wrong initial point.)

Many thanks in advance for those who will try to help me, I’m on it for a while now and I can’t find ressources that work :frowning:

Here is a screenshot showing the actual state of my deformation (objective is in red) + my code below

Here is the code of my Scult script:

 using Oculus.Interaction;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
 public class Sculpt : MonoBehaviour
 {
     [SerializeField]
     private Slider RadiusSlider;
 
     [SerializeField]
     private Slider StrengthSlider;
 
     [Range(.01f, 1)]
     public float radius = 0.5f;
 
     [Range(.01f, 5)]
     public float strength = 2.5f;
 
     [Range(.1f, 1000f)]
     public float smoothingFactor = 500f;
 
     public Mesh mesh;
     private Vector3[] vertices, modifiedVertices;
 
     public Camera cam;
     public RayInteractor rayInteractor;
 
     // Start is called before the first frame update
     void Start()
     {
         mesh = GetComponentInChildren<MeshFilter>().mesh;
         vertices = mesh.vertices;
         modifiedVertices = mesh.vertices;
     }
 
     // Update is called once per frame
     void Update()
     {
         radius = RadiusSlider.value;
         strength = StrengthSlider.value;
         RaycastHit hit;
         Ray ray = rayInteractor.Ray;
 
         if (OVRInput.Get(OVRInput.RawAxis1D.RIndexTrigger) > 0.0)
         {
             if (Physics.Raycast(ray, out hit, Mathf.Infinity))
             {
                 Debug.Log("WORKING -> Radius: " + radius+ "| Strength: " + strength);
                 Debug.Log(hit.point);
                 Vector3 dir = hit.normal;
                 for (int i = 0; i < modifiedVertices.Length; i++)
                 {
                     Vector3 dist = modifiedVertices[i] - hit.point;
                     float force = strength / (1f + hit.point.sqrMagnitude);
                     if (dist.sqrMagnitude < radius)
                     {
                         modifiedVertices[i] = modifiedVertices[i] + (dir * force) / smoothingFactor;
                     }
 
                 }
             }
             RecalculateMesh();
         }
 
     }
 
     public void Reset()
     {
         modifiedVertices = vertices;
         RecalculateMesh();
     }
 
     public void RecalculateMesh()
     {
         mesh.vertices = modifiedVertices;
         GetComponentInChildren<MeshFilter>().sharedMesh = mesh;
         mesh.RecalculateNormals();
     }
 }

1 Answer

1

@Ailuru - I think the issue lies in the deformation calculation. Specifically, the calculation of the force and its direction might be causing the problem. You’re calculating the force with respect to the square of the hit point’s distance from the origin (0,0,0). This could cause unexpected behaviour if the mesh isn’t centered at the origin or if you’re working in a larger scene. Instead, you should calculate the force with respect to the distance from the hit point to the current vertex. (see the sample code I have posted below)

Furthermore, you’re using the hit.normal as the deformation direction. This represents the direction in which the mesh surface is facing at the point of impact. If you want the deformation to move towards the controller, you should calculate the direction from the hit point to the controller position.

this is sort of what I mean (warning untested):

void Update()
{
    radius = RadiusSlider.value;
    strength = StrengthSlider.value;
    RaycastHit hit;
    Ray ray = rayInteractor.Ray;

    if (OVRInput.Get(OVRInput.RawAxis1D.RIndexTrigger) > 0.0)
    {
        if (Physics.Raycast(ray, out hit, Mathf.Infinity))
        {
            Debug.Log("WORKING -> Radius: " + radius+ "| Strength: " + strength);
            Debug.Log(hit.point);
            Vector3 dir = cam.transform.position - hit.point; // Changed direction
            for (int i = 0; i < modifiedVertices.Length; i++)
            {
                Vector3 dist = modifiedVertices *- hit.point;*

float force = strength / (1f + dist.sqrMagnitude); // Changed force calculation
if (dist.sqrMagnitude < radius)
{
modifiedVertices = modifiedVertices + (dir * force) / smoothingFactor;
}
}
}
RecalculateMesh();
}
}
Try this code and see if it improves your mesh deformation behaviour.

Thanks for your quick answer, unfortunately it hasn't changed anything :( [207657-explication2.png|207657]