private void Update(ref Vector3D cameraPos, ref Vector3 cameraForward, float farPlaneDistance) { ProfilerShort.Begin("MyRenderClipmap.Update"); LastCameraPosition = cameraPos; if (!Environment.Is64BitProcess) { UseCache = false; } if (NeedsResetCache) { MyClipmap.CellsCache.Reset(); NeedsResetCache = false; } for (uint lod = 0; lod < m_lodLevels.Length; lod++) { if (m_lodLevels[lod].IsDitheringInProgress()) { m_lodLevels[lod].UpdateDithering(); } } Vector3D localPosition; Vector3D.Transform(ref cameraPos, ref m_invWorldMatrix, out localPosition); Vector3 localForward; Vector3.TransformNormal(ref cameraForward, ref m_invWorldMatrix, out localForward); double cellSizeHalf = MyVoxelCoordSystems.RenderCellSizeInMetersHalf(0); double threshold = cellSizeHalf / 4.0f; float thresholdRotation = 0.03f; if (!m_updateClippingFrustum && (Vector3D.DistanceSquared(localPosition, m_lastClippingPosition) > threshold) || (Vector3.DistanceSquared(localForward, m_lastClippingForward) > thresholdRotation) || m_invalidated > 0) { ResetClipping(); m_lastClippingPosition = localPosition; m_lastClippingForward = localForward; } float camDistanceFromCenter = Vector3.Distance(m_massiveCenter, cameraPos); if (m_requestCollector.SentRequestsEmpty && m_updateClippingFrustum) { ProfilerShort.Begin("DoClipping"); //Top priority for 0 lod when invalidated (drill) if (m_invalidated == 2) { m_lodLevels[0].DoClipping(camDistanceFromCenter, localPosition, farPlaneDistance, m_requestCollector, true, 1); m_lodLevels[0].DiscardClippedCells(m_requestCollector); m_lodLevels[0].UpdateCellsInScene(camDistanceFromCenter, localPosition); if (!m_requestCollector.SentRequestsEmpty) { m_requestCollector.Submit(); ProfilerShort.End(); // DoClipping ProfilerShort.End(); // Update return; } m_updateClippingFrustum = false; m_invalidated = 1; } else { //Most important frustum culling for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod) { ProfilerShort.Begin("Lod " + lod); m_lodLevels[lod].DoClipping(camDistanceFromCenter, localPosition, farPlaneDistance, m_requestCollector, true, 1); ProfilerShort.End(); } //ProfilerShort.End(); ProfilerShort.Begin("KeepOrDiscardClippedCells"); for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod) { m_lodLevels[lod].DiscardClippedCells(m_requestCollector); } ProfilerShort.End(); ProfilerShort.Begin("UpdateCellsInScene"); for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod) { m_lodLevels[lod].UpdateCellsInScene(camDistanceFromCenter, localPosition); } ProfilerShort.End(); if (!m_requestCollector.SentRequestsEmpty) { m_requestCollector.Submit(); ProfilerShort.End(); // DoClipping ProfilerShort.End(); // Update return; } m_invalidated = 0; m_notReady.Remove(this); m_updateClippingFrustum = false; } ProfilerShort.End(); } ProfilerShort.End(); }
private void Update(ref Vector3D cameraPos, float farPlaneDistance) { ProfilerShort.Begin("MyRenderClipmap.Update"); Vector3D localPosition; Vector3D.Transform(ref cameraPos, ref m_invWorldMatrix, out localPosition); double cellSizeHalf = MyVoxelCoordSystems.RenderCellSizeInMetersHalf(0); double threshold = cellSizeHalf * cellSizeHalf; if (!m_updateClipping && Vector3D.DistanceSquared(localPosition, m_lastClippingPosition) > threshold) { m_updateClipping = true; } //modified clipping routine //we clip only when there are no old requests since we are not able to combine //multiple clippings reasonably //(need the structure to hold and merge result otherwise holes are inevitable) if (!m_updateClipping && m_requestCollector.SentRequestsEmpty && m_clipingAdjustment < 5) { m_clipingAdjustment += 2; m_updateClipping = true; } if (m_updateClipping) { m_requestCollector.Submit(); if (m_requestCollector.SentRequestsEmpty) { ProfilerShort.Begin("KeepOrDiscardClippedCells"); for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod) { m_lodLevels[lod].KeepOrDiscardClippedCells(m_requestCollector); } ProfilerShort.End(); if (!ENABLE_CLIPPING_ADJUSTMENT) { m_clipingAdjustment = 1; } var startLod = MathHelper.Clamp(-1 * m_clipingAdjustment, 0, m_lodLevels.Length - 1); ProfilerShort.Begin("DoClipping"); if (NEW_VOXEL_CLIPPING) { m_lodLevels[startLod].DoClipping(localPosition, m_requestCollector, MathHelper.Clamp(m_clipingAdjustment, 0, 5)); } else { Debug.Assert(m_scaleGroup == MyClipmapScaleEnum.Normal); for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod) { ProfilerShort.Begin("Lod " + lod); m_lodLevels[lod].DoClipping_Old(localPosition, farPlaneDistance, m_requestCollector); ProfilerShort.End(); } } ProfilerShort.End(); if (m_requestCollector.SentRequestsEmpty) { m_clipingAdjustment += 2; } } //else // m_clipingAdjustment -= 2; m_lastClippingPosition = localPosition; m_updateClipping = false; } ProfilerShort.Begin("UpdateCellsInScene"); for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod) { m_lodLevels[lod].UpdateCellsInScene(localPosition); } ProfilerShort.End(); m_clipingAdjustment = MathHelper.Clamp(m_clipingAdjustment, -m_lodLevels.Length + 3, 5); m_requestCollector.Submit(); if (m_requestCollector.SentRequestsEmpty) { m_notReady.Remove(this); } ProfilerShort.End(); }