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); }
public void AddMeshInstance(CRenderContext rc, Graphics.Mesh.CGfxMesh mesh, RName clusterName, GamePlay.Component.GPlacementComponent placement) { var worldMatrix = placement.WorldMatrix; uint instStart = (uint)mGpuInstanceDatas.Count; for (int i = 0; i < mesh.MtlMeshArray.Length; i++) { var data = new GpuMeshInstanceData(); data.VTMaterialId.x = 1;//(uint)GetOrAddMaterialId(mesh.MtlMeshArray[i].MtlInst); data.Matrix = worldMatrix; Matrix.Invert(ref data.Matrix, out data.InvMatrix); data.Matrix.Transpose(); data.InvMatrix.Transpose(); mGpuInstanceDatas.Add(data); //var module = CEngine.Instance.GetCurrentModule(); //module.World.AddActor(); } uint indexOffset; Cluster.ClusteredMesh cluster = GetClusteredMesh(rc, clusterName, out indexOffset); for (int i = 0; i < cluster.ClusterDatas.Count; i++) { Cluster.GpuCluster gpuCluster = cluster.ClusterDatas[i]; gpuCluster.InstanceId += instStart; gpuCluster.StartFaceIndex += indexOffset / 3; BoundingBox tmpBox = new BoundingBox(gpuCluster.BoundCenter - gpuCluster.BoundExtent, gpuCluster.BoundCenter + gpuCluster.BoundExtent); tmpBox = BoundingBox.Transform(ref tmpBox, ref worldMatrix); gpuCluster.BoundCenter = tmpBox.GetCenter(); gpuCluster.BoundExtent = tmpBox.GetSize() * 0.5f; mGpuClusters.Add(gpuCluster); } }