private void MoveSelectionToSphere(ISphere s) { /* Set new position */ transform.position = s.transform.position; s.ResetColor(); /* Clear spheres object */ ClearHighlightedAndResetColor(); spheres_.Clear(); /* Set info displayed */ center_sphere_ = s; info_ui_.SetAtom(s); /* Get the new spheres within radius */ Collider[] hitColliders = Physics.OverlapSphere(this.transform.position, Atoms.SELECTION_MODE_SPHERE_RADIUS); foreach (Collider c in hitColliders) { ISphere sphere = c.gameObject.GetComponent <ISphere>(); if (sphere == null || sphere == s) { continue; } AddSphere(sphere); } }
/* FPS counter */ //void OnGUI() { // GUI.Label(new Rect(0, 0, 100, 100), (1.0f / Time.smoothDeltaTime).ToString()); //} void Update() { /* If the bring forward the panel button is hit, the ray cast only in UI layer */ if (Input.GetKey(KeyCode.Space)) { bool ui_hit = RayCastUIlayer(); if (ui_hit) { return; } } RaycastHit hit; /* * Perform ray casting towards the camera direction, move the ray origin slightly forward to avoid intersections with spheres that * we are currently inside */ bool ray_cast_hit = Physics.Raycast(Camera.main.transform.position + Camera.main.transform.forward * AtomicRadii.ball_and_stick_radius, Camera.main.transform.forward, out hit, 100.0f); /* Process model movement input */ if (Input.GetKey(KeyCode.Keypad1)) { MoveTowardsSelectedObject(speed_object_towards_move); } if (Input.GetKey(KeyCode.Keypad7)) { MoveTowardsSelectedObject(-speed_object_towards_move); } if (Input.GetKey(KeyCode.Keypad4)) { transform.position = transform.position - Camera.main.transform.right * speed_object_vertical_move; } if (Input.GetKey(KeyCode.Keypad6)) { transform.position = transform.position + Camera.main.transform.right * speed_object_vertical_move; } if (Input.GetKey(KeyCode.Keypad8)) { transform.position = transform.position + Camera.main.transform.up * speed_object_vertical_move; } if (Input.GetKey(KeyCode.Keypad5)) { transform.position = transform.position - Camera.main.transform.up * speed_object_vertical_move; } /* Check ray cast against UI */ if (ray_cast_hit) { Debug.DrawRay(Camera.main.transform.position, Camera.main.transform.forward * hit.distance, Color.white); ButtonEvent button = hit.transform.GetComponent <ButtonEvent>(); if (button != null) { ProcessRayCastUIHit(hit); } } /* Process state machine */ if (state == STATE.EXPLORING_ATOMS) { /* If there is a selected atom, and the discard button is pressed, then destory selection */ if (selected_atom_ != null) { if (Input.GetKeyDown(KeyCode.Escape) == true) { ClearHighlighted(); selected_atom_ = null; Destroy(selection_plane_previous_); return; } return; } /* Else process ray cast hit */ if (ray_cast_hit) { ProcessRayCastHit(hit); } else { /* If ray cast failed, clear highlighting */ ClearHighlighted(); if (exploring_method_ != ExploringMethod.CHAINS) { ClearColored(); } //Debug.DrawRay(Camera.main.transform.position, Camera.main.transform.forward * 1000, Color.white); } } else if (state == STATE.ATOM_DISTANCES) { /* If discard button, then reset state */ if (Input.GetKeyDown(KeyCode.Escape)) { ResetState(true); return; } /* if we have selected an atom, process distances */ if (selected_atom_ != null) { SelectionPlaneSpheres plane = selection_plane_previous_.GetComponent <SelectionPlaneSpheres>(); /* * Get the current selected atom, and if it's different than the previous, and the marked button is pressed * mark atom, and calculate distance */ int current_index = atom_selected_id_ % 4; ISphere previously_added = ((current_index == 0) ? atoms_selected_[3] : atoms_selected_[current_index - 1]); if (Input.GetKeyDown(KeyCode.E) && previously_added != plane.center_sphere_) { atoms_selected_[current_index] = plane.center_sphere_; atom_selected_id_++; /* If marked atom object is null, spawn it */ if (marked_atom_object_ == null) { marked_atom_object_ = Instantiate(prefab_marked_atom_, plane.center_sphere_.transform.position, Quaternion.identity); marked_atom_object_.transform.parent = this.transform; } /* Calculate radius of the atom based on the viusalization method, and move marked atom object */ float selected_atom_radius; if (GetVisualizationMethod() == VisualizationMethod.BALL_AND_STICK) { selected_atom_radius = AtomicRadii.ball_and_stick_radius; } else { selected_atom_radius = AtomicRadii.GetCovalentRadius(plane.center_sphere_.atom_.element_); } marked_atom_object_.transform.position = plane.center_sphere_.transform.position + 1.4f * Vector3.up * selected_atom_radius; marked_sphere_ = plane.center_sphere_.gameObject; /* If the previously marked atom is not null, then calculate distance */ if (previously_added != null) { Vector3 middle = (previously_added.transform.position + plane.center_sphere_.transform.position) / 2; /* Destroy the previous atom distance object from the world */ if (atom_distance_previous_ != null) { Destroy(atom_distance_previous_); } /* and spawn the new in the middle of the distance */ atom_distance_previous_ = Instantiate(prefab_atom_distance_, middle, Quaternion.identity); atom_distance_previous_.transform.parent = transform; AtomDistance temp = atom_distance_previous_.GetComponent <AtomDistance>(); temp.atom1_ = previously_added; temp.atom2_ = plane.center_sphere_; } } return; } /* If there is not selected atom, process ray casting as usual */ if (ray_cast_hit) { ProcessRayCastHit(hit); } else { ClearHighlighted(); if (exploring_method_ != ExploringMethod.CHAINS) { ClearColored(); } } } else if (state == STATE.BOND_ANGLES) { /* If discard button is hit, reset state */ if (Input.GetKeyDown(KeyCode.Escape)) { ResetState(true); return; } /* If selection is spawned, process selected bonds */ if (selected_bond_ != null) { SelectionPlaneCylinders plane = selection_plane_previous_.GetComponent <SelectionPlaneCylinders>(); int current_index = bonds_selected_id_ % 2; ICylinder previously_added = ((current_index == 0) ? bonds_selected_[1] : bonds_selected_[current_index - 1]); /* if the precious is different than the currently selected, select bond, and the arc */ if (previously_added != plane.center_cylinder_) { bonds_selected_[current_index] = plane.center_cylinder_; bonds_selected_id_++; if (previously_added != null) { if (arc_previous_ != null) { Destroy(arc_previous_); } SpawnArc(bonds_selected_[0], bonds_selected_[1]); } } return; } /* Else, process ray casting for bonds */ if (ray_cast_hit) { ClearHighlighted(); ICylinder icylinder = hit.transform.GetComponent <ICylinder>(); if (icylinder != null) { icylinder.SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.WHITE); previously_highlighted_bond_ = icylinder; /* If bond seleted, spawn selection object */ if (Input.GetMouseButtonDown(0) == true) { selected_bond_ = icylinder; SpawnSelectionPlaneCylinders(); } } } else { ClearHighlighted(); } } else if (state == STATE.TORSION_ANGLE) { /* if the torsion planed has been spawned, highlight the atoms that participate in it */ if (torsion_plane_spawned_) { atoms_selected_[0].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.GREEN); atoms_selected_[1].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.GREEN); atoms_selected_[2].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.GREEN); atoms_selected_[3].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.GREEN); } /* If discard is pushed, and the torsion planed is spawned, go back to atom selection * else reset and destroy selection */ if (Input.GetKeyDown(KeyCode.Escape)) { if (torsion_plane_spawned_) { ISphere last_added_sphere = ((atom_selected_id_ == 0) ? atoms_selected_[3] : atoms_selected_[atom_selected_id_ - 1]); ResetState(false); selected_atom_ = last_added_sphere; SpawnSelectionPlaneSpheres(); info_ui_.SetAtom(last_added_sphere); } else { ResetState(true); } return; } /* If selection is spawned, then process the currently selected atom */ if (selected_atom_ != null) { SelectionPlaneSpheres plane = selection_plane_previous_.GetComponent <SelectionPlaneSpheres>(); ISphere previously_added = ((atom_selected_id_ == 0) ? atoms_selected_[3] : atoms_selected_[atom_selected_id_ - 1]); if (Input.GetKeyDown(KeyCode.E) && atom_selected_id_ < 4 && previously_added != plane.center_sphere_) { atoms_selected_[atom_selected_id_ % 4] = plane.center_sphere_; info_ui_.SetTorsionAtom(atom_selected_id_, plane.center_sphere_.atom_.name_); atom_selected_id_++; /* If reached 4 selected atoms, spawn the torsion plane object */ if (atom_selected_id_ == 4) { SpawnTorsionAngle(); selected_atom_ = null; Destroy(selection_plane_previous_); torsion_plane_spawned_ = true; } } return; } /* Else ray cast as usual */ if (ray_cast_hit && !torsion_plane_spawned_) { ProcessRayCastHit(hit); } else { ClearHighlighted(); if (exploring_method_ != ExploringMethod.CHAINS) { ClearColored(); } } } /* End of torsion angle state */ }