void Update() { baseTransformMatrix = new DualMatrix4x3(baseTransform.position, baseTransform.rotation, baseTransform.localScale); //Set up the variables to optimize optimizer.Add(transform.position, "position"); optimizer.Add(transform.up, "yBasis"); optimizer.Add(transform.forward, "zBasis"); optimizer.Add(transform.localScale, "scale"); optimizer.CalculateErrorDerivative = CalculateErrorDerivative; //Calculate and Apply the Instantaneous Gradients at this point in time transform.position -= optimizer.CalcErrorGradient("position") * alpha; Vector3 forwardBasis = transform.forward - (optimizer.CalcErrorGradient("zBasis") * alpha); Vector3 upBasis = transform.up - (optimizer.CalcErrorGradient("yBasis") * alpha); transform.rotation = Quaternion.LookRotation(forwardBasis, upBasis); transform.localScale -= optimizer.CalcErrorGradient("scale") * alpha; }
/// <summary>This sample program has 3 options, and will use the the optimizer /// to run a test scenario. Two options are picked, and we will simulate user interest in one, /// then user sentiment changing to favor the second option.</summary> private static void TestOptimizer() { var optimizer = new Optimizer(); // define the available options Option[] options = new Option[] { Option.Named("Orange"), Option.Named("Green"), Option.Named("White") }; optimizer.Add(options[0]); optimizer.Add(options[1]); optimizer.Add(options[2]); // pick two options, and define when user interest will change var firstWinner = options[2]; // white var secondWinner = options[1]; // green var switchRatio = .35f; // 35% of the way through the test set int tries = 100; // the test set for (int i = 0; i < tries; i++) { Option selected = optimizer.Choose().Result; // don't care about asyncrony in this particular example Console.WriteLine("Choosing: {0}", selected); // decide which chosen option 'the users' will prefer bool isFirstBatch = (float)tries * switchRatio > i; if (isFirstBatch && selected == firstWinner) { firstWinner.IncrementSuccesses(); } else if (!isFirstBatch && selected == secondWinner) { secondWinner.IncrementSuccesses(); } } Console.WriteLine("\nResults! We expect that ({0}) will have the highest success rate, and ({1}) will be in second place", secondWinner, firstWinner); Console.WriteLine("\nThis is the final result after {0} tries\n{1}", tries, optimizer); }
void Start() { //Initialize mesh and state variables MeshFilter filter = GetComponent <MeshFilter>(); bodyMesh = Instantiate(filter.mesh); bodyMesh.MarkDynamic(); bodyVerts = new NativeArray <Vector3>(bodyMesh.vertices, Allocator.Persistent); kabschVerts = new NativeArray <Vector4>(Array.ConvertAll(bodyVerts.ToArray(), (p => new Vector4(p.x, p.y, p.z, 1f))), Allocator.Persistent); originalVerts = bodyMesh.vertices; int[] triangles = bodyMesh.triangles; Vector3Int[] tris = new Vector3Int[triangles.Length / 3]; for (int i = 0; i < tris.Length; i++) { tris[i] = new Vector3Int(triangles[i * 3], triangles[(i * 3) + 1], triangles[(i * 3) + 2]); } bodyTriangles = new NativeArray <Vector3Int>(tris, Allocator.Persistent); bodyNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); renderNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); prevBodyVerts = new NativeArray <Vector3>(new Vector3[bodyVerts.Length], Allocator.Persistent); accumulatedDisplacements = new NativeArray <Vector4>(new Vector4[bodyVerts.Length], Allocator.Persistent); for (int i = 0; i < bodyVerts.Length; i++) { prevBodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } filter.mesh = bodyMesh; renderNormalsArray = new Vector3[renderNormals.Length]; bodyVertsArray = new Vector3[bodyVerts.Length]; kabschVertsArray = new Vector4[kabschVerts.Length]; //Create Distance Constraints from Triangles in Mesh constraintsList = new List <Verlet.DistConstraint>(bodyVerts.Length * 3); Verlet.setUpConstraints(bodyMesh, constraintsList, false); constraintsArray = new NativeArray <Verlet.DistConstraint>(constraintsList.ToArray(), Allocator.Persistent); //Scale gravity by the size of this Mesh Renderer scaledGravity = new Vector3(Physics.gravity.x / transform.lossyScale.x, Physics.gravity.y / transform.lossyScale.y, Physics.gravity.z / transform.lossyScale.z); initialVolume = Verlet.VolumeOfMesh(bodyVerts, bodyTriangles); optimizer.CalculateErrorDerivative = CalculateErrorDerivative; optimizer.Add(1f, "xScale"); optimizer.Add(Vector3.up, "yBasis"); optimizer.Add(Vector3.forward, "zBasis"); }