public void getVisibleNodes(List <SpatialQuadTreeCell> nodes, BFrustum frust) { mRootCell.getLeafChildrenIntersectingFrustum(nodes, frust); }
public void getLeafChildrenIntersectingFrustum(List <SpatialQuadTreeCell> nodes, BFrustum frust) { if (intersectsFrustum(frust)) { if (mChildren != null) { for (uint i = 0; i < (int)eQNKidEnum.cNumQuadTreeKids; i++) { if (mChildren[i] != null) { mChildren[i].getLeafChildrenIntersectingFrustum(nodes, frust); } } } else { nodes.Add(this); } } }
void ChunkMarchAndSend() { // TODO: is this the most efficient it can be? int maxChunks = TheServer.CVars.n_chunkspertick.ValueI; int chunksFound = 0; if (LoadRelPos.IsNaN() || LoadRelDir.IsNaN() || LoadRelDir.LengthSquared() < 0.1f) { return; } Matrix proj = Matrix.CreatePerspectiveFieldOfViewRH(Max_FOV * (double)Utilities.PI180, 1, 0.5f, 3000f); Matrix view = Matrix.CreateLookAtRH((LoadRelPos - LoadRelDir * 8).ToBVector(), (LoadRelPos + LoadRelDir * 8).ToBVector(), new Vector3(0, 0, 1)); Matrix combined = view * proj; BFrustum bfs = new BFrustum(combined); Vector3i start = TheRegion.ChunkLocFor(LoadRelPos); HashSet <Vector3i> seen = new HashSet <Vector3i>(); Queue <Vector3i> toSee = new Queue <Vector3i>(); toSee.Enqueue(start); while (toSee.Count > 0) { Vector3i cur = toSee.Dequeue(); seen.Add(cur); if (Math.Abs(cur.X - start.X) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cur.Y - start.Y) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cur.Z - start.Z) > (ViewRadiusInChunks + ViewRadExtra5Height)) { continue; } if (Math.Abs(cur.X - start.X) <= ViewRadiusInChunks && Math.Abs(cur.Y - start.Y) <= ViewRadiusInChunks && Math.Abs(cur.Z - start.Z) <= ViewRadiusInChunks) { if (TryChunk(cur, 1)) { chunksFound++; if (chunksFound > maxChunks) { return; } } } else if (Math.Abs(cur.X - start.X) <= (ViewRadiusInChunks + ViewRadExtra2) && Math.Abs(cur.Y - start.Y) <= (ViewRadiusInChunks + ViewRadExtra2) && Math.Abs(cur.Z - start.Z) <= (ViewRadiusInChunks + ViewRadExtra2Height)) { if (TryChunk(cur, 2)) { chunksFound++; if (chunksFound > maxChunks) { return; } } } else { if (TryChunk(cur, 5)) { chunksFound++; if (chunksFound > maxChunks) { return; } } } for (int i = 0; i < MoveDirs.Length; i++) { Vector3i t = cur + MoveDirs[i]; if (!seen.Contains(t) && !toSee.Contains(t)) { //toSee.Enqueue(t); for (int j = 0; j < MoveDirs.Length; j++) { if (Vector3.Dot(MoveDirs[j].ToVector3(), LoadRelDir.ToBVector()) < -0.8f) // TODO: Wut? { continue; } Vector3i nt = cur + MoveDirs[j]; if (!seen.Contains(nt) && !toSee.Contains(nt)) { bool val = false; Chunk ch = TheRegion.GetChunk(t); if (ch == null) { val = true; } // TODO: Oh, come on! else if (MoveDirs[i].X == -1) { if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.XP_XM]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.XP_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.XP_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_XP]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_XP]; } } else if (MoveDirs[i].X == 1) { if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.XP_XM]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.XM_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.XM_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_XM]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_XM]; } } else if (MoveDirs[i].Y == -1) { if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.YP_YM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.XM_YP]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.XP_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_YP]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_YP]; } } else if (MoveDirs[i].Y == 1) { if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.YP_YM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.XM_YP]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.XP_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_YP]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_YP]; } } else if (MoveDirs[i].Z == -1) { if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_ZM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.ZP_XM]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_XP]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.ZP_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_YP]; } } else if (MoveDirs[i].Z == 1) { if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZP_ZM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_XM]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.ZM_XP]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.ZM_YP]; } } if (val) { Location min = nt.ToLocation() * Chunk.CHUNK_SIZE; if (bfs.ContainsBox(min, min + new Location(Chunk.CHUNK_SIZE))) { toSee.Enqueue(nt); } else { seen.Add(nt); } } } } } } } }
public bool intersectsFrustum(BFrustum frust) { return(frust.AABBVisible(mAABBMin.toVec3(), mAABBMax.toVec3())); }
void ChunkMarchAndSend() { // TODO: is this the most efficient it can be? int maxChunks = TheServer.CVars.n_chunkspertick.ValueI; int chunksFound = 0; if (LoadRelPos.IsNaN() || LoadRelDir.IsNaN() || LoadRelDir.LengthSquared() < 0.1f) { return; } Matrix proj = Matrix.CreatePerspectiveFieldOfViewRH(Max_FOV * (double)Utilities.PI180, 1, 0.5f, 3000f); Matrix view = Matrix.CreateLookAtRH((LoadRelPos - LoadRelDir * 8).ToBVector(), (LoadRelPos + LoadRelDir * 8).ToBVector(), new Vector3(0, 0, 1)); Matrix combined = view * proj; BFrustum bfs = new BFrustum(combined); Vector3i start = TheRegion.ChunkLocFor(LoadRelPos); HashSet<Vector3i> seen = new HashSet<Vector3i>(); Queue<Vector3i> toSee = new Queue<Vector3i>(); toSee.Enqueue(start); while (toSee.Count > 0) { Vector3i cur = toSee.Dequeue(); seen.Add(cur); if (Math.Abs(cur.X - start.X) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cur.Y - start.Y) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cur.Z - start.Z) > (ViewRadiusInChunks + ViewRadExtra5Height)) { continue; } if (Math.Abs(cur.X - start.X) <= ViewRadiusInChunks && Math.Abs(cur.Y - start.Y) <= ViewRadiusInChunks && Math.Abs(cur.Z - start.Z) <= ViewRadiusInChunks) { if (TryChunk(cur, 1)) { chunksFound++; if (chunksFound > maxChunks) { return; } } } else if (Math.Abs(cur.X - start.X) <= (ViewRadiusInChunks + ViewRadExtra2) && Math.Abs(cur.Y - start.Y) <= (ViewRadiusInChunks + ViewRadExtra2) && Math.Abs(cur.Z - start.Z) <= (ViewRadiusInChunks + ViewRadExtra2Height)) { if (TryChunk(cur, 2)) { chunksFound++; if (chunksFound > maxChunks) { return; } } } else { if (TryChunk(cur, 5)) { chunksFound++; if (chunksFound > maxChunks) { return; } } } for (int i = 0; i < MoveDirs.Length; i++) { Vector3i t = cur + MoveDirs[i]; if (!seen.Contains(t) && !toSee.Contains(t)) { //toSee.Enqueue(t); for (int j = 0; j < MoveDirs.Length; j++) { if (Vector3.Dot(MoveDirs[j].ToVector3(), LoadRelDir.ToBVector()) < -0.8f) // TODO: Wut? { continue; } Vector3i nt = cur + MoveDirs[j]; if (!seen.Contains(nt) && !toSee.Contains(nt)) { bool val = false; Chunk ch = TheRegion.GetChunk(t); if (ch == null) { val = true; } // TODO: Oh, come on! else if (MoveDirs[i].X == -1) { if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.XP_XM]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.XP_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.XP_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_XP]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_XP]; } } else if (MoveDirs[i].X == 1) { if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.XP_XM]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.XM_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.XM_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_XM]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_XM]; } } else if (MoveDirs[i].Y == -1) { if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.YP_YM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.XM_YP]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.XP_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_YP]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_YP]; } } else if (MoveDirs[i].Y == 1) { if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.YP_YM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.XM_YP]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.XP_YP]; } else if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_YP]; } else if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_YP]; } } else if (MoveDirs[i].Z == -1) { if (MoveDirs[j].Z == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_ZM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.ZP_XM]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_XP]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.ZP_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.ZP_YP]; } } else if (MoveDirs[i].Z == 1) { if (MoveDirs[j].Z == -1) { val = ch.Reachability[(int)ChunkReachability.ZP_ZM]; } else if (MoveDirs[j].X == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_XM]; } else if (MoveDirs[j].X == 1) { val = ch.Reachability[(int)ChunkReachability.ZM_XP]; } else if (MoveDirs[j].Y == -1) { val = ch.Reachability[(int)ChunkReachability.ZM_YM]; } else if (MoveDirs[j].Y == 1) { val = ch.Reachability[(int)ChunkReachability.ZM_YP]; } } if (val) { Location min = nt.ToLocation() * Chunk.CHUNK_SIZE; if (bfs.ContainsBox(min, min + new Location(Chunk.CHUNK_SIZE))) { toSee.Enqueue(nt); } else { seen.Add(nt); } } } } } } } }