コード例 #1
0
        protected override void ReadEntitiesInRange()
        {
            m_entitiesInRange.Clear();
            m_hits.Clear();
            MyPhysics.CastRay(m_origin, FrontPoint, m_hits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);

            DetectionInfo value            = new DetectionInfo();
            bool          encounteredModel = false;

            foreach (var hit in m_hits)
            {
                var hitInfo = hit.HkHitInfo;
                if (hitInfo.Body == null)
                {
                    continue;
                }
                var entity = hitInfo.GetHitEntity();

                if (entity == null)
                {
                    continue;
                }
                var rootEntity = entity.GetTopMostParent();
                if (!IgnoredEntities.Contains(rootEntity))
                {
                    Vector3D detectionPoint = hit.Position;

                    MyCubeGrid grid = rootEntity as MyCubeGrid;
                    if (grid != null)
                    {
                        var shape    = hitInfo.Body.GetShape();
                        int shapeIdx = 0;
                        if (grid.Physics.IsWelded || grid.GetPhysicsBody().WeldInfo.Children.Count != 0)
                        {
                            if (shape.IsContainer())
                            {
                                shape    = shape.GetContainer().GetShape(hitInfo.GetShapeKey(0));
                                shapeIdx = 1;
                            }
                        }
                        if (!GetShapeCenter(shape, hitInfo.GetShapeKey(shapeIdx), grid, ref detectionPoint))
                        {
                            if (grid.GridSizeEnum == MyCubeSize.Large)
                            {
                                detectionPoint += hit.HkHitInfo.Normal * -0.08f;
                            }
                            else
                            {
                                detectionPoint += hit.HkHitInfo.Normal * -0.02f;
                            }
                        }
                    }

                    if (m_entitiesInRange.TryGetValue(rootEntity.EntityId, out value))
                    {
                        var oldDistance = Vector3.DistanceSquared(value.DetectionPoint, m_origin);
                        var newDistance = Vector3.DistanceSquared(detectionPoint, m_origin);
                        if (oldDistance > newDistance)
                        {
                            m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity as MyEntity, detectionPoint);
                        }
                    }
                    else
                    {
                        m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity as MyEntity, detectionPoint);
                    }

                    if (entity is MyEnvironmentSector && !encounteredModel)
                    {
                        var sector   = entity as MyEnvironmentSector;
                        var shapekey = hitInfo.GetShapeKey(0);
                        var itemId   = sector.GetItemFromShapeKey(shapekey);
                        if (sector.DataView.Items[itemId].ModelIndex < 0)
                        {
                            continue;
                        }
                        encounteredModel = true;
                        m_entitiesInRange[entity.EntityId] = new DetectionInfo(sector, detectionPoint, itemId);
                    }
                }
            }

            LineD line = new LineD(m_origin, FrontPoint);

            using (m_raycastResults.GetClearToken())
            {
                MyGamePruningStructure.GetAllEntitiesInRay(ref line, m_raycastResults);
                foreach (var segment in m_raycastResults)
                {
                    if (segment.Element == null)
                    {
                        continue;
                    }
                    var rootEntity = segment.Element.GetTopMostParent();
                    if (!IgnoredEntities.Contains(rootEntity))
                    {
                        MyCubeBlock block = segment.Element as MyCubeBlock;
                        if (block == null)
                        {
                            continue;
                        }

                        Vector3D point = new Vector3D();

                        if (block.SlimBlock.HasPhysics == false)
                        {
                            MatrixD  blockWorldMatrixNormalizedInv = block.PositionComp.WorldMatrixNormalizedInv;
                            Vector3D localOrigin = Vector3D.Transform(m_origin, ref blockWorldMatrixNormalizedInv);
                            Vector3D localFront  = Vector3D.Transform(FrontPoint, ref blockWorldMatrixNormalizedInv);
                            Ray      ray         = new Ray(localOrigin, Vector3.Normalize(localFront - localOrigin));
                            //MyRenderProxy.DebugDrawAABB(block.WorldAABB, Color.Red.ToVector3(), 1.0f, 1.0f, false);
                            float?dist = ray.Intersects(block.PositionComp.LocalAABB);
                            dist += 0.01f;
                            if (dist.HasValue && dist <= m_rayLength)
                            {
                                point = m_origin + Vector3D.Normalize(FrontPoint - m_origin) * dist.Value;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // This entity was caught by Havok raycast
                            continue;
                        }

                        if (m_entitiesInRange.TryGetValue(rootEntity.EntityId, out value))
                        {
                            if (Vector3.DistanceSquared(value.DetectionPoint, m_origin) > Vector3.DistanceSquared(point, m_origin))
                            {
                                m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, point);
                            }
                        }
                        else
                        {
                            m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, point);
                        }
                    }
                }
            }
        }
