public override void OnBeforeRemovedFromContainer()
        {
            m_useObjectComp = null;

            if (Container.Entity.InScene)
            {
                Debug.Assert(m_respawns.Contains(this), "Double remove of respawn component from the respawns list");
                m_respawns.Remove(this);
            }

            base.OnBeforeRemovedFromContainer();
        }
示例#2
0
        private void GetUseComponentsFromParentStructure(IMyEntity currentEntity, List <MyUseObjectsComponentBase> useComponents)
        {
            MyUseObjectsComponentBase item = currentEntity.Components.Get <MyUseObjectsComponentBase>();

            if (item != null)
            {
                useComponents.Add(item);
            }
            if (currentEntity.Parent != null)
            {
                this.GetUseComponentsFromParentStructure(currentEntity.Parent, useComponents);
            }
        }
示例#3
0
        protected override void DoDetection(bool useHead)
        {
            if (Character == MySession.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.Visible = false;
            }

            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;
                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;


            //VRageRender.MyRenderProxy.DebugDrawLine3D(from, to, Color.Red, Color.Green, true);
            //VRageRender.MyRenderProxy.DebugDrawSphere(headPos, 0.05f, Color.Red.ToVector3(), 1.0f, false);

            MyPhysics.CastRay(from, to, m_hits);

            bool hasInteractive = false;

            int index = 0;

            while (index < m_hits.Count && (m_hits[index].HkHitInfo.Body == null || m_hits[index].HkHitInfo.Body.UserObject == Character.Physics ||
                                            (Character.VirtualPhysics != null && m_hits[index].HkHitInfo.Body.UserObject == Character.VirtualPhysics) || m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT))) // Skip invalid hits and self character
            {
                index++;
            }

            if (index < m_hits.Count)
            {
                //We must take only closest hit (others are hidden behind)
                var h           = m_hits[index];
                var entity      = h.HkHitInfo.Body.GetEntity();
                var interactive = entity as IMyUseObject;

                // TODO: Uncomment to enforce that character must face object by front to activate it
                //if (TestInteractionDirection(head.Forward, h.Position - GetPosition()))
                //return;

                if (entity != null)
                {
                    MyUseObjectsComponentBase useObject = null;
                    entity.Components.TryGet <MyUseObjectsComponentBase>(out useObject);
                    if (useObject != null)
                    {
                        interactive = useObject.GetInteractiveObject(h.HkHitInfo.GetShapeKey(0));
                    }
                }

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

                if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, (Vector3D)h.Position)) < interactive.InteractiveDistance && Character == MySession.ControlledEntity)
                {
                    MyHud.SelectedObjectHighlight.Visible           = true;
                    MyHud.SelectedObjectHighlight.InteractiveObject = interactive;

                    UseObject      = interactive;
                    hasInteractive = true;
                }
            }

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

                UseObject = null;
            }
        }
        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();
        }
        protected override void DoDetection(bool useHead)
        {
            if (Character == MySession.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.Visible = false;
            }

            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.5f;

            StartPosition = from;

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

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

            try
            {
                EnableDetectorsInArea(from);

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

                int index = 0;
                while (index < m_hits.Count && (m_hits[index].HkHitInfo.Body == null || m_hits[index].HkHitInfo.GetHitEntity() == Character ||
                                                m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT))) // Skip invalid hits and self character
                {
                    index++;
                }

                if (index < m_hits.Count)
                {
                    hitEntity   = m_hits[index].HkHitInfo.GetHitEntity();
                    ShapeKey    = m_hits[index].HkHitInfo.GetShapeKey(0);
                    HitPosition = m_hits[index].Position;
                    HitNormal   = m_hits[index].HkHitInfo.Normal;
                    HitMaterial = m_hits[index].HkHitInfo.Body.GetBody().GetMaterialAt(HitPosition + HitNormal * 0.1f);
                    HitBody     = m_hits[index].HkHitInfo.Body;
                }
            }
            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.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.Visible           = true;
                MyHud.SelectedObjectHighlight.InteractiveObject = interactive;

                UseObject      = interactive;
                hasInteractive = true;
            }

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

                UseObject = null;
            }

            DisableDetectors();
        }
 void Container_ComponentRemoved(Type compType, MyEntityComponentBase component)
 {
     if (compType == typeof(MyUseObjectsComponentBase))
         m_useObjectComp = null;
 }
 void Container_ComponentAdded(Type compType, MyEntityComponentBase component)
 {
     if (compType == typeof(MyUseObjectsComponentBase))
         m_useObjectComp = component as MyUseObjectsComponentBase;
 }
