Beispiel #1
0
        protected override void DoDetection(bool useHead)
        {
            if (Character == MySession.Static.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.RemoveHighlight();
            }

            var head    = Character.GetHeadMatrix(false);
            var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head)

            Vector3D from;
            Vector3D dir;

            if (!useHead)
            {
                //Ondrej version
                var cameraMatrix = MySector.MainCamera.WorldMatrix;
                //var cameraMatrix = Character.Get3rdBoneMatrix(true, true);
                dir  = cameraMatrix.Forward;
                from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir);
            }
            else
            {
                //Petr version
                dir  = head.Forward;
                from = headPos;
            }

            Vector3D to = from + dir * MyConstants.DEFAULT_INTERACTIVE_DISTANCE;

            StartPosition = from;

            MatrixD   matrix    = MatrixD.CreateTranslation(from);
            HkShape   shape     = new HkSphereShape(ShapeRadius);
            IMyEntity hitEntity = null;

            ShapeKey    = uint.MaxValue;
            HitPosition = Vector3D.Zero;
            HitNormal   = Vector3.Zero;
            HitMaterial = MyStringHash.NullOrEmpty;
            m_hits.Clear();

            try
            {
                EnableDetectorsInArea(from);

                MyPhysics.CastShapeReturnContactBodyDatas(to, shape, ref matrix, 0, 0f, m_hits);

                if (m_hits.Count > 0)
                {
                    int index = 0;

                    bool isValidBlock    = false;
                    bool isPhysicalBlock = false;

                    do
                    {
                        isValidBlock = m_hits[index].HkHitInfo.Body != null && m_hits[index].HkHitInfo.GetHitEntity() != Character && m_hits[index].HkHitInfo.GetHitEntity() != null && !m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT);

                        isPhysicalBlock = m_hits[index].HkHitInfo.GetHitEntity() != null && m_hits[index].HkHitInfo.GetHitEntity().Physics != null;

                        if (hitEntity == null && isValidBlock)
                        {
                            hitEntity = m_hits[index].HkHitInfo.GetHitEntity();
                            ShapeKey  = m_hits[index].HkHitInfo.GetShapeKey(0);
                        }

                        // Set hit material etc. only for object's that have physical representation in the world, this exclude detectors
                        if (HitMaterial.Equals(MyStringHash.NullOrEmpty) && isValidBlock && isPhysicalBlock)
                        {
                            HitBody     = m_hits[index].HkHitInfo.Body;
                            HitPosition = m_hits[index].Position;
                            HitNormal   = m_hits[index].HkHitInfo.Normal;
                            HitMaterial = m_hits[index].HkHitInfo.Body.GetBody().GetMaterialAt(HitPosition + HitNormal * 0.1f);
                        }

                        index++;
                    } while (index < m_hits.Count && (!isValidBlock || !isPhysicalBlock));
                }
            }
            finally
            {
                shape.RemoveReference();
            }

            bool hasInteractive = false;

            var interactive = hitEntity as IMyUseObject;

            DetectedEntity = hitEntity;

            if (hitEntity != null)
            {
                MyUseObjectsComponentBase useObject = null;
                hitEntity.Components.TryGet <MyUseObjectsComponentBase>(out useObject);
                if (useObject != null)
                {
                    interactive = useObject.GetInteractiveObject(ShapeKey);
                }
            }

            if (UseObject != null && interactive != null && UseObject != interactive)
            {
                UseObject.OnSelectionLost();
            }

            if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, HitPosition)) < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity)
            {
                HandleInteractiveObject(interactive);

                UseObject      = interactive;
                hasInteractive = true;
            }

            if (!hasInteractive)
            {
                if (UseObject != null)
                {
                    UseObject.OnSelectionLost();
                }

                UseObject = null;
            }

            DisableDetectors();
        }
        private void DoDetection(bool useHead, bool doModelIntersection)
        {
            if (Character == MySession.Static.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.RemoveHighlight();
            }

            var      head = Character.GetHeadMatrix(false);
            Vector3D from = head.Translation;
            Vector3D dir  = head.Forward;

            if (!useHead)
            {
                var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head)

                if (Character == MySession.Static.LocalCharacter)
                {
                    from = MySector.MainCamera.WorldMatrix.Translation;
                    dir  = MySector.MainCamera.WorldMatrix.Forward;

                    from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, from, (Vector3)dir);
                }
                else
                {
                    from = headPos;
                    dir  = head.Forward;
                }
            }

            Vector3D to = from + dir * 2.5;//MyConstants.DEFAULT_INTERACTIVE_DISTANCE;

            StartPosition = from;

            MatrixD   matrix    = MatrixD.CreateTranslation(from);
            HkShape   shape     = new HkSphereShape(ShapeRadius);
            IMyEntity hitEntity = null;

            ShapeKey    = uint.MaxValue;
            HitPosition = Vector3D.Zero;
            HitNormal   = Vector3.Zero;
            HitMaterial = MyStringHash.NullOrEmpty;
            HitTag      = null;
            m_hits.Clear();

            Vector3 interactivePosition = Vector3D.Zero;

            try
            {
                EnableDetectorsInArea(from);

                MyPhysics.CastShapeReturnContactBodyDatas(to, shape, ref matrix, 0, 0f, m_hits);

                m_rayOrigin    = from;
                m_rayDirection = dir;
                m_hits.Sort(CompareHits);

                if (m_hits.Count > 0)
                {
                    bool isValidBlock    = false;
                    bool isPhysicalBlock = false;

                    for (int index = 0; index < m_hits.Count; index++)
                    {
                        HkRigidBody body   = m_hits[index].HkHitInfo.Body;
                        IMyEntity   entity = m_hits[index].HkHitInfo.GetHitEntity();

                        // Ignore self-interaction
                        if (entity == Character)
                        {
                            continue;
                        }

                        if (entity is VRage.Game.Entity.MyEntitySubpart)
                        {
                            entity = entity.Parent;
                        }

                        isValidBlock    = body != null && entity != null && entity != Character && !body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT);
                        isPhysicalBlock = entity != null && entity.Physics != null;

                        if (hitEntity == null && isValidBlock)
                        {
                            hitEntity = entity;
                            ShapeKey  = m_hits[index].HkHitInfo.GetShapeKey(0);
                        }

                        // If hit-entity is a grid, raycast it to see which block we hit first
                        if (entity is MyCubeGrid)
                        {
                            MyCubeGrid    grid     = entity as MyCubeGrid;
                            List <MyCube> cubeList = grid.RayCastBlocksAllOrdered(from, to);
                            if (cubeList != null && cubeList.Count > 0)
                            {
                                var slimblock = cubeList[0].CubeBlock;
                                if (slimblock.FatBlock != null)
                                {
                                    entity          = slimblock.FatBlock;
                                    isPhysicalBlock = true;
                                    hitEntity       = entity;
                                    ShapeKey        = 0;
                                }
                            }
                        }

                        // Set hit material etc. only for object's that have physical representation in the world, this exclude detectors
                        if (HitMaterial.Equals(MyStringHash.NullOrEmpty) && isValidBlock && isPhysicalBlock)
                        {
                            HitBody     = body;
                            HitNormal   = m_hits[index].HkHitInfo.Normal;
                            HitPosition = m_hits[index].GetFixedPosition();
                            HitMaterial = body.GetBody().GetMaterialAt(HitPosition);

                            interactivePosition = HitPosition;
                            break;
                        }
                        else if (body != null)
                        {
                            interactivePosition = m_hits[index].GetFixedPosition();
                            break;
                        }

                        index++;
                    }
                }
            }
            finally
            {
                shape.RemoveReference();
            }

            bool hasInteractive = false;

            var interactive = hitEntity as IMyUseObject;

            DetectedEntity = hitEntity;

            if (hitEntity != null)
            {
                MyUseObjectsComponentBase useObject = null;
                hitEntity.Components.TryGet <MyUseObjectsComponentBase>(out useObject);
                if (useObject != null)
                {
                    interactive = useObject.GetInteractiveObject(ShapeKey);
                }

                // Do accurate collision checking on model
                if (doModelIntersection)
                {
                    LineD line      = new LineD(from, to);
                    var   character = hitEntity as MyCharacter;
                    if (character == null)
                    {
                        MyIntersectionResultLineTriangleEx?result;
                        bool success = hitEntity.GetIntersectionWithLine(ref line, out result, IntersectionFlags.ALL_TRIANGLES);
                        if (success)
                        {
                            HitPosition = result.Value.IntersectionPointInWorldSpace;
                            HitNormal   = result.Value.NormalInWorldSpace;
                        }
                    }
                    else
                    {
                        bool success = character.GetIntersectionWithLine(ref line, ref CharHitInfo);
                        if (success)
                        {
                            HitPosition = CharHitInfo.Triangle.IntersectionPointInWorldSpace;
                            HitNormal   = CharHitInfo.Triangle.NormalInWorldSpace;
                            HitTag      = CharHitInfo;
                        }
                    }
                }
            }

            if (UseObject != null && interactive != null && UseObject != interactive)
            {
                UseObject.OnSelectionLost();
            }

            if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, interactivePosition)) < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity)
            {
                HandleInteractiveObject(interactive);

                UseObject      = interactive;
                hasInteractive = true;
            }

            if (!hasInteractive)
            {
                if (UseObject != null)
                {
                    UseObject.OnSelectionLost();
                }

                UseObject = null;
            }

            DisableDetectors();
        }
