Пример #1
0
 void InitCameraInfo()
 {
     if (m_TargetCamera != null)
     {
         var lookAt = m_TargetCamInfo.lookAt;
         m_IsCamOri = m_TargetCamera.orthographic;
         if (m_TargetCamera.orthographic)
         {
             m_TargetCamInfo             = new PVSCameraInfo();
             m_TargetCamInfo.far         = m_TargetCamera.farClipPlane;
             m_TargetCamInfo.near        = m_TargetCamera.nearClipPlane;
             m_TargetCamInfo.fieldOfView = m_TargetCamera.orthographicSize;
         }
         else
         {
             m_TargetCamInfo             = new PVSCameraInfo();
             m_TargetCamInfo.far         = m_TargetCamera.farClipPlane;
             m_TargetCamInfo.near        = m_TargetCamera.nearClipPlane;
             m_TargetCamInfo.fieldOfView = m_TargetCamera.fieldOfView;
         }
         m_TargetCamInfo.lookAt     = lookAt;
         m_TargetCamInfo.aspect     = m_TargetCamera.aspect;
         m_TargetCamInfo.position   = m_TargetCamera.transform.position;
         m_TargetCamInfo.cullMatrix = m_TargetCamera.cullingMatrix;
     }
 }
Пример #2
0
 public PVSBakerThread(Vector3[] cellArray, PVSCell[] results, PVSBounds[] bounds, int startIdx, int endIdx, PVSCameraInfo camInfo, bool isOriCam)
 {
     m_CellArray = cellArray;
     m_Results   = results;
     m_Bounds    = bounds;
     m_StartIdx  = startIdx;
     m_EndIdx    = endIdx;
     m_CamInfo   = camInfo;
     m_IsOriCam  = isOriCam;
 }
Пример #3
0
        private void CellRays(int cellIdx, Vector3 cellPos, PVSBounds[] bounds, PVSCameraInfo camInfo, bool isOriCam)
        {
            var cell = m_Results[cellIdx];

            cell.ResetVisible();

            Vector3 right  = camInfo.right;
            Vector3 up     = camInfo.up;
            Vector3 lookAt = camInfo.lookAt;

            if (isOriCam)
            {
                // 正交攝影機
                var width  = camInfo.CameraWidth;
                var height = camInfo.CameraHeight;

                float   perX   = GetPerX(width);
                float   perY   = GetPerY(height);
                Vector3 halfV  = (right * width / 2.0f + up * height / 2.0f);
                Vector3 minVec = cellPos - halfV;

                float stepY = 0;

                while (stepY <= height)
                {
                    float   stepX = 0;
                    Vector3 yy    = stepY * up;
                    while (stepX <= width)
                    {
                        Vector3 startPt     = minVec + stepX * right + yy + lookAt * camInfo.near;
                        Ray     ray         = new Ray(startPt, lookAt);
                        float   tutDistance = 0;
                        while (true)
                        {
                            int collisionIdx = PVSRayTrack.sdPVSCells(ref ray, bounds, ref tutDistance);
                            if (collisionIdx >= 0)
                            {
                                var b = m_Bounds[collisionIdx];
                                cell.SetVisible(b.id, true);
                                break;
                            }
                            if (tutDistance > (camInfo.far - camInfo.near))
                            {
                                break;
                            }
                        }

                        stepX += perX;
                    }
                    stepY += perY;
                }

                lock (cell) {
                    cell.isEditorDone = true;
                }
            }
            else
            {
                // 透視攝影機
                var     width  = camInfo.farWidth;
                var     height = camInfo.farHeight;
                float   perX   = GetPerX(width);
                float   perY   = GetPerY(height);
                Vector3 halfV  = (right * width / 2.0f + up * height / 2.0f);
                Vector3 minVec = cellPos - halfV;
                float   d      = camInfo.far;

                float stepY = 0;

                while (stepY < height)
                {
                    float   stepX = 0;
                    Vector3 yy    = stepY * up;
                    while (stepX < width)
                    {
                        Vector3 endPt       = minVec + stepX * right + yy + lookAt * d;
                        Vector3 dir         = (endPt - camInfo.position).normalized;
                        Ray     ray         = new Ray(camInfo.position, dir);
                        float   tutDistance = 0;
                        while (true)
                        {
                            int collisionIdx = PVSRayTrack.sdPVSCells(ref ray, bounds, ref tutDistance);
                            if (collisionIdx >= 0)
                            {
                                var b = m_Bounds[collisionIdx];
                                cell.SetVisible(b.id, true);
                                break;
                            }
                            if (tutDistance > camInfo.far)
                            {
                                break;
                            }
                        }

                        stepX += perX;
                    }
                    stepY += perY;
                }

                lock (cell) {
                    cell.isEditorDone = true;
                }
            }
        }