示例#8
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();
        }
        protected override void DoDetection(bool useHead)
        {
            ProfilerShort.Begin("DoDetection");
            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;
                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;
            LineD intersectionLine = new LineD(from, to);

            // Processing of hit entities
            var  geometryHit  = MyEntities.GetIntersectionWithLine(ref intersectionLine, null, null, ignoreFloatingObjects: false);
            bool hasUseObject = false;

            if (geometryHit.HasValue)
            {
                var hitEntity = geometryHit.Value.Entity;

                // Cube Grids are special case
                var cubeGrid = hitEntity as MyCubeGrid;
                if (cubeGrid != null)
                {
                    // For hit cube grids get the fat hit fatblock instead.
                    var slimBlock = cubeGrid.GetTargetedBlock(geometryHit.Value.IntersectionPointInWorldSpace);
                    if (slimBlock != null && slimBlock.FatBlock != null)
                    {
                        hitEntity = slimBlock.FatBlock;
                    }
                }

                m_hitUseComponents.Clear();
                var hitUseObject = hitEntity as IMyUseObject;
                // Retrive all above use components from parent structure. (Because of subParts)
                GetUseComponentsFromParentStructure(hitEntity, m_hitUseComponents);
                // Check for UseObjects and entities with UseObjectComponentBase.
                // Assuming that entity cannot be IMyUseObject and have UseObjectComponentBase in hierarchy
                // at the same time.
                if (hitUseObject != null || m_hitUseComponents.Count > 0)
                {
                    if (m_hitUseComponents.Count > 0)
                    {
                        // Process the valid hit entity
                        var    closestDetectorDistance       = float.MaxValue;
                        double physicalHitDistance           = Vector3D.Distance(from, geometryHit.Value.IntersectionPointInWorldSpace);
                        MyUseObjectsComponentBase hitUseComp = null;
                        // Evaluate the set of found detectors and try to find the closest one
                        foreach (var hitUseComponent in m_hitUseComponents)
                        {
                            float detectorDistance;
                            var   interactive = hitUseComponent.RaycastDetectors(from, to, out detectorDistance);
                            detectorDistance *= MyConstants.DEFAULT_INTERACTIVE_DISTANCE;
                            if (Math.Abs(detectorDistance) < Math.Abs(closestDetectorDistance) &&
                                (detectorDistance < physicalHitDistance)) // Remove to fix the problem with picking through physic bodies,
                            {                                             // but will introduce new problem with detectors inside physic bodies.
                                closestDetectorDistance = detectorDistance;
                                hitUseComp   = hitUseComponent;
                                hitEntity    = hitUseComponent.Entity;
                                hitUseObject = interactive;
                            }
                        }

                        // Detector found
                        if (hitUseComp != null)
                        {
                            // Process successful hit with results
                            var detectorPhysics = hitUseComp.DetectorPhysics;
                            HitMaterial    = detectorPhysics.GetMaterialAt(HitPosition);
                            HitBody        = geometryHit.Value.Entity.Physics.RigidBody;
                            HitPosition    = geometryHit.Value.IntersectionPointInWorldSpace;
                            DetectedEntity = hitEntity;
                        }
                    }
                    else
                    {
                        // Case for hitting IMyUseObject already before even looking for UseComponent.
                        // Floating object case.
                        HitMaterial = hitEntity.Physics.GetMaterialAt(HitPosition);
                        HitBody     = hitEntity.Physics.RigidBody;
                    }

                    // General logic for processing both cases.
                    if (hitUseObject != null)
                    {
                        HitPosition    = geometryHit.Value.IntersectionPointInWorldSpace;
                        DetectedEntity = hitEntity;

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

                        if (Character == MySession.Static.ControlledEntity && hitUseObject.SupportedActions != UseActionEnum.None)
                        {
                            HandleInteractiveObject(hitUseObject);

                            UseObject    = hitUseObject;
                            hasUseObject = true;
                        }
                    }
                }
            }

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

                UseObject = null;
            }

            ProfilerShort.End();
        }
