예제 #1
0
        public OBBCoords?GetOBBCoord(Vector3D worldPosition)
        {
            int index = 0;

            while (index < this.m_obbs.Length)
            {
                int num2 = 0;
                while (true)
                {
                    if (num2 >= this.m_obbs[0].Length)
                    {
                        index++;
                        break;
                    }
                    MyOrientedBoundingBoxD xd = this.m_obbs[index][num2].Value;
                    if (xd.Contains(ref worldPosition))
                    {
                        return(new OBBCoords?(new OBBCoords {
                            OBB = xd,
                            Coords = new Vector2I(index, num2)
                        }));
                    }
                    num2++;
                }
            }
            return(null);
        }
예제 #2
0
        public MyOrientedBoundingBoxD?GetOBB(Vector3D worldPosition)
        {
            MyOrientedBoundingBoxD?[][] obbs = this.m_obbs;
            int index = 0;

            while (index < obbs.Length)
            {
                MyOrientedBoundingBoxD?[] nullableArray2 = obbs[index];
                int num2 = 0;
                while (true)
                {
                    if (num2 >= nullableArray2.Length)
                    {
                        index++;
                        break;
                    }
                    MyOrientedBoundingBoxD?nullable = nullableArray2[num2];
                    MyOrientedBoundingBoxD xd       = nullable.Value;
                    if (xd.Contains(ref worldPosition))
                    {
                        return(nullable);
                    }
                    num2++;
                }
            }
            return(null);
        }
예제 #3
0
        public static unsafe void DisableItemsInObb(this MyEnvironmentSector sector, ref MyOrientedBoundingBoxD obb)
        {
            if (sector.DataView == null)
            {
                return;
            }

            obb.Center -= sector.SectorCenter;

            for (int sectorInd = 0; sectorInd < sector.DataView.LogicalSectors.Count; sectorInd++)
            {
                var logicalSector = sector.DataView.LogicalSectors[sectorInd];
                var logicalItems  = logicalSector.Items;
                var cnt           = logicalItems.Count;

                fixed(ItemInfo *items = logicalItems.GetInternalArray())
                for (int i = 0; i < cnt; ++i)
                {
                    if (items[i].DefinitionIndex >= 0 && obb.Contains(ref items[i].Position))
                    {
                        logicalSector.EnableItem(i, false);
                    }
                }
            }
        }
