public void AddNode(int x, int z, T node) { _nodeStatuses[x, z] = new NodeIndicator(this, _aabbMins[x, z], _aabbMaxs[x, z]) { Node = node }; }
public void CreateUnitedInstance(InstancingDraw[] instancingData) { if (instancingData[0].State == InstancingDrawState.NotInitialized || _newInstanceCountLimit) { var dataLength = instancingData.Length; for (int i = 0; i < dataLength; ++i) { instancingData[i].SetInstancingCount(_cachedNodes.Length, _maxInstanceCountPerRenderInUnit[i]); } } if (_previousInstantiatingNode != null) { if (_previousInstantiatingNode.IsDuringInstantiation) { _previousInstantiatingNode.SetInstantiated(); var count = _cachedNodes.Length; var index = 0; for (; index < count; ++index) { if (_cachedNodes[index] == null) { _cachedNodes[index] = _previousInstantiatingNode; break; } } if (index == count) { logger.InfoFormat("Full Exception, mins: {0}, maxs: {1}", _previousInstantiatingNode.Mins.ToStringExt(), _previousInstantiatingNode.Maxs.ToStringExt()); } if (!_newInstanceCountLimit) { ReplaceBuffer(_previousInstantiatingNode.Node, index, instancingData); } } else { _previousInstantiatingNode.Node.ReleaseBuffer(); } _previousInstantiatingNode = null; } if (_newInstanceCountLimit) { var count = _cachedNodes.Length; for (int i = 0; i < count; ++i) { if (_cachedNodes[i] != null) { ReplaceBuffer(_cachedNodes[i].Node, i, instancingData); } } _newInstanceCountLimit = false; } if (_curInstantiatingNode != null) { _previousInstantiatingNode = _curInstantiatingNode; _curInstantiatingNode = null; } var drawCount = instancingData.Length; for (int i = 0; i < drawCount; ++i) { if (instancingData[i].State == InstancingDrawState.Enable) { instancingData[i].ClearRealBlockCount(); var count = _cachedNodes.Length; for (int j = 0; j < count; ++j) { var node = _cachedNodes[j]; if (node != null) { if (node.IsOutOfRange) { _cachedNodes[j] = null; continue; } if (node.IsActive) { var realCount = node.Node.GetInstancingDataCount(i); instancingData[i].SetRealBlockCount(j, realCount); } } } } } }
public void DistanceAndFrustumCulling(CameraFrustum frustum) { var viewPoint = frustum.ViewPoint; var halfSize = _clusterDimensions / 2; var minVisiblePosX = viewPoint.x - _cullingDistance; var minVisiblePosZ = viewPoint.z - _cullingDistance; var maxVisiblePosX = minVisiblePosX + _cullingDistance * 2; var maxVisiblePosZ = minVisiblePosZ + _cullingDistance * 2; int curVisibleStartX = Mathf.FloorToInt(minVisiblePosX / _clusterSize) + halfSize; int curVisibleStartZ = Mathf.FloorToInt(minVisiblePosZ / _clusterSize) + halfSize; int curVisibleEndX = Mathf.CeilToInt(maxVisiblePosX / _clusterSize) + halfSize; int curVisibleEndZ = Mathf.CeilToInt(maxVisiblePosZ / _clusterSize) + halfSize; bool enoughRoom = true; for (int i = _lastVisibleStartX; i < _lastVisibleEndX; ++i) { for (int j = _lastVisibleStartZ; j < _lastVisibleEndZ; ++j) { if (i >= 0 && i < _clusterDimensions && j >= 0 && j < _clusterDimensions) { var cluster = _nodeClusters[i, j]; if (cluster == null) { continue; } var node = cluster.DistanceAndFrustumCulling(viewPoint, enoughRoom); if (node != null && enoughRoom) { _curInstantiatingNode = node; enoughRoom = false; } } } } if (_lastVisibleStartX != curVisibleStartX || _lastVisibleEndX != curVisibleEndX || _lastVisibleStartZ != curVisibleStartZ || _lastVisibleEndZ != curVisibleEndZ) { for (int i = curVisibleStartX; i < curVisibleEndX; ++i) { for (int j = curVisibleStartZ; j < curVisibleEndZ; ++j) { if (i >= 0 && i < _clusterDimensions && j >= 0 && j < _clusterDimensions) { var cluster = _nodeClusters[i, j]; if (cluster == null) { continue; } var node = cluster.DistanceAndFrustumCulling(viewPoint, enoughRoom); if (node != null && enoughRoom) { _curInstantiatingNode = node; enoughRoom = false; } } } } _lastVisibleStartX = curVisibleStartX; _lastVisibleEndX = curVisibleEndX; _lastVisibleStartZ = curVisibleStartZ; _lastVisibleEndZ = curVisibleEndZ; } if (!enoughRoom) { _curInstantiatingNode.SetInstantiating(); _curInstantiatingNode.Node.BuildBuffer(_curInstantiatingNode.HeightBuffer()); } var count = _cachedNodes.Length; for (int i = 0; i < count; ++i) { var node = _cachedNodes[i]; if (node != null && node.IsInstantiated) { node.IsActive = frustum.IsDetailNodeVisible(node.Mins, node.Maxs); } } }