예제 #1
0
        void Update()
        {
#if UNITY_EDITOR
            FoliageLog.Assert(m_FoliageData != null);
#endif
            // Camera used for culling
            m_CurrentFrameCameraCull = m_Settings.m_UsedCameraCulling;

            // Camera used for drawing
            m_CurrentFrameCameraDraw = m_Settings.m_UsedCameraDrawing;
            m_CurrentFrameLayer      = LayerMask.NameToLayer(m_Settings.m_UsedLayer);

            // Extract the planes
            ExtractPlanes(m_CameraPlanes, m_CurrentFrameCameraCull.projectionMatrix * m_CurrentFrameCameraCull.worldToCameraMatrix);

            // Set the position
            m_CurrentFrameCameraPosition = m_CurrentFrameCameraCull.transform.position;

            // Set the bend position
            m_CurrentFrameBendPosition = m_Settings.m_BendTransform != null ? m_Settings.m_BendTransform.position : m_CurrentFrameCameraPosition;

            // Current cell position
            currentCell.Set(m_CurrentFrameCameraPosition);

            m_CurrentFrameAllowIndirect = m_Settings.m_AllowDrawInstancedIndirect;

            m_DrawStats.Reset();

            // Copy the wind for SpeedTree types
            for (int i = 0; i < m_FoliageTypesArray.Length; i++)
            {
                if (m_FoliageTypesArray[i].IsSpeedTreeType)
                {
                    m_FoliageTypesArray[i].CopyBlock();
                }
            }

            bool  applyShadowCorrection       = m_Settings.m_ApplyShadowPoppingCorrection;
            float shadowCorrectionDistanceSqr = m_Settings.m_ShadowPoppingCorrection * m_Settings.m_ShadowPoppingCorrection;

            // We iterate only as many cells as we need
            FoliageCell.IterateNeighboring(currentCell, m_CellNeighborCount, (int hash) =>
            {
                FoliageCellDataRuntime data;

                if (m_FoliageData.m_FoliageData.TryGetValue(hash, out data))
                {
                    // If it is within distance and in the frustum
                    float distanceSqr = data.m_Bounds.SqrDistance(m_CurrentFrameCameraPosition);

                    // Check for the maximum distance
                    if (distanceSqr <= m_MaxDistanceAllSqr && GeometryUtility.TestPlanesAABB(m_CameraPlanes, data.m_Bounds))
                    {
                        // Process the big cells if we are withing the tree distance
                        if (distanceSqr <= m_MaxDistanceTreeSqr)
                        {
                            ProcessCellTree(data, distanceSqr, applyShadowCorrection, shadowCorrectionDistanceSqr, false);
                        }

                        // Process subdivided cells only if we have instancing enabled and only if it is within the distance proximity for grass
                        if (distanceSqr <= m_MaxDistanceGrassSqr && m_Settings.m_DrawInstanced)
                        {
                            ProcessCellGrass(data);
                        }

                        m_DrawStats.m_ProcessedCells++;
                    }
                    else if (distanceSqr <= shadowCorrectionDistanceSqr)
                    {
                        ProcessCellTree(data, distanceSqr, applyShadowCorrection, shadowCorrectionDistanceSqr, true);
                    }
                }
            });

#if UNITY_EDITOR
            if (Time.frameCount % 300 == 0)
            {
                FoliageLog.i(string.Format("Proc cells:{0} Proc subdiv cells: {1} Proc tree instances: {2} Proc draw calls: {3}",
                                           m_DrawStats.m_ProcessedCells,
                                           m_DrawStats.m_ProcessedCellsSubdiv,
                                           m_DrawStats.m_ProcessedInstances,
                                           m_DrawStats.m_ProcessedDrawCalls));
            }
#endif
        }
        private void Update()
        {
            if (!m_Settings.m_WatchedTransform)
            {
                return;
            }

            m_CameraPosTemp = m_Settings.m_WatchedTransform.position;

            float x = m_CameraPosTemp.x - m_LastPosition.x;
            float y = m_CameraPosTemp.y - m_LastPosition.y;
            float z = m_CameraPosTemp.z - m_LastPosition.z;

            float distWalked = x * x + y * y + z * z;

            // If we didn't walked enough, return
            if (distWalked > m_Settings.m_CollisionRefreshDistance * m_Settings.m_CollisionRefreshDistance)
            {
                // Update last position
                m_LastPosition = m_CameraPosTemp;

                m_Layer = LayerMask.NameToLayer(m_Settings.m_UsedLayer);

                // Reset counter
                m_DataIssuedActiveColliders = 0;

                // Reset all the cache's data
                foreach (CollisionCache cache in m_Cache.Values)
                {
                    if (cache != null)
                    {
                        cache.Reset();
                    }
                }

                // Set the current cell
                currentCell.Set(m_LastPosition);

                // Refresh eveything
                float collDistSqr = m_Settings.m_CollisionDistance * m_Settings.m_CollisionDistance;

                // Iterate cells
                FoliageCell.IterateNeighboring(currentCell, 1, (int hash) =>
                {
                    FoliageCellDataRuntime data;

                    if (m_FoliageData.m_FoliageData.TryGetValue(hash, out data))
                    {
                        // If it is within distance and in the frustum
                        float distanceSqr = data.m_Bounds.SqrDistance(m_LastPosition);

                        if (distanceSqr <= collDistSqr)
                        {
                            ProcessCell(data, collDistSqr);
                        }
                    }
                });
            }

#if UNITY_EDITOR
            if (Time.frameCount % 300 == 0)
            {
                FoliageLog.i("Issued colliders: " + m_DataIssuedActiveColliders);
            }
#endif
        }