Ejemplo n.º 1
0
        public override void Update()
        {
            if (Input.HasMouse)
            {
                ClickResult clickResult;
                Utils.ScreenPositionToWorldPositionRaycast(Input.MousePosition, Camera, this.GetSimulation(), out clickResult);

                var isMoving = (Input.IsMouseButtonDown(MouseButton.Left) && lastClickResult.Type == ClickType.Ground && clickResult.Type == ClickType.Ground);

                var isHighlit = (!isMoving && clickResult.Type == ClickType.LootCrate);

                // Character continuous moving
                if (isMoving)
                {
                    lastClickResult.WorldPosition = clickResult.WorldPosition;
                    MoveDestinationEventKey.Broadcast(lastClickResult);
                }

                // Object highlighting
                if (isHighlit)
                {
                    var modelComponentA = Highlight?.Get<ModelComponent>();
                    var modelComponentB = clickResult.ClickedEntity.Get<ModelComponent>();

                    if (modelComponentA != null && modelComponentB != null)
                    {
                        var materialCount = modelComponentB.Materials.Count;
                        modelComponentA.Model = modelComponentB.Model;
                        modelComponentA.Materials.Clear();
                        for (int i = 0; i < materialCount; i++)
                            modelComponentA.Materials.Add(i, HighlightMaterial);

                        modelComponentA.Entity.Transform.UseTRS = false;
                        modelComponentA.Entity.Transform.LocalMatrix = modelComponentB.Entity.Transform.WorldMatrix;
                    }
                }
                else
                {
                    var modelComponentA = Highlight?.Get<ModelComponent>();
                    if (modelComponentA != null)
                        modelComponentA.Entity.Transform.LocalMatrix = Matrix.Scaling(0);
                }
            }

            // Mouse-based camera rotation. Only enabled after you click the screen to lock your cursor, pressing escape cancels this
            foreach (var pointerEvent in Input.PointerEvents.Where(x => x.State == PointerState.Down))
            {
                ClickResult clickResult;
                if (Utils.ScreenPositionToWorldPositionRaycast(pointerEvent.Position, Camera, this.GetSimulation(),
                    out clickResult))
                {
                    lastClickResult = clickResult;
                    MoveDestinationEventKey.Broadcast(clickResult);

                    if (ClickEffect != null && clickResult.Type == ClickType.Ground)
                    {
                        this.SpawnPrefabInstance(ClickEffect, null, 1.2f, Matrix.RotationQuaternion(Quaternion.BetweenDirections(Vector3.UnitY, clickResult.HitResult.Normal)) * Matrix.Translation(clickResult.WorldPosition));
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public static bool ScreenPositionToWorldPositionRaycast(Vector2 screenPos, CameraComponent camera, Simulation simulation, out ClickResult clickResult)
        {
            Matrix invViewProj = Matrix.Invert(camera.ViewProjectionMatrix);

            Vector3 sPos;

            sPos.X = screenPos.X * 2f - 1f;
            sPos.Y = 1f - screenPos.Y * 2f;

            sPos.Z = 0f;
            var vectorNear = Vector3.Transform(sPos, invViewProj);

            vectorNear /= vectorNear.W;

            sPos.Z = 1f;
            var vectorFar = Vector3.Transform(sPos, invViewProj);

            vectorFar /= vectorFar.W;

            clickResult.ClickedEntity = null;
            clickResult.WorldPosition = Vector3.Zero;
            clickResult.Type          = ClickType.Empty;
            clickResult.HitResult     = new HitResult();

            var minDistance = float.PositiveInfinity;

            var result = new FastList <HitResult>();

            simulation.RaycastPenetrating(vectorNear.XYZ(), vectorFar.XYZ(), result);
            foreach (var hitResult in result)
            {
                ClickType type = ClickType.Empty;

                var staticBody = hitResult.Collider as StaticColliderComponent;
                if (staticBody != null)
                {
                    if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter1)
                    {
                        type = ClickType.Ground;
                    }

                    if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter2)
                    {
                        type = ClickType.LootCrate;
                    }

                    if (type != ClickType.Empty)
                    {
                        var distance = (vectorNear.XYZ() - hitResult.Point).LengthSquared();
                        if (distance < minDistance)
                        {
                            minDistance               = distance;
                            clickResult.Type          = type;
                            clickResult.HitResult     = hitResult;
                            clickResult.WorldPosition = hitResult.Point;
                            clickResult.ClickedEntity = hitResult.Collider.Entity;
                        }
                    }
                }
            }

            return(clickResult.Type != ClickType.Empty);
        }
Ejemplo n.º 3
0
        public static bool ScreenPositionToWorldPositionRaycast(Vector2 screenPos, CameraComponent camera, Simulation simulation, out ClickResult clickResult)
        {
            Matrix invViewProj = Matrix.Invert(camera.ViewProjectionMatrix);

            Vector3 sPos;
            sPos.X = screenPos.X * 2f - 1f;
            sPos.Y = 1f - screenPos.Y * 2f;

            sPos.Z = 0f;
            var vectorNear = Vector3.Transform(sPos, invViewProj);
            vectorNear /= vectorNear.W;

            sPos.Z = 1f;
            var vectorFar = Vector3.Transform(sPos, invViewProj);
            vectorFar /= vectorFar.W;

            clickResult.ClickedEntity = null;
            clickResult.WorldPosition = Vector3.Zero;
            clickResult.Type = ClickType.Empty;
            clickResult.HitResult = new HitResult();

            var minDistance = float.PositiveInfinity;

            var result = simulation.RaycastPenetrating(vectorNear.XYZ(), vectorFar.XYZ());
            foreach (var hitResult in result)
            {
                ClickType type = ClickType.Empty;
                
                var staticBody = hitResult.Collider as StaticColliderComponent;
                if (staticBody != null)
                {
                    if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter1)
                        type = ClickType.Ground;

                    if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter2)
                        type = ClickType.LootCrate;

                    if (type != ClickType.Empty)
                    {
                        var distance = (vectorNear.XYZ() - hitResult.Point).LengthSquared();
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            clickResult.Type = type;
                            clickResult.HitResult = hitResult;
                            clickResult.WorldPosition = hitResult.Point;
                            clickResult.ClickedEntity = hitResult.Collider.Entity;
                        }
                    }
                }
            }

            return (clickResult.Type != ClickType.Empty);
        }