예제 #4
0
        public static bool IsPositionInSafeZone(Vector3D position)
        {
            foreach (var safezone in safezoneList)
            {
                var  zoneEntity    = safezone as IMyEntity;
                var  checkPosition = position;
                bool inZone        = false;

                if (safezone.Shape == MySafeZoneShape.Sphere)
                {
                    if (zoneEntity.PositionComp.WorldVolume.Contains(checkPosition) == ContainmentType.Contains)
                    {
                        inZone = true;
                    }
                }
                else
                {
                    MyOrientedBoundingBoxD myOrientedBoundingBoxD = new MyOrientedBoundingBoxD(zoneEntity.PositionComp.LocalAABB, zoneEntity.PositionComp.WorldMatrix);
                    inZone = myOrientedBoundingBoxD.Contains(ref checkPosition);
                }

                if (inZone == true)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        private bool OriginalSpotClear()
        {
            List <MyEntity> entities = new List <MyEntity>();

            MyGamePruningStructure.GetAllEntitiesInOBB(ref BoxD, entities);

            bool SpotCleared = true;

            foreach (var entity in entities.OfType <MyCubeGrid>())
            {
                MyOrientedBoundingBoxD OBB = new MyOrientedBoundingBoxD(entity.PositionComp.LocalAABB, entity.WorldMatrix);

                ContainmentType Type = BoxD.Contains(ref OBB);

                //Log.Info($"{entity.DisplayName} Type: {Type.ToString()}");

                if (Type == ContainmentType.Contains || Type == ContainmentType.Intersects)
                {
                    SpotCleared = false;
                    _Response.Respond("There are potentially other grids in the way. Attempting to spawn around the location to avoid collisions.");
                    break;
                }
            }

            return(SpotCleared);
        }
예제 #6
0
        private static bool HasBlocksInside(MyCubeGrid grid, ref MyOrientedBoundingBoxD obb)
        {
            Vector3I center = grid.WorldToGridInteger(obb.Center);
            double   radius = obb.HalfExtent.Length();

            radius *= grid.GridSizeR;
            Vector3I gridMin    = grid.Min;
            Vector3I gridMax    = grid.Max;
            double   radiusSq   = radius * radius;
            int      radiusCeil = (int)Math.Ceiling(radius);

            BoundingSphereD cubeSphere = new BoundingSphereD(new Vector3D(), grid.GridSizeHalf * Math.Sqrt(3));

            Vector3I max = Vector3I.Min(Vector3I.One * radiusCeil, gridMax - center);
            Vector3I min = Vector3I.Max(Vector3I.One * -radiusCeil, gridMin - center);
            int      x, y, z;

            for (x = min.X; x <= max.X; ++x)
            {
                for (y = min.Y; y <= max.Y; ++y)
                {
                    for (z = min.Z; z <= max.Z; ++z)
                    {
                        if (x * x + y * y + z * z >= radiusSq)
                        {
                            continue;
                        }

                        Vector3I offset = new Vector3I(x, y, z);

                        Vector3I cubePos = center + offset;
                        MyCube   cube;
                        if (!grid.TryGetCube(cubePos, out cube))
                        {
                            continue;
                        }

                        IMySlimBlock slim = cube.CubeBlock;
                        if (slim.IsDestroyed)
                        {
                            continue;
                        }

                        cubeSphere.Center = grid.GridIntegerToWorld(cubePos);
                        if (obb.Contains(ref cubeSphere) != ContainmentType.Disjoint)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
예제 #7
0
        private static bool IsAllowed(MySafeZone safezone, MyOrientedBoundingBoxD obb, IMyEntity original = null)
        {
            if (!safezone.Enabled)
            {
                return(true);
            }

            if (safezone.AccessTypeGrids == Sandbox.Common.ObjectBuilders.MySafeZoneAccess.Whitelist)
            {
                return(false);
            }

            if (safezone.Shape == Sandbox.Common.ObjectBuilders.MySafeZoneShape.Box)
            {
                var zoneOBB = new MyOrientedBoundingBoxD(safezone.PositionComp.LocalAABB, safezone.PositionComp.WorldMatrixRef);
                if (obb.Contains(ref zoneOBB) == ContainmentType.Disjoint)
                {
                    return(true);
                }
            }
            else
            {
                var zoneSphere = new BoundingSphereD(safezone.PositionComp.GetPosition(), safezone.Radius);
                if (obb.Contains(ref zoneSphere) == ContainmentType.Disjoint)
                {
                    return(true);
                }
            }

            // 512 = VRage.Game.ObjectBuilders.Components.MySafeZoneAction.BuildingProjections
            if (original == null)
            {
                return(safezone.IsActionAllowed(obb.GetAABB(), CastProhibit(safezone.AllowedActions, 512)));
            }
            return(safezone.IsActionAllowed((MyEntity)original, CastProhibit(safezone.AllowedActions, 512)));
        }
예제 #8
0
        //IsPositionInSafeZone
        public static bool IsPositionInSafeZone(Vector3D position)
        {
            var zones = GetSafeZones();

            foreach (var safezone in zones)
            {
                var zoneEntity = safezone as IMyEntity;

                if (zoneEntity == null)
                {
                    continue;
                }

                if (safezone.Enabled == false)
                {
                    continue;
                }

                var  checkPosition = position;
                bool inZone        = false;

                if (safezone.Shape == MySafeZoneShape.Sphere)
                {
                    if (Vector3D.Distance(zoneEntity.PositionComp.WorldVolume.Center, position) < safezone.Radius)
                    {
                        inZone = true;
                    }
                }
                else
                {
                    MyOrientedBoundingBoxD myOrientedBoundingBoxD = new MyOrientedBoundingBoxD(zoneEntity.PositionComp.LocalAABB, zoneEntity.PositionComp.WorldMatrix);
                    inZone = myOrientedBoundingBoxD.Contains(ref checkPosition);
                }

                if (inZone == true)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #9
0
        private unsafe void DisableOtherItemsInVMap(MyVoxelBase voxelMap)
        {
            MyOrientedBoundingBoxD obb = MyOrientedBoundingBoxD.Create((BoundingBoxD)voxelMap.PositionComp.LocalAABB, voxelMap.PositionComp.WorldMatrix);
            var center = obb.Center;

            var box = voxelMap.PositionComp.WorldAABB;

            m_entities.Clear();
            MyGamePruningStructure.GetAllEntitiesInBox(ref box, m_entities, MyEntityQueryType.Static);

            for (int eIndex = 0; eIndex < m_entities.Count; ++eIndex)
            {
                var sector = m_entities[eIndex] as MyEnvironmentSector;

                if (sector == null || sector.DataView == null)
                {
                    continue;
                }

                obb.Center = center - sector.SectorCenter;

                for (int sectorInd = 0; sectorInd < sector.DataView.LogicalSectors.Count; sectorInd++)
                {
                    var logicalSector = sector.DataView.LogicalSectors[sectorInd];
                    var logicalItems  = logicalSector.Items;
                    var cnt           = logicalItems.Count;

                    fixed(ItemInfo *items = logicalItems.GetInternalArray())
                    for (int i = 0; i < cnt; ++i)
                    {
                        var point = items[i].Position + sector.SectorCenter;

                        if (items[i].DefinitionIndex >= 0 && obb.Contains(ref items[i].Position) &&
                            voxelMap.CountPointsInside(&point, 1) > 0 && !IsVoxelItem(sector, items[i].DefinitionIndex))
                        {
                            logicalSector.EnableItem(i, false);
                        }
                    }
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Calculates amount of volume of a bounding box in voxels.
        /// </summary>
        /// <param name="localAabb">Local bounding box to query for.</param>
        /// <param name="worldMatrix">World matrix of the bounding box.</param>
        /// <returns>Pair of floats where 1st value is Volume amount and 2nd value is ratio of Volume amount to Whole volume.</returns>
        public MyTuple <float, float> GetVoxelContentInBoundingBox_Fast(BoundingBoxD localAabb, MatrixD worldMatrix)
        {
            MatrixD toVoxel = worldMatrix * PositionComp.WorldMatrixNormalizedInv;
            MatrixD toGrid; MatrixD.Invert(ref toVoxel, out toGrid);

            BoundingBoxD transAABB = localAabb.Transform(toVoxel);

            transAABB.Translate(SizeInMetresHalf + StorageMin);
            Vector3I minI = Vector3I.Floor(transAABB.Min);
            Vector3I maxI = Vector3I.Ceiling(transAABB.Max);

            double vol              = localAabb.Volume / MyVoxelConstants.VOXEL_VOLUME_IN_METERS;
            int    K                = Math.Max((MathHelper.Log2Ceiling((int)vol) - MathHelper.Log2Ceiling(100)) / 3, 0);
            float  voxelSizeAtLod   = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << K);
            float  voxelVolumeAtLod = voxelSizeAtLod * voxelSizeAtLod * voxelSizeAtLod;

            minI >>= K;
            maxI >>= K;

            // localAabb.Inflate(1 * voxelSizeAtLod);

            var offset = ((Size >> 1) + StorageMin) >> K;

            m_tempStorage.Resize(maxI - minI + 1);
            Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, K, minI, maxI);

            float resultVolume   = 0;
            float resultPercent  = 0;
            int   hitVolumeBoxes = 0;

            MyOrientedBoundingBoxD worldbbox = new MyOrientedBoundingBoxD(localAabb, worldMatrix);

            Vector3I coord, cache;

            for (coord.Z = minI.Z, cache.Z = 0; coord.Z <= maxI.Z; coord.Z++, cache.Z++)
            {
                for (coord.Y = minI.Y, cache.Y = 0; coord.Y <= maxI.Y; coord.Y++, cache.Y++)
                {
                    for (coord.X = minI.X, cache.X = 0; coord.X <= maxI.X; coord.X++, cache.X++)
                    {
                        Vector3D voxelPos = (coord - offset) * voxelSizeAtLod;

                        Vector3D gridPoint;
                        Vector3D.Transform(ref voxelPos, ref toGrid, out gridPoint);

                        ContainmentType cont;
                        //localAabb.Contains(ref gridPoint, out cont);

                        var voxelToWorld = WorldMatrix;
                        voxelToWorld.Translation -= (Vector3D)StorageMin + SizeInMetresHalf;

                        BoundingBoxD voxelBox = new BoundingBoxD();
                        voxelBox.Min = ((Vector3D)(coord) - .5) * voxelSizeAtLod;
                        voxelBox.Max = ((Vector3D)(coord) + .5) * voxelSizeAtLod;

                        MyOrientedBoundingBoxD voxelBbox = new MyOrientedBoundingBoxD(voxelBox, voxelToWorld);

                        cont = worldbbox.Contains(ref voxelBbox);

                        if (cont == ContainmentType.Disjoint)
                        {
                            //VRageRender.MyRenderProxy.DebugDrawOBB(
                            //new MyOrientedBoundingBoxD(voxelBox, voxelToWorld), Color.Red, 0.1f,
                            //true, false);
                            continue;
                        }

                        float content = m_tempStorage.Content(ref cache) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;



                        //VRageRender.MyRenderProxy.DebugDrawOBB(voxelBbox, Color.Aqua, content,
                        //   true, false);

                        resultVolume  += content * voxelVolumeAtLod;
                        resultPercent += content;
                        hitVolumeBoxes++;
                    }
                }
            }

            resultPercent /= hitVolumeBoxes;
            //float localAABBVol = (float)localAabb.Volume;
            //if (localAABBVol < resultVolume)
            //    resultPercent *= (float)localAabb.Volume / resultVolume;


            //VRageRender.MyRenderProxy.DebugDrawOBB(worldbbox, Color.Yellow, 0,
            //                true, false);
            //VRageRender.MyRenderProxy.DebugWaitForFrameFinish();


            return(new MyTuple <float, float>(resultVolume, resultPercent));
        }
예제 #11
0
        /// <summary>
        /// Handles camera collisions with environment
        /// </summary>
        /// <returns>False if no correct position was found</returns>
        private void HandleIntersection(MyEntity controlledEntity)
        {
            Debug.Assert(controlledEntity != null);
            MyEntity parentEntity           = controlledEntity.GetTopMostParent() ?? controlledEntity;
            var      parentEntityAsCubeGrid = parentEntity as MyCubeGrid;

            if (parentEntityAsCubeGrid != null && parentEntityAsCubeGrid.IsStatic)
            {
                parentEntity = controlledEntity;  // cancel previous assignment, topmost parent is a station, we need smaller bounding box
            }
            // line from target to eye
            LineD line = new LineD(m_target, m_position);
            // oriented bb of the entity
            MyOrientedBoundingBoxD safeObb = GetEntitySafeOBB(parentEntity);
            // oriented bb of the entity + camera radius
            MyOrientedBoundingBoxD safeObbWithCollisionExtents =
                new MyOrientedBoundingBoxD(safeObb.Center, safeObb.HalfExtent + (controlledEntity.Parent == null ? 0.5 : 2.0) * CAMERA_RADIUS, safeObb.Orientation);

            // start = target, end = eye
            // find safe start...
            LineD    safeOBBLine      = new LineD(line.From + line.Direction * 2 * safeObb.HalfExtent.Length(), line.From);
            double?  safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine);
            Vector3D castStartSafe    = safeIntersection != null ? (safeOBBLine.From + safeOBBLine.Direction * safeIntersection.Value) : m_target;

            if (controlledEntity.Parent != null && safeIntersection != null)
            {
                MatrixD shapeCastStart = MatrixD.CreateTranslation(castStartSafe);
                HkShape hkSphere       = new HkSphereShape(CAMERA_RADIUS * 2);
                var     hitInfo        = MyPhysics.CastShapeReturnContactBodyData(m_target, hkSphere, ref shapeCastStart, 0, 0);

                //VRageRender.MyRenderProxy.DebugDrawCapsule(castStartSafe, m_target, CAMERA_RADIUS * 2, Color.Orange, false);

                MyEntity hitEntity = hitInfo.HasValue ? hitInfo.Value.HkHitInfo.GetHitEntity() as MyEntity : null;
                MyEntity entity    = controlledEntity;

                var hitEntityWeldingGroup = hitEntity != null?MyWeldingGroups.Static.GetGroup(hitEntity) : null;

                bool weldingGroupEquals = false;

                while (entity != null && !weldingGroupEquals)
                {
                    if (hitEntityWeldingGroup == MyWeldingGroups.Static.GetGroup(entity))
                    {
                        weldingGroupEquals = true;
                    }

                    entity = entity.Parent;
                }

                if (hitInfo.HasValue && hitEntityWeldingGroup != null && weldingGroupEquals)
                {
                    castStartSafe = castStartSafe + hitInfo.Value.HkHitInfo.HitFraction * (m_target - castStartSafe);
                }
                else
                {
                    safeObb = GetEntitySafeOBB(controlledEntity);
                    safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeObb.Center, safeObb.HalfExtent + 0.5f * CAMERA_RADIUS, safeObb.Orientation);
                    safeIntersection            = safeObbWithCollisionExtents.Intersects(ref safeOBBLine);
                    castStartSafe = safeIntersection != null ? (safeOBBLine.From + safeOBBLine.Direction * safeIntersection.Value) : m_target;
                }
                hkSphere.RemoveReference();
            }

            // raycast against occluders
            Vector3D safePositionCandidate;

            //double lastSafeMinimumDistance = m_safeMinimumDistance;
            m_safeMinimumDistance = controlledEntity is MyCharacter ? 0 : (castStartSafe - m_target).Length(); // store current safe minimum dist
            m_safeMinimumDistance = Math.Max(m_safeMinimumDistance, MIN_VIEWER_DISTANCE);
            //if (lastSafeMinimumDistance + 30.0f < m_safeMinimumDistance)
            //{
            //    castStartSafe = m_target + (castStartSafe - m_target) / m_safeMinimumDistance * lastSafeMinimumDistance;
            //    m_safeMinimumDistance = lastSafeMinimumDistance;
            //}
            Vector3D raycastOrigin = (controlledEntity is MyCharacter) ? m_target : castStartSafe;
            MyCameraRaycastResult raycastResult = RaycastOccludingObjects(controlledEntity, ref raycastOrigin, ref m_position,
                                                                          ref castStartSafe, out safePositionCandidate);

            if (controlledEntity is MyCharacter && safeObb.Contains(ref safePositionCandidate))
            {
                raycastResult = MyCameraRaycastResult.FoundOccluderNoSpace;
            }

            // visual debugging :)
            if (m_debugDraw)
            {
                VRageRender.MyRenderProxy.DebugDrawOBB(safeObb, Color.Red, 0.1f, false, true);
                VRageRender.MyRenderProxy.DebugDrawOBB(safeObbWithCollisionExtents, Color.Yellow, 0.0f, false, true);
                VRageRender.MyRenderProxy.DebugDrawArrow3D(safeOBBLine.From, safeOBBLine.To, Color.White, Color.Purple,
                                                           false);
                VRageRender.MyRenderProxy.DebugDrawArrow3D(safeOBBLine.From, castStartSafe, Color.White, Color.Red,
                                                           false);
                VRageRender.MyRenderProxy.DebugDrawArrow3D(castStartSafe, m_position, Color.White, Color.Orange, false);

                VRageRender.MyRenderProxy.DebugDrawSphere(castStartSafe, 0.2f, Color.Green, 1.0f, false, true);
                VRageRender.MyRenderProxy.DebugDrawSphere(safePositionCandidate, 1.0f, Color.LightPink, 1, false);
            }

            switch (raycastResult)
            {
            case MyCameraRaycastResult.Ok:
            case MyCameraRaycastResult.FoundOccluder:
                m_positionCurrentIsSafe = true;
                {
                    double distFromCandidateToTarget = (safePositionCandidate - m_target).Length();
                    if (m_disableSpringThisFrame)
                    {
                        m_lastRaycastDist = (float)distFromCandidateToTarget;
                    }

                    if (!m_disableSpringThisFrame &&
                        ((distFromCandidateToTarget > m_lastRaycastDist + CAMERA_RADIUS && distFromCandidateToTarget > m_safeMinimumDistance) ||
                         raycastResult == MyCameraRaycastResult.Ok))
                    {
                        // now we need it from the other side
                        double newDist = (safePositionCandidate - m_position).Length();
                        // new safe position is further from target => change over time (zoom out)
                        if (m_positionSafeZoomingOutTimeout <= 0)
                        {
                            float distDiffZoomSpeed = 1 -
                                                      MathHelper.Clamp((float)Math.Abs(m_lastRaycastDist - newDist), 0.0f,
                                                                       1.0f - MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS);
                            m_positionSafeZoomingOutSpeed += distDiffZoomSpeed;
                            m_positionSafeZoomingOutSpeed  = MathHelper.Clamp(m_positionSafeZoomingOutSpeed, 0.0f,
                                                                              1.0f);

                            Vector3D targetToPosSafe     = m_positionSafe - m_target;
                            double   lenTargetToPosSafe  = targetToPosSafe.Length();
                            Vector3D rotatedPositionSafe = m_target +
                                                           Vector3D.Normalize(safePositionCandidate - m_target) *
                                                           lenTargetToPosSafe;
                            m_positionSafe = Vector3D.Lerp(rotatedPositionSafe, safePositionCandidate,
                                                           m_positionSafeZoomingOutSpeed);
                        }
                        else
                        {
                            m_positionSafeZoomingOutTimeout -= MyEngineConstants.UPDATE_STEP_SIZE_IN_MILLISECONDS;

                            Vector3D targetToPosSafe    = m_positionSafe - m_target;
                            double   lenTargetToPosSafe = targetToPosSafe.Length();
                            m_positionSafe = m_target + Vector3D.Normalize(safePositionCandidate - m_target) * lenTargetToPosSafe;
                        }
                    }
                    else
                    {
                        // new safe position is closer or closer than safe distance => instant change
                        m_positionSafeZoomingOutSpeed   = 0.0f; // set zooming out speed to zero for next time
                        m_positionSafeZoomingOutTimeout = 0;    // controlledEntity.Parent != null ? m_positionSafeZoomingOutDefaultTimeoutMs : 0;
                        m_positionSafe           = safePositionCandidate;
                        m_disableSpringThisFrame = true;
                        m_positionCurrentIsSafe  = distFromCandidateToTarget >= m_safeMinimumDistance;
                    }
                }
                break;

            //case MyCameraRaycastResult.FoundOccluderNoSpace:
            default:
                m_positionSafeZoomingOutSpeed = 1.0f;     // we're in first person, change instantly to third if possible
                m_positionCurrentIsSafe       = false;
                break;
            }

            m_lastRaycastDist = (float)(m_positionSafe - m_position).Length();

            if (m_debugDraw)
            {
                VRageRender.MyRenderProxy.DebugDrawSphere(m_positionSafe, 0.225f, Color.Purple, 1, false);
                VRageRender.MyRenderProxy.DebugDrawSphere(safePositionCandidate, 0.2f, Color.Azure, 1, false);
            }
        }
예제 #12
0
        /// <summary>
        /// Calculates amount of volume of a bounding box in voxels.
        /// </summary>
        /// <param name="localAabb">Local bounding box to query for.</param>
        /// <param name="worldMatrix">World matrix of the bounding box.</param>
        /// <returns>Pair of floats where 1st value is Volume amount and 2nd value is ratio of Volume amount to Whole volume.</returns>
        public MyTuple<float,float> GetVoxelContentInBoundingBox_Fast(BoundingBoxD localAabb, MatrixD worldMatrix)
        {
            MatrixD toVoxel = worldMatrix * PositionComp.WorldMatrixNormalizedInv;
            MatrixD toGrid; MatrixD.Invert(ref toVoxel, out toGrid);

            BoundingBoxD transAABB = localAabb.TransformFast(toVoxel);
            transAABB.Translate(SizeInMetresHalf + StorageMin);
            Vector3I minI = Vector3I.Floor(transAABB.Min);
            Vector3I maxI = Vector3I.Ceiling(transAABB.Max);

            double vol = localAabb.Volume / MyVoxelConstants.VOXEL_VOLUME_IN_METERS;
            int K = Math.Max((MathHelper.Log2Ceiling((int)vol) - MathHelper.Log2Ceiling(100)) / 3, 0);
            float voxelSizeAtLod = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << K);
            float voxelVolumeAtLod = voxelSizeAtLod * voxelSizeAtLod * voxelSizeAtLod;
            minI >>= K;
            maxI >>= K;

           // localAabb.Inflate(1 * voxelSizeAtLod);

            var offset = ((Size >> 1) + StorageMin) >> K;

            m_tempStorage.Resize(maxI - minI + 1);
            Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, K, minI, maxI);

            float resultVolume = 0;
            float resultPercent = 0;
            int hitVolumeBoxes = 0;

            MyOrientedBoundingBoxD worldbbox = new MyOrientedBoundingBoxD(localAabb, worldMatrix);

            Vector3I coord, cache;
            for (coord.Z = minI.Z, cache.Z = 0; coord.Z <= maxI.Z; coord.Z++, cache.Z++)
            {
                for (coord.Y = minI.Y, cache.Y = 0; coord.Y <= maxI.Y; coord.Y++, cache.Y++)
                {
                    for (coord.X = minI.X, cache.X = 0; coord.X <= maxI.X; coord.X++, cache.X++)
                    {
                        Vector3D voxelPos = (coord - offset) * voxelSizeAtLod;

                        Vector3D gridPoint;
                        Vector3D.Transform(ref voxelPos, ref toGrid, out gridPoint);

                        ContainmentType cont;
                        //localAabb.Contains(ref gridPoint, out cont);

                        var voxelToWorld = WorldMatrix;
                        voxelToWorld.Translation -= (Vector3D)StorageMin + SizeInMetresHalf;

                        BoundingBoxD voxelBox = new BoundingBoxD();
                        voxelBox.Min = ((Vector3D)(coord) - .5) * voxelSizeAtLod;
                        voxelBox.Max = ((Vector3D)(coord) + .5) * voxelSizeAtLod;

                        MyOrientedBoundingBoxD voxelBbox = new MyOrientedBoundingBoxD(voxelBox, voxelToWorld);

                        cont = worldbbox.Contains(ref voxelBbox);

                        if (cont == ContainmentType.Disjoint)
                        {
                            //VRageRender.MyRenderProxy.DebugDrawOBB(
                            //new MyOrientedBoundingBoxD(voxelBox, voxelToWorld), Color.Red, 0.1f,
                            //true, false);
                            continue;
                        }

                        float content = m_tempStorage.Content(ref cache) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;



                        //VRageRender.MyRenderProxy.DebugDrawOBB(voxelBbox, Color.Aqua, content,
                        //   true, false);

                        resultVolume += content * voxelVolumeAtLod;
                        resultPercent += content;
                        hitVolumeBoxes++;
                    }
                }
            }

            resultPercent /= hitVolumeBoxes; 
            //float localAABBVol = (float)localAabb.Volume;
            //if (localAABBVol < resultVolume)
            //    resultPercent *= (float)localAabb.Volume / resultVolume;


            //VRageRender.MyRenderProxy.DebugDrawOBB(worldbbox, Color.Yellow, 0,
            //                true, false);
            //VRageRender.MyRenderProxy.DebugWaitForFrameFinish();


            return new MyTuple<float, float>(resultVolume, resultPercent);
        }
예제 #13
0
        public static unsafe void DisableItemsInObb(this MyEnvironmentSector sector, ref MyOrientedBoundingBoxD obb)
        {
            if (sector.DataView == null)
                return;

            obb.Center -= sector.SectorCenter;

            for (int sectorInd = 0; sectorInd < sector.DataView.LogicalSectors.Count; sectorInd++)
            {
                var logicalSector = sector.DataView.LogicalSectors[sectorInd];
                var logicalItems = logicalSector.Items;
                var cnt = logicalItems.Count;

                fixed (ItemInfo* items = logicalItems.GetInternalArray())
                    for (int i = 0; i < cnt; ++i)
                    {
                        if (items[i].DefinitionIndex >= 0 && obb.Contains(ref items[i].Position))
                            logicalSector.EnableItem(i, false);
                    }
            }
        }
예제 #14
0
        static ContainmentType ContainsAdv(this MyOrientedBoundingBoxD obb, BoundingFrustumD frust, HashSet <Vector3D> internalPoints, out bool noCorners)
        {
            var points = new Vector3D[8];

            obb.GetCorners(points, 0);
            int inside = 0;

            for (int i = 0; i < points.Length; i++)
            {
                if (frust.Contains(points[i]) != ContainmentType.Disjoint)
                {
                    inside++;
                    internalPoints.Add(points[i]);
                }
            }
            noCorners = false;
            switch (inside)
            {
            case (8):
                return(ContainmentType.Contains);

            default:
                if (internalPoints.Count != 0 || frust.Contains(obb.GetAABB()) != ContainmentType.Disjoint)
                {
                    noCorners = true;
                    var res   = new HashSet <Vector3D>();
                    var lines = frust.GetLines();
                    for (int i = 0; i < lines.Length; i++)
                    {
                        var from = obb.Contains(ref lines[i].From);
                        var to   = obb.Contains(ref lines[i].To);
                        if (from && to)
                        {
                            res.Add(lines[i].From);
                            res.Add(lines[i].To);
                        }
                        else if (from)
                        {
                            res.Add(lines[i].From);
                            res.Add(lines[i].GetPoint(obb.Intersects(ref lines[i]).Value));
                        }
                        else if (to)
                        {
                            res.Add(lines[i].To);
                            var back = lines[i].Reverse();
                            res.Add(back.GetPoint(obb.Intersects(ref back).Value));
                        }
                        else
                        {
                            var first  = obb.Intersects(ref lines[i]);
                            var back   = lines[i].Reverse();
                            var second = obb.Intersects(ref back);
                            if (first != null)
                            {
                                res.Add(lines[i].GetPoint(first.Value));
                            }
                            if (second != null)
                            {
                                res.Add(back.GetPoint(second.Value));
                            }
                        }
                    }
                    lines = obb.GetLines();
                    for (int i = 0; i < lines.Length; i++)
                    {
                        var from = frust.Contains(lines[i].From) != ContainmentType.Disjoint;
                        var to   = frust.Contains(lines[i].To) != ContainmentType.Disjoint;
                        if (from && to)
                        {
                            res.Add(lines[i].From);
                            res.Add(lines[i].To);
                        }
                        else if (from)
                        {
                            res.Add(lines[i].From);
                            res.Add(lines[i].GetPoint(frust.Intersects(lines[i].ToRay()).Value));
                        }
                        else if (to)
                        {
                            res.Add(lines[i].To);
                            res.Add(lines[i].Reverse().GetPoint(frust.Intersects(lines[i].ToReversedRay()).Value));
                        }
                        else
                        {
                            var first  = frust.Intersects(lines[i].ToRay());
                            var second = frust.Intersects(lines[i].ToReversedRay());
                            if (first != null)
                            {
                                res.Add(lines[i].GetPoint(first.Value));
                            }
                            if (second != null)
                            {
                                res.Add(lines[i].Reverse().GetPoint(second.Value));
                            }
                        }
                    }

                    foreach (var r in res)
                    {
                        internalPoints.Add(r);
                    }
                    if (internalPoints.Count > 0)
                    {
                        return(ContainmentType.Intersects);
                    }
                }
                return(ContainmentType.Disjoint);
            }
        }
예제 #15
0
        private void DrawActiveLeads()
        {
            var s     = _session;
            var focus = s.TrackingAi.Construct.Data.Repo.FocusData;

            MyEntity target;

            if (!MyEntities.TryGetEntityById(focus.Target[focus.ActiveId], out target) && target.Physics == null)
            {
                return;
            }

            var targetSphere = target.PositionComp.WorldVolume;

            float    maxLeadLength;
            Vector3D fullAveragePos;

            if (!ComputeLead(target, targetSphere.Center, out maxLeadLength, out fullAveragePos))
            {
                return;
            }

            var lineStart   = targetSphere.Center;
            var lineNormDir = Vector3D.Normalize(fullAveragePos - lineStart);
            var ray         = new RayD(lineStart, lineNormDir);

            var rayDist = s.CameraFrustrum.Intersects(ray);

            if (!s.Camera.IsInFrustum(ref targetSphere) || rayDist == null)
            {
                return;
            }

            var lineEnd      = lineStart + (lineNormDir * maxLeadLength);
            var endScreenPos = s.Camera.WorldToScreen(ref lineEnd);

            var worldLine = new LineD(lineEnd, lineStart, maxLeadLength);

            var obb        = new MyOrientedBoundingBoxD(target.PositionComp.LocalAABB, target.PositionComp.WorldMatrixRef);
            var lineLength = obb.Intersects(ref worldLine) ?? 0;

            if (lineLength < 0.2f)
            {
                return;
            }

            var lineScale = (float)(0.1 * s.ScaleFov);

            var startScreenPos = s.Camera.WorldToScreen(ref lineStart);
            var scaledAspect   = lineScale * _session.AspectRatio;

            var      scale              = s.Settings.ClientConfig.HudScale;
            var      fontScale          = scale * s.ScaleFov;
            Vector3D fursthestScreenPos = Vector3D.Zero;
            double   furthestDist       = 0;
            var      element            = 0;

            for (int i = 0; i < _leadInfos.Count; i++)
            {
                var info = _leadInfos[i];

                if (obb.Contains(ref info.Position))
                {
                    continue;
                }

                var screenPos       = s.Camera.WorldToScreen(ref info.Position);
                var lockedScreenPos = MyUtils.GetClosestPointOnLine(ref startScreenPos, ref endScreenPos, ref screenPos);

                var distSqr = Vector3D.DistanceSquared(lockedScreenPos, startScreenPos);
                if (distSqr > furthestDist)
                {
                    furthestDist       = distSqr;
                    fursthestScreenPos = lockedScreenPos;
                }

                var textColor = !info.WillHit ? new Vector4(1, 1, 1, 1) : new Vector4(1, 0.025f, 0.025f, 1);

                string textLine1     = (i + 1).ToString();
                var    fontFocusSize = !info.WillHit ? 8 : 11;
                var    fontSize      = (float)Math.Round(fontFocusSize * fontScale, 2);
                var    fontHeight    = 0.75f;
                var    fontAge       = -1;
                var    fontJustify   = Hud.Justify.Center;
                var    fontType      = Hud.FontType.Shadow;
                var    elementId     = 2000 + element++;
                s.HudUi.AddText(text: textLine1, x: (float)lockedScreenPos.X, y: (float)lockedScreenPos.Y, elementId: elementId, ttl: fontAge, color: textColor, justify: fontJustify, fontType: fontType, fontSize: fontSize, heightScale: fontHeight);
            }

            var endDotPos = new Vector2D(fursthestScreenPos.X, fursthestScreenPos.Y);

            endDotPos.X *= scaledAspect;
            endDotPos.Y *= lineScale;

            var lineEndScreenPos = Vector3D.Transform(new Vector3D(endDotPos.X, endDotPos.Y, -0.1), s.CameraMatrix);

            var culledLineStart      = lineEnd - (lineNormDir * lineLength);
            var culledStartScreenPos = s.Camera.WorldToScreen(ref culledLineStart);

            var culledStartDotPos = new Vector2D(culledStartScreenPos.X, culledStartScreenPos.Y);

            culledStartDotPos.X *= scaledAspect;
            culledStartDotPos.Y *= lineScale;

            var lineStartScreenPos = Vector3D.Transform(new Vector3D(culledStartDotPos.X, culledStartDotPos.Y, -0.1), s.CameraMatrix);

            var lineColor     = new Vector4(0.5f, 0.5f, 1, 1);
            var lineMagnitude = lineEndScreenPos - lineStartScreenPos;

            MyTransparentGeometry.AddLineBillboard(_laserLine, lineColor, lineStartScreenPos, lineMagnitude, 1f, lineScale * 0.005f);

            var avgScreenPos       = s.Camera.WorldToScreen(ref fullAveragePos);
            var avgLockedScreenPos = MyUtils.GetClosestPointOnLine(ref startScreenPos, ref endScreenPos, ref avgScreenPos);

            var dotpos = new Vector2D(avgLockedScreenPos.X, avgLockedScreenPos.Y);

            dotpos.X          *= scaledAspect;
            dotpos.Y          *= lineScale;
            avgLockedScreenPos = Vector3D.Transform(new Vector3D(dotpos.X, dotpos.Y, -0.1), s.CameraMatrix);

            var size                = (float)((0.00125f * scale) * s.ScaleFov);
            var left                = (Vector3)s.CameraMatrix.Left;
            var up                  = (Vector3)s.CameraMatrix.Up;
            var repColor            = new Vector4(1, 1, 1, 1);
            var time                = s.Tick % 20; // forward and backward total time
            var increase            = time < 10;
            var directionalTimeStep = increase ? time : 19 - time;
            var textureMap          = s.HudUi.PaintedTexture[directionalTimeStep];

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref avgLockedScreenPos, size, size, ref left, ref up);
            MyTransparentGeometry.AddTriangleBillboard(quad.Point0, quad.Point1, quad.Point2, Vector3.Zero, Vector3.Zero, Vector3.Zero, textureMap.P0, textureMap.P1, textureMap.P3, textureMap.Material, 0, avgLockedScreenPos, repColor, BlendTypeEnum.PostPP);
            MyTransparentGeometry.AddTriangleBillboard(quad.Point0, quad.Point3, quad.Point2, Vector3.Zero, Vector3.Zero, Vector3.Zero, textureMap.P0, textureMap.P2, textureMap.P3, textureMap.Material, 0, avgLockedScreenPos, repColor, BlendTypeEnum.PostPP);

            _leadInfos.Clear();
        }