예제 #1
0
    public void ManageRecursive(PlanetChunkProperties chunk)
    {
        if (NeedsSplit(chunk) && chunk.LODLevel < MaxLodLevel)
        {
            if (chunk.isSplit)
            {
                bool childrenGeneratingFlag = false;

                foreach (PlanetChunkProperties child in chunk.Children)
                {
                    childrenGeneratingFlag |= child.ChunkObject.IsCalculating;
                    ManageRecursive(child);
                }

                if (!childrenGeneratingFlag)
                {
                    HideChunk(chunk);
                }

                chunk.isSpliting = false;
            }
            else
            {
                AddToSplitPool(chunk);
            }
        }
        else
        {
            Merge(chunk);
        }
    }
예제 #2
0
 public void AddToSplitPool(PlanetChunkProperties chunk)
 {
     if (!SplitPool.Contains(chunk))
     {
         SplitPool.Enqueue(chunk);
     }
 }
예제 #3
0
    public void Split(PlanetChunkProperties chunk)
    {
        if (chunk.ChunkObject != null)
        {
            if (NeedsSplit(chunk))
            {
                if (chunk.Children == null)
                {
                    chunk.Children = new PlanetChunkProperties[4];
                    CreateChunk(chunk, chunk.min, 0);
                    CreateChunk(chunk, chunk.MiddleLeft, 1);
                    CreateChunk(chunk, chunk.BottomMiddle, 2);
                    CreateChunk(chunk, chunk.Middle, 3);
                }
                else
                {
                    foreach (PlanetChunkProperties child in chunk.Children)
                    {
                        EnableChunk(child);
                    }
                }

                chunk.isMerged = false;
            }
        }
    }
예제 #4
0
 //Create a Chunk
 public void CreateChunk(PlanetChunkProperties parent, Vector2 min, int index)
 {
     parent.Chunks[index] =
         CreateChunkProperties(parent, parent.Rotation, parent.Size / 2f, parent.LODLevel + 1, min);
     parent.Chunks[index].ChunkObject = GetFreeChunkObject(parent.Chunks[index]);
     parent.Chunks[index].Bounds      = parent.Chunks[index].ChunkObject.GetComponent <MeshRenderer>().bounds;
 }
예제 #5
0
 //Update the chunk's position
 public PlanetChunkObject UpdateChunkObject(PlanetChunkProperties chunkProperties, PlanetChunkObject chunk)
 {
     chunk.transform.localPosition = Vector3.zero;
     chunk.Properties            = chunkProperties;
     chunkProperties.ChunkObject = chunk;
     UpdateChunkMesh(chunk);
     return(chunk);
 }
예제 #6
0
    //Create the root planet node
    public void CreateRoot(Vector3 rotationDir, float angle)
    {
        PlanetChunkProperties p =
            CreateChunkProperties(null, Quaternion.AngleAxis(angle, rotationDir), 1f, 0, Vector2.zero);

        GetFreeChunkObject(p);
        rootChunks.Add(p);
    }
예제 #7
0
    public void EnableChunk(PlanetChunkProperties chunk)
    {
        if (chunk.ChunkObject == null)
        {
            chunk.ChunkObject = GetFreeChunkObject(chunk);
        }

        chunk.ChunkObject.SetVisible(true);
    }
예제 #8
0
    public bool NeedsSplit(PlanetChunkProperties chunk)
    {
        var maxVerError =
            (chunk.maxGeoError / Mathf.Sqrt(chunk.ChunkObject.Renderer.bounds
                                            .SqrDistance(MainCamera.transform
                                                         .position)) /*Vector3.Distance(Planet.MainCamera.transform.position,Center * Planet.SphereRadius)*/
            ) * K;

        return(maxVerError > MaxError);
    }
예제 #9
0
 public void HideChunk(PlanetChunkProperties chunk)
 {
     if (chunk.ChunkObject != null)
     {
         if (chunk.ChunkObject.IsVisible)
         {
             chunk.ChunkObject.SetVisible(false);
         }
     }
 }
