Skip to content

Instantly share code, notes, and snippets.

@fum1h1ro
Created May 9, 2012 07:23
Show Gist options
  • Save fum1h1ro/2642652 to your computer and use it in GitHub Desktop.
Save fum1h1ro/2642652 to your computer and use it in GitHub Desktop.
Unity3DでMeshのPostureを固定する
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