public static void Fitting(PatchSkeletalMesh smesh, PatchSkeleton skl) { FTimer.Resume("Fitting:SetCtrl"); // スケルトンに合わせて制御点を移動 foreach (var kv in smesh.skeletalControlPointDict) { PatchSkeletonBone b = kv.Key; List <PointF> orgPts = kv.Value; PatchSkeletonBone br = CorrespondingBone(skl, b); if (br == null) { continue; } if (orgPts.Count <= 1) { continue; } for (int i = 0; i < orgPts.Count; i++) { float t = (float)i / (orgPts.Count - 1); // smesh.skeletalControlPointExpandToXXXの値にしたがって、src, dst方向にそれぞれ伸長させる float exSrc = smesh.endJoints.Contains(b.src.name) ? smesh.srcStretchRatio : 0; float exDst = smesh.endJoints.Contains(b.dst.name) ? smesh.dstStretchRatio : 0; float dx = br.dst.position.X - br.src.position.X; float dy = br.dst.position.Y - br.src.position.Y; t *= 1 + exSrc + exDst; float lx = dx * t; float ly = dy * t; float ox = -dx * exSrc; float oy = -dy * exSrc; float x = br.src.position.X + ox + lx; float y = br.src.position.Y + oy + ly; // float x = br.src.position.X * (1 - t) + br.dst.position.X * t; // float y = br.src.position.Y * (1 - t) + br.dst.position.Y * t; PatchControlPoint c = smesh.mesh.FindControlPoint(orgPts[i]); if (c == null) { continue; } smesh.mesh.TranslateControlPoint(c.position, new PointF(x, y), false); } // スケルトン(mesh.skl)も動かす b.src.position = br.src.position; b.dst.position = br.dst.position; } FTimer.Pause("Fitting:SetCtrl"); // 制御点の移動を反映してメッシュ変形 FTimer.Resume("Fitting:FlushDefomation"); smesh.mesh.FlushDefomation(); FTimer.Pause("Fitting:FlushDefomation"); }
public void TestPause() { FTimer t = new FTimer(3); t.Start(4); // override original duration float startTime = t.StartTime; // pausing fiddles with the timer's start time, so don't depend on it while faking time. Assert.That(t.Duration, Is.EqualTo(4f)); Assert.That(t.StartTime, Is.EqualTo(Time.time)); #if FILUTIL_DEBUG t._SetNow(startTime + 1); AssertState(t, 1, 0.25f, true, false, false); t.Pause(); AssertState(t, 1, 0.25f, true, true, false); t._SetNow(startTime + 1); AssertState(t, 1, 0.25f, true, true, false); t._SetNow(startTime + 2); t.Unpause(); AssertState(t, 1, 0.25f, true, false, false); t._SetNow(startTime + 3); AssertState(t, 2, 0.50f, true, false, false); t.Pause(true); t._SetNow(startTime + 7); AssertState(t, 2, 0.50f, true, true, false); t._SetNow(startTime + 9); AssertState(t, 2, 0.50f, true, true, false); t._SetNow(startTime + 10); t.Pause(false); AssertState(t, 2, 0.50f, true, false, false); t._SetNow(startTime + 12); AssertState(t, 4, 1, true, false, true); #endif }
public void FlushDefomation() { FTimer.Resume("FlushDefomation:begin"); // 制御点をPatchMesh, ARAPで同期させる arap.UpdateControlPoint(controlPoints.Select(c => c.position).ToList()); FTimer.Pause("FlushDefomation:begin"); FTimer.Resume("FlushDefomation:flush"); // ARAP変形 arap.FlushDefomation(); FTimer.Pause("FlushDefomation:flush"); FTimer.Resume("FlushDefomation:end"); // 結果を取得 List <PointF> ptList = arap.CopyMeshPointList(); for (int i = 0; i < vertices.Count; i++) { vertices[i].position = ptList[i]; } FTimer.Pause("FlushDefomation:end"); }
public void TestDelay() { FTimer t = new FTimer(3); t.Restart(4); // Restart and Start are exactly the same. float startTime = t.StartTime; t.Extend(2); Assert.That(t.Duration, Is.EqualTo(6)); Assert.That(t.StartTime, Is.EqualTo(Time.time)); t.Delay(1); Assert.That(t.Duration, Is.EqualTo(6)); Assert.That(t.StartTime, Is.EqualTo(startTime + 1)); // Delay can cause Elapsed to go negative, but Normalized will always be clamped to [0,1]. AssertState(t, -1, 0, true, false, false); #if FILUTIL_DEBUG t._SetNow(startTime + 3); AssertState(t, 2, 2f / 6f, true, false, false); t.Delay(2); AssertState(t, 0, 0, true, false, false); // Extend and Delay should work while Paused. t._SetNow(startTime + 6); t.Pause(); AssertState(t, 3, 0.5f, true, true, false); t.Delay(2); AssertState(t, 1, 1f / 6f, true, true, false); t.Extend(2); AssertState(t, 1, 1f / 8f, true, true, false); // We can force finish while paused. t.FinishImmediately(); AssertState(t, 8, 1, true, true, true); #endif }
void RigidMLS() { if (controls.Count < 3) return; if (weights == null || A00 == null || A01 == null || A10 == null || A11 == null || D == null) return; #if USE_PARALLEL_FOR System.Threading.Tasks.Parallel.For(0, meshPointList.Count, vIdx => #else for (int vIdx = 0; vIdx < meshPointList.Count; vIdx++) #endif { FTimer.Resume("1"); int offset = vIdx * controls.Count; // 追加 2014/11/08 int nonzeroCnt = 0; for (int i = 0; i < controls.Count; i++) if (weights[i + offset] != 0) nonzeroCnt++; FTimer.Pause("1"); if (nonzeroCnt <= 1) { #if USE_PARALLEL_FOR return; #else continue; #endif } FTimer.Resume("2"); bool flg = false; for (int i = offset; i < offset + controls.Count; i++) { if (float.IsInfinity(weights[i])) { // infに飛んでたらcontrols[i]自体を返す meshPointList[vIdx] = controls[i - offset]; flg = true; break; } } FTimer.Pause("2"); if (flg) { #if USE_PARALLEL_FOR return; #else continue; #endif } FTimer.Resume("3"); PointF? Qa = AverageWeight(controls, weights, vIdx); FTimer.Pause("3"); if (Qa == null || !Qa.HasValue) { #if USE_PARALLEL_FOR return; #else continue; #endif } FTimer.Resume("4"); meshPointList[vIdx] = Qa.Value; float fx = 0; float fy = 0; for (int i = 0; i < controls.Count; i++) { int idx = i + vIdx * controls.Count; float qx = controls[i].X - Qa.Value.X; float qy = controls[i].Y - Qa.Value.Y; fx += qx * A00[idx] + qy * A10[idx]; fy += qx * A01[idx] + qy * A11[idx]; } FTimer.Pause("4"); FTimer.Resume("5"); float lenD = (float)Math.Sqrt(D[vIdx].X * D[vIdx].X + D[vIdx].Y * D[vIdx].Y); float lenf = (float)Math.Sqrt(fx * fx + fy * fy); float k = lenD / (0.01f + lenf); PointF pt = meshPointList[vIdx]; pt.X += fx * k; pt.Y += fy * k; meshPointList[vIdx] = pt; FTimer.Pause("5"); }