Пример #1
0
            public key_animal_data collect_body_parts(float head_height_percentage, float neck_length, int no_legs, float leg_depth_percentage)
            {
                corpus = null;
                corpus = Centre(torso);

                find_region();
                float x_ordinate_of_torso_front = top_corner.x - max_radius;
                float x_ordinate_of_torso_back  = max_radius - bottom_corner.x;
                float leg_depth_factor          = System.Math.Min(x_ordinate_of_torso_back, x_ordinate_of_torso_front);
                // float leg_depth_percentage;

                // code for affixing head
                Vector3 base_of_neck   = new Vector3(corpus.joints[1].X, corpus.joints[1].Y, corpus.joints[1].Z);
                float   radius_of_neck = corpus.joints[1].Radius;
                Vector3 neck           = new Vector3(0, 0, 0);

                neck.z = 0;
                neck.y = ((head_height_percentage / 100) * 2 - 1) * radius_of_neck;
                neck.x = (float)System.Math.Sqrt(radius_of_neck * radius_of_neck - (neck.y) * (neck.y));     //NEW
                neck   = Vector3.Normalize(neck);
                neck   = neck * neck_length;
                neck   = base_of_neck + neck;       //NEW
                Vector3 chin     = new Vector3(skull.joints[1].X + base_of_neck.x + neck.x, skull.joints[1].Y + base_of_neck.y + neck.y, skull.joints[1].Z + base_of_neck.z);
                var     metalist = new List <metaball>();

                for (int i = 0; i < corpus.joints.Length; i++)
                {
                    metalist.Add(corpus.joints[i]);
                }
                key_animal_data results = new key_animal_data();
                Vector3         connected_head_centre = new Vector3(base_of_neck.x + neck.x, base_of_neck.y + neck.y, base_of_neck.z);

                results.head_position = connected_head_centre;
                // results.head_position = new Vector3(-connected_head_centre.z, connected_head_centre.y, connected_head_centre.x);
                results.main_radius = skull.joints[0].Radius;
                results.chin_radius = skull.joints[1].Radius;
                results.main_chin_vertical_distance = (connected_head_centre.y - chin.y);
                metalist.Add(new metaball(base_of_neck.x + neck.x, base_of_neck.y + neck.y, base_of_neck.z, skull.joints[0].Radius));
                metalist.Add(new metaball(chin.x, chin.y, chin.z, skull.joints[1].Radius));

                if (no_legs > 0)
                {
                    //shifting leg so that highest joint is at zero vector
                    corporial new_leg = new corporial();
                    new_leg.joints = new metaball[hind_leg.joints.Length];             // new leg is a copy of hind_leg but shifted so that the highest joint (ie the shoulder if it had 4 joints) is at (0,0,0)
                    Vector3 tmp = new Vector3(0, 0, 0);
                    for (int i = 0; i < hind_leg.joints.Length; i++)
                    {
                        tmp = new Vector3(
                            hind_leg.joints[i].X,
                            hind_leg.joints[i].Y,
                            hind_leg.joints[i].Z
                            ) - new Vector3(
                            hind_leg.joints[hind_leg.joints.Length - 1].X,
                            hind_leg.joints[hind_leg.joints.Length - 1].Y,
                            hind_leg.joints[hind_leg.joints.Length - 1].Z
                            );
                        new_leg.joints[i] = new metaball(
                            tmp.x,
                            tmp.y,
                            tmp.z,
                            hind_leg.joints[i].Radius
                            );
                    }
                    new_leg = anitclockwise_rotate_piontwo(new_leg);
                    if (no_legs < 2)
                    {
                        leg_depth_percentage = 0;
                    }
                    //finding base z ordinate for leg, based on the radius of the nearest metaball
                    float closest_metaball_radius = 0;
                    float distance = Single.MaxValue;
                    float tmp_d;
                    for (int i = 0; i < metalist.Count; i++)
                    {
                        tmp_d = (leg_depth_factor * (leg_depth_percentage / 100) - metalist[i].X);
                        tmp_d = tmp_d * tmp_d;
                        if (tmp_d < distance)
                        {
                            distance = tmp_d;
                            closest_metaball_radius = metalist[i].Radius;
                        }
                    }
                    Vector3 leg_connector_position = new Vector3(
                        new_leg.joints[new_leg.joints.Length - 1].X - leg_depth_factor * (leg_depth_percentage / 100),
                        new_leg.joints[new_leg.joints.Length - 1].Y,
                        new_leg.joints[new_leg.joints.Length - 1].Z - closest_metaball_radius
                        );
                    for (int i = 0; i < new_leg.joints.Length; i++)
                    {
                        new_leg.joints[i].X = new_leg.joints[i].X + leg_connector_position.x;
                        new_leg.joints[i].Y = new_leg.joints[i].Y + leg_connector_position.y;
                        new_leg.joints[i].Z = new_leg.joints[i].Z + leg_connector_position.z;
                        metalist.Add(new_leg.joints[i]);
                    }
                    var mirror_leg = mirror_in_xy(new_leg);
                    for (int i = 0; i < mirror_leg.joints.Length; i++)
                    {
                        metalist.Add(mirror_leg.joints[i]);
                    }
                    if (no_legs == 2)
                    {
                        var front_leg        = mirror_in_zy(new_leg);
                        var front_mirror_leg = mirror_in_zy(mirror_leg);
                        for (int i = 0; i < front_leg.joints.Length; i++)
                        {
                            metalist.Add(front_leg.joints[i]);
                            metalist.Add(front_mirror_leg.joints[i]);
                        }
                    }
                }
                corpus.joints = metalist.ToArray();
                // corpus = anitclockwise_rotate_piontwo(corpus);
                // corpus = mirror_in_xy(corpus);
                return(results);
            }