示例#10
0
        protected override void DoDetection(bool useHead)
        {
            Vector3D vectord2;
            Vector3D forward;

            if (ReferenceEquals(base.Character, MySession.Static.ControlledEntity))
            {
                MyHud.SelectedObjectHighlight.RemoveHighlight();
            }
            MatrixD  xd         = base.Character.GetHeadMatrix(false, true, false, false, false);
            Vector3D planePoint = xd.Translation - (xd.Forward * 0.3);

            if (useHead)
            {
                forward  = xd.Forward;
                vectord2 = planePoint;
            }
            else
            {
                MatrixD worldMatrix = MySector.MainCamera.WorldMatrix;
                forward  = worldMatrix.Forward;
                vectord2 = MyUtils.LinePlaneIntersection(planePoint, (Vector3)forward, worldMatrix.Translation, (Vector3)forward);
            }
            Vector3D to = vectord2 + (forward * MyConstants.DEFAULT_INTERACTIVE_DISTANCE);

            base.StartPosition = vectord2;
            LineD line = new LineD(vectord2, to);
            MyIntersectionResultLineTriangleEx?nullable = Sandbox.Game.Entities.MyEntities.GetIntersectionWithLine(ref line, base.Character, null, false, false, true, IntersectionFlags.ALL_TRIANGLES, 0f, true);
            bool flag = false;

            if (nullable != null)
            {
                IMyEntity currentEntity = nullable.Value.Entity;
                Vector3D  intersectionPointInWorldSpace = nullable.Value.IntersectionPointInWorldSpace;
                if ((currentEntity is MyCubeGrid) && (nullable.Value.UserObject != null))
                {
                    MySlimBlock cubeBlock = (nullable.Value.UserObject as MyCube).CubeBlock;
                    if ((cubeBlock != null) && (cubeBlock.FatBlock != null))
                    {
                        currentEntity = cubeBlock.FatBlock;
                    }
                }
                this.m_hitUseComponents.Clear();
                IMyUseObject interactive = currentEntity as IMyUseObject;
                this.GetUseComponentsFromParentStructure(currentEntity, this.m_hitUseComponents);
                if ((interactive != null) || (this.m_hitUseComponents.Count > 0))
                {
                    if (this.m_hitUseComponents.Count <= 0)
                    {
                        base.HitMaterial = currentEntity.Physics.GetMaterialAt(base.HitPosition);
                        base.HitBody     = currentEntity.Physics.RigidBody;
                    }
                    else
                    {
                        float  maxValue = float.MaxValue;
                        double num2     = Vector3D.Distance(vectord2, intersectionPointInWorldSpace);
                        MyUseObjectsComponentBase base2 = null;
                        foreach (MyUseObjectsComponentBase base3 in this.m_hitUseComponents)
                        {
                            float        num3;
                            IMyUseObject obj3 = base3.RaycastDetectors(vectord2, to, out num3);
                            num3 *= MyConstants.DEFAULT_INTERACTIVE_DISTANCE;
                            if ((Math.Abs(num3) < Math.Abs(maxValue)) && (num3 < num2))
                            {
                                maxValue      = num3;
                                base2         = base3;
                                currentEntity = base3.Entity;
                                interactive   = obj3;
                            }
                        }
                        if (base2 != null)
                        {
                            base.HitMaterial    = base2.DetectorPhysics.GetMaterialAt(base.HitPosition);
                            this.HitBody        = nullable.Value.Entity.Physics?.RigidBody;
                            base.HitPosition    = intersectionPointInWorldSpace;
                            base.DetectedEntity = currentEntity;
                        }
                    }
                    if (interactive != null)
                    {
                        base.HitPosition    = intersectionPointInWorldSpace;
                        base.DetectedEntity = currentEntity;
                        if ((ReferenceEquals(base.Character, MySession.Static.ControlledEntity) && (interactive.SupportedActions != UseActionEnum.None)) && !base.Character.IsOnLadder)
                        {
                            HandleInteractiveObject(interactive);
                            base.UseObject = interactive;
                            flag           = true;
                        }
                        if (base.Character.IsOnLadder)
                        {
                            base.UseObject = null;
                        }
                    }
                }
            }
            if (!flag)
            {
                base.UseObject = null;
            }
        }
        protected override void DoDetection(bool useHead)
        {
            if (Character == MySession.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.Visible = false;
            }

            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;
                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;

            MatrixD   matrix      = MatrixD.CreateTranslation(from);
            HkShape   shape       = new HkSphereShape(SHAPE_RADIUS);
            IMyEntity hitEntity   = null;
            int       shapeKey    = -1;
            Vector3D  hitPosition = Vector3D.Zero;

            m_hits.Clear();

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

                int index = 0;
                while (index < m_hits.Count && (m_hits[index].Body == null || m_hits[index].Body.UserObject == Character.Physics ||
                                                (Character.VirtualPhysics != null && m_hits[index].Body.UserObject == Character.VirtualPhysics) || m_hits[index].Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT))) // Skip invalid hits and self character
                {
                    index++;
                }

                if (index < m_hits.Count)
                {
                    hitEntity   = m_hits[index].Body.GetEntity();
                    shapeKey    = m_hits[index].ShapeKey;
                    hitPosition = m_hits[index].HitPosition;
                }
            }
            finally
            {
                shape.RemoveReference();
            }

            bool hasInteractive = false;

            var interactive = hitEntity as IMyUseObject;

            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.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.Visible           = true;
                MyHud.SelectedObjectHighlight.InteractiveObject = interactive;

                UseObject      = interactive;
                hasInteractive = true;
            }

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

                UseObject = null;
            }
        }
