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); }
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; }