// Use this for initialization void Initialize() { m_vertices = Icosphere.GenerateIcosphere(1f, m_nbSubdivisions); m_segments = new List <IcoSegment>(); for (int i = 0; i < m_vertices.Count / 3; ++i) { Vector3 v0 = m_vertices[3 * i + 0]; Vector3 v1 = m_vertices[3 * i + 1]; Vector3 v2 = m_vertices[3 * i + 2]; GameObject segment = new GameObject(); segment.transform.position = transform.position; segment.name = "segment" + i; segment.transform.parent = transform; segment.AddComponent <MeshRenderer>(); segment.GetComponent <MeshRenderer>().material = m_segmentMaterial; segment.layer = LayerMask.NameToLayer("Planet"); IcoSegment icoSeg = segment.AddComponent <IcoSegment>(); m_segments.Add(icoSeg); icoSeg.heightLevel = m_defaultHeightLevel; icoSeg.icoPlanet = this; icoSeg.SetBaseVertices(v0, v1, v2); m_segmentJoints.Add(segment.AddComponent <MTK_PlanetSegmentJoint>()); MTK_Interactable interactable = segment.AddComponent <MTK_Interactable>(); interactable.isDistanceGrabbable = false; interactable.isGrabbable = false; interactable.isDroppable = false; } }
public static int[] MinHeightAtCorners(IcoSegment segment) { int[] heights = new int[3]; for (int i = 0; i < 3; ++i) { heights[i] = MinHeightAtCorner(segment, i); } return(heights); }
protected void Awake() { rigidbody = transform.parent.GetComponent <Rigidbody>(); m_icoPlanet = transform.parent.GetComponent <IcoPlanet>(); m_icoSegment = GetComponent <IcoSegment>(); m_parentJoint = GetComponentInParent <MTK_JointType_Fixed>(); m_oldHeight = m_icoSegment.heightLevel; }
public int IndexCorrespondingleftVertice(IcoSegment segment, IcoSegment target) { for (int i = 0; i < 3; ++i) { if (target.neighbours[i] == segment) { return((i + 1) % 3); } } return(-1); }
public IcoSegment LeftFrom(IcoSegment segment) { for (int i = 0; i < 3; ++i) { if (m_neighbours[i] == segment) { return(m_neighbours[(i + 1) % 3]); } } return(null); }
static bool UpdateFullLoopLeft(IcoSegment segment, int side) { IcoSegment current = segment.neighbours[side]; IcoSegment previous = segment; while (current != segment) { current.UpdateSegment(); IcoSegment tmp = current; current = current.LeftFrom(previous); previous = tmp; } return(true); }
public static int MaxHeightAtCorner(IcoSegment segment, int corner) { int max = int.MinValue; IcoSegment current = segment.neighbours[corner]; IcoSegment previous = segment; while (current != segment) { max = Mathf.Max(max, current.heightLevel); IcoSegment tmp = current; current = current.LeftFrom(previous); previous = tmp; } return(max); }
public void SetTesselationLevel(int nbSubdivisions, int heightMultiplier = 1) { m_nbSubdivisions = nbSubdivisions; List <IcoSegment> oldSegmentsList = m_segments; // Generate new geometry Initialize(); // Set height levels on the new geometry foreach (IcoSegment segment in m_segments) { Vector3 center = segment.Center(); float closestAngle = float.MaxValue; IcoSegment closestSegment = oldSegmentsList[0]; foreach (IcoSegment oldSeg in oldSegmentsList) { float angle = Vector3.Angle(center, oldSeg.Center()); if (angle < closestAngle) { closestAngle = angle; closestSegment = oldSeg; } } segment.heightLevel = heightMultiplier * closestSegment.heightLevel; } foreach (IcoSegment segment in m_segments) { segment.GenerateCollider(); } foreach (IcoSegment segment in m_segments) { segment.FindNeighbours(); } foreach (IcoSegment segment in m_segments) { segment.UpdateSegment(); } foreach (IcoSegment segment in oldSegmentsList) { Destroy(segment); } }
void TerraformDown(bool state) { if (state) { RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit, 1000f, LayerMask.GetMask("Planet"))) { IcoSegment segment = hit.collider.gameObject.GetComponent <IcoSegment>(); if (segment) { --segment.heightLevel; segment.UpdateSegment(); segment.UpdateNeighbours(); } } } }
public static bool LoopLeftBelowLevel(IcoSegment segment, int side, int level) { IcoSegment current = segment.neighbours[side]; IcoSegment previous = segment; while (current != segment) { if (current.heightLevel < level) { return(false); } IcoSegment tmp = current; current = current.LeftFrom(previous); previous = tmp; } return(true); }
MTK_Interactable GetCandidate(Collider other) { IcoSegment seg = other.gameObject.GetComponent <IcoSegment>(); if (seg && fingerCollider && seg.IsInside(fingerCollider.position, other)) { return(null); } MTK_Interactable candidate = other.GetComponent <MTK_Interactable>(); if (!(candidate && candidate.isGrabbable) && other.attachedRigidbody) { candidate = other.attachedRigidbody.GetComponent <MTK_Interactable>(); } return(candidate); }
public static void FindSegmentType(IcoSegment segment, out IcoSegment.SegmentType outType, out int outOrientation) { // Reset for (int i = 0; i < 3; ++i) { ms_corners[i] = false; ms_sides[i] = false; } for (int i = 0; i < 3; ++i) { if (segment.neighbours[i].heightLevel < segment.heightLevel) { ms_sides[i] = true; } if (!FullLoopLeft(segment, i)) { ms_corners[i] = true; } } EdgesSidesToType(segment, ms_corners, ms_sides, out outType, out outOrientation); }
public void FindNeighbours() { for (int i = 0; i < 3; ++i) { Vector3 edge = (m_baseVertices[i] + m_baseVertices[(i + 1) % 3]) / 2; float closestAngle = float.MaxValue; IcoSegment closestSegment = icoPlanet.Segments[0]; foreach (IcoSegment otherSeg in icoPlanet.Segments) { if (otherSeg != this) { float angle = Vector3.Angle(edge, otherSeg.Center()); if (angle < closestAngle) { closestAngle = angle; closestSegment = otherSeg; } } } m_neighbours[i] = closestSegment; } }
void Teleport(bool state) { if (state) { RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit, 1000f)) { IcoSegment segment = hit.collider.gameObject.GetComponent <IcoSegment>(); if (segment) { int index = 0; foreach (IcoSegment seg in segment.icoPlanet.Segments) { if (seg == segment) { m_colonisator.selectedSegment = index; break; } ++index; } } } } }
private static void EdgesSidesToType(IcoSegment segment, bool[] corners, bool[] sides, out IcoSegment.SegmentType outType, out int outOrientation) { int[] minCorner = new int[3]; int[] maxCorner = new int[3]; // level int nbLower = 0; int nbHigher = 0; int nbLowerPlus = 0; int nbHigherPlus = 0; int nbEqual = 0; // Shape int nbCorners = 0; int nbSides = 0; // Finding int corner = 0; int side = 0; int noCorner = 0; int noSide = 0; int lowest = 0; int highest = 0; for (int i = 0; i < 3; ++i) { minCorner[i] = MinHeightAtCorner(segment, i); maxCorner[i] = MaxHeightAtCorner(segment, i); // Corners if (minCorner[i] < segment.heightLevel) { ++nbLower; } if (maxCorner[i] > segment.heightLevel) { ++nbHigher; } if (minCorner[i] + 1 < segment.heightLevel) { ++nbLowerPlus; } if (maxCorner[i] - 1 > segment.heightLevel) { ++nbHigherPlus; } if (maxCorner[i] == minCorner[i] && minCorner[i] == segment.heightLevel) { ++nbEqual; } if (minCorner[i] < minCorner[lowest]) { lowest = i; } if (minCorner[i] > minCorner[highest]) { highest = i; } // Corners if (corners[i]) { ++nbCorners; corner = i; } else { noCorner = i; } // Sides if (sides[i]) { ++nbSides; side = i; } else { noSide = i; } } /* print( * "minCorner:" + minCorner[0] + minCorner[1] + minCorner[2] + * " maxCorner:" + maxCorner[0] + maxCorner[1] + maxCorner[2] + * " nbLower:" + nbLower + " nbHigher:" + nbHigher + " nbEqual:" + nbEqual + * " nbLowerPlus:" + nbLowerPlus + " nbHigherPlus:" + nbHigherPlus);*/ outOrientation = 0; if (nbCorners == 0 && nbSides == 0) { outType = IcoSegment.SegmentType.full; } else if (nbCorners == 1 && nbSides == 0) { outType = IcoSegment.SegmentType.corner1; outOrientation = corner; } else if (nbCorners == 2 && nbSides == 0) { outType = IcoSegment.SegmentType.corner2; outOrientation = noCorner; } else if (nbCorners == 3 && nbSides == 0) { outType = IcoSegment.SegmentType.corner3; } else if (nbCorners == 3 && nbSides == 2) { if (MinHeightAtCorner(segment, (noSide + 2) % 3) < segment.heightLevel - 1) { outOrientation = (noSide + 2) % 3; outType = IcoSegment.SegmentType.side2Corner; } else { outOrientation = noSide; outType = IcoSegment.SegmentType.side2; } } else if (nbCorners == 3 && nbSides == 3) { if (nbLowerPlus == 3) { outType = IcoSegment.SegmentType.side3corner3; } else if (nbLowerPlus == 2 && nbLower == 3) { outType = IcoSegment.SegmentType.side3corner2; outOrientation = highest; } else { outType = IcoSegment.SegmentType.side3; } } else if (nbSides == 1 && nbCorners > 0) { if (corners[(side + 2) % 3]) { outType = IcoSegment.SegmentType.sidecorner; outOrientation = side; } else { outType = IcoSegment.SegmentType.side1; outOrientation = (side + 2) % 3; } } else if (nbSides == 1) { outType = IcoSegment.SegmentType.side1; outOrientation = noSide; } else if (nbSides == 2) { outType = IcoSegment.SegmentType.side2; outOrientation = noSide; } else if (nbSides == 3) { outType = IcoSegment.SegmentType.side3; } else { outType = IcoSegment.SegmentType.full; outOrientation = 0; } }