Ejemplo n.º 1
0
    // 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;
        }
    }
Ejemplo n.º 2
0
 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;
    }
Ejemplo n.º 4
0
 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);
 }
Ejemplo n.º 5
0
 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);
 }
Ejemplo n.º 6
0
    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);
    }
Ejemplo n.º 7
0
    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);
    }
Ejemplo n.º 8
0
    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);
        }
    }
Ejemplo n.º 9
0
 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();
             }
         }
     }
 }
Ejemplo n.º 10
0
    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);
    }
Ejemplo n.º 11
0
    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);
    }
Ejemplo n.º 12
0
    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);
    }
Ejemplo n.º 13
0
    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;
        }
    }
Ejemplo n.º 14
0
 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;
                 }
             }
         }
     }
 }
Ejemplo n.º 15
0
    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;
        }
    }