Created
May 11, 2018 00:14
-
-
Save twobob/5e49cfa4e50846c235a073e0c5521b6f to your computer and use it in GitHub Desktop.
DefamationMangler deformation mangler (totally untested for 4 years)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
using System.Collections; | |
using System.Collections.Generic; | |
public class DefamationMangler : MonoBehaviour | |
{ | |
[MenuItem("Tools/DefamationMangler %#d")] | |
static void AlignMeshVertices() | |
{ | |
Undo.RecordObjects(Selection.transforms, "Mangle To Surface"); | |
VerticesInit(); | |
} | |
[MenuItem("Tools/Reset A Plane %#r")] | |
static void ResetMeshVertices() | |
{ | |
Undo.RecordObjects(Selection.transforms, "deMangle To Surface"); | |
foreach (GameObject go in Selection.gameObjects) | |
{ | |
MeshFilter filter = go.GetComponent(typeof(MeshFilter)) as MeshFilter; | |
if (filter != null) | |
{ | |
Mesh mesh = filter.sharedMesh; | |
go.transform.localScale = Vector3.one; | |
for (int m = 0; m < mesh.subMeshCount; m++) | |
{ | |
Vector3[] verts = mesh.vertices; | |
for (int i = 0; i < verts.Length; i++) | |
{ | |
if (go.transform.rotation.eulerAngles.x == 0) | |
{ | |
verts[i].y = 0; | |
} | |
else if (go.transform.rotation.eulerAngles.x == 270) | |
{ | |
verts[i].z =0; | |
} | |
else | |
{ | |
print("UNKNOWN OBJECT ROTATION ARGH! FIX IT in the rotation!"); | |
} | |
} | |
List<Vector3> vertList = new List<Vector3>(verts); | |
Debug.Log(vertList.Count); | |
mesh.SetVertices(vertList); | |
} | |
} | |
} | |
} | |
private static void VerticesInit() | |
{ | |
foreach (GameObject go in Selection.gameObjects) | |
{ | |
MeshFilter filter = go.GetComponent(typeof(MeshFilter)) as MeshFilter; | |
if (filter != null) | |
{ | |
ResetMeshVertices(); | |
// add some clearance | |
go.transform.position += (Vector3.up * 10f); | |
DefamationMangle(ref filter, go); | |
} | |
else | |
{ | |
print("gameobject " + go.name + " has no mesh filter"); | |
} | |
} | |
} | |
public static Vector3 FindClosest(float target, IList<Vector3> list) | |
{ | |
Vector3 result = list[0]; | |
float minDelta = float.MaxValue; | |
foreach (Vector3 x in list) | |
{ | |
// Can't use Math.Abs() | |
float delta = (x.y < target) ? (target - x.y) : (x.y - target); | |
if (delta < minDelta) | |
{ | |
minDelta = delta; | |
result = x; | |
} | |
} | |
return result; | |
} | |
static void DefamationMangle(ref MeshFilter filter, GameObject go) | |
{ | |
print("==BEGIN=="); | |
if (filter != null) | |
{ | |
Mesh mesh = filter.sharedMesh; | |
go.transform.localScale = Vector3.one; | |
for (int m = 0; m < mesh.subMeshCount; m++) | |
{ | |
List<Vector3> RealWorldLocations = new List<Vector3>(mesh.vertices.Length); | |
Debug.Log(mesh.subMeshCount); | |
int[] triangles = mesh.GetTriangles(m); | |
Vector3[] verts; | |
float midY; | |
float highestY = 0f; | |
float lowestY = 0; | |
float range; | |
print("1st Range Setup"); | |
SetupTheRealWorldRanges(go, mesh, out RealWorldLocations, out midY, out highestY, out lowestY, out range); | |
print("MID Y:" + midY); | |
//HAAAACKKKK | |
// Vector3 TheVertexLocation = FindClosest(midY, RealWorldLocations); | |
Vector3 TheVertexLocation = Vector3.zero; // = FindClosest(highestY, RealWorldLocations); | |
float closestResult = float.MaxValue; | |
foreach (var item in RealWorldLocations) | |
{ | |
RaycastHit InitialTestHit; | |
bool WeDidHit = Physics.Raycast(item + (Vector3.up * 10), -Vector3.up, out InitialTestHit); | |
float distance = item.y - InitialTestHit.point.y; | |
// print("For location: " + item + " is " + (distance - 10f)); | |
if (distance < closestResult) | |
{ | |
closestResult = distance; | |
TheVertexLocation = item; | |
} | |
} | |
// print("Shortest Y is:"+ TheVertexLocation); | |
//Vector3 TheVertexLocation = go.transform.position; | |
// move to the approximate middle; | |
// print(TheVertexLocation); | |
// OFFSET!! | |
// print(TheVertexLocation - go.transform.position); | |
RaycastHit VertexInitialTestHit; | |
bool DidHit = Physics.Raycast(TheVertexLocation + (Vector3.up * 10), -Vector3.up, out VertexInitialTestHit); | |
print("REQUIRED OFFSET FOR BEST ORIGIN: " + ((TheVertexLocation - VertexInitialTestHit.point) - (Vector3.up * 10))); | |
print("REQUIRED OFFSET FOR BEST ORIGIN: " + ((TheVertexLocation - VertexInitialTestHit.point) - (Vector3.up * 10)).y); | |
// DISABLED FOR NOW | |
go.transform.position -= TheVertexLocation - VertexInitialTestHit.point; | |
print("2st Range Setup"); | |
SetupTheRealWorldHitRanges(go, RealWorldLocations, out midY, out highestY, out lowestY, out range); | |
print("MID Y:" + midY); | |
print("FINAL RANGE: " + range); | |
print("FINAL highestY: " + highestY); | |
print("FINAL lowestY: " + lowestY); | |
verts = mesh.vertices; | |
for (int i = 0; i < verts.Length; i++) | |
{ | |
RaycastHit hit; | |
Vector3 worldPt = go.transform.TransformPoint(mesh.vertices[i]);// currentVert]); | |
// print("CURRENT: " + mesh.vertices[i]);// currentVert]); | |
// currentVert--; | |
if (Physics.Raycast(worldPt + (Vector3.up * 10), -Vector3.up, out hit)) | |
{ | |
Vector3 targetPosition = hit.point; | |
// Take the test from the highest point. | |
Vector3 ActualOffset = worldPt - targetPosition; | |
// print("Actual Y: "+ActualOffset.y); | |
// create normalised version of the y - using the range. | |
// offset to - 0.5 - 0.5 range | |
Vector2 NormalisingHolder = new Vector2(ActualOffset.y, range).normalized; | |
// print(NormalisingHolder.x); | |
float normalisedResult = (NormalisingHolder.x * 1) + 0.5f; | |
// Debug.Log("NORMALISED RESULT FOR VERTEX:" + normalisedResult); | |
// print("setting vertex index:" + i); | |
if (go.transform.rotation.eulerAngles.x == 0) | |
{ | |
verts[i].y = -normalisedResult; | |
} | |
else if (go.transform.rotation.eulerAngles.x == 270) | |
{ | |
verts[i].z = -normalisedResult; | |
} | |
else | |
{ | |
print("UNKNOWN OBJECT ROTATION ARGH! FIX IT in the rotation!"); | |
} | |
// Debug.Log("DIFF: " + ActualOffset); | |
} | |
// mesh.SetTriangles(triangles, m); | |
} | |
List<Vector3> vertList = new List<Vector3>(verts); | |
// Debug.Log(vertList.Count); | |
mesh.SetVertices(vertList); | |
mesh.RecalculateNormals(); | |
mesh.RecalculateBounds(); | |
go.transform.localScale = new Vector3(1, 1, range * 1.2f); | |
go.transform.position += (Vector3.up * (range * .95f)); | |
Transform[] transforms = Selection.transforms; | |
foreach (Transform myTransform in transforms) | |
{ | |
RaycastHit hit; | |
if (Physics.Raycast(myTransform.position, -Vector3.up, out hit)) | |
{ | |
Vector3 targetPosition = hit.point; | |
if (myTransform.gameObject.GetComponent<MeshFilter>() != null) | |
{ | |
verts = mesh.vertices; | |
// go.transform.position = go.transform.position - (Vector3.up * (range * 0.4f)); | |
} | |
} | |
} | |
} | |
} | |
} | |
private static void SetupTheRealWorldRanges(GameObject go, Mesh mesh, out List<Vector3> RealWorldLocations, out float midY, out float highestY, out float lowestY, out float range) | |
{ | |
RealWorldLocations = new List<Vector3>(mesh.vertices.Length); | |
Vector3[] verts = mesh.vertices; | |
// print("VERT COUNT: "+verts.Length); | |
highestY = float.MinValue; | |
lowestY = float.MaxValue; | |
for (int i = 0; i < verts.Length; i++) | |
{ | |
Vector3 worldPt = go.transform.TransformPoint(mesh.vertices[i]); | |
RealWorldLocations.Add(worldPt); | |
if (worldPt.y > highestY) | |
{ | |
highestY = worldPt.y; | |
} | |
if (worldPt.y < lowestY) | |
{ | |
lowestY = worldPt.y; | |
} | |
} | |
range = highestY - lowestY; | |
midY = lowestY + (range * 0.5f); | |
} | |
private static void SetupTheRealWorldHitRanges(GameObject go, List<Vector3> RealWorldLocations, out float midY, out float highestY, out float lowestY, out float range) | |
{ | |
// print("LOCATIONS COUNT: "+RealWorldLocations.Count); | |
highestY = float.MinValue; | |
lowestY = float.MaxValue; | |
for (int i = 0; i < RealWorldLocations.Count; i++) | |
{ | |
RaycastHit hit; | |
// bool DidHit = Physics.Raycast(worldPt + (Vector3.up * 10), -Vector3.up, out hit) | |
if (Physics.Raycast(RealWorldLocations[i] + (Vector3.up * 10), -Vector3.up, out hit)) | |
{ | |
Vector3 worldPt = hit.point; // go.transform.TransformPoint(RealWorldLocations[i]); | |
// print(worldPt); | |
if (worldPt.y > highestY) | |
{ | |
highestY = worldPt.y; | |
} | |
if (worldPt.y < lowestY) | |
{ | |
lowestY = worldPt.y; | |
} | |
} | |
} | |
range = highestY - lowestY; | |
midY = lowestY + (range * 0.5f); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment