Created
May 9, 2012 07:23
-
-
Save fum1h1ro/2642652 to your computer and use it in GitHub Desktop.
Unity3DでMeshのPostureを固定する
This file contains 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; | |
using System.Collections; | |
public class FreezeMesh : MonoBehaviour { | |
[Flags] | |
enum FreezeFlag { | |
kSCALE = 1<<0, | |
kROTATION, | |
kTRANSLATION, | |
kPROCESS_SHARED, | |
} | |
[MenuItem("Tools/FreezeMesh/Freeze Scale")] | |
static void DoFreezeScale() { | |
DoFreezing(FreezeFlag.kSCALE); | |
} | |
[MenuItem("Tools/FreezeMesh/Freeze Rotation")] | |
static void DoFreezeRotation() { | |
DoFreezing(FreezeFlag.kROTATION); | |
} | |
[MenuItem("Tools/FreezeMesh/Freeze Position")] // Unity用語に合わせた | |
static void DoFreezeTranslation() { | |
DoFreezing(FreezeFlag.kTRANSLATION); | |
} | |
[MenuItem("Tools/FreezeMesh/")] | |
[MenuItem("Tools/FreezeMesh/Freeze Scale(Shared Mesh)")] | |
static void DoFreezeScaleShared() { | |
DoFreezing(FreezeFlag.kSCALE | FreezeFlag.kPROCESS_SHARED); | |
} | |
[MenuItem("Tools/FreezeMesh/Freeze Rotation(Shared Mesh)")] | |
static void DoFreezeRotationShared() { | |
DoFreezing(FreezeFlag.kROTATION | FreezeFlag.kPROCESS_SHARED); | |
} | |
[MenuItem("Tools/FreezeMesh/Freeze Position(Shared Mesh)")] | |
static void DoFreezeTranslationShared() { | |
DoFreezing(FreezeFlag.kTRANSLATION | FreezeFlag.kPROCESS_SHARED); | |
} | |
static void DoFreezing(FreezeFlag flag) { | |
Undo.RegisterUndo(Selection.gameObjects, "Freeze Mesh"); | |
//Undo.RegisterSceneUndo("(Debug)Freeze Mesh"); | |
foreach (GameObject obj in Selection.gameObjects) { | |
Freeze(obj, flag); | |
EditorUtility.SetDirty(obj); | |
} | |
} | |
// メッシュをコピーする | |
// もしかしたら、これでは不完全かもしれない | |
static Mesh DuplicateMesh(Mesh mesh) { | |
Mesh newmesh = new Mesh(); | |
newmesh.vertices = (Vector3[])mesh.vertices.Clone(); | |
newmesh.normals = (Vector3[])mesh.normals.Clone(); | |
newmesh.tangents = (Vector4[])mesh.tangents.Clone(); | |
newmesh.uv = (Vector2[])mesh.uv.Clone(); | |
newmesh.uv2 = (Vector2[])mesh.uv2.Clone(); | |
newmesh.colors = (Color[])mesh.colors.Clone(); | |
newmesh.subMeshCount = mesh.subMeshCount; | |
for (int i = 0; i < mesh.subMeshCount; ++i) | |
newmesh.SetTriangles(mesh.GetTriangles(i), i); | |
newmesh.boneWeights = (BoneWeight[])mesh.boneWeights.Clone(); | |
newmesh.bindposes = (Matrix4x4[])mesh.bindposes.Clone(); | |
return newmesh; | |
} | |
static void Freeze(GameObject obj, FreezeFlag flag) { | |
bool processshared = ((flag & FreezeFlag.kPROCESS_SHARED) == FreezeFlag.kPROCESS_SHARED); | |
MeshFilter meshfilter = obj.GetComponent<MeshFilter>(); | |
Mesh mesh = (processshared)? meshfilter.sharedMesh : DuplicateMesh(meshfilter.sharedMesh); | |
Vector3 trs = Vector3.zero; | |
Quaternion rot = Quaternion.identity; | |
Vector3 sca = new Vector3(1.0f, 1.0f, 1.0f); | |
if ((flag & FreezeFlag.kSCALE) == FreezeFlag.kSCALE) { | |
sca = obj.transform.localScale; | |
obj.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); | |
} | |
if ((flag & FreezeFlag.kROTATION) == FreezeFlag.kROTATION) { | |
rot = obj.transform.localRotation; | |
obj.transform.localRotation = Quaternion.identity; | |
} | |
if ((flag & FreezeFlag.kTRANSLATION) == FreezeFlag.kTRANSLATION) { | |
trs = obj.transform.localPosition; | |
obj.transform.localPosition = Vector3.zero; | |
} | |
Matrix4x4 mtx = Matrix4x4.TRS(trs, rot, sca); | |
mesh.vertices = MultiplyPoint(mtx, mesh.vertices); | |
mesh.normals = MultiplyVector(mtx, mesh.normals, true); | |
mesh.RecalculateBounds(); | |
if (!processshared) { | |
DestroyImmediate(meshfilter); | |
obj.AddComponent<MeshFilter>().mesh = mesh; | |
} | |
} | |
static Vector3[] MultiplyPoint(Matrix4x4 mtx, Vector3[] vec) { | |
int len = vec.Length; | |
Vector3[] newvec = new Vector3[len]; | |
for (int i = 0; i < len; ++i) { | |
newvec[i] = mtx.MultiplyPoint(vec[i]); | |
} | |
return newvec; | |
} | |
static Vector3[] MultiplyVector(Matrix4x4 mtx, Vector3[] vec, bool ignorescale) { | |
Matrix4x4 mtx2 = Matrix4x4.identity; | |
if (ignorescale) { | |
for (int i = 0; i < 3; ++i) { | |
mtx2.SetColumn(i, mtx.GetColumn(i).normalized); | |
} | |
} else { | |
mtx2 = mtx; | |
} | |
int len = vec.Length; | |
Vector3[] newvec = new Vector3[len]; | |
for (int i = 0; i < len; ++i) { | |
newvec[i] = mtx2.MultiplyVector(vec[i]); | |
} | |
return newvec; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment