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;
    }
Beispiel #2
0
        /// <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");
    }