void CalculateAsteroidsTask() { cubeCount = 0; Vector3 position; BoundingFrustum frustum; lock (_camera) { position = _camera.Position; frustum = _camera.Frustum; } var close = AsteroidFieldShared.GetCloseCube(cameraPos, field.CubeSize); int amountCubes = (int)Math.Floor((field.FillDist / field.CubeSize)) + 1; for (int x = -amountCubes; x <= amountCubes; x++) { for (int y = -amountCubes; y <= amountCubes; y++) { for (int z = -amountCubes; z <= amountCubes; z++) { var center = close + new Vector3(x, y, z) * field.CubeSize; var closestDistance = (Vector3.Distance(center, position) - cubeRadius); if (closestDistance >= field.FillDist || closestDistance >= lastFog) { continue; } if (!field.Zone.Shape.ContainsPoint(center)) { continue; } var cubeSphere = new BoundingSphere(center, cubeRadius); if (!frustum.Intersects(cubeSphere)) { continue; } float tval; if (!AsteroidFieldShared.CubeExists(center, field.EmptyCubeFrequency, out tval)) { continue; } if (GetExclusionZone(center) != null) { continue; } cubes[cubeCount++] = new CalculatedCube(center, field.CubeRotation.GetRotation(tval) * Matrix4x4.CreateTranslation(center)); } } } }
void CalculateAsteroids() { Vector3 position; BoundingFrustum frustum; lock (_camera) { position = _camera.Position; frustum = _camera.Frustum; } ZfrustumCulled = ZexistCulled = ZexcludeCulled = ZshapeCulled = 0; var close = AsteroidFieldShared.GetCloseCube(cameraPos, field.CubeSize); var cubeRad = new Vector3(field.CubeSize) * 0.5f; int amountCubes = (int)Math.Floor((field.FillDist / field.CubeSize)) + 1; for (int x = -amountCubes; x <= amountCubes; x++) { for (int y = -amountCubes; y <= amountCubes; y++) { for (int z = -amountCubes; z <= amountCubes; z++) { var center = close + new Vector3(x * field.CubeSize, y * field.CubeSize, z * field.CubeSize); if (!field.Zone.Shape.ContainsPoint(center)) { continue; } //var cubeBox = new BoundingBox(center - cubeRad, center + cubeRad); //if (!frustum.Intersects(cubeBox)) //continue; var cubeSphere = new BoundingSphere(center, field.CubeSize * 0.5f); if (!frustum.Intersects(cubeSphere)) { continue; } float tval; if (!AsteroidFieldShared.CubeExists(center, field.EmptyCubeFrequency, out tval)) { continue; } if (GetExclusionZone(center) != null) { continue; } cubes[cubeCount++] = new CalculatedCube(center, Matrix4.CreateTranslation(center) * field.CubeRotation.GetRotation(tval)); } } } _asteroidsCalculated = true; }
public override void FixedUpdate(TimeSpan time) { var world = Parent.GetWorld(); var player = world.GetObject("player"); if (player == null) { return; } if (VectorMath.DistanceSquared(player.PhysicsComponent.Body.Position, Field.Zone.Position) > activateDist) { return; } var cds = (Field.CubeSize + COLLIDE_DISTANCE); cds *= cds; for (int i = bodies.Count - 1; i >= 0; i--) { var distance = VectorMath.DistanceSquared(player.PhysicsComponent.Body.Position, bodies[i].Position); if (distance > cds) { world.Physics.RemoveObject(bodies[i]); bodies.RemoveAt(i); } } var close = AsteroidFieldShared.GetCloseCube(player.PhysicsComponent.Body.Position, Field.CubeSize); var cubeRad = new Vector3(Field.CubeSize) * 0.5f; int amountCubes = (int)Math.Floor((COLLIDE_DISTANCE / Field.CubeSize)) + 1; for (int x = -amountCubes; x <= amountCubes; x++) { for (int y = -amountCubes; y <= amountCubes; y++) { for (int z = -amountCubes; z <= amountCubes; z++) { var center = close + new Vector3(x * Field.CubeSize, y * Field.CubeSize, z * Field.CubeSize); if (!Field.Zone.Shape.ContainsPoint(center)) { continue; } if (VectorMath.DistanceSquared(player.PhysicsComponent.Body.Position, center) > cds) { continue; } float tval; if (!AsteroidFieldShared.CubeExists(center, Field.EmptyCubeFrequency, out tval)) { continue; } if (GetExclusionZone(center) != null) { continue; } bool create = true; for (int i = 0; i < bodies.Count; i++) { if ((bodies[i].Position - center).LengthFast < 3) { create = false; break; } } if (create) { var transform = Field.CubeRotation.GetRotation(tval) * Matrix4.CreateTranslation(center); var body = phys.AddStaticObject(transform, shape); bodies.Add(body); } } } } }
void CalculateBillboards() { Vector3 position; BoundingFrustum frustum; billboardCount = 0; lock (_camera) { position = _camera.Position; frustum = _camera.Frustum; } var close = AsteroidFieldShared.GetCloseCube(cameraPos, field.FillDist * 2); var checkRad = field.FillDist + field.BillboardSize.Y; int checkCount = 0; for (var x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { var center = close + new Vector3(x, y, z) * (field.FillDist * 2); //early bail for billboards too far if (Vector3.Distance(position, center) - checkRad > field.FillDist) { continue; } //bail billboards outside of zone - avoids popping if (field.Zone.Shape.ScaledDistance(center) > 1.1f) { continue; } //rotate var rotation = AsteroidCubeRotation.Default.GetRotation(AsteroidFieldShared.PositionHash(center)); for (int i = 0; i < billboardCube.Length; i++) { var spritepos = center + Vector3.Transform(billboardCube[i].Position, rotation); //cull individual billboards too far if (Vector3.Distance(position, spritepos) > field.FillDist) { continue; } billboardBuffer[checkCount] = billboardCube[i]; billboardBuffer[checkCount].Position = spritepos; billboardBuffer[checkCount++].Distance = Vector3.DistanceSquared(center, cameraPos); } } } } //Highly unlikely this check will succeed. If it does there's something wrong with the cube code if (checkCount > field.BillboardCount) { if (!warnedTooManyBillboards) { warnedTooManyBillboards = true; FLLog.Warning("Asteroids", "Too many billboards in sort task for field " + field.Zone.Nickname); } Array.Sort(billboardBuffer, 0, checkCount); //Get closest checkCount = field.BillboardCount; } //Cull ones that aren't on screen for (int i = 0; i < checkCount; i++) { var billboard = billboardBuffer[i]; var sphere = new BoundingSphere(billboard.Position, billboard.Size * 1.5f); if (!frustum.Intersects(sphere)) { continue; } calculatedBillboards[billboardCount++] = billboard; } }