public void AddNode(int x, int z, T node) { _nodeStatuses[x, z] = new GpuInstancingNodeIndicator(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].SetInstancingFullSizeParam(_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; if (index >= _cachedNodesActualLength) { _cachedNodesActualLength = index + 1; } break; } } if (index == count) { _logger.Error("Full Exception"); } if (!_newInstanceCountLimit) { ReplaceBuffer(_previousInstantiatingNode.Node, index, instancingData); } } else { _previousInstantiatingNode.Node.ReleaseBuffer(); } _previousInstantiatingNode = null; } if (_newInstanceCountLimit) { for (int i = 0; i < _cachedNodesActualLength; ++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(); bool canShrink = true; for (int j = _cachedNodesActualLength; j > 0; --j) { var index = j - 1; var node = _cachedNodes[index]; if (node != null) { if (node.IsOutOfRange) { _cachedNodes[index] = null; if (canShrink) { _cachedNodesActualLength = j - 1; } continue; } if (node.IsActive) { var realCount = node.Node.GetInstancingDataCount(i); instancingData[i].SetRealBlockCount(index, realCount); } canShrink = false; } } } } }
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()); } for (int i = 0; i < _cachedNodesActualLength; ++i) { var node = _cachedNodes[i]; if (node != null && node.IsInstantiated) { node.IsActive = frustum.IsNodeVisible(node); } } }