// Fbx could have been exported any which way so still need to do try all mappings to find correct public bool ParseMorph(BinaryReader br, string id) { MegaMorphOMatic mr = (MegaMorphOMatic)target; switch (id) { case "Max": mr.Max = br.ReadSingle(); break; case "Min": mr.Min = br.ReadSingle(); break; case "UseLim": mr.UseLimit = (br.ReadInt32() == 1); break; // This will only be changed points, but we need scale case "StartPoints": // Mapping MegaTargetMesh tm = new MegaTargetMesh(); tm.verts = MegaParse.ReadP3l(br); // make a vector if (!TryMapping1(tm, mr)) { EditorUtility.DisplayDialog("Mapping Failed!", "Mapping failed!", "OK"); EditorUtility.ClearProgressBar(); return(false); } break; case "Channel": mr.chanBank.Add(LoadChan(br)); break; case "Animation": LoadAnimation(mr, br); break; default: return(false); } return(true); }
// This is common to other morpher void DisplayChannel(MegaMorphOMatic morph, MegaMorphChan channel) { if ( GUILayout.Button(channel.mName) ) channel.showparams = !channel.showparams; GUI.backgroundColor = new Color(1, 1, 1); if ( channel.showparams ) { channel.mName = EditorGUILayout.TextField("Name", channel.mName); if ( channel.mTargetCache != null && channel.mTargetCache.Count > 0 ) { channel.mActiveOverride = EditorGUILayout.Toggle("Active", channel.mActiveOverride); channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, channel.mSpinmin, channel.mSpinmax); //.0f, 100.0f); channel.mCurvature = EditorGUILayout.FloatField("Tension", channel.mCurvature); } channel.mUseLimit = EditorGUILayout.Toggle("Use Limit", channel.mUseLimit); if ( channel.mUseLimit ) { channel.mSpinmin = EditorGUILayout.FloatField("Min", channel.mSpinmin); channel.mSpinmax = EditorGUILayout.FloatField("Max", channel.mSpinmax); } EditorGUILayout.BeginHorizontal(); PushCols(); GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f); GUI.backgroundColor = new Color(1.5f, 0.5f, 0.5f); if ( GUILayout.Button("Delete Channel") ) morph.chanBank.Remove(channel); EditorGUILayout.EndHorizontal(); PopCols(); if ( channel.mTargetCache != null && channel.mTargetCache.Count > 0 ) { channel.showtargets = EditorGUILayout.Foldout(channel.showtargets, "Targets"); if ( channel.showtargets ) { if ( channel.mTargetCache != null ) { for ( int i = 0; i < channel.mTargetCache.Count; i++ ) DisplayTarget(morph, channel, channel.mTargetCache[i], i); } } } } else { if ( channel.mActiveOverride && channel.mTargetCache != null && channel.mTargetCache.Count > 0 ) { channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, channel.mSpinmin, channel.mSpinmax); //.0f, 100.0f); } } }
// This is for new morpher #if false public void Rebuild(MegaMorphOMatic mp, Vector3[] op) { if (mTargetCache != null && mTargetCache.Count > 0 && op != null && mTargetCache[0].points != null) { if (mp.oPoints.Length == mTargetCache[0].points.Length) { //Debug.Log("oplen " + mp.oPoints.Length + " tclen " + mTargetCache[0].points.Length); mDeltas = new Vector3[op.Length]; for (int i = 0; i < mTargetCache[0].points.Length; i++) { mDeltas[i] = (mTargetCache[0].points[i] - op[i]) / 100.0f; } } } }
bool AnimCallback(BinaryReader br, string id) { MegaMorphOMatic mr = (MegaMorphOMatic)target; switch (id) { case "Chan": int cn = br.ReadInt32(); currentChan = mr.chanBank[cn]; break; case "Anim": currentChan.control = LoadAnim(br); break; default: return(false); } return(true); }
void LoadMorph() { MegaMorphOMatic mr = (MegaMorphOMatic)target; string filename = EditorUtility.OpenFilePanel("Morph-O-Matic Morph File", lastpath, "mmf"); if (filename == null || filename.Length < 1) { return; } lastpath = filename; // Clear what we have mr.chanBank.Clear(); ParseFile(filename, MorphCallback); mr.animate = false; float looptime = 0.0f; // Set Looptime and animate if there is an anim for (int i = 0; i < mr.chanBank.Count; i++) { MegaMorphChan mc = mr.chanBank[i]; if (mc.control != null) { mr.animate = true; float t = mc.control.Times[mc.control.Times.Length - 1]; if (t > looptime) { looptime = t; } } } if (mr.animate) { mr.looptime = looptime; } BuildData(); }
// Remove morph and pass tolerance then can morph to Utils // TODO: report error if target vert counts dont match base mapping bool DoMapping(MegaModifiers mod, MegaMorphOMatic morph, MegaTargetMesh tm, float scale, bool flipyz, bool negx) { for (int i = 0; i < mod.verts.Length; i++) { float a = (float)i / (float)mod.verts.Length; EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a); int map = MegaUtils.FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, i); if (map == -1) { // Failed EditorUtility.ClearProgressBar(); return(false); } } EditorUtility.ClearProgressBar(); return(true); }
Vector3 ConvertPoint(Vector3 v) { MegaMorphOMatic mr = (MegaMorphOMatic)target; Vector3 p = v * mr.importScale; if (mr.negx) { p.x = -p.x; } if (mr.flipyz) { float y = p.y; p.y = p.z; p.z = y; } return(p); }
void DisplayTarget(MegaMorphOMatic morph, MegaMorphChan channel, MegaMorphTarget mt, int num) { PushCols(); EditorGUI.indentLevel = 1; mt.name = EditorGUILayout.TextField("Name", mt.name); //mt.percent = EditorGUILayout.Slider("Percent", mt.percent, 0.0f, 100.0f); mt.percent = EditorGUILayout.Slider("Percent", mt.percent, channel.mSpinmin, channel.mSpinmax); //.0f, 100.0f); EditorGUILayout.BeginHorizontal(); if ( mt.points == null || mt.points.Length != morph.oPoints.Length ) GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f); else GUI.backgroundColor = new Color(0.0f, 1.0f, 0.0f); GUI.backgroundColor = new Color(1.0f, 0.5f, 0.5f); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 0; PopCols(); }
// Remove morph and pass tolerance then can morph to Utils // TODO: report error if target vert counts dont match base mapping bool DoMapping(MegaModifiers mod, MegaMorphOMatic morph, MegaTargetMesh tm, float scale, bool flipyz, bool negx) { for ( int i = 0; i < mod.verts.Length; i++ ) { float a = (float)i / (float)mod.verts.Length; EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a); int map = MegaUtils.FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, i); if ( map == -1 ) { // Failed EditorUtility.ClearProgressBar(); return false; } } EditorUtility.ClearProgressBar(); return true; }
bool GetDelta(MegaMorphTarget targ, int v, out Vector3 delta, out float w) { MegaMorphOMatic mod = (MegaMorphOMatic)target; if (targ.loadpoints != null) { for (int i = 0; i < targ.loadpoints.Length; i++) { int id = targ.loadpoints[i].id; if (id == v) { delta = targ.loadpoints[i].p - mod.oPoints[id]; w = targ.loadpoints[i].w; return(true); } } } delta = Vector3.zero; w = 0.0f; return(false); }
void DisplayTarget(MegaMorphOMatic morph, MegaMorphChan channel, MegaMorphTarget mt, int num) { PushCols(); EditorGUI.indentLevel = 1; mt.name = EditorGUILayout.TextField("Name", mt.name); //mt.percent = EditorGUILayout.Slider("Percent", mt.percent, 0.0f, 100.0f); mt.percent = EditorGUILayout.Slider("Percent", mt.percent, channel.mSpinmin, channel.mSpinmax); //.0f, 100.0f); EditorGUILayout.BeginHorizontal(); if (mt.points == null || mt.points.Length != morph.oPoints.Length) { GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f); } else { GUI.backgroundColor = new Color(0.0f, 1.0f, 0.0f); } GUI.backgroundColor = new Color(1.0f, 0.5f, 0.5f); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 0; PopCols(); }
void LoadAnimation(MegaMorphOMatic mr, BinaryReader br) { MegaParse.Parse(br, AnimCallback); }
// This is common to other morpher void DisplayChannel(MegaMorphOMatic morph, MegaMorphChan channel) { if (GUILayout.Button(channel.mName)) { channel.showparams = !channel.showparams; } GUI.backgroundColor = new Color(1, 1, 1); if (channel.showparams) { channel.mName = EditorGUILayout.TextField("Name", channel.mName); if (channel.mTargetCache != null && channel.mTargetCache.Count > 0) { channel.mActiveOverride = EditorGUILayout.Toggle("Active", channel.mActiveOverride); channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, channel.mSpinmin, channel.mSpinmax); //.0f, 100.0f); channel.mCurvature = EditorGUILayout.FloatField("Tension", channel.mCurvature); } channel.mUseLimit = EditorGUILayout.Toggle("Use Limit", channel.mUseLimit); if (channel.mUseLimit) { channel.mSpinmin = EditorGUILayout.FloatField("Min", channel.mSpinmin); channel.mSpinmax = EditorGUILayout.FloatField("Max", channel.mSpinmax); } EditorGUILayout.BeginHorizontal(); PushCols(); GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f); GUI.backgroundColor = new Color(1.5f, 0.5f, 0.5f); if (GUILayout.Button("Delete Channel")) { morph.chanBank.Remove(channel); } EditorGUILayout.EndHorizontal(); PopCols(); if (channel.mTargetCache != null && channel.mTargetCache.Count > 0) { channel.showtargets = EditorGUILayout.Foldout(channel.showtargets, "Targets"); if (channel.showtargets) { if (channel.mTargetCache != null) { for (int i = 0; i < channel.mTargetCache.Count; i++) { DisplayTarget(morph, channel, channel.mTargetCache[i], i); } } } } } else { if (channel.mActiveOverride && channel.mTargetCache != null && channel.mTargetCache.Count > 0) { channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, channel.mSpinmin, channel.mSpinmax); //.0f, 100.0f); } } }
// Build the morphing data // each target holds only the points that differe from the base so need to build table showing for each // target the points that differ public void BuildData() { MegaMorphOMatic mod = (MegaMorphOMatic)target; List <MOMVert> verts = new List <MOMVert>(); for (int c = 0; c < mod.chanBank.Count; c++) { MegaMorphChan chan = mod.chanBank[c]; int maxverts = 0; for (int t = 0; t < chan.mTargetCache.Count - 1; t++) { MegaMorphTarget targ = chan.mTargetCache[t]; MegaMorphTarget targ1 = chan.mTargetCache[t + 1]; // if t is 0 then just use the points Vector3 delta = Vector3.zero; Vector3 delta1 = Vector3.zero; float w = 1.0f; verts.Clear(); for (int v = 0; v < mod.oPoints.Length; v++) { bool t1 = GetDelta(targ, v, out delta, out w); bool t2 = GetDelta(targ1, v, out delta1, out w); if (t1 || t2) //GetDelta(targ, v, out delta, out w) || GetDelta(targ1, v, out delta1, out w) ) { MOMVert vert = new MOMVert(); vert.id = v; vert.w = w; vert.start = delta; vert.delta = delta1 - delta; verts.Add(vert); } } if (verts.Count > maxverts) { maxverts = verts.Count; } if (verts.Count > 0) { targ.mompoints = verts.ToArray(); } } for (int t = 0; t < chan.mTargetCache.Count; t++) { chan.mTargetCache[t].loadpoints = null; } chan.diff = new Vector3[maxverts]; } }
public override void OnInspectorGUI() { MegaMorphOMatic morph = (MegaMorphOMatic)target; PushCols(); if (GUILayout.Button("Import MorphOMatic File")) { LoadMorph(); EditorUtility.SetDirty(target); } // Basic mod stuff showmodparams = EditorGUILayout.Foldout(showmodparams, "Modifier Common Params"); if (showmodparams) { morph.Label = EditorGUILayout.TextField("Label", morph.Label); morph.MaxLOD = EditorGUILayout.IntField("MaxLOD", morph.MaxLOD); morph.ModEnabled = EditorGUILayout.Toggle("Mod Enabled", morph.ModEnabled); morph.DisplayGizmo = EditorGUILayout.Toggle("Display Gizmo", morph.DisplayGizmo); morph.Order = EditorGUILayout.IntField("Order", morph.Order); morph.gizCol1 = EditorGUILayout.ColorField("Giz Col 1", morph.gizCol1); morph.gizCol2 = EditorGUILayout.ColorField("Giz Col 2", morph.gizCol2); } morph.animate = EditorGUILayout.Toggle("Animate", morph.animate); if (morph.animate) { morph.animtime = EditorGUILayout.FloatField("AnimTime", morph.animtime); morph.looptime = EditorGUILayout.FloatField("LoopTime", morph.looptime); morph.speed = EditorGUILayout.FloatField("Speed", morph.speed); morph.repeatMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("RepeatMode", morph.repeatMode); } EditorGUILayout.BeginHorizontal(); PushCols(); if (morph.mapping == null || morph.mapping.Length == 0) { GUI.backgroundColor = Color.red; } else { GUI.backgroundColor = Color.green; } PopCols(); if (GUILayout.Button("Add Channel")) { if (morph.chanBank == null) { morph.chanBank = new List <MegaMorphChan>(); } MegaMorphChan nc = new MegaMorphChan(); nc.mName = "Empty"; morph.chanBank.Add(nc); } EditorGUILayout.EndHorizontal(); string bname = "Hide Channels"; if (!showchannels) { bname = "Show Channels"; } if (GUILayout.Button(bname)) { showchannels = !showchannels; } #if false if (showchannels && morph.chanBank != null) { for (int i = 0; i < morph.chanBank.Count; i++) { PushCols(); if ((i & 1) == 0) { GUI.backgroundColor = ChanCol1; } else { GUI.backgroundColor = ChanCol2; } DisplayChannel(morph, morph.chanBank[i]); PopCols(); } } #else morph.limitchandisplay = EditorGUILayout.Toggle("Compact Display", morph.limitchandisplay); if (showchannels && morph.chanBank != null) { if (morph.limitchandisplay) { morph.startchannel = EditorGUILayout.IntField("Start", morph.startchannel); morph.displaychans = EditorGUILayout.IntField("Display", morph.displaychans); if (morph.displaychans < 0) { morph.displaychans = 0; } if (morph.startchannel < 0) { morph.startchannel = 0; } if (morph.startchannel >= morph.chanBank.Count - 1) { morph.startchannel = morph.chanBank.Count - 1; } int end = morph.startchannel + morph.displaychans; if (end >= morph.chanBank.Count) { end = morph.chanBank.Count; } for (int i = morph.startchannel; i < end; i++) { PushCols(); if ((i & 1) == 0) { GUI.backgroundColor = ChanCol1; } else { GUI.backgroundColor = ChanCol2; } DisplayChannel(morph, morph.chanBank[i]); PopCols(); } } else { for (int i = 0; i < morph.chanBank.Count; i++) { PushCols(); if ((i & 1) == 0) { GUI.backgroundColor = ChanCol1; } else { GUI.backgroundColor = ChanCol2; } DisplayChannel(morph, morph.chanBank[i]); PopCols(); } } } #endif extraparams = EditorGUILayout.Foldout(extraparams, "Extra Params"); if (extraparams) { ChanCol1 = EditorGUILayout.ColorField("Channel Col 1", ChanCol1); ChanCol2 = EditorGUILayout.ColorField("Channel Col 2", ChanCol2); } PopCols(); if (GUI.changed) { EditorUtility.SetDirty(target); } }
// We should know the mapping // remove morph pass tolerance instead bool TryMapping1(MegaTargetMesh tm, MegaMorphOMatic morph) { MegaModifiers mod = morph.GetComponent<MegaModifiers>(); if ( mod == null ) { EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK"); return false; } // Get extents for mod verts and for imported meshes, if not the same then scale Vector3 min1,max1; Vector3 min2,max2; Vector3 ex1 = MegaUtils.Extents(mod.verts, out min1, out max1); Vector3 ex2 = MegaUtils.Extents(tm.verts, out min2, out max2); // need min max on all axis so we can produce an offset to add float d1 = ex1.x; float d2 = ex2.x; float scl = d1 / d2; //d2 / d1; bool flipyz = false; bool negx = false; // So try to match first vert using autoscale and no flip bool mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if ( !mapped ) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if ( !mapped ) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) ) { flipyz = false; negx = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if ( !mapped ) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); } } } if ( mapped ) { morph.importScale = scl; morph.flipyz = flipyz; morph.negx = negx; // if mapping was ok set opoints morph.oPoints = tm.verts.ToArray(); for ( int i = 0; i < morph.oPoints.Length; i++ ) { Vector3 p = morph.oPoints[i]; if ( negx ) p.x = -p.x; if ( flipyz ) { float z = p.z; p.z = p.y; p.y = z; } morph.oPoints[i] = p * morph.importScale; } morph.mapping = new MegaMomVertMap[morph.oPoints.Length]; for ( int i = 0; i < morph.oPoints.Length; i++ ) { //int[] indices = morph.FindVerts(morph.oPoints[i], mod); int[] indices = FindVerts(morph.oPoints[i], mod); morph.mapping[i] = new MegaMomVertMap(); morph.mapping[i].indices = indices; //morph.FindVerts(morph.oPoints[i], mod); } return true; } return false; }
// This is for new morpher public void Rebuild(MegaMorphOMatic mp, Vector3[] op) { if ( mTargetCache != null && mTargetCache.Count > 0 && op != null && mTargetCache[0].points != null ) { if ( mp.oPoints.Length == mTargetCache[0].points.Length ) { //Debug.Log("oplen " + mp.oPoints.Length + " tclen " + mTargetCache[0].points.Length); mDeltas = new Vector3[op.Length]; for ( int i = 0; i < mTargetCache[0].points.Length; i++ ) { mDeltas[i] = (mTargetCache[0].points[i] - op[i]) / 100.0f; } } } }
// We should know the mapping // remove morph pass tolerance instead bool TryMapping1(MegaTargetMesh tm, MegaMorphOMatic morph) { MegaModifiers mod = morph.GetComponent <MegaModifiers>(); if (mod == null) { EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK"); return(false); } // Get extents for mod verts and for imported meshes, if not the same then scale Vector3 min1, max1; Vector3 min2, max2; Vector3 ex1 = MegaUtils.Extents(mod.verts, out min1, out max1); Vector3 ex2 = MegaUtils.Extents(tm.verts, out min2, out max2); // need min max on all axis so we can produce an offset to add float d1 = ex1.x; float d2 = ex2.x; float scl = d1 / d2; //d2 / d1; bool flipyz = false; bool negx = false; // So try to match first vert using autoscale and no flip bool mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if (!mapped) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if (!mapped) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) ) { flipyz = false; negx = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if (!mapped) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); } } } if (mapped) { morph.importScale = scl; morph.flipyz = flipyz; morph.negx = negx; // if mapping was ok set opoints morph.oPoints = tm.verts.ToArray(); for (int i = 0; i < morph.oPoints.Length; i++) { Vector3 p = morph.oPoints[i]; if (negx) { p.x = -p.x; } if (flipyz) { float z = p.z; p.z = p.y; p.y = z; } morph.oPoints[i] = p * morph.importScale; } morph.mapping = new MegaMomVertMap[morph.oPoints.Length]; for (int i = 0; i < morph.oPoints.Length; i++) { //int[] indices = morph.FindVerts(morph.oPoints[i], mod); int[] indices = FindVerts(morph.oPoints[i], mod); morph.mapping[i] = new MegaMomVertMap(); morph.mapping[i].indices = indices; //morph.FindVerts(morph.oPoints[i], mod); } return(true); } return(false); }