示例#12
0
        protected override void DoDetection(bool useHead)
        {
            ProfilerShort.Begin("DoDetection");
            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;
                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;

            // Processing of hit entities
            MyPhysics.CastRay(from, to, m_hits, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer);
            bool hasUseObject = false;
            int  index        = 0;

            while (index < m_hits.Count)
            {
                var hitEntity = m_hits[index].HkHitInfo.GetHitEntity();

                // Skip invalid hits
                if (m_hits[index].HkHitInfo.Body == null ||
                    hitEntity == null ||
                    hitEntity == Character ||
                    m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT) ||
                    m_hits[index].HkHitInfo.Body.Layer == MyPhysics.CollisionLayers.VoxelLod1CollisionLayer)
                {
                    index++;
                    continue;
                }

                // Cube Grids are special case
                var cubeGrid = hitEntity as MyCubeGrid;
                if (cubeGrid != null)
                {
                    // Correct the hit position (Physics offset)
                    var correctedPosition = m_hits[index].Position
                                            - m_hits[index].HkHitInfo.Normal * m_hits[index].HkHitInfo.GetConvexRadius();
                    // For hit cube grids get the fat hit fatblock instead.
                    var slimBlock = cubeGrid.GetTargetedBlock(correctedPosition);
                    if (slimBlock != null && slimBlock.FatBlock != null)
                    {
                        hitEntity = slimBlock.FatBlock;
                    }
                }

                m_hitUseComponents.Clear();
                var hitUseObject = hitEntity as IMyUseObject;
                // Retrive all above use components from parent structure. (Because of subParts)
                GetUseComponentsFromParentStructure(hitEntity, m_hitUseComponents);
                // Check for UseObjects and entities with UseObjectComponentBase.
                // Assuming that entity cannot be IMyUseObject and have UseObjectComponentBase in hierarchy
                // at the same time.
                if (hitUseObject != null || m_hitUseComponents.Count > 0)
                {
                    if (m_hitUseComponents.Count > 0)
                    {
                        // Process the valid hit entity
                        var closestDetectorDistance          = float.MaxValue;
                        MyUseObjectsComponentBase hitUseComp = null;
                        // Evaluate the set of found detectors and try to find the closest one
                        foreach (var hitUseComponent in m_hitUseComponents)
                        {
                            float detectorDistance;
                            var   interactive = hitUseComponent.RaycastDetectors(from, to, out detectorDistance);
                            if (Math.Abs(detectorDistance) < Math.Abs(closestDetectorDistance))
                            {
                                closestDetectorDistance = detectorDistance;
                                hitUseComp   = hitUseComponent;
                                hitEntity    = hitUseComponent.Entity;
                                hitUseObject = interactive;
                            }
                        }

                        // Detector found
                        if (hitUseComp != null)
                        {
                            // Process successful hit with results
                            var detectorPhysics = hitUseComp.DetectorPhysics;
                            HitMaterial    = detectorPhysics.GetMaterialAt(HitPosition);
                            HitBody        = m_hits[index].HkHitInfo.Body;
                            HitPosition    = m_hits[index].Position;
                            DetectedEntity = hitEntity;
                        }
                    }
                    else
                    {
                        // Case for hitting IMyUseObject already before even looking for UseComponent.
                        // Floating object case.
                        HitMaterial = hitEntity.Physics.GetMaterialAt(HitPosition);
                        HitBody     = m_hits[index].HkHitInfo.Body;
                    }

                    // General logic for processing both cases.
                    if (hitUseObject != null)
                    {
                        HitPosition    = m_hits[index].Position;
                        DetectedEntity = hitEntity;

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

                        if (hitUseObject.SupportedActions != UseActionEnum.None && Character == MySession.Static.ControlledEntity)
                        {
                            HandleInteractiveObject(hitUseObject);

                            UseObject    = hitUseObject;
                            hasUseObject = true;
                        }
                    }
                    break;
                }

                index++;
            }

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

                UseObject = null;
            }

            ProfilerShort.End();
        }
