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