public void PositionCompositionTest()
        {
            // Arrange
            var node1 = EntityManager.SpawnEntity("dummy");
            var node2 = EntityManager.SpawnEntity("dummy");
            var node3 = EntityManager.SpawnEntity("dummy");
            var node4 = EntityManager.SpawnEntity("dummy");

            var node1Trans = node1.GetComponent <IServerTransformComponent>();
            var node2Trans = node2.GetComponent <IServerTransformComponent>();
            var node3Trans = node3.GetComponent <IServerTransformComponent>();
            var node4Trans = node4.GetComponent <IServerTransformComponent>();

            node1Trans.WorldPosition = new Vector2(0, 0);
            node2Trans.WorldPosition = new Vector2(1, 1);
            node3Trans.WorldPosition = new Vector2(2, 2);
            node4Trans.WorldPosition = new Vector2(0, 2);

            node2Trans.AttachParent(node1Trans);
            node3Trans.AttachParent(node2Trans);
            node4Trans.AttachParent(node3Trans);

            //Act
            node1Trans.LocalRotation = new Angle(MathHelper.Pi / 2);

            //Assert
            var result = node4Trans.WorldPosition;

            Assert.That(FloatMath.CloseTo(result.X, -2), result.ToString);
            Assert.That(FloatMath.CloseTo(result.Y, 0), result.ToString);
        }
        public IEnumerable <IEntity> GetEntitiesIntersecting(MapId mapId, Vector2 position)
        {
            foreach (var entity in GetEntities())
            {
                var transform = entity.Transform;
                if (transform.MapID != mapId)
                {
                    continue;
                }

                if (entity.TryGetComponent <BoundingBoxComponent>(out var component))
                {
                    if (component.WorldAABB.Contains(position))
                    {
                        yield return(entity);
                    }
                }
                else
                {
                    if (FloatMath.CloseTo(transform.GridPosition.X, position.X) && FloatMath.CloseTo(transform.GridPosition.Y, position.Y))
                    {
                        yield return(entity);
                    }
                }
            }
        }
            protected override void Update(FrameEventArgs args)
            {
                base.Update(args);

                _timer += args.DeltaSeconds;
                _timer %= TimerCycle;

                var charge = _parent.Charge ?? 0;

                int level;

                if (FloatMath.CloseTo(charge, 0))
                {
                    level = 0;
                }
                else
                {
                    level = 1 + (int)MathF.Round(charge * 6);
                }

                if (level == 1)
                {
                    // Flash the last light.
                    _sections[0].PanelOverride = _timer > TimerCycle / 2 ? _styleBoxLit : _styleBoxUnlit;
                }
                else
                {
                    _sections[0].PanelOverride = level > 2 ? _styleBoxLit : _styleBoxUnlit;
                }

                _sections[1].PanelOverride = level > 3 ? _styleBoxLit : _styleBoxUnlit;
                _sections[2].PanelOverride = level > 4 ? _styleBoxLit : _styleBoxUnlit;
                _sections[3].PanelOverride = level > 5 ? _styleBoxLit : _styleBoxUnlit;
                _sections[4].PanelOverride = level > 6 ? _styleBoxLit : _styleBoxUnlit;
            }