示例#13
0
        private void DoDetection(bool useHead, bool doModelIntersection)
        {
            bool flag;

            if (ReferenceEquals(base.Character, MySession.Static.ControlledEntity))
            {
                MyHud.SelectedObjectHighlight.RemoveHighlight();
            }
            MatrixD  xd          = base.Character.GetHeadMatrix(false, true, false, false, false);
            Vector3D translation = xd.Translation;
            Vector3D forward     = xd.Forward;

            if (!useHead)
            {
                Vector3D planePoint = xd.Translation - (xd.Forward * 0.3);
                if (!ReferenceEquals(base.Character, MySession.Static.LocalCharacter))
                {
                    translation = planePoint;
                    forward     = xd.Forward;
                }
                else
                {
                    translation = MySector.MainCamera.WorldMatrix.Translation;
                    forward     = MySector.MainCamera.WorldMatrix.Forward;
                    translation = MyUtils.LinePlaneIntersection(planePoint, (Vector3)forward, translation, (Vector3)forward);
                }
            }
            Vector3D to = translation + (forward * 2.5);

            base.StartPosition = translation;
            MatrixD   transform = MatrixD.CreateTranslation(translation);
            HkShape   shape     = (HkShape) new HkSphereShape(this.ShapeRadius);
            IMyEntity objA      = null;

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

            try
            {
                bool flag2;
                bool flag3;
                int  num;
                base.EnableDetectorsInArea(translation);
                MyPhysics.CastShapeReturnContactBodyDatas(to, shape, ref transform, 0, 0f, this.m_hits, true);
                this.m_rayOrigin    = translation;
                this.m_rayDirection = forward;
                this.m_hits.Sort(new Comparison <MyPhysics.HitInfo>(this.CompareHits));
                if (this.m_hits.Count <= 0)
                {
                    goto TR_0012;
                }
                else
                {
                    flag2 = false;
                    flag3 = false;
                    num   = 0;
                }
                goto TR_002F;
TR_0017:
                num++;
TR_002F:
                while (true)
                {
                    if (num >= this.m_hits.Count)
                    {
                        break;
                    }
                    HkRigidBody hkEntity  = this.m_hits[num].HkHitInfo.Body;
                    IMyEntity   hitEntity = this.m_hits[num].HkHitInfo.GetHitEntity();
                    if (!ReferenceEquals(hitEntity, base.Character))
                    {
                        int num1;
                        if (hitEntity is MyEntitySubpart)
                        {
                            hitEntity = hitEntity.Parent;
                        }
                        if (((hkEntity == null) || (hitEntity == null)) || ReferenceEquals(hitEntity, base.Character))
                        {
                            num1 = 0;
                        }
                        else
                        {
                            num1 = (int)!hkEntity.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT);
                        }
                        flag2 = (bool)num1;
                        flag3 = (hitEntity != null) && (hitEntity.Physics != null);
                        if (ReferenceEquals(objA, null) & flag2)
                        {
                            objA          = hitEntity;
                            base.ShapeKey = this.m_hits[num].HkHitInfo.GetShapeKey(0);
                        }
                        if (hitEntity is MyCubeGrid)
                        {
                            List <MyCube> list = (hitEntity as MyCubeGrid).RayCastBlocksAllOrdered(translation, to);
                            if ((list != null) && (list.Count > 0))
                            {
                                MySlimBlock cubeBlock = list[0].CubeBlock;
                                if (cubeBlock.FatBlock != null)
                                {
                                    flag3         = true;
                                    objA          = cubeBlock.FatBlock;
                                    base.ShapeKey = 0;
                                }
                            }
                        }
                        if (!((base.HitMaterial.Equals(MyStringHash.NullOrEmpty) & flag2) & flag3))
                        {
                            if (hkEntity == null)
                            {
                                num++;
                                goto TR_0017;
                            }
                            else
                            {
                                zero = this.m_hits[num].GetFixedPosition();
                            }
                        }
                        else
                        {
                            base.HitBody     = hkEntity;
                            base.HitNormal   = this.m_hits[num].HkHitInfo.Normal;
                            base.HitPosition = this.m_hits[num].GetFixedPosition();
                            base.HitMaterial = hkEntity.GetBody().GetMaterialAt(base.HitPosition);
                            zero             = (Vector3)base.HitPosition;
                        }
                        break;
                    }
                    goto TR_0017;
                }
            }
            finally
            {
                shape.RemoveReference();
            }
