int MorphedVerts(MegaMorph mr, MegaMorphChan channel) { int count = 0; for (int v = 0; v < mr.oPoints.Length; v++) { Vector3 p = mr.oPoints[v]; bool morphed = false; for (int i = 0; i < channel.mTargetCache.Count; i++) { MegaMorphTarget mt = channel.mTargetCache[i]; if (!p.Equals(mt.points[v])) { morphed = true; break; } } if (morphed) { count++; } } return(count); }
void LoadTarget(MegaMorphTarget mt) { MegaMorph mr = (MegaMorph)target; string filename = EditorUtility.OpenFilePanel("Morph Target", lastpath, "obj"); if (filename == null || filename.Length < 1) { return; } lastpath = filename; List <MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx); if (targets != null && targets.Count > 0) { MegaTargetMesh tm = targets[0]; if (tm.verts.Count != mr.oPoints.Length) { EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK"); } else { mt.points = tm.verts.ToArray(); mt.name = tm.name; } } }
// remove mPoints from channel, just use target list, if targets.Count == 1 then use delta // first target goes into mPoints // guess we should update any targets who we have already, ie use name void LoadTargets(MegaMorphChan channel) { MegaMorph mr = (MegaMorph)target; string filename = EditorUtility.OpenFilePanel("Morph Targets", lastpath, "obj"); if (filename == null || filename.Length < 1) { return; } lastpath = filename; List <MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx); if (targets != null) { if (channel.mName == "Empty") { channel.mName = Path.GetFileNameWithoutExtension(filename); } // Now need to check that each target has correct num verts and face list matches for (int i = 0; i < targets.Count; i++) { MegaTargetMesh tm = targets[i]; if (tm.verts.Count != mr.oPoints.Length) { EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK"); } else { // See if we have a target with this name, if so update that MegaMorphTarget mt = channel.GetTarget(tm.name); if (mt == null) // add a new target { mt = new MegaMorphTarget(); mt.name = tm.name; channel.mTargetCache.Add(mt); } mt.points = tm.verts.ToArray(); //for ( int v = 0; v < mt.points.Length; v++ ) //{ //if ( mt.points[v] == mr.oPoints[v] ) //Debug.Log("Vert " + v + " isnt morphed"); //} } } channel.ResetPercent(); channel.Rebuild(mr); // rebuild delta for 1st channel } mr.BuildCompress(); }
void CompressChannel(MegaMorph mr, MegaMorphChan mc) { // for now change system to work off mapping, just have 1 to 1 mapping to test its working mc.mapping = new int[mr.oPoints.Length]; for (int i = 0; i < mr.oPoints.Length; i++) { mc.mapping[i] = i; } #if false BitArray modded = new BitArray(mr.oPoints.Length); modded.SetAll(false); for (int t = 0; t < mc.mTargetCache.Count; t++) { MegaMorphTarget mt = mc.mTargetCache[t]; for (int i = 0; i < mr.oPoints.Length; i++) { if (mt.points[i] != mr.oPoints[i]) // Have a threshold for this { modded[i] = true; break; } } } List <int> points = new List <int>(); for (int i = 0; i < modded.Count; i++) { if (modded[i]) { points.Add(i); } } // points now holds indexes of morphed verts for the channel, so now need to collapse points Vector3[] pts = new Vector3[points.Count]; for (int t = 0; t < mc.mTargetCache.Count; t++) { MegaMorphTarget mt = mc.mTargetCache[t]; for (int i = 0; i < points.Count; i++) { pts[i] = mt.points[points[i]]; } pts.CopyTo(mt.points, 0); } // If one target deal with deltas #endif }
public MegaMorphTarget LoadTarget(BinaryReader br) { MegaMorphTarget target = new MegaMorphTarget(); currentTarget = target; //Parse(br, ParseTarget); MegaParse.Parse(br, ParseTarget); return target; }
public MegaMorphTarget LoadTarget(BinaryReader br) { MegaMorphTarget target = new MegaMorphTarget(); currentTarget = target; MegaParse.Parse(br, ParseTarget); return(target); }
Vector3 Cubic(MegaMorphTarget t, int pointnum, float alpha) { // Linear for now, will have coefs in here for cubic Vector3 v = t.mompoints[pointnum].delta; v.x *= alpha; v.y *= alpha; v.z *= alpha; return v; }
Vector3 Cubic(MegaMorphTarget t, int pointnum, float alpha) { // Linear for now, will have coefs in here for cubic Vector3 v = t.mompoints[pointnum].delta; v.x *= alpha; v.y *= alpha; v.z *= alpha; return(v); }
void SwapTargets(MegaMorphChan chan, int t1, int t2) { if (t1 >= 0 && t1 < chan.mTargetCache.Count && t2 >= 0 && t2 < chan.mTargetCache.Count && t1 != t2) { MegaMorphTarget mt1 = chan.mTargetCache[t1]; MegaMorphTarget mt2 = chan.mTargetCache[t2]; float per = mt1.percent; mt1.percent = mt2.percent; mt2.percent = per; chan.mTargetCache.RemoveAt(t1); chan.mTargetCache.Insert(t2, mt1); EditorUtility.SetDirty(target); } }
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(); }
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(); }
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 LoadTarget(MegaMorphTarget mt) { MegaMorph mr = (MegaMorph)target; string filename = EditorUtility.OpenFilePanel("Morph Target", lastpath, "obj"); if ( filename == null || filename.Length < 1 ) return; lastpath = filename; List<MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx); if ( targets != null && targets.Count > 0 ) { MegaTargetMesh tm = targets[0]; if ( tm.verts.Count != mr.oPoints.Length ) { EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK"); } else { mt.points = tm.verts.ToArray(); mt.name = tm.name; } } }
// remove mPoints from channel, just use target list, if targets.Count == 1 then use delta // first target goes into mPoints // guess we should update any targets who we have already, ie use name void LoadTargets(MegaMorphChan channel) { MegaMorph mr = (MegaMorph)target; string filename = EditorUtility.OpenFilePanel("Morph Targets", lastpath, "obj"); if ( filename == null || filename.Length < 1 ) return; lastpath = filename; List<MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx); if ( targets != null ) { if ( channel.mName == "Empty" ) channel.mName = Path.GetFileNameWithoutExtension(filename); // Now need to check that each target has correct num verts and face list matches for ( int i = 0; i < targets.Count; i++ ) { MegaTargetMesh tm = targets[i]; if ( tm.verts.Count != mr.oPoints.Length ) EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK"); else { // See if we have a target with this name, if so update that MegaMorphTarget mt = channel.GetTarget(tm.name); if ( mt == null ) // add a new target { mt = new MegaMorphTarget(); mt.name = tm.name; channel.mTargetCache.Add(mt); } mt.points = tm.verts.ToArray(); //for ( int v = 0; v < mt.points.Length; v++ ) //{ //if ( mt.points[v] == mr.oPoints[v] ) //Debug.Log("Vert " + v + " isnt morphed"); //} } } channel.ResetPercent(); channel.Rebuild(mr); // rebuild delta for 1st channel } mr.BuildCompress(); }
// Still need to be able to add in unity meshes void DisplayTarget(MegaMorph 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); 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); if ( GUILayout.Button("Load") ) { LoadTarget(mt); } GUI.backgroundColor = new Color(1.0f, 0.5f, 0.5f); if ( GUILayout.Button("Delete") ) { MegaMorphTarget mt0 = channel.mTargetCache[0]; channel.mTargetCache.Remove(mt); channel.ResetPercent(); if ( channel.mTargetCache.Count > 0 && channel.mTargetCache[0] != mt0 ) channel.Rebuild(morph); } GUI.backgroundColor = new Color(1.0f, 1.0f, 0.5f); if ( GUILayout.Button("Up") ) { if ( num > 0 ) { SwapTargets(channel, num, num - 1); if ( num == 1 ) channel.Rebuild(morph); } } GUI.backgroundColor = new Color(0.5f, 1.0f, 1.0f); if ( GUILayout.Button("Dn") ) { if ( num < channel.mTargetCache.Count - 1 ) { SwapTargets(channel, num, num + 1); if ( num == 0 ) channel.Rebuild(morph); } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 0; PopCols(); }
// Still need to be able to add in unity meshes void DisplayTarget(MegaMorph 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); 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); } if (GUILayout.Button("Load")) { LoadTarget(mt); } GUI.backgroundColor = new Color(1.0f, 0.5f, 0.5f); if (GUILayout.Button("Delete")) { MegaMorphTarget mt0 = channel.mTargetCache[0]; channel.mTargetCache.Remove(mt); channel.ResetPercent(); if (channel.mTargetCache.Count > 0 && channel.mTargetCache[0] != mt0) { channel.Rebuild(morph); } } GUI.backgroundColor = new Color(1.0f, 1.0f, 0.5f); if (GUILayout.Button("Up")) { if (num > 0) { SwapTargets(channel, num, num - 1); if (num == 1) { channel.Rebuild(morph); } } } GUI.backgroundColor = new Color(0.5f, 1.0f, 1.0f); if (GUILayout.Button("Dn")) { if (num < channel.mTargetCache.Count - 1) { SwapTargets(channel, num, num + 1); if (num == 0) { channel.Rebuild(morph); } } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 0; PopCols(); }
void DisplayChannel(MegaMorph morph, MegaMorphChan channel, int num) { if ( GUILayout.Button(num + " - " + 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, 0.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); if ( GUILayout.Button("Load Targets") ) LoadTargets(channel); GUI.backgroundColor = new Color(0.5f, 1.0f, 0.5f); if ( GUILayout.Button("Add Target") ) { if ( channel.mTargetCache == null ) channel.mTargetCache = new List<MegaMorphTarget>(); MegaMorphTarget mt = new MegaMorphTarget(); channel.mTargetCache.Add(mt); channel.ResetPercent(); } 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, 0.0f, 100.0f); } }
void DisplayChannel(MegaMorph morph, MegaMorphChan channel, int num) { if (GUILayout.Button(num + " - " + 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, 0.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); if (GUILayout.Button("Load Targets")) { LoadTargets(channel); } GUI.backgroundColor = new Color(0.5f, 1.0f, 0.5f); if (GUILayout.Button("Add Target")) { if (channel.mTargetCache == null) { channel.mTargetCache = new List <MegaMorphTarget>(); } MegaMorphTarget mt = new MegaMorphTarget(); channel.mTargetCache.Add(mt); channel.ResetPercent(); } 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, 0.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]; } }
// We should just modify the internal points then map them out at the end public override void Modify(MegaModifiers mc) { verts.CopyTo(sverts, 0); // This should only blit totally untouched verts for (int i = 0; i < chanBank.Count; i++) { MegaMorphChan chan = chanBank[i]; chan.UpdatePercent(); float fChannelPercent = chan.Percent; // check for change since last frame on percent, if none just add in diff // Can we keep each chan delta then if not changed can just add it in if (fChannelPercent == chan.fChannelPercent) { MegaMorphTarget trg = chan.mTargetCache[chan.targ]; for (int pointnum = 0; pointnum < trg.mompoints.Length; pointnum++) { int p = trg.mompoints[pointnum].id; int c = mapping[p].indices.Length; Vector3 df = chan.diff[pointnum]; for (int m = 0; m < c; m++) { int index = mapping[p].indices[m]; sverts[index].x += df.x; sverts[index].y += df.y; sverts[index].z += df.z; } } } else { chan.fChannelPercent = fChannelPercent; if (chan.mTargetCache != null && chan.mTargetCache.Count > 0 && chan.mActiveOverride) { if (chan.mUseLimit || glUseLimit) { if (glUseLimit) { fChannelPercent = Mathf.Clamp(fChannelPercent, glMin, glMax); } else { fChannelPercent = Mathf.Clamp(fChannelPercent, chan.mSpinmin, chan.mSpinmax); } } int targ = 0; float alpha = 0.0f; if (fChannelPercent < chan.mTargetCache[0].percent) { targ = 0; //alpha = 0.0f; alpha = (fChannelPercent - chan.mTargetCache[targ].percent) / (chan.mTargetCache[targ + 1].percent - chan.mTargetCache[targ].percent); //Debug.Log("alpha " + alpha + " percent " + fChannelPercent); } else { int last = chan.mTargetCache.Count - 1; if (fChannelPercent >= chan.mTargetCache[last].percent) { targ = last - 1; //alpha = 1.0f; alpha = (fChannelPercent - chan.mTargetCache[targ].percent) / (chan.mTargetCache[targ + 1].percent - chan.mTargetCache[targ].percent); } else { for (int t = 1; t < chan.mTargetCache.Count; t++) { if (fChannelPercent < chan.mTargetCache[t].percent) { targ = t - 1; alpha = (fChannelPercent - chan.mTargetCache[targ].percent) / (chan.mTargetCache[t].percent - chan.mTargetCache[targ].percent); //Debug.Log("alpha1 " + alpha + " percent1 " + fChannelPercent); break; } } } } MegaMorphTarget trg = chan.mTargetCache[targ]; chan.targ = targ; for (int pointnum = 0; pointnum < trg.mompoints.Length; pointnum++) { int p = trg.mompoints[pointnum].id; // Save so if chan doesnt change we dont need to recalc Vector3 df = trg.mompoints[pointnum].start; df.x += trg.mompoints[pointnum].delta.x * alpha; df.y += trg.mompoints[pointnum].delta.y * alpha; df.z += trg.mompoints[pointnum].delta.z * alpha; chan.diff[pointnum] = df; for (int m = 0; m < mapping[p].indices.Length; m++) { int index = mapping[p].indices[m]; sverts[index].x += df.x; sverts[index].y += df.y; sverts[index].z += df.z; } } } } } }
public void ModifyMT(MegaModifiers mc, int tindex, int cores) { if (tindex > 0) { return; } Modify(mc); return; for (int i = 0; i < chanBank.Count; i++) { MegaMorphChan chan = chanBank[i]; // check for change since last frame on percent, if none just add in diff // Can we keep each chan delta then if not changed can just add it in if (chan.fProgression == chan.fChannelPercent) { MegaMorphTarget trg = chan.mTargetCache[chan.targ]; int startvert = 0; //(tindex * step); int endvert = trg.mompoints.Length; //startvert + step; for (int pointnum = startvert; pointnum < endvert; pointnum++) { int p = trg.mompoints[pointnum].id; int c = mapping[p].indices.Length; Vector3 df = chan.diff[pointnum]; for (int m = 0; m < c; m++) { int ix = mapping[p].indices[m]; sverts[ix].x += df.x; sverts[ix].y += df.y; sverts[ix].z += df.z; } } } else { chan.fChannelPercent = chan.fProgression; float fChannelPercent = chan.fChannelPercent; if (chan.mTargetCache != null && chan.mTargetCache.Count > 0 && chan.mActiveOverride) { MegaMorphTarget trg = chan.mTargetCache[chan.targ]; //int step = trg.mompoints.Length / cores; int startvert = 0; //(tindex * step); int endvert = trg.mompoints.Length; //startvert + step; //if ( tindex == cores - 1 ) // endvert = trg.mompoints.Length; // So should we update channels then add them all up? if (chan.cubic) { for (int pointnum = startvert; pointnum < endvert; pointnum++) { int p = trg.mompoints[pointnum].id; int c = mapping[p].indices.Length; Vector3 df = trg.mompoints[pointnum].start; Vector3 cu = Cubic(trg, pointnum, chan.alpha); df.x += cu.x * chan.alpha; df.y += cu.y * chan.alpha; df.z += cu.z * chan.alpha; chan.diff[pointnum] = df; for (int m = 0; m < c; m++) { int ix = mapping[p].indices[m]; sverts[ix].x += df.x; sverts[ix].y += df.y; sverts[ix].z += df.z; } } } else { for (int pointnum = startvert; pointnum < endvert; pointnum++) { int p = trg.mompoints[pointnum].id; int c = mapping[p].indices.Length; // Save so if chan doesnt change we dont need to recalc Vector3 df = trg.mompoints[pointnum].start; df.x += trg.mompoints[pointnum].delta.x * chan.alpha; df.y += trg.mompoints[pointnum].delta.y * chan.alpha; df.z += trg.mompoints[pointnum].delta.z * chan.alpha; chan.diff[pointnum] = df; for (int m = 0; m < c; m++) { int ix = mapping[p].indices[m]; sverts[ix].x += df.x; sverts[ix].y += df.y; sverts[ix].z += df.z; } } } } } } }