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));
                    }
                }
            }
        }
예제 #2
0
        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;
        }
예제 #3
0
        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;
            }
        }