Exemple #4
0
        /// <inheritdoc />
        public IEnumerable <IEntity> GetEntitiesIntersecting(MapId mapId, Vector2 position, bool approximate = false)
        {
            const float range = .00001f / 2;
            var         aabb  = new Box2(position, position).Enlarged(range);

            if (mapId == MapId.Nullspace)
            {
                yield break;
            }

            var newResults = _entityTreesPerMap[mapId].Query(aabb, approximate);


            foreach (var entity in newResults)
            {
                if (entity.TryGetComponent(out ICollidableComponent component))
                {
                    if (component.WorldAABB.Contains(position))
                    {
                        yield return(entity);
                    }
                }
                else
                {
                    var transform = entity.Transform;
                    var entPos    = transform.WorldPosition;
                    if (FloatMath.CloseTo(entPos.X, position.X) &&
                        FloatMath.CloseTo(entPos.Y, position.Y))
                    {
                        yield return(entity);
                    }
                }
            }
        }
        public void ParentWorldPositionRoundingErrorTest()
        {
            // Arrange
            var node1 = EntityManager.SpawnEntity("dummy");
            var node2 = EntityManager.SpawnEntity("dummy");
            var node3 = EntityManager.SpawnEntity("dummy");

            var node1Trans = node1.GetComponent <IServerTransformComponent>();
            var node2Trans = node2.GetComponent <IServerTransformComponent>();
            var node3Trans = node3.GetComponent <IServerTransformComponent>();

            node1Trans.WorldPosition = new Vector2(0, 0);
            node2Trans.WorldPosition = new Vector2(1, 1);
            node3Trans.WorldPosition = new Vector2(2, 2);

            node2Trans.AttachParent(node1Trans);
            node3Trans.AttachParent(node2Trans);

            // Act
            var oldWpos = node3Trans.WorldPosition;

            for (var i = 0; i < 10000; i++)
            {
                var dx = i % 2 == 0 ? 5 : -5;
                node1Trans.WorldPosition += new Vector2(dx, dx);
                node2Trans.WorldPosition += new Vector2(dx, dx);
                node3Trans.WorldPosition += new Vector2(dx, dx);
            }

            var newWpos = node3Trans.WorldPosition;

            // Assert
            Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y), newWpos.ToString);
            Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y), newWpos.ToString);
        }
Exemple #6
0
 public IEnumerable <IEntity> GetEntitiesAt(Vector2 position)
 {
     foreach (var entity in GetEntities())
     {
         var transform = entity.GetComponent <ITransformComponent>();
         if (FloatMath.CloseTo(transform.LocalPosition.X, position.X) && FloatMath.CloseTo(transform.LocalPosition.Y, position.Y))
         {
             yield return(entity);
         }
     }
 }
 public IEnumerable <IEntity> GetEntitiesAt(Vector2 position)
 {
     foreach (var entity in GetEntities())
     {
         var transform = entity.Transform;
         if (FloatMath.CloseTo(transform.GridPosition.X, position.X) && FloatMath.CloseTo(transform.GridPosition.Y, position.Y))
         {
             yield return(entity);
         }
     }
 }
Exemple #8
0
 public IEnumerable <IEntity> GetEntitiesAt(MapId mapId, Vector2 position)
 {
     foreach (var entity in _entityTreesPerMap[mapId].Query(position))
     {
         var transform = entity.Transform;
         if (FloatMath.CloseTo(transform.GridPosition.X, position.X) && FloatMath.CloseTo(transform.GridPosition.Y, position.Y))
         {
             yield return(entity);
         }
     }
 }
Exemple #9
0
        protected internal override void MouseWheel(GUIMouseWheelEventArgs args)
        {
            base.MouseWheel(args);

            if (FloatMath.CloseTo(0, args.Delta.Y))
            {
                return;
            }

            _scrollBar.Value -= _getScrollSpeed() * args.Delta.Y;
            _isAtBottom       = _scrollBar.IsAtEnd;
        }
        public void ParentRotationRoundingErrorTest()
        {
            IoCManager.Resolve <IGameTiming>().InSimulation = true;

            // Arrange
            var node1 = EntityManager.SpawnEntity("dummy", InitialPos);
            var node2 = EntityManager.SpawnEntity("dummy", InitialPos);
            var node3 = EntityManager.SpawnEntity("dummy", InitialPos);

            var node1Trans = node1.Transform;
            var node2Trans = node2.Transform;
            var node3Trans = node3.Transform;

            node1Trans.WorldPosition = new Vector2(0, 0);
            node2Trans.WorldPosition = new Vector2(1, 1);
            node3Trans.WorldPosition = new Vector2(2, 2);

            node2Trans.AttachParent(node1Trans);
            node3Trans.AttachParent(node2Trans);

            // Act
            var oldWpos = node3Trans.WorldPosition;

            for (var i = 0; i < 100; i++)
            {
                node1Trans.LocalRotation += new Angle(MathHelper.Pi);
                node2Trans.LocalRotation += new Angle(MathHelper.Pi);
                node3Trans.LocalRotation += new Angle(MathHelper.Pi);
            }

            var newWpos = node3Trans.WorldPosition;

            //NOTE: Yes, this does cause a non-zero error

            // Assert

            Assert.Multiple(() =>
            {
                Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y));
                Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y));
            });
        }
