- Home /
Flattening a mesh by deforming it
I have created an infinite low poly looking terrain mesh, it's not a terrain GameObject it's just a normal mesh being instantiated when I get close and disabled when a get too far away, but then came the flattening terrain for building and so forth and this became a problem the unity "Paint Vertices" in the "Procedural Examples" project works for what I'm trying to do but only lifts the vertices or lowers the vertices relative to themselves for example if I had a vertice at 2.4 on the y axis and another at 3.4 and I was lowering them by 1.2 they would be both lowered in relative to themselves meaning it would turn out at 1.2 and 2.2. Also, the "Paint Vertices" Script is in Java Script, I prefer c# if you can.
if anyone can help me it would be greatly appreciated.
Thanks
Paint Vertices Script
var radius = 1.0; var pull = -0.01; private var unappliedMesh : MeshFilter;
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 DeformMesh (mesh : Mesh, position : Vector3, power : float, inRadius : float) { 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;
}
mesh.vertices = vertices;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
function Update () {
// When no button is pressed we update the mesh collider
if (!Input.GetMouseButton (0))
{
// Apply collision mesh when we let go of button
ApplyMeshCollider();
return;
}
// Did we hit the surface?
if(Input.GetMouseButton (0))
{
var hit : RaycastHit;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
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, radius);
}
}
}
}
function ApplyMeshCollider () { if (unappliedMesh && unappliedMesh.GetComponent(MeshCollider)) { this.gameObject.GetComponent(MeshCollider).sharedmesh = unappliedMesh.mesh; unappliedMesh = null; } unappliedMesh = null; }
Your answer
Follow this Question
Related Questions
Adding vertices to procedural mesh generator 2 Answers
How to add vertex points to a mesh 1 Answer
Modifying plane to fit view frustrum issue 0 Answers
How to manipulate(flatten) the Mesh of an object 0 Answers
Handles does not modify mesh... 1 Answer