예제 #10
0
    public void DisableChunk(PlanetChunkProperties chunk)
    {
        if (chunk.ChunkObject.Collider != null)
        {
            chunk.ChunkObject.Collider.enabled = false;
        }

        HideChunk(chunk);
        AddToChunkPool(chunk.ChunkObject);
        chunk.ChunkObject = null;
        chunk.Active      = false;
    }
예제 #11
0
    private void Update()
    {
        ManageChunks();
        UpdateNoise();

        if (SplitPool.Count > 0 && lastSplitTime - Time.time <= 0)
        {
            PlanetChunkProperties c = SplitPool.Dequeue();
            Split(c);
            lastSplitTime = Time.time + 1f / MaxSplitsPerSecond;
        }
    }
예제 #12
0
    /// <summary>
    /// Get Free Chunk object if none exists, create
    /// </summary>
    public PlanetChunkObject GetFreeChunkObject(PlanetChunkProperties chunkProperties)
    {
        PlanetChunkObject c = GetChunkObjectFromPool();

        if (c == null)
        {
            c = CreateBasicChunkObject();
        }

        UpdateChunkObject(chunkProperties, c);

        return(c);
    }
예제 #13
0
    public void Merge(PlanetChunkProperties chunk)
    {
        if (!chunk.isMerged)
        {
            if (chunk.Children != null)
            {
                foreach (PlanetChunkProperties child in chunk.Children)
                {
                    MergeChildren(chunk, child);
                }
            }

            EnableChunk(chunk);
            chunk.isMerged = true;
        }
    }
예제 #14
0
    void MergeChildren(PlanetChunkProperties parent, PlanetChunkProperties child)
    {
        if (!child.isMerged)
        {
            if (child.Children != null)
            {
                foreach (PlanetChunkProperties c in child.Children)
                {
                    //recursively merge
                    MergeChildren(parent, c);
                }
            }
        }

        DisableChunk(child);
        parent.isMerged = true;
    }
예제 #15
0
    public PlanetChunkProperties CreateChunkProperties(PlanetChunkProperties parent, Quaternion rotation,
                                                       float Size, int LodLevel, Vector2 min)
    {
        PlanetChunkProperties chunk = new PlanetChunkProperties();

        chunk.Rotation = rotation;
        chunk.Parent   = parent;

        chunk.LODLevel = LodLevel;
        chunk.Size     = Size;
        chunk.min      = min;
        chunk.Center   = (chunk.Rotation * new Vector3(chunk.Middle.x - 0.5f, 1f, chunk.Middle.y - 0.5f)).normalized *
                         SphereRadius;

        chunk.maxGeoError = Mathf.Pow(2f, MaxLodLevel - chunk.LODLevel);
        return(chunk);
    }
예제 #16
0
    public PlanetChunkProperties GetNearestChunkProperties(Vector3 point)
    {
        if (rootChunks == null)
        {
            return(null);
        }
        float nearestDistance = float.PositiveInfinity;
        PlanetChunkProperties nearestChunk = null;

        foreach (var rootChunk in rootChunks)
        {
            float d = (rootChunk.Bounds.center - point).sqrMagnitude;
            if (d < nearestDistance)
            {
                nearestDistance = d;
                nearestChunk    = rootChunk;
            }
        }

        return(GetNearestChunkProperties(nearestChunk, point));
    }
예제 #17
0
    private PlanetChunkProperties GetNearestChunkProperties(PlanetChunkProperties parent, Vector3 point)
    {
        if (parent.Chunks == null)
        {
            return(parent);
        }
        float nearestDistance = float.PositiveInfinity;
        PlanetChunkProperties nearestChunk = null;

        foreach (var chunk in parent.Chunks)
        {
            float d = (chunk.Bounds.center - point).sqrMagnitude;
            if (d < nearestDistance)
            {
                nearestChunk    = chunk;
                nearestDistance = d;
            }
        }

        return(GetNearestChunkProperties(nearestChunk, point));
    }