/* Change selection radius */ public void ChangeRadius() { transform.localScale = 2 * new Vector3(Atoms.SELECTION_MODE_SPHERE_RADIUS, Atoms.SELECTION_MODE_SPHERE_RADIUS, Atoms.SELECTION_MODE_SPHERE_RADIUS); /* Set radius of the transparent sphere */ ISphere s = GetComponent <ISphere>(); s.SetRadius(Atoms.SELECTION_MODE_SPHERE_RADIUS); /* Reset cylinders within the previous radius */ for (int i = 0; i < cylinders_.Count; i++) { ICylinder cylinder = cylinders_[i]; cylinder.SetHighlighted(0); cylinder.ResetColor(); } cylinders_.Clear(); /* Get the new cylinders within radius */ Collider[] hitColliders = Physics.OverlapSphere(this.transform.position, Atoms.SELECTION_MODE_SPHERE_RADIUS); foreach (Collider c in hitColliders) { ICylinder cylinder = c.gameObject.GetComponent <ICylinder>(); if (cylinder == null || cylinder == center_cylinder_) { continue; } AddCylinder(cylinder); } }
/* Spawn a selection sphere for 2D navigation for the currently selected atom */ private void SpawnSelectionPlaneSpheres() { if (selection_plane_previous_ != null) { Destroy(selection_plane_previous_); } selection_plane_previous_ = Instantiate(prefab_selection_plane_spheres_, selected_atom_.transform.position, Quaternion.identity); selection_plane_previous_.transform.parent = transform; SelectionPlaneSpheres plane = selection_plane_previous_.GetComponent <SelectionPlaneSpheres>(); plane.visualization = selection_visualization_; plane.center_sphere_ = selected_atom_; /* Get and set the spheres within the selection radius */ ClearHighlighted(); Collider[] hitColliders = Physics.OverlapSphere(selected_atom_.transform.position, SELECTION_MODE_SPHERE_RADIUS); foreach (Collider c in hitColliders) { ISphere s = c.gameObject.GetComponent <ISphere>(); if (s == null || s == selected_atom_) { continue; } plane.AddSphere(s); } }
/* The following change function are called by string reference, from the world UI buttons */ public void ChangeVisualizationMethod() { if (visualization_method_ == VisualizationMethod.BALL_AND_STICK) { SetVisualizationMethod(VisualizationMethod.SPACE_FILLING); /* * If we are to change visualization method to space filling, change the marked atom object * since its position depends on the radius, and if we are bond angles mode, destroy reset state * since there are no bonds anymore */ if (marked_atom_object_ != null) { ISphere sphere = marked_sphere_.GetComponent <ISphere>(); marked_atom_object_.transform.position = sphere.transform.position + 1.4f * Vector3.up * AtomicRadii.GetCovalentRadius(sphere.atom_.element_); } if (state == STATE.BOND_ANGLES) { ResetState(true); } } else { SetVisualizationMethod(VisualizationMethod.BALL_AND_STICK); if (marked_atom_object_ != null) { ISphere sphere = marked_sphere_.GetComponent <ISphere>(); marked_atom_object_.transform.position = sphere.transform.position + 1.4f * Vector3.up * AtomicRadii.ball_and_stick_radius; } } }
/* Calculate a unique identifier for a residues, since different chains use the same ids */ private int CalculateUniqueResidueIdentifier(ISphere sphere) { int resiude = sphere.atom_.res_seq_; char chain_id = sphere.atom_.chain_id_; return(chain_id * 10000 + resiude); }
public void ChangeModeToBondAngles() { /* * If the previous state is not bond angles, and an atom was selected, then find the closest bond * and move the selection there */ if (state != STATE.BOND_ANGLES) { ISphere currently_selected_sphere = null; if (selection_plane_previous_ != null) { currently_selected_sphere = selection_plane_previous_.GetComponent <SelectionPlaneSpheres>().center_sphere_; } ResetState(true); if (currently_selected_sphere != null) { ICylinder nearest_bond = GetNearestBond(currently_selected_sphere.transform.position, 2 * AtomicRadii.GetCovalentRadius(currently_selected_sphere.atom_.element_)); if (nearest_bond != null) { selected_bond_ = nearest_bond; SpawnSelectionPlaneCylinders(); } } } else { ResetState(false); } state = STATE.BOND_ANGLES; transform.GetChild(1).GetComponent <ModePanel>().SetState(state); info_ui_.ResetInfo(); }
public void ChangeModeToTorsionAngles() { /* * If the previous state is bond angles, and a bond was selected, then find the closest atom * and move the selection there */ if (state == STATE.BOND_ANGLES) { ICylinder currently_selected_cylinder = null; if (selection_plane_previous_ != null) { currently_selected_cylinder = selection_plane_previous_.GetComponent <SelectionPlaneCylinders>().center_cylinder_; } ResetState(true); if (currently_selected_cylinder != null) { ISphere nearest_atom = GetNearestAtom(currently_selected_cylinder.transform.position, 2 * AtomicRadii.ball_and_stick_radius); if (nearest_atom != null) { selected_atom_ = nearest_atom; SpawnSelectionPlaneSpheres(); } } } else { ResetState(false); } state = STATE.TORSION_ANGLE; transform.GetChild(1).GetComponent <ModePanel>().SetState(state); }
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); } }
/* Get nearest atom given a position and a radius */ private ISphere GetNearestAtom(Vector3 position, float radius) { Collider[] hitColliders = Physics.OverlapSphere(position, radius); ISphere current_nearest = null; float nearest_distance = radius; foreach (Collider c in hitColliders) { ISphere s = c.gameObject.GetComponent <ISphere>(); if (s == null) { continue; } float distance = Vector3.Distance(position, s.transform.position); if (distance < nearest_distance) { nearest_distance = distance; current_nearest = s; } } return(current_nearest); }
/* Color a chain */ private void ColorChain(ISphere isphere) { foreach (ISphere s in chains_dictionary[isphere.atom_.chain_id_]) { s.FixColor(new Color(0, 0.8f, 0)); colored_spheres_.Add(s); } }
public void SetAtom(ISphere s) { SetElement(s.atom_.element_); SetResiude(s.atom_.res_name_); SetAtomName(s.atom_.name_); SetChain(s.atom_.chain_id_.ToString()); SetOccupancy(s.atom_.occupancy_.ToString("F2")); SetTempFactor(s.atom_.temp_factor_.ToString("F1")); }
//public void OnDrawGizmos() { // if (state == STATE.SELECTED_ATOM) { // Gizmos.DrawWireSphere(selected_atom_.transform.position, AtomicRadii.ball_and_stick_bond_radius * 10); // } //} /* Set a random color to a sphere, currently not used */ private void SetRandomColor(ISphere isphere) { Color rcolor = new Color(UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f)); foreach (ISphere s in atoms_dictionary[isphere.atom_.element_]) { s.SetColor(rcolor); } }
private void InsertToChainsDictionary(ISphere sphere) { char chain = sphere.atom_.chain_id_; if (!chains_dictionary.ContainsKey(chain)) { chains_dictionary.Add(chain, new List <ISphere>()); } chains_dictionary[chain].Add(sphere); }
private void InsertToAtomsDictionary(ISphere sphere) { string atom_name = sphere.atom_.element_; if (!atoms_dictionary.ContainsKey(atom_name)) { atoms_dictionary.Add(atom_name, new List <ISphere>()); } atoms_dictionary[atom_name].Add(sphere); }
private void InsertToResiudesDictionary(ISphere sphere) { int residue_key = CalculateUniqueResidueIdentifier(sphere); if (!residue_dictionary.ContainsKey(residue_key)) { residue_dictionary.Add(residue_key, new List <ISphere>()); } residue_dictionary[residue_key].Add(sphere); }
/// <summary> /// Compares two spheres for equality. /// </summary> /// <param name="ISphere">A sphere to compare with.</param> /// <returns>True if both match; False otherwise.</returns> public Boolean Equals(ISphere <T> ISphere) { if ((Object)ISphere == null) { return(false); } return(this.Left.Equals(ISphere.Left) && this.Top.Equals(ISphere.Top) && this.Radius.Equals(ISphere.Radius)); }
/* Highlight a residue */ private void HighLightResidue(ISphere isphere) { ClearHighlighted(); int residue_key = CalculateUniqueResidueIdentifier(isphere); foreach (ISphere s in residue_dictionary[residue_key]) { s.SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.WHITE); highlighted_spheres_.Add(s); } }
/// <summary> /// Checks if the given sphere shares some /// area with this sphere. /// </summary> /// <param name="Sphere">A sphere of type T.</param> /// <returns>True if the sphere shares some area with this sphere; False otherwise.</returns> public Boolean Overlaps(ISphere <T> Sphere) { #region Initial Checks if (Sphere == null) { throw new ArgumentNullException("The given sphere must not be null!"); } #endregion if (Center.DistanceTo(Sphere.Center).IsLessThanOrEquals(Math.Add(Radius, Sphere.Radius))) { return(true); } return(true); }
/* Process ray cast hit against atoms */ private void ProcessRayCastHit(RaycastHit hit) { /* Hit a sphere? */ ISphere isphere = hit.transform.GetComponent <ISphere>(); if (isphere != null) { /* Check if selection of an atom is triggered */ if (Input.GetMouseButtonDown(0) == true) { selected_atom_ = isphere; SpawnSelectionPlaneSpheres(); return; } /* If not, set highlighting based on the visulization method */ info_ui_.SetAtom(isphere); if (exploring_method_ == ExploringMethod.RESIDUES && !highlighted_spheres_.Contains(isphere)) { ClearHighlighted(); HighLightResidue(isphere); } else if (exploring_method_ == ExploringMethod.CHAINS) { /* Highlight residue */ if (!highlighted_spheres_.Contains(isphere)) { ClearHighlighted(); HighLightResidue(isphere); } /* Color chain */ if (!colored_spheres_.Contains(isphere)) { ClearColored(); ColorChain(isphere); } } } }
void Start() { /* Set the scale based on the selection radius used */ transform.localScale = 2 * new Vector3(Atoms.SELECTION_MODE_SPHERE_RADIUS, Atoms.SELECTION_MODE_SPHERE_RADIUS, Atoms.SELECTION_MODE_SPHERE_RADIUS); /* Make the selection sphere transparent */ ISphere s = GetComponent <ISphere>(); s.SetTransparent(true); s.SetRadius(Atoms.SELECTION_MODE_SPHERE_RADIUS); s.SetColor(new Color(0.1f, 0.1f, 0.1f, 0)); /* Set color circle parameters */ colors_ = new Color[3, 3]; colors_[0, 0] = color_bottom_left; colors_[0, 1] = color_bottom; colors_[0, 2] = color_bottom_right; colors_[1, 0] = color_left; colors_[1, 2] = color_right; colors_[2, 0] = color_top_left; colors_[2, 1] = color_top; colors_[2, 2] = color_top_right; /* Set arrow parameters */ arrows_ = new GameObject[3, 3]; arrows_[0, 0] = Instantiate(prefab_arrow_bottom_left, new Vector3(0, 0, 0), Quaternion.identity); arrows_[0, 1] = Instantiate(prefab_arrow_bottom, new Vector3(0, 0, 0), Quaternion.identity); arrows_[0, 2] = Instantiate(prefab_arrow_bottom_right, new Vector3(0, 0, 0), Quaternion.identity); arrows_[1, 0] = Instantiate(prefab_arrow_left, new Vector3(0, 0, 0), Quaternion.identity); arrows_[1, 2] = Instantiate(prefab_arrow_right, new Vector3(0, 0, 0), Quaternion.identity); arrows_[2, 0] = Instantiate(prefab_arrow_top_left, new Vector3(0, 0, 0), Quaternion.identity); arrows_[2, 1] = Instantiate(prefab_arrow_top, new Vector3(0, 0, 0), Quaternion.identity); arrows_[2, 2] = Instantiate(prefab_arrow_top_right, new Vector3(0, 0, 0), Quaternion.identity); //arrows_[0, 0].transform.parent = transform; //arrows_[0, 1].transform.parent = transform; //arrows_[0, 2].transform.parent = transform; //arrows_[1, 0].transform.parent = transform; //arrows_[1, 2].transform.parent = transform; //arrows_[2, 0].transform.parent = transform; //arrows_[2, 1].transform.parent = transform; //arrows_[2, 2].transform.parent = transform; arrows_[0, 0].SetActive(false); arrows_[0, 1].SetActive(false); arrows_[0, 2].SetActive(false); arrows_[1, 0].SetActive(false); arrows_[1, 2].SetActive(false); arrows_[2, 0].SetActive(false); arrows_[2, 1].SetActive(false); arrows_[2, 2].SetActive(false); if (visualization == SelectionVisualizationMethod.ARROWS) { transform.GetChild(0).gameObject.SetActive(false); } else { transform.GetChild(0).gameObject.SetActive(true); } /* Get info box object */ info_ui_ = Camera.main.transform.Find("AtomInfoBox").GetComponent <AtomInfoBox>(); /* Get parent atoms object */ atoms_object_ = transform.parent.GetComponent <Atoms>(); }
public void Apply(ISphere sphere) { var builder = new BuildSphereGeometry <T>(); builder.Build(_geometry, _tessellationHints, _colors, sphere); }
/* Reset the current state * @param destroy_selection If true, destroy the 2D selection object */ private void ResetState(bool destroy_selection) { switch (state) { case STATE.EXPLORING_ATOMS: if (selection_plane_previous_ != null) { if (destroy_selection) { Destroy(selection_plane_previous_); selected_atom_ = null; info_ui_.ResetInfo(); } } break; case STATE.ATOM_DISTANCES: if (selection_plane_previous_ != null) { if (destroy_selection) { Destroy(selection_plane_previous_); selected_atom_ = null; info_ui_.ResetInfo(); } } if (atom_distance_previous_ != null) { Destroy(atom_distance_previous_); } if (marked_atom_object_ != null) { Destroy(marked_atom_object_); } marked_sphere_ = null; atoms_selected_[0] = null; atoms_selected_[1] = null; atoms_selected_[2] = null; atoms_selected_[3] = null; atom_selected_id_ = 0; break; case STATE.BOND_ANGLES: if (selection_plane_previous_ != null) { if (destroy_selection) { Destroy(selection_plane_previous_); selected_bond_ = null; } } if (arc_previous_ != null) { Destroy(arc_previous_); } if (bonds_selected_[0] != null) { bonds_selected_[0].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.NO_HIGHLIGHT); } if (bonds_selected_[1] != null) { bonds_selected_[1].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.NO_HIGHLIGHT); } bonds_selected_[0] = null; bonds_selected_[1] = null; bonds_selected_id_ = 0; break; case STATE.TORSION_ANGLE: if (selection_plane_previous_ != null) { if (destroy_selection) { Destroy(selection_plane_previous_); selected_atom_ = null; info_ui_.ResetInfo(); } } if (torsion_angle_previous_ != null) { Destroy(torsion_angle_previous_); } if (atoms_selected_[0] != null) { atoms_selected_[0].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.NO_HIGHLIGHT); } if (atoms_selected_[1] != null) { atoms_selected_[1].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.NO_HIGHLIGHT); } if (atoms_selected_[2] != null) { atoms_selected_[2].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.NO_HIGHLIGHT); } if (atoms_selected_[3] != null) { atoms_selected_[3].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.NO_HIGHLIGHT); } atoms_selected_[0] = null; atoms_selected_[1] = null; atoms_selected_[2] = null; atoms_selected_[3] = null; atom_selected_id_ = 0; torsion_plane_spawned_ = false; info_ui_.ClearTorsionAtoms(); break; default: break; } ClearColored(); ClearHighlighted(); }
public static bool IsInside(this ISphere self, ISphere sphere, float margin = 0) { var distance = Vector3.Distance(self.Position, sphere.Position); return(distance + self.Radius < sphere.Radius + margin); }
public static BoundingBox FromSphere(ISphere sphere) { return new BoundingBox(2 * sphere.Radius); }
public static bool RaySphereTest(Ray r, ISphere s) { float det, b; Vector3 p = r.Position - s.AbsolutePosition; Vector3 d = Vector3.Normalize(r.Direction); b = -Vector3.Dot(p, d); det = b * b - Vector3.Dot(p,p) + s.Radius * s.Radius; if (det < 0) { return false; } det = (float)Math.Sqrt(det); float i1 = b - det; float i2 = b + det; // intersecting with ray? if (i2 < 0) return false; if (i1 < 0) i1 = 0; return true; }
public static Vector3 SphereAvoidance(Vehicle3D me, ISphere[] spheres, float cylinderLength, float cylinderRadius) { var closestIntersectionX = float.MaxValue; ISphere closestSphere = null; foreach (var sp in spheres) { var sqrEffectiveRadius = cylinderLength * cylinderLength + sp.radius * sp.radius; var me2sp = sp.position - me.position; if (sqrEffectiveRadius < me2sp.sqrMagnitude) continue; var localSphereCenterX = Vector3.Dot(me.forward, me2sp); if (localSphereCenterX <= 0) continue; var sqrLocalSphereCenterY = Vector3.Cross(me.forward, me2sp).sqrMagnitude; var outerRadius = sp.radius + cylinderRadius; if ((outerRadius * outerRadius) < sqrLocalSphereCenterY) continue; var d = Mathf.Sqrt(sp.radius * sp.radius - sqrLocalSphereCenterY); var intersectionX = localSphereCenterX - d; if (intersectionX < 0) intersectionX = localSphereCenterX + d; if (intersectionX < closestIntersectionX) { closestIntersectionX = intersectionX; closestSphere = sp; } } if (closestIntersectionX == float.MaxValue) return Vector3.zero; var toSp = closestSphere.position - me.position; var distMult = 1.0f + (cylinderLength - closestIntersectionX) / cylinderLength; var sideForce = Vector3.Dot(me.forward, toSp) * me.forward - toSp; var sideForceMag = sideForce.magnitude; sideForce *= (closestSphere.radius + cylinderRadius - sideForceMag) / sideForceMag * distMult; var breakForce = -0.2f * (cylinderLength - closestIntersectionX) * toSp.normalized; return sideForce + breakForce; }
void Update() { /* Calculate the coordiinate system transformation matrix */ CalculateInverseTransform(); /* highlight and color center sphere */ center_sphere_.SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.GREEN); center_sphere_.SetCPKColor(); /* Calculate positions and reset colors and highlighting for spheres within the radius */ plane_positions_ = new List <Vector3>(spheres_.Count); for (int i = 0; i < spheres_.Count; i++) { ISphere s = spheres_[i]; Vector4 sphere_world_position = new Vector4(s.transform.position.x, s.transform.position.y, s.transform.position.z, 1); Vector4 sphere_plane_position = ITM_ * sphere_world_position; plane_positions_.Add(sphere_plane_position); s.SetHighlighted(0); s.SetCPKColor(); } /* Calculate spheres available for selection and their directions */ FillArray(); /* Highlight the spheres that can be navigated to, set the arrow directions based on the visualization used, or set the colors */ for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { int s = array_[i, j]; /* If no sphere mapped in this direction, skip */ if (s == -1) { continue; } spheres_[s].SetHighlighted(HighlightColors.HIGHLIGHT_COLOR.WHITE); if (visualization == SelectionVisualizationMethod.COLOR_CIRCLE) { spheres_[s].SetColor(colors_[j, i]); } else { /* If arrows navigation used, calculate atomic radius used based on the atoms viusalization method */ float atom_radius; if (atoms_object_.GetVisualizationMethod() == Atoms.VisualizationMethod.BALL_AND_STICK) { atom_radius = AtomicRadii.ball_and_stick_radius; } else { atom_radius = AtomicRadii.GetCovalentRadius(spheres_[s].atom_.element_); } /* and set the arrow objects in front of the atom */ arrows_[j, i].SetActive(true); arrows_[j, i].transform.position = spheres_[s].transform.position + Vector3.Normalize(Camera.main.transform.position - spheres_[s].transform.position) * 1.2f * atom_radius; /* make arrows face the camera */ arrows_[j, i].transform.rotation = Quaternion.LookRotation(arrows_[j, i].transform.position - Camera.main.transform.position, Camera.main.transform.up); } } } /* Get the index for the selected sphere based on the control input */ int sphere_index = GetDirectionInput(); if (sphere_index != -1) { ISphere s = spheres_[sphere_index]; /* If clicked as well, move the selection */ if (Input.GetMouseButtonDown(0)) { MoveSelectionToSphere(s); } else { /* Make input selected sphere white */ s.SetColor(Color.white); } } }
public void AddSphere(ISphere s) { spheres_.Add(s); }
public void SetPosition(ISphere s, Vector3 Right) { transform.position = s.transform.position + Right * (Atoms.SELECTION_MODE_SPHERE_RADIUS + 0.06f + GetHalfSizeX()); }
/* 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 */ }
internal void Build(IGeometry <T> geometry, ITessellationHints hints, Vector3[] colors, ISphere sphere) { if (hints.NormalsType == NormalsType.PerFace) { throw new ArgumentException("Per-Face Normals are not supported for spheres"); } if (hints.ColorsType == ColorsType.ColorPerFace) { throw new ArgumentException("Per-Face Colors are not supported for spheres"); } if (hints.ColorsType == ColorsType.ColorPerVertex) { throw new ArgumentException("Per-Vertex Colors are not supported for spheres"); } if (colors.Length < 1) { throw new ArgumentException("Must provide at least one color for spheres"); } uint numSegments = 40; uint numRows = 20; var ratio = hints.DetailRatio; if (ratio > 0.0f && ratio != 1.0f) { numRows = (uint)(numRows * ratio); if (numRows < MIN_NUM_ROWS) { numRows = MIN_NUM_ROWS; } numSegments = (uint)(numSegments * ratio); if (numSegments < MIN_NUM_SEGMENTS) { numSegments = MIN_NUM_SEGMENTS; } } var lDelta = (float)System.Math.PI / (float)numRows; var vDelta = 1.0f / (float)numRows; var angleDelta = (float)System.Math.PI * 2.0f / numSegments; var texCoordHorzDelta = 1.0f / numSegments; if (hints.CreateBackFace) { var lBase = -(float)System.Math.PI * 0.5f; var rBase = 0.0f; var zBase = -sphere.Radius; var vBase = 0.0f; var nzBase = -1.0f; var nRatioBase = 0.0f; for (uint rowi = 0; rowi < numRows; ++rowi) { var lTop = (float)(lBase + lDelta); var rTop = (float)System.Math.Cos(lTop) * sphere.Radius; var zTop = (float)System.Math.Sin(lTop) * sphere.Radius; var vTop = vBase + vDelta; var nzTop = (float)System.Math.Sin(lTop); var nRatioTop = (float)System.Math.Cos(lTop); Begin(); var angle = 0.0f; var texCoord = 0.0f; for (uint topi = 0; topi < numSegments; ++topi, angle += angleDelta, texCoord += texCoordHorzDelta) { var c = (float)System.Math.Cos(angle); var s = (float)System.Math.Sin(angle); Normal3f(-c * nRatioBase, -s * nRatioBase, -nzBase); TexCoord2f(texCoord, vBase); Vertex3f(c * rBase, s * rBase, zBase); Normal3f(-c * nRatioTop, -s * nRatioTop, -nzTop); TexCoord2f(texCoord, vTop); Vertex3f(c * rTop, s * rTop, zTop); } // do last point by hand to ensure no round off errors. Normal3f(-nRatioBase, 0.0f, -nzBase); TexCoord2f(1.0f, vBase); Vertex3f(rBase, 0.0f, zBase); Normal3f(-nRatioTop, 0.0f, -nzTop); TexCoord2f(1.0f, vTop); Vertex3f(rTop, 0.0f, zTop); End(); lBase = lTop; rBase = rTop; zBase = zTop; vBase = vTop; nzBase = nzTop; nRatioBase = nRatioTop; } } if (hints.CreateFrontFace) { var lBase = -(float)System.Math.PI * 0.5f; var rBase = 0.0f; var zBase = -sphere.Radius; var vBase = 0.0f; var nzBase = -1.0f; var nRatioBase = 0.0f; for (uint rowi = 0; rowi < numRows; ++rowi) { var lTop = lBase + lDelta; var rTop = (float)System.Math.Cos(lTop) * sphere.Radius; var zTop = (float)System.Math.Sin(lTop) * sphere.Radius; var vTop = vBase + vDelta; var nzTop = (float)System.Math.Sin(lTop); var nRatioTop = (float)System.Math.Cos(lTop); Begin(); var angle = 0.0f; var texCoord = 0.0f; for (uint topi = 0; topi < numSegments; ++topi, angle += angleDelta, texCoord += texCoordHorzDelta) { float c = (float)System.Math.Cos(angle); float s = (float)System.Math.Sin(angle); Normal3f(c * nRatioTop, s * nRatioTop, nzTop); TexCoord2f(texCoord, vTop); Vertex3f(c * rTop, s * rTop, zTop); Normal3f(c * nRatioBase, s * nRatioBase, nzBase); TexCoord2f(texCoord, vBase); Vertex3f(c * rBase, s * rBase, zBase); } // do last point by hand to ensure no round off errors. Normal3f(nRatioTop, 0.0f, nzTop); TexCoord2f(1.0f, vTop); Vertex3f(rTop, 0.0f, zTop); Normal3f(nRatioBase, 0.0f, nzBase); TexCoord2f(1.0f, vBase); Vertex3f(rBase, 0.0f, zBase); End(); lBase = lTop; rBase = rTop; zBase = zTop; vBase = vTop; nzBase = nzTop; nRatioBase = nRatioTop; } } BuildVertexAndIndexArrays(out var vertexArray, out var indexArray, colors); geometry.VertexData = vertexArray; geometry.IndexData = indexArray; geometry.VertexLayout = VertexLayoutHelpers.GetLayoutDescription(typeof(T)); var pSet = DrawElements <T> .Create( geometry, PrimitiveTopology.TriangleList, (uint)geometry.IndexData.Length, 1, 0, 0, 0); geometry.PrimitiveSets.Add(pSet); }
void Start() { List <Atom> atoms; List <List <int> > connections; string model_name; try { model_name = ParseInputModelFile(); PDBParser.ParseAtomsAndConnections(@"Assets/MModels/" + model_name, out atoms, out connections); } catch (System.IO.IOException) { print("Parsing input error"); return; } /* Spawn the objects */ foreach (Atom atom in atoms) { /* Units in Nano meters */ Vector3 atom_position = new Vector3(atom.x_, atom.y_, atom.z_); atoms_bounding_box_.AddPoint(atom_position); /* Instantiate the atom */ GameObject temp = Instantiate(prefab_atom, atom_position, Quaternion.identity); temp.transform.parent = transform; temp.isStatic = this.gameObject.isStatic; /* Find ISphere component, and set the atom information */ ISphere isphere = temp.GetComponent <ISphere>(); isphere.atom_ = atom; ispheres_.Add(isphere); /* Insert to the dictionaries used */ InsertToAtomsDictionary(isphere); InsertToResiudesDictionary(isphere); InsertToChainsDictionary(isphere); } /* Parse connections, currently the application does not do something with these connections */ foreach (List <int> c in connections) { int atom_id = c[0]; for (int i = 1; i < c.Count; i++) { ISphere connection_isphere = ispheres_[c[i]]; ispheres_[atom_id].connections_.Add(connection_isphere); } } /* Spawn bonds */ Transform bonds_transform = transform.GetChild(0); int bonds = 0; /* For all resisudes */ foreach (KeyValuePair <int, List <ISphere> > value in residue_dictionary) { /* Get combinations of two atoms */ List <ISphere> resiude_atoms = value.Value; for (int ia = 0; ia < resiude_atoms.Count; ia++) { ISphere a = resiude_atoms[ia]; Vector3 a_position = a.transform.position; float a_covalent_radius = AtomicRadii.GetCovalentRadius(a.atom_.element_); for (int ib = 0; ib < resiude_atoms.Count; ib++) { if (!(ia > ib)) { continue; } ISphere b = resiude_atoms[ib]; Vector3 b_position = b.transform.position; float b_covalent_radius = AtomicRadii.radii_covalent[b.atom_.element_]; /* If their distance is smaller then the sume of radius + plus a bias, then spawn a bond */ float distance = Vector3.Distance(a_position, b_position); if (distance <= a_covalent_radius + b_covalent_radius + 0.015) { bonds++; GameObject temp = Instantiate(prefab_bond, a_position, Quaternion.identity); temp.transform.parent = bonds_transform; temp.isStatic = this.gameObject.isStatic; /* Rotate it accordingly */ Vector3 direction = b_position - a_position; Quaternion toRotation = Quaternion.FromToRotation(new Vector3(0, 1, 0), direction); temp.transform.rotation = toRotation; /* Set size and radius */ ICylinder icylinder = temp.GetComponent <ICylinder>(); icylinder.radius_ = AtomicRadii.ball_and_stick_bond_radius; icylinder.height_ = distance; } } } } Debug.Log("Spawned: " + bonds + " bonds"); /* Position the model and the camera in the world */ SetCameraAndPanelBoxPosition(atoms_bounding_box_); bonds_selected_[0] = null; bonds_selected_[1] = null; /* Set some default info on the world panel */ SELECTION_MODE_SPHERE_RADIUS = AtomicRadii.ball_and_stick_radius * 5.0f; transform.GetChild(1).GetComponent <ModePanel>().SetRadius(SELECTION_MODE_SPHERE_RADIUS); info_ui_ = Camera.main.transform.Find("AtomInfoBox").GetComponent <AtomInfoBox>(); }
public static AABB3D FromSphere(ISphere sphere) { return new AABB3D(sphere.PositionV3, 2 * sphere.Radius); }