Beispiel #3
0
        private void DoDetection(bool useHead, bool doModelIntersection)
        {
            if (Character == MySession.Static.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.RemoveHighlight();
            }

            var head    = Character.GetHeadMatrix(false);
            var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head)

            Vector3D from;
            Vector3D dir;

            if (!useHead)
            {
                //Ondrej version
                //var cameraMatrix = MySector.MainCamera.WorldMatrix;
                var cameraMatrix = Character.Get3rdBoneMatrix(true, true);
                dir  = cameraMatrix.Forward;
                from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir);
            }
            else
            {
                //Petr version
                dir  = head.Forward;
                from = headPos;
            }

            Vector3D to = from + dir * 2.5;//MyConstants.DEFAULT_INTERACTIVE_DISTANCE;

            StartPosition = from;

            MatrixD   matrix    = MatrixD.CreateTranslation(from);
            HkShape   shape     = new HkSphereShape(ShapeRadius);
            IMyEntity hitEntity = null;

            ShapeKey    = uint.MaxValue;
            HitPosition = Vector3D.Zero;
            HitNormal   = Vector3.Zero;
            HitMaterial = MyStringHash.NullOrEmpty;
            HitTag      = null;
            m_hits.Clear();

            Vector3 interactivePosition = Vector3D.Zero;

            try
            {
                EnableDetectorsInArea(from);

                MyPhysics.CastShapeReturnContactBodyDatas(to, shape, ref matrix, 0, 0f, m_hits);

                m_hits.Sort(delegate(MyPhysics.HitInfo info1, MyPhysics.HitInfo info2)
                {
                    float dot1 = Vector3.Dot(head.Forward, Vector3.Normalize(info1.Position - StartPosition));
                    float dot2 = Vector3.Dot(head.Forward, Vector3.Normalize(info2.Position - StartPosition));
                    return(dot1.CompareTo(dot2));
                });

                if (m_hits.Count > 0)
                {
                    int index = 0;

                    bool isValidBlock    = false;
                    bool isPhysicalBlock = false;

                    do
                    {
                        HkRigidBody body   = m_hits[index].HkHitInfo.Body;
                        IMyEntity   entity = m_hits[index].HkHitInfo.GetHitEntity();

                        if (entity is VRage.Game.Entity.MyEntitySubpart)
                        {
                            entity = entity.Parent;
                        }

                        isValidBlock = body != null && entity != null && entity != Character && !body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT);

                        isPhysicalBlock = entity != null && entity.Physics != null;

                        if (hitEntity == null && isValidBlock)
                        {
                            hitEntity = entity;
                            ShapeKey  = m_hits[index].HkHitInfo.GetShapeKey(0);
                        }

                        // Set hit material etc. only for object's that have physical representation in the world, this exclude detectors
                        if (HitMaterial.Equals(MyStringHash.NullOrEmpty) && isValidBlock && isPhysicalBlock)
                        {
                            HitBody     = body;
                            HitNormal   = m_hits[index].HkHitInfo.Normal;
                            HitPosition = m_hits[index].GetFixedPosition();
                            HitMaterial = body.GetBody().GetMaterialAt(HitPosition);

                            interactivePosition = HitPosition;
                        }
                        else if (body != null)
                        {
                            interactivePosition = m_hits[index].GetFixedPosition();
                        }

                        index++;
                    } while (index < m_hits.Count && (!isValidBlock || !isPhysicalBlock));
                }
            }
            finally
            {
                shape.RemoveReference();
            }

            bool hasInteractive = false;

            var interactive = hitEntity as IMyUseObject;

            DetectedEntity = hitEntity;

            if (hitEntity != null)
            {
                MyUseObjectsComponentBase useObject = null;
                hitEntity.Components.TryGet <MyUseObjectsComponentBase>(out useObject);
                if (useObject != null)
                {
                    interactive = useObject.GetInteractiveObject(ShapeKey);
                }

                // Do accurate collision checking on model
                if (doModelIntersection)
                {
                    LineD line      = new LineD(from, to);
                    var   character = hitEntity as MyCharacter;
                    if (character == null)
                    {
                        MyIntersectionResultLineTriangleEx?result;
                        bool success = hitEntity.GetIntersectionWithLine(ref line, out result, IntersectionFlags.ALL_TRIANGLES);
                        if (success)
                        {
                            HitPosition = result.Value.IntersectionPointInWorldSpace;
                            HitNormal   = result.Value.NormalInWorldSpace;
                        }
                    }
                    else
                    {
                        bool success = character.GetIntersectionWithLine(ref line, ref CharHitInfo);
                        if (success)
                        {
                            HitPosition = CharHitInfo.Triangle.IntersectionPointInWorldSpace;
                            HitNormal   = CharHitInfo.Triangle.NormalInWorldSpace;
                            HitTag      = CharHitInfo;
                        }
                    }
                }
            }

            if (UseObject != null && interactive != null && UseObject != interactive)
            {
                UseObject.OnSelectionLost();
            }

            if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, interactivePosition)) < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity)
            {
                HandleInteractiveObject(interactive);

                UseObject      = interactive;
                hasInteractive = true;
            }

            if (!hasInteractive)
            {
                if (UseObject != null)
                {
                    UseObject.OnSelectionLost();
                }

                UseObject = null;
            }

            DisableDetectors();
        }