TR_0012:
            flag = false;
            IMyUseObject interactive = objA as IMyUseObject;

            base.DetectedEntity = objA;
            if (objA != null)
            {
                MyUseObjectsComponentBase component = null;
                objA.Components.TryGet <MyUseObjectsComponentBase>(out component);
                if (component != null)
                {
                    interactive = component.GetInteractiveObject(base.ShapeKey);
                }
                if (doModelIntersection)
                {
                    LineD       line      = new LineD(translation, to);
                    MyCharacter character = objA as MyCharacter;
                    if (character == null)
                    {
                        MyIntersectionResultLineTriangleEx?nullable;
                        if (objA.GetIntersectionWithLine(ref line, out nullable, IntersectionFlags.ALL_TRIANGLES))
                        {
                            base.HitPosition = nullable.Value.IntersectionPointInWorldSpace;
                            base.HitNormal   = nullable.Value.NormalInWorldSpace;
                        }
                    }
                    else if (character.GetIntersectionWithLine(ref line, ref base.CharHitInfo, IntersectionFlags.ALL_TRIANGLES))
                    {
                        base.HitPosition = base.CharHitInfo.Triangle.IntersectionPointInWorldSpace;
                        base.HitNormal   = base.CharHitInfo.Triangle.NormalInWorldSpace;
                        base.HitTag      = base.CharHitInfo;
                    }
                }
            }
            if (((interactive != null) && ((interactive.SupportedActions != UseActionEnum.None) && (Vector3D.Distance(translation, zero) < interactive.InteractiveDistance))) && ReferenceEquals(base.Character, MySession.Static.ControlledEntity))
            {
                HandleInteractiveObject(interactive);
                base.UseObject = interactive;
                flag           = true;
            }
            if (!flag)
            {
                base.UseObject = null;
            }
            base.DisableDetectors();
        }
示例#14
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();
        }