コード例 #2
0
        protected override void ReadEntitiesInRange()
        {
            m_entitiesInRange.Clear();
            m_hits.Clear();
            MyPhysics.CastRay(m_origin, FrontPoint, m_hits, MyPhysics.ObjectDetectionCollisionLayer);

            DetectionInfo value = new DetectionInfo();

            foreach (var hit in m_hits)
            {
                if (hit.HkHitInfo.Body == null)
                {
                    continue;
                }
                var entity = hit.HkHitInfo.Body.GetEntity();
                if (entity == null)
                {
                    continue;
                }
                var rootEntity = entity.GetTopMostParent();
                if (!IgnoredEntities.Contains(rootEntity))
                {
                    Vector3D fixedDetectionPoint = hit.Position;
                    if (rootEntity is MyCubeGrid)
                    {
                        MyCubeGrid grid = rootEntity as MyCubeGrid;
                        if (grid.GridSizeEnum == Common.ObjectBuilders.MyCubeSize.Large)
                        {
                            fixedDetectionPoint += hit.HkHitInfo.Normal * -0.08f;
                        }
                        else
                        {
                            fixedDetectionPoint += hit.HkHitInfo.Normal * -0.02f;
                        }
                    }

                    if (m_entitiesInRange.TryGetValue(rootEntity.EntityId, out value))
                    {
                        if (Vector3.DistanceSquared(value.DetectionPoint, m_origin) > Vector3.DistanceSquared(fixedDetectionPoint, m_origin))
                        {
                            m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity as MyEntity, fixedDetectionPoint);
                        }
                    }
                    else
                    {
                        m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity as MyEntity, fixedDetectionPoint);
                    }
                }
            }

            LineD line = new LineD(m_origin, FrontPoint);

            using (m_raycastResults.GetClearToken())
            {
                MyGamePruningStructure.GetAllEntitiesInRay(ref line, m_raycastResults);
                foreach (var segment in m_raycastResults)
                {
                    if (segment.Element == null)
                    {
                        continue;
                    }
                    var rootEntity = segment.Element.GetTopMostParent();
                    if (!IgnoredEntities.Contains(rootEntity))
                    {
                        if (!(segment.Element is MyCubeBlock))
                        {
                            continue;
                        }

                        Vector3D point = new Vector3D();

                        MyCubeBlock block = segment.Element as MyCubeBlock;
                        if (block.SlimBlock.HasPhysics == false)
                        {
                            Vector3D localOrigin = Vector3D.Transform(m_origin, block.PositionComp.WorldMatrixNormalizedInv);
                            Vector3D localFront  = Vector3D.Transform(FrontPoint, block.PositionComp.WorldMatrixNormalizedInv);
                            Ray      ray         = new Ray(localOrigin, Vector3.Normalize(localFront - localOrigin));
                            //MyRenderProxy.DebugDrawAABB(block.WorldAABB, Color.Red.ToVector3(), 1.0f, 1.0f, false);
                            float?dist = ray.Intersects(block.PositionComp.LocalAABB);
                            dist += 0.01f;
                            if (dist.HasValue && dist <= m_rayLength)
                            {
                                point = m_origin + Vector3D.Normalize(FrontPoint - m_origin) * dist.Value;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // This entity was caught by Havok raycast
                            continue;
                        }

                        if (m_entitiesInRange.TryGetValue(rootEntity.EntityId, out value))
                        {
                            if (Vector3.DistanceSquared(value.DetectionPoint, m_origin) > Vector3.DistanceSquared(point, m_origin))
                            {
                                m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, point);
                            }
                        }
                        else
                        {
                            m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, point);
                        }
                    }
                }
            }
        }