x


problem deforming mesh colliders

I've basically just taken the paintverticles.js script from the file this page, and implemented it into a more fps-like scene.

The script works nicely the first time I deform each mesh, pushing the verticals up or down when clicked (depending on wether or not I'm holding down left shift), and updating the collision mesh so the character reacts to the terrain nicely.

However, when I release the mouse button after the first deform, and click to deform the same mesh again, the mesh filter is deformed, but the mesh collider is not. (i.e., the block is bent, but other colliders ignore the newly bent section)

Here's my modified version of PaintVerticles.js I'm using.

(this should be simple to figure this out, but I'm new to programming, so I'm stumped easily.)

var radius = 1.0;
var pull = 10.0;
private var unappliedMesh : MeshFilter;
//var digSound = AudioClip;

enum FallOff { Gauss, Linear, Needle }
var fallOff = FallOff.Gauss;

static function LinearFalloff (distance : float , inRadius : float) {
    return Mathf.Clamp01(1.0 - distance / inRadius);
}

static function GaussFalloff (distance : float , inRadius : float) {
    return Mathf.Clamp01 (Mathf.Pow (360.0, -Mathf.Pow (distance / inRadius, 2.5) - 0.01));
}

function NeedleFalloff (dist : float, inRadius : float)
{
    return -(dist*dist) / (inRadius * inRadius) + 1.0;
}

//function dig () {
//  if (digSound)
//  {
//   AudioSource.PlayClipAtPoint(digSound, transform.position);
//  }
//}

function DeformMesh (mesh : Mesh, position : Vector3, power : float, inRadius : float, deformDirection : int) {
    var vertices = mesh.vertices;
    var normals = mesh.normals;
    var sqrRadius = inRadius * inRadius;

    // Calculate averaged normal of all surrounding vertices   
    var averageNormal = Vector3.zero;
    for (var i=0;i<vertices.length;i++)
    {
       var sqrMagnitude = (vertices[i] - position).sqrMagnitude;
       // Early out if too far away
       if (sqrMagnitude > sqrRadius)
         continue;

       var distance = Mathf.Sqrt(sqrMagnitude);
       var falloff = LinearFalloff(distance, inRadius);
       averageNormal += falloff * normals[i];
    }
    averageNormal = averageNormal.normalized;

    // Deform vertices along averaged normal
    for (i=0;i<vertices.length;i++)
    {
       sqrMagnitude = (vertices[i] - position).sqrMagnitude;
       // Early out if too far away
       if (sqrMagnitude > sqrRadius)
         continue;

       distance = Mathf.Sqrt(sqrMagnitude);
       switch (fallOff)
       {
         case FallOff.Gauss:
          falloff = GaussFalloff(distance, inRadius);
          break;
         case FallOff.Needle:
          falloff = NeedleFalloff(distance, inRadius);
          break;
         default:
          falloff = LinearFalloff(distance, inRadius);
          break;
       }

       vertices[i] += averageNormal * falloff * power * deformDirection;
    }

    mesh.vertices = vertices;
    mesh.RecalculateNormals();
    mesh.RecalculateBounds();
}


function Update () {
    // When no mouse button is pressed we update the mesh collider

    if (!Input.GetMouseButton (0))
    {
       // Apply collision mesh when we let go of button
       ApplyMeshCollider();
       return;
    }
    var deformDirection = 1;
    var inversion = -1;
    if (Input.GetKey("left shift"))
    {
       deformDirection*=inversion;
    }
    var hit : RaycastHit;
    var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    // Did we hit the surface?
    if (Physics.Raycast (ray, hit))
    {
       var filter : MeshFilter = hit.collider.GetComponent(MeshFilter);
       if (filter)
       {
         // Don't update mesh collider every frame since physX
         // does some heavy processing to optimize the collision mesh.
         // So this is not fast enough for real time updating every frame
         if (filter != unappliedMesh)
         {
          ApplyMeshCollider();
          unappliedMesh = filter;
         }

         // Deform mesh
         var relativePoint = filter.transform.InverseTransformPoint(hit.point);
         DeformMesh(filter.mesh, relativePoint, pull * Time.deltaTime, radius, -deformDirection);
       }
    }
}

function ApplyMeshCollider () {
    if (unappliedMesh && unappliedMesh.GetComponent(MeshCollider)) 
    {
       unappliedMesh.GetComponent(MeshCollider).mesh = unappliedMesh.mesh;
    }

    unappliedMesh = null;
}
more ▼

asked Apr 11 '12 at 11:11 PM

DanceWreck gravatar image

DanceWreck
36 1 1 2

Where is this script originally from? I first saw this in @nighthawx349 's question : http://answers.unity3d.com/questions/274269/mesh-deformation.html

I'm about to start on my own mesh deformations, so shall keep watch and post any findings =]

EDIT : nevermind, I found it. Didn't know this package existed =]

http://unity3d.com/support/resources/example-projects/procedural-examples about to d'load and look at : Crumple mesh modifier - A mesh deformed by Perlin Noise.

But to answer your question (and without reading the script), at some point the mesh should be assigned to the collider :

this.transform.GetComponent(MeshCollider).sharedMesh = myMesh;

http://docs.unity3d.com/Documentation/ScriptReference/MeshCollider-sharedMesh.html

Jul 04 '12 at 01:51 PM alucardj
(comments are locked)
10|3000 characters needed characters left

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3460
x495
x116
x19

asked: Apr 11 '12 at 11:11 PM

Seen: 653 times

Last Updated: Jul 04 '12 at 02:04 PM