コード例 #1
0
ファイル: SceneDataSM3.cs プロジェクト: huangdonghai/titan3d
        private unsafe bool FrustumCull(ref Cluster.GpuCluster cluster, ref CBMeshBatch cbMesh)
        {
            Vector3 position = cluster.BoundCenter;
            Vector3 extent   = cluster.BoundExtent;
            Vector3 minPos   = position - extent;
            Vector3 maxPos   = position + extent;

            if (cbMesh.GpuDrivenFrustumMinPoint.X > maxPos.X ||
                cbMesh.GpuDrivenFrustumMinPoint.Y > maxPos.Y ||
                cbMesh.GpuDrivenFrustumMinPoint.Z > maxPos.Z)
            {
                return(true);
            }

            if (cbMesh.GpuDrivenFrustumMaxPoint.X < minPos.X ||
                cbMesh.GpuDrivenFrustumMaxPoint.Y < minPos.Y ||
                cbMesh.GpuDrivenFrustumMaxPoint.Z < minPos.Z)
            {
                return(true);
            }

            fixed(CBMeshBatch *pCBuffer = &cbMesh)
            {
                Vector4 *planes    = (Vector4 *)pCBuffer;
                Vector3  absNormal = new Vector3();

                for (uint i = 0; i < 6; ++i)
                {
                    absNormal.X = (planes->X > 0) ? (planes->X) : (-planes->X);
                    absNormal.Y = (planes->Y > 0) ? (planes->Y) : (-planes->Y);
                    absNormal.Z = (planes->Z > 0) ? (planes->Z) : (-planes->Z);
                    Vector3 *planeNormal = (Vector3 *)planes;
                    float    dist        = Vector3.Dot(position, *planeNormal) + planes->W;
                    float    df          = Vector3.Dot(absNormal, extent);
                    if (dist - df > 0)
                    {
                        return(true);
                    }
                    planes++;
                }
            }

            return(false);
        }
コード例 #2
0
ファイル: SceneDataSM3.cs プロジェクト: huangdonghai/titan3d
        private unsafe void UpdateIndexBufferCPU(CCommandList cmd, Graphics.CGfxCamera Camera)
        {
            if (mCpuDrawIndexBuffer == null)
            {
                return;
            }
            CBMeshBatch cbMesh = new CBMeshBatch();
            {
                var pPlanes = stackalloc Plane[6];
                Camera.CullingFrustum.GetPlanes(pPlanes);
                CBMeshBatch *pCBuffer  = &cbMesh;
                Plane *      planesTar = (Plane *)pCBuffer;
                for (uint i = 0; i < 6; i++)
                {
                    planesTar[i] = pPlanes[i];
                }
                cbMesh.GpuDrivenCameraPosition = Camera.CullingFrustum.TipPos;
                BoundingBox box = new BoundingBox();
                Camera.CullingFrustum.GetBoundBox(ref box);
                cbMesh.GpuDrivenFrustumMinPoint = box.Minimum;
                cbMesh.GpuDrivenFrustumMaxPoint = box.Maximum;
                cbMesh.MeshBatchVertexStride    = (uint)AllVertices.Count;
                cbMesh.ClusterNumber            = (uint)GpuClusters.Count;

                UpdateCBMeshbatch(cmd, Camera);
            }

            UInt32_3 tri = new UInt32_3();

            mDrawIndices.Clear();
            for (int i = 0; i < GpuClusters.Count; i++)
            {
                var cluster = GpuClusters[i];
                var GpuDrivenCameraDirection = GpuClusters[i].BoundCenter - cbMesh.GpuDrivenCameraPosition;
                var cameraDirInBoundSpace    = Vector3.TransposeTransformNormal(GpuDrivenCameraDirection, GpuInstanceDatas[(int)cluster.InstanceId].InvMatrix);
                if (FrustumCull(ref cluster, ref cbMesh) == false)
                {
                    UInt64 visBits = 0;
                    if (cameraDirInBoundSpace.X >= 0)
                    {
                        visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_NX];
                    }
                    else
                    {
                        visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_X];
                    }
                    if (cameraDirInBoundSpace.Y >= 0)
                    {
                        visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_NY];
                    }
                    else
                    {
                        visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_Y];
                    }
                    if (cameraDirInBoundSpace.Z >= 0)
                    {
                        visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_NZ];
                    }
                    else
                    {
                        visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_Z];
                    }

                    uint InstanceStartIndex = cbMesh.MeshBatchVertexStride * cluster.InstanceId;
                    for (int j = 0; j < cluster.FaceCount; j++)
                    {
                        if (TestBit(visBits, j) == false)
                        {
                            continue;
                        }
                        int srcIndex = (int)(cluster.StartFaceIndex + j) * 3;
                        tri.x = InstanceStartIndex + AllIndices[srcIndex];
                        tri.y = InstanceStartIndex + AllIndices[srcIndex + 1];
                        tri.z = InstanceStartIndex + AllIndices[srcIndex + 2];
                        mDrawIndices.Add(tri);
                    }
                }
            }

            mDrawArgs.InstanceCount         = 1;
            mDrawArgs.IndexCountPerInstance = (uint)mDrawIndices.Count * 3;
            uint size = (uint)(mDrawIndices.Count * sizeof(UInt32_3));

            if (mCpuDrawIndexBuffer.Desc.ByteWidth > size)
            {
                mCpuDrawIndexBuffer.UpdateBuffData(cmd, mDrawIndices.GetBufferPtr(), size);
            }
        }