Exemple #11
0
        protected override void FrameUpdate(FrameEventArgs args)
        {
            base.FrameUpdate(args);

            _timeLeft -= args.DeltaSeconds;

            if (_timeLeft <= FadeTime)
            {
                // Update alpha if we're fading.
                Modulate = Color.White.WithAlpha(_timeLeft / FadeTime);
            }

            if (_senderEntity.Deleted || _timeLeft <= 0)
            {
                // Timer spawn to prevent concurrent modification exception.
                Timer.Spawn(0, Die);
                return;
            }

            // Lerp to our new vertical offset if it's been modified.
            if (FloatMath.CloseTo(_verticalOffsetAchieved - VerticalOffset, 0, 0.1))
            {
                _verticalOffsetAchieved = VerticalOffset;
            }
            else
            {
                _verticalOffsetAchieved = FloatMath.Lerp(_verticalOffsetAchieved, VerticalOffset, 10 * args.DeltaSeconds);
            }

            var worldPos = _senderEntity.Transform.WorldPosition;

            worldPos += (0, EntityVerticalOffset);

            var lowerCenter = _eyeManager.WorldToScreen(worldPos) / UIScale;
            var screenPos   = lowerCenter - (Width / 2, ContentHeight + _verticalOffsetAchieved);

            LayoutContainer.SetPosition(this, screenPos);

            var height = FloatMath.Clamp(lowerCenter.Y - screenPos.Y, 0, ContentHeight);

            LayoutContainer.SetSize(this, (Size.X, height));
        }
        public override void FrameUpdate(float frameTime)
        {
            var currentEye  = _eyeManager.CurrentEye;
            var inputSystem = EntitySystemManager.GetEntitySystem <InputSystem>();

            var direction = 0;

            if (inputSystem.CmdStates[EngineKeyFunctions.CameraRotateRight] == BoundKeyState.Down)
            {
                direction += 1;
            }

            if (inputSystem.CmdStates[EngineKeyFunctions.CameraRotateLeft] == BoundKeyState.Down)
            {
                direction -= 1;
            }

            // apply camera rotation
            if (direction != 0)
            {
                currentEye.Rotation += CameraRotateSpeed * frameTime * direction;
                currentEye.Rotation  = currentEye.Rotation.Reduced();
            }
            else
            {
                // snap to cardinal directions
                var closestDir = currentEye.Rotation.GetCardinalDir().ToVec();
                var currentDir = currentEye.Rotation.ToVec();

                var dot = Vector2.Dot(closestDir, currentDir);
                if (FloatMath.CloseTo(dot, 1, CameraSnapTolerance))
                {
                    currentEye.Rotation = closestDir.ToAngle();
                }
            }

            foreach (var entity in RelevantEntities)
            {
                var eyeComp = entity.GetComponent <EyeComponent>();
                eyeComp.UpdateEyePosition();
            }
        }
        public void ParentTransRotateTest()
        {
            // Arrange
            var parent      = EntityManager.SpawnEntity("dummy");
            var child       = EntityManager.SpawnEntity("dummy");
            var parentTrans = parent.GetComponent <IServerTransformComponent>();
            var childTrans  = child.GetComponent <IServerTransformComponent>();

            parentTrans.WorldPosition = new Vector2(1, 1);
            childTrans.WorldPosition  = new Vector2(2, 1);
            childTrans.AttachParent(parentTrans);

            //Act
            parentTrans.LocalRotation = new Angle(MathHelper.Pi / 2);

            //Assert
            var result = childTrans.WorldPosition;

            Assert.That(FloatMath.CloseTo(result.X, 1), result.ToString);
            Assert.That(FloatMath.CloseTo(result.Y, 2), result.ToString);
        }
        public void ParentRotateTest()
        {
            // Arrange
            var parent      = EntityManager.SpawnEntity("dummy", InitialPos);
            var child       = EntityManager.SpawnEntity("dummy", InitialPos);
            var parentTrans = parent.Transform;
            var childTrans  = child.Transform;

            parentTrans.WorldPosition = new Vector2(0, 0);
            childTrans.WorldPosition  = new Vector2(2, 0);
            childTrans.AttachParent(parentTrans);

            //Act
            parentTrans.LocalRotation = new Angle(MathHelper.Pi / 2);

            //Assert
            var result = childTrans.WorldPosition;

            Assert.That(FloatMath.CloseTo(result.X, 0), result.ToString);
            Assert.That(FloatMath.CloseTo(result.Y, 2), result.ToString);
        }
 public IEnumerable <IEntity> GetEntitiesIntersecting(Vector2 position)
 {
     foreach (var entity in GetEntities())
     {
         if (entity.TryGetComponent <BoundingBoxComponent>(out var component))
         {
             if (component.WorldAABB.Contains(position))
             {
                 yield return(entity);
             }
         }
         else
         {
             var transform = entity.GetComponent <ITransformComponent>();
             if (FloatMath.CloseTo(transform.LocalPosition.X, position.X) && FloatMath.CloseTo(transform.LocalPosition.Y, position.Y))
             {
                 yield return(entity);
             }
         }
     }
 }
        public void ParentRotationRoundingErrorTest()
        {
            // Arrange
            var node1 = EntityManager.SpawnEntity("dummy");
            var node2 = EntityManager.SpawnEntity("dummy");
            var node3 = EntityManager.SpawnEntity("dummy");

            var node1Trans = node1.GetComponent <IServerTransformComponent>();
            var node2Trans = node2.GetComponent <IServerTransformComponent>();
            var node3Trans = node3.GetComponent <IServerTransformComponent>();

            node1Trans.WorldPosition = new Vector2(0, 0);
            node2Trans.WorldPosition = new Vector2(1, 1);
            node3Trans.WorldPosition = new Vector2(2, 2);

            node2Trans.AttachParent(node1Trans);
            node3Trans.AttachParent(node2Trans);

            // Act
            var oldWpos = node3Trans.WorldPosition;

            for (var i = 0; i < 100; i++)
            {
                node1Trans.LocalRotation += new Angle(MathHelper.Pi);
                node2Trans.LocalRotation += new Angle(MathHelper.Pi);
                node3Trans.LocalRotation += new Angle(MathHelper.Pi);
            }

            var newWpos = node3Trans.WorldPosition;

            //NOTE: Yes, this does cause a non-zero error

            // Assert
            Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y), newWpos.ToString);
            Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y), newWpos.ToString);
        }
        public override ConstraintResult ApplyTo <TActual>(TActual actual)
        {
            if (!(Expected is IApproxEquatable <TActual> equatable))
            {
                if (Expected is float f1 && actual is float f2)
                {
                    if (Tolerance != null)
                    {
                        return(new ConstraintResult(this, actual, FloatMath.CloseTo(f1, f2, Tolerance.Value)));
                    }

                    return(new ConstraintResult(this, actual, FloatMath.CloseTo(f1, f2)));
                }

                if (Expected is double d1 && actual is float d2)
                {
                    if (Tolerance != null)
                    {
                        return(new ConstraintResult(this, actual, FloatMath.CloseTo(d1, d2, Tolerance.Value)));
                    }

                    return(new ConstraintResult(this, actual, FloatMath.CloseTo(d1, d2)));
                }

                return(new ConstraintResult(this, actual, false));
            }

            if (Tolerance != null)
            {
                return(new ConstraintResult(this, actual, equatable.EqualsApprox(actual, Tolerance.Value)));
            }
            else
            {
                return(new ConstraintResult(this, actual, equatable.EqualsApprox(actual)));
            }
        }
        private void DrawLightsAndFov(Box2 worldBounds, IEye eye)
        {
            if (!_lightManager.Enabled)
            {
                return;
            }

            var map = eye.Position.MapId;

            var(lights, expandedBounds) = GetLightsToRender(map, worldBounds);

            UpdateOcclusionGeometry(map, expandedBounds, eye.Position.Position);

            DrawFov(eye);

            var shadowMatrices = new Matrix4[lights.Count];

            using (DebugGroup("Draw shadow depth"))
            {
                PrepareDepthDraw(_shadowRenderTarget);
                GL.CullFace(CullFaceMode.Back);

                if (_lightManager.DrawShadows)
                {
                    for (var i = 0; i < lights.Count; i++)
                    {
                        var(light, lightPos) = lights[i];

                        DrawOcclusionDepth(lightPos, ShadowMapSize, light.Radius, i, out shadowMatrices[i]);
                    }
                }

                FinalizeDepthDraw();
            }

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, _lightRenderTarget.ObjectHandle.Handle);
            GLClearColor(Color.FromSrgb(AmbientLightColor));
            GL.Clear(ClearBufferMask.ColorBufferBit);

            var(lightW, lightH) = GetLightMapSize();
            GL.Viewport(0, 0, lightW, lightH);

            var lightShader = _loadedShaders[_lightShaderHandle].Program;

            lightShader.Use();

            SetTexture(TextureUnit.Texture1, ShadowTexture);
            lightShader.SetUniformTextureMaybe("shadowMap", TextureUnit.Texture1);

            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);

            var     lastRange = float.NaN;
            var     lastPower = float.NaN;
            var     lastColor = new Color(float.NaN, float.NaN, float.NaN, float.NaN);
            Texture lastMask  = null;

            for (var i = 0; i < lights.Count; i++)
            {
                var(component, lightPos) = lights[i];
                var transform = component.Owner.Transform;

                var circle = new Circle(lightPos, component.Radius);

                if (!circle.Intersects(worldBounds))
                {
                    continue;
                }

                Texture mask     = null;
                var     rotation = Angle.Zero;
                if (component.Mask != null)
                {
                    mask     = component.Mask;
                    rotation = component.Rotation;

                    if (component.MaskAutoRotate)
                    {
                        rotation += transform.WorldRotation;
                    }
                }

                var maskTexture = mask ?? Texture.White;
                if (lastMask != maskTexture)
                {
                    SetTexture(TextureUnit.Texture0, maskTexture);
                    lastMask = maskTexture;
                    lightShader.SetUniformTextureMaybe(UniIMainTexture, TextureUnit.Texture0);
                }

                if (!FloatMath.CloseTo(lastRange, component.Radius))
                {
                    lastRange = component.Radius;
                    lightShader.SetUniformMaybe("lightRange", lastRange);
                }

                if (!FloatMath.CloseTo(lastPower, component.Energy))
                {
                    lastPower = component.Energy;
                    lightShader.SetUniformMaybe("lightPower", lastPower);
                }

                if (lastColor != component.Color)
                {
                    lastColor = component.Color;
                    lightShader.SetUniformMaybe("lightColor", lastColor);
                }

                lightShader.SetUniformMaybe("lightCenter", lightPos);
                lightShader.SetUniformMaybe("lightIndex", (i + 0.5f) / ShadowTexture.Height);
                lightShader.SetUniformMaybe("shadowMatrix", shadowMatrices[i], false);

                var offset = new Vector2(component.Radius, component.Radius);

                Matrix3 matrix;
                if (mask == null)
                {
                    matrix = Matrix3.Identity;
                }
                else
                {
                    // Only apply rotation if a mask is said, because else it doesn't matter.
                    matrix = Matrix3.CreateRotation(rotation);
                }

                (matrix.R0C2, matrix.R1C2) = lightPos;

                _drawQuad(-offset, offset, matrix, lightShader);
            }

            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            ApplyLightingFovToBuffer(eye);

            BlurOntoWalls(eye);

            MergeWallLayer();

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            GL.Viewport(0, 0, ScreenSize.X, ScreenSize.Y);

            _lightingReady = true;
        }
