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); } }
public void AddToSplitPool(PlanetChunkProperties chunk) { if (!SplitPool.Contains(chunk)) { SplitPool.Enqueue(chunk); } }
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; } } }
//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; }
//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); }
//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); }
public void EnableChunk(PlanetChunkProperties chunk) { if (chunk.ChunkObject == null) { chunk.ChunkObject = GetFreeChunkObject(chunk); } chunk.ChunkObject.SetVisible(true); }
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); }
public void HideChunk(PlanetChunkProperties chunk) { if (chunk.ChunkObject != null) { if (chunk.ChunkObject.IsVisible) { chunk.ChunkObject.SetVisible(false); } } }
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; }
private void Update() { ManageChunks(); UpdateNoise(); if (SplitPool.Count > 0 && lastSplitTime - Time.time <= 0) { PlanetChunkProperties c = SplitPool.Dequeue(); Split(c); lastSplitTime = Time.time + 1f / MaxSplitsPerSecond; } }
/// <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); }
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; } }
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; }
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); }
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)); }
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)); }