예제 #1
0
        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();
        }
예제 #2
0
        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();
        }