Пример #4
0
        private void ProcessCurrentScene(bool isOnlyInit = false)
        {
            // 获得当前场景NavMesh
            if (isOnlyInit)
            {
                var tris = UnityEngine.AI.NavMesh.CalculateTriangulation();
                if (tris.vertices == null || tris.indices == null || tris.indices.Length <= 0 || tris.vertices.Length <= 0)
                {
                    Debug.LogError("当前场景没有NavMesh");
                    return;
                }

                m_PVSItemIDS = GameObject.FindObjectOfType <PVSItemIDS>();
                if (m_PVSItemIDS == null)
                {
                    GameObject obj = new GameObject("PVSItemIDS", typeof(PVSItemIDS));
                    m_PVSItemIDS = obj.GetComponent <PVSItemIDS>();
                }

                Vector3 minVec = Vector3.zero;
                Vector3 maxVec = Vector3.zero;
                for (int i = 0; i < tris.vertices.Length; ++i)
                {
                    var vec = tris.vertices [i];
                    if (i == 0)
                    {
                        minVec = vec;
                        maxVec = vec;
                    }
                    else
                    {
                        minVec.x = Mathf.Min(minVec.x, vec.x);
                        minVec.y = Mathf.Min(minVec.y, vec.y);
                        minVec.z = Mathf.Min(minVec.z, vec.z);

                        maxVec.x = Mathf.Max(maxVec.x, vec.x);
                        maxVec.y = Mathf.Max(maxVec.y, vec.y);
                        maxVec.z = Mathf.Max(maxVec.z, vec.z);
                    }
                }

                float camY = this.CamHeight;

                //  处理区域
                Vector3 center = (maxVec + minVec) / 2.0f;
                Vector3 size   = (maxVec - minVec);
                size.x = Mathf.Abs(size.x);
                size.y = Mathf.Abs(size.y);
                size.z = Mathf.Abs(size.z);

                m_SearchBounds = new Bounds(center, size);

                int col = Mathf.CeilToInt(size.x / PVSCell.CellSize);
                int row = Mathf.CeilToInt(size.z / PVSCell.CellSize);



                Vector3   halfSize = new Vector3(PVSCell.CellSize, 0, PVSCell.CellSize) / 2.0f;
                Vector3[] arr      = new Vector3[col * row];
                for (int r = 0; r < row; ++r)
                {
                    for (int c = 0; c < col; ++c)
                    {
                        int     idx = c + r * col;
                        Vector3 pt  = new Vector3(c * PVSCell.CellSize + minVec.x, center.y, r * PVSCell.CellSize + minVec.z) + halfSize;
                        UnityEngine.AI.NavMeshHit hit;
                        if (UnityEngine.AI.NavMesh.SamplePosition(pt, out hit, PVSCell.CellSize, int.MaxValue))
                        {
                            pt.y = hit.position.y + camY / 2.0f;
                        }
                        else
                        {
                            // 再搜索四个角,看是否有效,否则直接SIZE为0
                            Vector3 c1 = pt - halfSize;
                            Vector3 c2 = pt - new Vector3(halfSize.x, 0, -halfSize.z);
                            Vector3 c3 = pt + halfSize;
                            Vector3 c4 = pt + new Vector3(halfSize.x, 0, -halfSize.z);

                            if ((!UnityEngine.AI.NavMesh.SamplePosition(c1, out hit, PVSCell.CellSize, int.MaxValue)) &&
                                (!UnityEngine.AI.NavMesh.SamplePosition(c2, out hit, PVSCell.CellSize, int.MaxValue)) &&
                                (!UnityEngine.AI.NavMesh.SamplePosition(c3, out hit, PVSCell.CellSize, int.MaxValue)) &&
                                (!UnityEngine.AI.NavMesh.SamplePosition(c4, out hit, PVSCell.CellSize, int.MaxValue))
                                )
                            {
                                pt = Vector3.zero;
                                m_CellIngoreArray.Add(idx);
                            }
                        }

                        arr [idx] = pt;
                    }
                }

                m_CellArray = arr;



                return;
            }

            var size1 = m_SearchBounds.size;
            int col1  = Mathf.CeilToInt(size1.x / PVSCell.CellSize);
            int row1  = Mathf.CeilToInt(size1.z / PVSCell.CellSize);

            InitPVSMeshes();
            InitCellResults();


            ClearThreads();
            if (m_CheckCellBuffer != null)
            {
                m_CheckCellBuffer.Dispose();
                m_CheckCellBuffer = null;
            }

            if (m_CameraBuffer != null)
            {
                m_CameraBuffer.Dispose();
                m_CameraBuffer = null;
            }

            if (m_BakerMode == PVSSceneBakerMode.CameraRTCpuMode || m_BakerMode == PVSSceneBakerMode.CameraRTComputeMode)
            {
                if (m_PVSCellShader == null)
                {
                    Debug.LogError("PVS烘焙ComputeShader找不到");
                    return;
                }

                PVSCameraRtTrack camRtTrack = new PVSCameraRtTrack();
                camRtTrack.Start(m_TargetCamera, m_CellsResult, m_PVSItemIDS, m_TargetCamInfo.lookAt, m_PVSCellShader, m_BakerMode == PVSSceneBakerMode.CameraRTComputeMode);
                OnCpuThreadDone();
                return;
            }

            if (!SystemInfo.supportsComputeShaders || m_BakerMode == PVSSceneBakerMode.CpuThreadMode)
            {
                if (m_BakerMode == PVSSceneBakerMode.ComputeShaderMode)
                {
                    Debug.LogError("设备不支持ComputeShader");
                }
                // 开启线程模式
                CreateThreadMode();
                return;
            }


            m_CheckCellBuffer = new ComputeBuffer(m_CellArray.Length, Marshal.SizeOf(typeof(Vector3)));
            m_CheckCellBuffer.SetData(m_CellArray);

            m_CameraBuffer = new ComputeBuffer(1, Marshal.SizeOf(typeof(PVSCameraInfo)));
            PVSCameraInfo[] camArr = new PVSCameraInfo[1];
            camArr[0] = m_TargetCamInfo;
            m_CameraBuffer.SetData(camArr);

            if (m_PVSCellShader != null)
            {
                int main = m_PVSCellShader.FindKernel("PVSBaker");
                m_PVSCellShader.SetBuffer(main, "pvsBakerPosArray", m_CheckCellBuffer);
                m_PVSCellShader.SetBuffer(main, "camera", m_CameraBuffer);
                m_PVSCellShader.Dispatch(main, col1, row1, 1);
            }
            else
            {
                Debug.LogError("PVS烘焙ComputeShader找不到");
            }
        }