Пример #2
0
        public void Refresh(float size = 1, bool first_time = true)
        {
            size = security.clamp(0, 1, size);

            if (first_time)
            {
                interpolation = true;
                optimise      = true;
                save          = false;
                eye_details   = new key_animal_data();
                mode          = 3;
                distribute_parameters(size);
                mesh_filter    = GetComponent <MeshFilter>();
                eye_controls   = gameObject.transform.Find("eyes").gameObject.GetComponent <Oculus>();
                mouth_controls = gameObject.transform.Find("mouth").gameObject.GetComponent <Maw>();
                testman        = new animal((int)leg_joint_select, (int)body_joint_select);
                Stopwatch parameter_insert_time = new Stopwatch(); // TIME TESTING
                parameter_insert_time.Start();                     // TIME TESTING

                testman.render_mode = mode;
                float degrees_to_radians_scalefactor = ((float)(System.Math.PI * 2) / (360));
                testman.hind_leg.bones[0].XY      = foot_xy * degrees_to_radians_scalefactor;
                testman.hind_leg.bones[0].XZ      = foot_xz * degrees_to_radians_scalefactor;
                testman.hind_leg.bones[0].Length  = foot_length;
                testman.hind_leg.joints[0].Radius = paw_size;
                testman.hind_leg.joints[1].Radius = wrist_size;
                if (leg_joint_select > 2)
                {
                    // enable shin slider
                    testman.hind_leg.bones[1].XY      = shin_xy * degrees_to_radians_scalefactor;
                    testman.hind_leg.bones[1].XZ      = shin_xz * degrees_to_radians_scalefactor;
                    testman.hind_leg.bones[1].Length  = shin_length;
                    testman.hind_leg.joints[2].Radius = knee_size;
                }
                if (leg_joint_select == 4)
                {
                    testman.hind_leg.bones[2].XY      = thigh_xy * degrees_to_radians_scalefactor;
                    testman.hind_leg.bones[2].XZ      = thigh_xz * degrees_to_radians_scalefactor;
                    testman.hind_leg.bones[2].Length  = thigh_length;
                    testman.hind_leg.joints[3].Radius = shoulder_size;
                    // enable foot, shin and thigh sliders
                }
                testman.torso.bones[0].XY      = back_xy * degrees_to_radians_scalefactor;
                testman.torso.bones[0].Length  = back_length;
                testman.torso.joints[0].Radius = rear_size;
                testman.torso.joints[1].Radius = front_size;
                if (body_joint_select == 3)
                {
                    testman.torso.bones[1].XY      = belly_xy * degrees_to_radians_scalefactor;
                    testman.torso.bones[1].Length  = belly_length;
                    testman.torso.joints[2].Radius = belly_size;
                }
                testman.skull.joints[0].Radius = main_size;
                testman.skull.bones[0].XY      = jaw_xy * degrees_to_radians_scalefactor;
                testman.skull.bones[0].Length  = jaw_length;
                testman.skull.joints[1].Radius = chin_size;
                eye_details = testman.collect_body_parts(height_percent, neck_length, (int)number_of_leg_pairs, leg_depth);

                parameter_insert_time.Stop();                                                        // TIME TESTING
                UnityEngine.Debug.Log("parameter insertion time: " + parameter_insert_time.Elapsed); // TIME TESTING
            }


            // placing eye, finding eye coordinates
            Stopwatch eye_placing_time = new Stopwatch(); // TIME TESTING

            eye_placing_time.Start();                     // TIME TESTING

            // binary search
            var     source    = eye_details;
            float   y         = (eye_height_percent / 100) * (source.main_radius + source.main_chin_vertical_distance - source.chin_radius) + source.head_position.y - source.main_chin_vertical_distance + source.chin_radius;
            float   z         = (eye_width_percent / 100) * Mathf.Sqrt(Mathf.Pow(source.main_radius, 2) - Mathf.Pow(y - source.head_position.y, 2));
            float   x         = source.head_position.x + Mathf.Sqrt(Mathf.Pow(source.main_radius, 2) - Mathf.Pow(z, 2));
            Vector3 position  = new Vector3(x, y, z);
            float   in_or_out = Single.MaxValue;
            Vector3 extreme   = position + new Vector3(eye_details.main_radius * 10, 0, 0);
            Vector3 middle;

            for (int h = 0; h < 100; h++)
            {
                middle    = (extreme - position) / 2 + position;
                in_or_out = 0;
                for (int i = 0; i < testman.corpus.joints.Length; i++)
                {
                    in_or_out = in_or_out + testman.corpus.joints[i].evaluated_distance(middle);
                }
                if (in_or_out < 1)
                {
                    extreme = middle;
                }
                else
                {
                    position = middle;
                }
            }
            eye_controls.Refresh(position, 1.0F - 0.5F * size, (int)eye_type, false, first_time);


            eye_placing_time.Stop();                                                // TIME TESTING
            UnityEngine.Debug.Log("eye placing time: " + eye_placing_time.Elapsed); // TIME TESTING



            //placing mouth

            Stopwatch mouth_placing_time = new Stopwatch(); // TIME TESTING

            mouth_placing_time.Start();                     // TIME TESTING

            // binary search
            Stopwatch mouth_search_time = new Stopwatch(); // TIME TESTING

            mouth_search_time.Start();                     // TIME TESTING
            y         = source.head_position.y - source.main_chin_vertical_distance;
            y         = ((position.y - y) * mouth_height_percent / 100) + y;
            z         = 0;
            x         = source.head_position.x;
            position  = new Vector3(x, y, z);
            in_or_out = Single.MaxValue;
            extreme   = position + new Vector3(eye_details.main_radius * 10, 0, 0);
            for (int h = 0; h < 100; h++)
            {
                middle    = (extreme - position) / 2 + position;
                in_or_out = 0;
                for (int i = 0; i < testman.corpus.joints.Length; i++)
                {
                    in_or_out = in_or_out + testman.corpus.joints[i].evaluated_distance(middle);
                }
                if (in_or_out < 1)
                {
                    extreme = middle;
                }
                else
                {
                    position = middle;
                }
            }
            mouth_search_time.Stop();                                                 // TIME TESTING
            UnityEngine.Debug.Log("mouth search time: " + mouth_search_time.Elapsed); // TIME TESTING


            Stopwatch mouth_refresh_time = new Stopwatch();                             // TIME TESTING

            mouth_refresh_time.Start();                                                 // TIME TESTING
            mouth_controls.Refresh(position, 1.0F - 0.5F * size, (int)mouth_type, first_time);
            mouth_refresh_time.Stop();                                                  // TIME TESTING
            UnityEngine.Debug.Log("mouth refresh time: " + mouth_refresh_time.Elapsed); // TIME TESTING

            mouth_placing_time.Stop();                                                  // TIME TESTING
            UnityEngine.Debug.Log("mouth placing time: " + mouth_placing_time.Elapsed); // TIME TESTING


            if (first_time)
            {
                Stopwatch region_finding_time = new Stopwatch();                                  // TIME TESTING
                region_finding_time.Start();                                                      // TIME TESTING
                testman.find_region();
                region_finding_time.Stop();                                                       // TIME TESTING
                UnityEngine.Debug.Log("region finding time: " + region_finding_time.Elapsed);     // TIME TESTING

                Stopwatch region_partision_time = new Stopwatch();                                // TIME TESTING
                region_partision_time.Start();                                                    // TIME TESTING
                testman.partision_region(number_of_marching_cubes);
                region_partision_time.Stop();                                                     // TIME TESTING
                UnityEngine.Debug.Log("region partision time: " + region_partision_time.Elapsed); // TIME TESTING

                testman.interpolation = interpolation;
                testman.optimisation  = optimise;
                Stopwatch mesh_making_time = new Stopwatch();                           // TIME TESTING
                mesh_making_time.Start();                                               // TIME TESTING
                testman.make_mesh();
                mesh_making_time.Stop();                                                // TIME TESTING
                UnityEngine.Debug.Log("mesh making time: " + mesh_making_time.Elapsed); // TIME TESTING

                mesh_filter.mesh = testman.animal_mesh;
                float volume       = mesh_filter.mesh.bounds.size.x * mesh_filter.mesh.bounds.size.y * mesh_filter.mesh.bounds.size.z;
                float dim          = (float)System.Math.Pow(volume, (1.0f / 3.0f));
                float scale_factor = 1.0F / dim;
                transform.localScale = new Vector3(scale_factor, scale_factor, scale_factor);
            }

            if (save)
            {
                // Debug.Log("Saving animal to file...");
                testman.save_mesh();
            }
            save = false;
        }