Exemple #19
0
        private void _drawLights(Box2 worldBounds)
        {
            if (!_lightManager.Enabled)
            {
                return;
            }

            var map = _eyeManager.CurrentMap;

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, LightRenderTarget.ObjectHandle.Handle);
            var converted = Color.FromSrgb(new Color(0.1f, 0.1f, 0.1f));

            GL.ClearColor(converted.R, converted.G, converted.B, 1);
            GL.Clear(ClearBufferMask.ColorBufferBit);

            var(lightW, lightH) = _lightMapSize();
            GL.Viewport(0, 0, lightW, lightH);

            _lightShader.Use();

            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);

            var     lastRange = float.NaN;
            var     lastPower = float.NaN;
            var     lastColor = new Color(float.NaN, float.NaN, float.NaN, float.NaN);
            Texture lastMask  = null;

            foreach (var component in _componentManager.GetAllComponents <PointLightComponent>())
            {
                if (!component.Enabled || component.Owner.Transform.MapID != map)
                {
                    continue;
                }

                var transform = component.Owner.Transform;
                var lightPos  = transform.WorldMatrix.Transform(component.Offset);

                var lightBounds = Box2.CenteredAround(lightPos, Vector2.One * component.Radius * 2);

                if (!lightBounds.Intersects(worldBounds))
                {
                    continue;
                }

                Texture mask     = null;
                var     rotation = Angle.Zero;
                if (component.Mask != null)
                {
                    mask     = component.Mask;
                    rotation = component.Rotation;

                    if (component.MaskAutoRotate)
                    {
                        rotation += transform.WorldRotation;
                    }
                }

                var maskTexture = mask ?? Texture.White;
                if (lastMask != maskTexture)
                {
                    var maskHandle = _loadedTextures[((ClydeTexture)maskTexture).TextureId].OpenGLObject;
                    GL.ActiveTexture(TextureUnit.Texture0);
                    GL.BindTexture(TextureTarget.Texture2D, maskHandle.Handle);
                    lastMask = maskTexture;
                    _lightShader.SetUniformTexture("lightMask", TextureUnit.Texture0);
                }

                if (!FloatMath.CloseTo(lastRange, component.Radius))
                {
                    lastRange = component.Radius;
                    _lightShader.SetUniform("lightRange", lastRange);
                }

                if (!FloatMath.CloseTo(lastPower, component.Energy))
                {
                    lastPower = component.Energy;
                    _lightShader.SetUniform("lightPower", lastPower);
                }

                if (lastColor != component.Color)
                {
                    lastColor = component.Color;
                    _lightShader.SetUniform("lightColor", lastColor);
                }

                _lightShader.SetUniform("lightCenter", lightPos);

                var offset = new Vector2(component.Radius, component.Radius);

                Matrix3 matrix;
                if (mask == null)
                {
                    matrix = Matrix3.Identity;
                }
                else
                {
                    // Only apply rotation if a mask is said, because else it doesn't matter.
                    matrix = Matrix3.CreateRotation(rotation);
                }

                (matrix.R0C2, matrix.R1C2) = lightPos;

                _drawQuad(-offset, offset, ref matrix, _lightShader);
            }

            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            GL.Viewport(0, 0, ScreenSize.X, ScreenSize.Y);

            _lightingReady = true;
        }
Exemple #20
0
 public bool OnSnapBorder(Vector2 position)
 {
     return(FloatMath.CloseTo(position.X % SnapSize, SnapSize / 2) && FloatMath.CloseTo(position.Y % SnapSize, SnapSize / 2));
 }
Exemple #21
0
 public bool OnSnapCenter(Vector2 position)
 {
     return(FloatMath.CloseTo(position.X % SnapSize, 0) && FloatMath.CloseTo(position.Y % SnapSize, 0));
 }