Exemplo n.º 1
0
    List <TTexturePointBlockAndScore> GetRenderInstances(bool AddCulledBlocks)
    {
        var TexturePointBlocks = GetComponent <TexturePointBlockCache> ();
        var AllBlocks          = TexturePointBlocks.Blocks;

        var FilteredBlocks = new List <TTexturePointBlockAndScore>();

        //	sort, cull etc
        if (OnRenderFilter != null && OnRenderFilter.GetPersistentEventCount() > 0)
        {
            OnRenderFilter.Invoke(AllBlocks, AddCulledBlocks, FilteredBlocks);
        }
        else
        {
            foreach (var Block in AllBlocks)
            {
                var ScoredBlock = new TTexturePointBlockAndScore();
                ScoredBlock.Block = Block;
                FilteredBlocks.Add(ScoredBlock);
            }
        }

        return(FilteredBlocks);
    }
Exemplo n.º 2
0
    public void CullBlocks(List <TTexturePointBlock> AllBlocks, bool AddCulledBlocks, List <TTexturePointBlockAndScore> FilteredBlocks)
    {
        //	render everything if disabled
        if (!enabled)
        {
            foreach (var Block in AllBlocks)
            {
                var BlockScored = new TTexturePointBlockAndScore();
                BlockScored.Block = Block;
                FilteredBlocks.Add(BlockScored);
            }
            return;
        }

        var   Cam           = CullCamera;
        var   CameraPos     = Cam.transform.position;
        var   CameraForward = Cam.transform.localToWorldMatrix.MultiplyVector(Vector3.forward);
        float RestoreFov    = Cam.fieldOfView;

        if (OverrideFov > 0)
        {
            Cam.fieldOfView = OverrideFov;
        }
        var FrustumPlanes = GeometryUtility.CalculateFrustumPlanes(Cam);

        Cam.fieldOfView = RestoreFov;

        var CullDistanceNearSq = CullDistanceNear * CullDistanceNear;
        var CullDistanceFarSq  = CullDistanceFar * CullDistanceFar;


        if (RenderSpecificInstance != -1)
        {
            if (RenderSpecificInstance < AllBlocks.Count)
            {
                var InstanceScored = new TTexturePointBlockAndScore();
                InstanceScored.Block = AllBlocks [RenderSpecificInstance];

                InstanceScored.FrustumVisible = GeometryUtility.TestPlanesAABB(FrustumPlanes, InstanceScored.Block.BoundingBox);

                FilteredBlocks.Add(InstanceScored);
            }
            return;
        }



        foreach (var Block in AllBlocks)
        {
            var InstanceScored = new TTexturePointBlockAndScore();
            InstanceScored.Block = Block;
            Block.Lod            = Lod;

            var Box = Block.BoundingBox;


            //var InstancePos = Box.center;
            var InstancePos = Box.ClosestPoint(CameraPos);
            InstanceScored.DistanceSq = PopMath.Vector3_DistanceSquared(InstancePos, CameraPos);

            if (LodToDistance)
            {
                var Distance        = Mathf.Sqrt(InstanceScored.DistanceSq);
                var CullDistanceFar = Mathf.Sqrt(CullDistanceFarSq);
                Block.Lod = 1 - (Distance / CullDistanceFar);
                if (Distance <= LodDistanceMin)
                {
                    Block.Lod = 1;
                }
                Block.Lod *= Lod;
            }
            else if (LodToDistanceSquared)
            {
                var Distance        = InstanceScored.DistanceSq;
                var CullDistanceFar = CullDistanceFarSq;
                Block.Lod = 1 - (Distance / CullDistanceFar);
                if (Distance <= (LodDistanceMin * LodDistanceMin))
                {
                    Block.Lod = 1;
                }
                Block.Lod *= Lod;
            }

            InstanceScored.DistanceVisible = true;
            if (InstanceScored.DistanceSq > CullDistanceFarSq)
            {
                InstanceScored.DistanceVisible = false;
            }
            if (InstanceScored.DistanceSq < CullDistanceNearSq)
            {
                InstanceScored.DistanceVisible = false;
            }

            if (CullByDistance && !AddCulledBlocks && !InstanceScored.DistanceVisible)
            {
                continue;
            }

            var InstanceForward = InstancePos - CameraPos;
            InstanceForward.Normalize();
            InstanceScored.DotToCamera = Vector3.Dot(InstanceForward, CameraForward);

            InstanceScored.FrustumVisible = GeometryUtility.TestPlanesAABB(FrustumPlanes, Box);
            if (CullByFrustum && !AddCulledBlocks && !InstanceScored.FrustumVisible)
            {
                continue;
            }

            FilteredBlocks.Add(InstanceScored);
        }

        FilteredBlocks.Sort((a, b) => {
            if (FrustumDotRanges > 0)
            {
                var Dota = (int)(a.DotToCamera * FrustumDotRanges);
                var Dotb = (int)(b.DotToCamera * FrustumDotRanges);

                if (Dota > Dotb)
                {
                    return(-1);
                }
                if (Dota > Dotb)
                {
                    return(1);
                }
            }
            else
            {
                if (a.DotToCamera > b.DotToCamera)
                {
                    return(-1);
                }
                if (a.DotToCamera < b.DotToCamera)
                {
                    return(1);
                }
            }

            if (a.DistanceSq < b.DistanceSq)
            {
                return(-1);
            }
            if (a.DistanceSq > b.DistanceSq)
            {
                return(1);
            }

            return(0);
        }
                            );

        if (!AddCulledBlocks)
        {
            //	now clip
            if (FilteredBlocks.Count > MaxInstances)
            {
                FilteredBlocks.RemoveRange(MaxInstances, FilteredBlocks.Count - MaxInstances);
            }

            int TotalTriangles = 0;
            for (int i = 0; i < FilteredBlocks.Count; i++)
            {
                var InstanceTriangleCount = FilteredBlocks [i].Block.LodPointCount;

                if (LodToMaxTriangles)
                {
                }
                else
                {
                    //	clip
                    if (TotalTriangles + InstanceTriangleCount > MaxTriangles)
                    {
                        FilteredBlocks.RemoveRange(i, FilteredBlocks.Count - i);
                        break;
                    }
                }

                TotalTriangles += InstanceTriangleCount;
            }

            int LodToMaxTriangles_TriangleCount = 0;

            if (TotalTriangles > MaxTriangles && LodToMaxTriangles)
            {
                //	scale down all the LOD's to fit max triangles
                float LodScale = MaxTriangles / (float)TotalTriangles;
                                #if UNITY_EDITOR
                if (EnableDebug)
                {
                    Debug.Log("LodScale=" + LodScale);
                }
                                #endif

                foreach (var Block in FilteredBlocks)
                {
                    var OldTriangleCount = Block.Block.LodPointCount;
                    Block.Block.Lod *= LodScale;
                    var NewTriangleCount = Block.Block.LodPointCount;
                    LodToMaxTriangles_TriangleCount += NewTriangleCount;
                }
            }

                        #if UNITY_EDITOR
            if (EnableDebug)
            {
                Debug.Log("Total triangles=" + TotalTriangles + " (lod'd to " + LodToMaxTriangles_TriangleCount + ") total blocks=" + FilteredBlocks.Count);
            }
                        #endif
        }
    }