private void FindForestInitialCandidate()
        {
            BoundingBoxD groundBox = m_ground.PositionComp.WorldAABB;
            Vector3D boxSize = groundBox.Size;
            boxSize *= 0.1f;
            groundBox.Inflate(-boxSize);
            MyBBSetSampler sampler = new MyBBSetSampler(groundBox.Min, groundBox.Max);

            bool posIsValid = true;
            Vector3D worldPos = default(Vector3D);
            int counter = 0;
            do
            {
                // find random position for starting 
                worldPos = sampler.Sample();
                var worldPosProjected = worldPos;
                worldPosProjected.Y = 0.5f;
                posIsValid = true;
                counter++;
                Vector3D areaCheck = new Vector3D(20, 20, 20);
                foreach (var enqueued in m_initialForestLocations)
                {
                    // only interested in XZ plane
                    BoundingBoxD tmp = new BoundingBoxD(enqueued - areaCheck, enqueued + areaCheck);
                    tmp.Min.Y = 0;
                    tmp.Max.Y = 1;

                    if (tmp.Contains(worldPosProjected) == ContainmentType.Contains)
                    {
                        posIsValid = false;
                        break;
                    }
                }
            } while (!posIsValid && counter != 10);

            if (!posIsValid)
            {
                // could not find any position
                return;
            }

            var lineStart = new Vector3D(worldPos.X, groundBox.Max.Y, worldPos.Z);
            var lineEnd = new Vector3D(worldPos.X, groundBox.Min.Y, worldPos.Z);
            LineD line = new LineD(lineStart, lineEnd);
            VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = null;
            var correctGroundDefinition = MyDefinitionManager.Static.GetVoxelMaterialDefinition("Grass");
            var materialId = correctGroundDefinition.Index;

            if (m_ground.GetIntersectionWithLine(ref line, out result, VRage.Game.Components.IntersectionFlags.DIRECT_TRIANGLES))
            {
                Vector3D intersectionPoint = result.Value.IntersectionPointInWorldSpace;
                Vector3I voxelCoord, minRead, maxRead;
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(m_ground.PositionLeftBottomCorner, ref intersectionPoint, out voxelCoord);
                minRead = voxelCoord - Vector3I.One;
                maxRead = voxelCoord + Vector3I.One;
                m_ground.Storage.ReadRange(m_voxelCache, MyStorageDataTypeFlags.Material, 0, ref minRead, ref maxRead);

                var minLocal = Vector3I.Zero;
                var maxLocal = Vector3I.One * 2;
                var it = new Vector3I_RangeIterator(ref minLocal, ref maxLocal);
                while (it.IsValid())
                {
                    var vec = it.Current;
                    var material = m_voxelCache.Material(ref vec);
                    if (material == materialId)
                    {
                        // found a location
                        var desired = voxelCoord - Vector3I.One + vec;
                        Vector3D desiredWorldPosition = default(Vector3D);
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(m_ground.PositionLeftBottomCorner, ref desired, out desiredWorldPosition);
                        m_initialForestLocations.Enqueue(desiredWorldPosition);
                        break;
                    }

                    it.MoveNext();
                }
            }
        }
        public bool PointsInsideGizmo(List<Vector3> points, MyGizmoSpaceEnum gizmo, ref MatrixD invGridWorldMatrix, float gridSize, float inflate = 0.0f, bool onVoxel = false)
        {
            MatrixD m = new MatrixD();
            BoundingBoxD gizmoBox = new BoundingBoxD();
            GetGizmoPointTestVariables(ref invGridWorldMatrix, gridSize, out gizmoBox, out m, gizmo, inflate: inflate, onVoxel: onVoxel);

            foreach (var point in points)
            {
                Vector3 localPoint = Vector3.Transform(point, m);

                if (gizmoBox.Contains(localPoint) == ContainmentType.Contains)
                    return true;
            }
            return false;
        }
Example #3
0
        //1. Object A reaches borders
        //2. Make ideal cluster box B around A
        //3. Detect all cluster intersections C of B
        //4. Make union of all C and B to D
        //5. Find best division of D
        //6. Foreach dominant axis
        //6A  split until only allowed size
        //6B  leave lowest larger size
        //repeat 6 until dominant axis is allowed size or not splittable
        public void ReorderClusters(BoundingBoxD aabb, ulong objectId)
        {
            //1+2
            aabb.InflateToMinimum(IdealClusterSize);

            bool         isBoxSafe    = false;
            BoundingBoxD unionCluster = aabb;

            //3
            m_clusterTree.OverlapAllBoundingBox(ref unionCluster, m_resultList);
            HashSet <MyObjectData> objectsInUnion = new HashSet <MyObjectData>();

            while (!isBoxSafe)
            {
                //4
                objectsInUnion.Clear();
                objectsInUnion.Add(m_objectsData[objectId]);

                foreach (MyCluster collidedCluster in m_resultList)
                {
                    unionCluster.Include(collidedCluster.AABB);
                    foreach (var ob in m_objectsData.Where(x => collidedCluster.Objects.Contains(x.Key)).Select(x => x.Value))
                    {
                        objectsInUnion.Add(ob);
                    }
                }

                int oldClustersCount = m_resultList.Count;
                //3
                m_clusterTree.OverlapAllBoundingBox(ref unionCluster, m_resultList);

                isBoxSafe = oldClustersCount == m_resultList.Count; //Box is safe only if no new clusters were added

                m_staticTree.OverlapAllBoundingBox(ref unionCluster, m_objectDataResultList);
                foreach (var ob in m_objectDataResultList)
                {
                    if (m_objectsData[ob].Cluster != null)
                    {
                        if (!m_resultList.Contains(m_objectsData[ob].Cluster))
                        {
                            unionCluster.Include(m_objectsData[ob].Cluster.AABB);
                            isBoxSafe = false;
                        }
                    }
                }
            }

            m_staticTree.OverlapAllBoundingBox(ref unionCluster, m_objectDataResultList);
            foreach (var ob in m_objectDataResultList)
            {
                //var c = m_objectsData[ob].Cluster.AABB.Contains(unionCluster);
                System.Diagnostics.Debug.Assert(m_objectsData[ob].Cluster == null || m_objectsData[ob].Cluster.AABB.Contains(m_objectsData[ob].AABB) != ContainmentType.Disjoint, "Clusters failure");
                System.Diagnostics.Debug.Assert(m_objectsData[ob].Cluster == null || (m_clusters.Contains(m_objectsData[ob].Cluster) && m_resultList.Contains(m_objectsData[ob].Cluster)), "Static object is not inside found clusters");
                objectsInUnion.Add(m_objectsData[ob]);
            }

#if DEBUG
            foreach (var ob in objectsInUnion)
            {
                System.Diagnostics.Debug.Assert(ob.Cluster == null || (m_clusters.Contains(ob.Cluster) && m_resultList.Contains(ob.Cluster)), "There is object not belonging to found cluster!");
            }
#endif

            //5
            Stack <MyClusterDescription> clustersToDivide = new Stack <MyClusterDescription>();
            List <MyClusterDescription>  finalClusters    = new List <MyClusterDescription>();

            var unionClusterDesc = new MyClusterDescription()
            {
                AABB           = unionCluster,
                DynamicObjects = objectsInUnion.Where(x => x.ActivationHandler == null || !x.ActivationHandler.IsStaticForCluster).ToList(),
                StaticObjects  = objectsInUnion.Where(x => (x.ActivationHandler != null) && x.ActivationHandler.IsStaticForCluster).ToList(),
            };
            clustersToDivide.Push(unionClusterDesc);

            var staticObjectsToRemove = unionClusterDesc.StaticObjects.Where(x => x.Cluster != null).ToList();
            var staticObjectsTotal    = unionClusterDesc.StaticObjects.Count;


            while (clustersToDivide.Count > 0)
            {
                MyClusterDescription desc = clustersToDivide.Pop();

                if (desc.DynamicObjects.Count == 0)
                {
                    continue;
                }

                //minimal valid aabb usable for this cluster
                BoundingBoxD minimumCluster = BoundingBoxD.CreateInvalid();
                for (int i = 0; i < desc.DynamicObjects.Count; i++)
                {
                    MyObjectData objectData0 = desc.DynamicObjects[i];
                    BoundingBoxD aabb0       = objectData0.AABB.GetInflated(IdealClusterSize / 2);
                    minimumCluster.Include(aabb0);
                }

                //Divide along longest axis
                BoundingBoxD dividedCluster = minimumCluster;

                Vector3D currentMax  = minimumCluster.Max;
                int      longestAxis = minimumCluster.Size.AbsMaxComponent();

                switch (longestAxis)
                {
                case 0:
                    desc.DynamicObjects.Sort(AABBComparerX.Static);
                    break;

                case 1:
                    desc.DynamicObjects.Sort(AABBComparerY.Static);
                    break;

                case 2:
                    desc.DynamicObjects.Sort(AABBComparerZ.Static);
                    break;
                }

                bool isClusterSplittable = false;

                if (minimumCluster.Size.AbsMax() >= MaximumForSplit.AbsMax())
                {
                    for (int i = 1; i < desc.DynamicObjects.Count; i++)
                    {
                        MyObjectData objectData0 = desc.DynamicObjects[i - 1];
                        MyObjectData objectData1 = desc.DynamicObjects[i];

                        BoundingBoxD aabb0 = objectData0.AABB.GetInflated(IdealClusterSize / 2);
                        BoundingBoxD aabb1 = objectData1.AABB.GetInflated(IdealClusterSize / 2);

                        //two neigbour object have distance between them bigger than minimum
                        if ((aabb1.Min.GetDim(longestAxis) - aabb0.Max.GetDim(longestAxis)) > 0)
                        {
                            System.Diagnostics.Debug.Assert(aabb0.Max.GetDim(longestAxis) - minimumCluster.Min.GetDim(longestAxis) > 0, "Invalid minimal cluster");
                            isClusterSplittable = true;

                            currentMax.SetDim(longestAxis, aabb0.Max.GetDim(longestAxis));

                            break;
                        }
                    }
                }

                dividedCluster.Max = currentMax;

                dividedCluster.InflateToMinimum(IdealClusterSize);

                MyClusterDescription dividedClusterDesc = new MyClusterDescription()
                {
                    AABB           = dividedCluster,
                    DynamicObjects = new List <MyObjectData>(),
                    StaticObjects  = new List <MyObjectData>(),
                };

                foreach (var dynObj in desc.DynamicObjects.ToList())
                {
                    var cont = dividedCluster.Contains(dynObj.AABB);
                    if (cont == ContainmentType.Contains)
                    {
                        dividedClusterDesc.DynamicObjects.Add(dynObj);
                        desc.DynamicObjects.Remove(dynObj);
                    }

                    System.Diagnostics.Debug.Assert(cont != ContainmentType.Intersects, "Cannot split clusters in the middle of objects");
                }
                foreach (var statObj in desc.StaticObjects.ToList())
                {
                    var cont = dividedCluster.Contains(statObj.AABB);
                    if ((cont == ContainmentType.Contains) || (cont == ContainmentType.Intersects))
                    {
                        dividedClusterDesc.StaticObjects.Add(statObj);
                        desc.StaticObjects.Remove(statObj);
                    }
                }

                dividedClusterDesc.AABB = dividedCluster;

                if (desc.DynamicObjects.Count > 0)
                {
                    BoundingBoxD restCluster = BoundingBoxD.CreateInvalid();

                    foreach (var restbb in desc.DynamicObjects)
                    {
                        restCluster.Include(restbb.AABB.GetInflated(MinimumDistanceFromBorder));
                    }

                    restCluster.InflateToMinimum(IdealClusterSize);

                    MyClusterDescription restClusterDesc = new MyClusterDescription()
                    {
                        AABB           = restCluster,
                        DynamicObjects = desc.DynamicObjects.ToList(),
                        StaticObjects  = desc.StaticObjects.ToList(),
                    };

                    if (restClusterDesc.AABB.Size.AbsMax() > 2 * IdealClusterSize.AbsMax())
                    {
                        clustersToDivide.Push(restClusterDesc);
                    }
                    else
                    {
                        finalClusters.Add(restClusterDesc);
                    }
                }

                if (dividedClusterDesc.AABB.Size.AbsMax() > 2 * IdealClusterSize.AbsMax() && isClusterSplittable)
                {
                    clustersToDivide.Push(dividedClusterDesc);
                }
                else
                {
                    finalClusters.Add(dividedClusterDesc);
                }
            }

#if DEBUG
            //Check consistency
            for (int i = 0; i < finalClusters.Count; i++)
            {
                for (int j = 0; j < finalClusters.Count; j++)
                {
                    if (i != j)
                    {
                        var cont = finalClusters[i].AABB.Contains(finalClusters[j].AABB);
                        System.Diagnostics.Debug.Assert(cont == ContainmentType.Disjoint, "Overlapped clusters!");
                        if (cont != ContainmentType.Disjoint)
                        {
                        }
                    }
                }
            }
#endif

#if DEBUG
            Dictionary <MyCluster, List <ulong> > objectsPerRemovedCluster = new Dictionary <MyCluster, List <ulong> >();
            Dictionary <MyCluster, List <ulong> > dynamicObjectsInCluster  = new Dictionary <MyCluster, List <ulong> >();
            foreach (var finalCluster in finalClusters)
            {
                foreach (var ob in finalCluster.DynamicObjects)
                {
                    if (ob.Cluster != null)
                    {
                        if (!objectsPerRemovedCluster.ContainsKey(ob.Cluster))
                        {
                            objectsPerRemovedCluster[ob.Cluster] = new List <ulong>();
                        }

                        objectsPerRemovedCluster[ob.Cluster].Add(ob.Id);
                    }
                    else
                    {
                    }
                }
            }

            foreach (var removingCluster in objectsPerRemovedCluster)
            {
                dynamicObjectsInCluster[removingCluster.Key] = new List <ulong>();
                foreach (var ob in removingCluster.Key.Objects)
                {
                    if (!m_objectsData[ob].ActivationHandler.IsStaticForCluster)
                    {
                        dynamicObjectsInCluster[removingCluster.Key].Add(ob);
                    }
                }

                System.Diagnostics.Debug.Assert(removingCluster.Value.Count == dynamicObjectsInCluster[removingCluster.Key].Count, "Not all objects from removing cluster are going to new clusters!");
            }

            Dictionary <MyCluster, List <ulong> > staticObjectsInCluster = new Dictionary <MyCluster, List <ulong> >();
            foreach (var staticObj in staticObjectsToRemove)
            {
                System.Diagnostics.Debug.Assert(staticObj.Cluster != null, "Where to remove?");
                if (!staticObjectsInCluster.ContainsKey(staticObj.Cluster))
                {
                    staticObjectsInCluster[staticObj.Cluster] = new List <ulong>();
                }

                staticObjectsInCluster[staticObj.Cluster].Add(staticObj.Id);
            }
#endif

            HashSet <MyCluster> oldClusters = new HashSet <MyCluster>();
            HashSet <MyCluster> newClusters = new HashSet <MyCluster>();

            foreach (var staticObj in staticObjectsToRemove)
            {
                if (staticObj.Cluster != null)
                {
                    oldClusters.Add(staticObj.Cluster);
                    RemoveObjectFromCluster(staticObj, true);
                }
                else
                {
                }
            }

            foreach (var staticObj in staticObjectsToRemove)
            {
                if (staticObj.Cluster != null)
                {
                    staticObj.ActivationHandler.FinishRemoveBatch(staticObj.Cluster.UserData);
                    staticObj.Cluster = null;
                }
            }

            int staticObjectsAdded = 0;

            //Move objects from old clusters to new clusters, use batching
            foreach (var finalCluster in finalClusters)
            {
                BoundingBoxD clusterAABB = finalCluster.AABB;
                MyCluster    newCluster  = CreateCluster(ref clusterAABB);

#if DEBUG
                for (int i = 0; i < finalCluster.DynamicObjects.Count; i++)
                {
                    for (int j = 0; j < finalCluster.DynamicObjects.Count; j++)
                    {
                        if (i != j)
                        {
                            System.Diagnostics.Debug.Assert(finalCluster.DynamicObjects[i].Id != finalCluster.DynamicObjects[j].Id);
                        }
                    }
                }
#endif

                foreach (var obj in finalCluster.DynamicObjects)
                {
                    if (obj.Cluster != null)
                    {
                        oldClusters.Add(obj.Cluster);
                        RemoveObjectFromCluster(obj, true);
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(objectId == obj.Id || obj.ActivationHandler.IsStaticForCluster, "Dynamic object must have cluster");
                    }
                }

                foreach (var obj in finalCluster.DynamicObjects)
                {
                    if (obj.Cluster != null)
                    {
                        obj.ActivationHandler.FinishRemoveBatch(obj.Cluster.UserData);
                        obj.Cluster = null;
                    }
                }

                //Finish batches on old worlds and remove old worlds
                foreach (MyCluster oldCluster in oldClusters)
                {
                    if (OnFinishBatch != null)
                    {
                        OnFinishBatch(oldCluster.UserData);
                    }
                }


                foreach (var obj in finalCluster.DynamicObjects)
                {
                    AddObjectToCluster(newCluster, obj.Id, true);
                }

                foreach (var obj in finalCluster.StaticObjects)
                {
                    if (newCluster.AABB.Contains(obj.AABB) != ContainmentType.Disjoint)
                    {
                        AddObjectToCluster(newCluster, obj.Id, true);
                        staticObjectsAdded++;
                    }
                }

                newClusters.Add(newCluster);
            }

            System.Diagnostics.Debug.Assert(staticObjectsTotal >= staticObjectsAdded, "Static objects appeared out of union");

#if DEBUG
            //foreach (var finalCluster in finalClusters)
            //{
            //    foreach (var obj in finalCluster.DynamicObjects)
            //    {
            //        System.Diagnostics.Debug.Assert(!oldClusters.Contains(obj.Cluster), "Object was not added to correct cluster");
            //    }
            //}

            //foreach (var objectData in m_objectsData)
            //{
            //    if (!objectData.Value.ActivationHandler.IsStaticForCluster)
            //        System.Diagnostics.Debug.Assert(!oldClusters.Contains(objectData.Value.Cluster));
            //}

            //foreach (var objectData in m_objectsData)
            //{
            //    if (!objectData.Value.ActivationHandler.IsStaticForCluster)
            //        System.Diagnostics.Debug.Assert(m_clusters.Contains(objectData.Value.Cluster));
            //}
#endif
            foreach (MyCluster oldCluster in oldClusters)
            {
                RemoveCluster(oldCluster);
            }

            //Finish batches on new world and their objects
            foreach (MyCluster newCluster in newClusters)
            {
                if (OnFinishBatch != null)
                {
                    OnFinishBatch(newCluster.UserData);
                }

                foreach (var ob in newCluster.Objects)
                {
                    if (m_objectsData[ob].ActivationHandler != null)
                    {
                        m_objectsData[ob].ActivationHandler.FinishAddBatch();
                    }
                }
            }
        }
        public void ReorderClusters(BoundingBoxD aabb, ulong objectId = 18446744073709551615L)
        {
            using (this.m_clustersReorderLock.AcquireExclusiveUsing())
            {
                aabb.InflateToMinimum(IdealClusterSize);
                bool         flag = false;
                BoundingBoxD bbox = aabb;
                this.m_clusterTree.OverlapAllBoundingBox <MyCluster>(ref bbox, m_resultList, 0, true);
                HashSet <MyObjectData> source = new HashSet <MyObjectData>();
                while (!flag)
                {
                    source.Clear();
                    if (objectId != ulong.MaxValue)
                    {
                        source.Add(this.m_objectsData[objectId]);
                    }
                    using (List <MyCluster> .Enumerator enumerator = m_resultList.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            Func <KeyValuePair <ulong, MyObjectData>, bool> predicate = null;
                            MyCluster collidedCluster = enumerator.Current;
                            bbox.Include(collidedCluster.AABB);
                            if (predicate == null)
                            {
                                predicate = x => collidedCluster.Objects.Contains(x.Key);
                            }
                            foreach (MyObjectData data in from x in this.m_objectsData.Where <KeyValuePair <ulong, MyObjectData> >(predicate) select x.Value)
                            {
                                source.Add(data);
                            }
                        }
                    }
                    int num = m_resultList.Count;
                    this.m_clusterTree.OverlapAllBoundingBox <MyCluster>(ref bbox, m_resultList, 0, true);
                    flag = num == m_resultList.Count;
                    this.m_staticTree.OverlapAllBoundingBox <ulong>(ref bbox, m_objectDataResultList, 0, true);
                    foreach (ulong num2 in m_objectDataResultList)
                    {
                        if ((this.m_objectsData[num2].Cluster != null) && !m_resultList.Contains(this.m_objectsData[num2].Cluster))
                        {
                            bbox.Include(this.m_objectsData[num2].Cluster.AABB);
                            flag = false;
                        }
                    }
                }
                this.m_staticTree.OverlapAllBoundingBox <ulong>(ref bbox, m_objectDataResultList, 0, true);
                foreach (ulong num3 in m_objectDataResultList)
                {
                    source.Add(this.m_objectsData[num3]);
                }
                Stack <MyClusterDescription> stack = new Stack <MyClusterDescription>();
                List <MyClusterDescription>  list  = new List <MyClusterDescription>();
                MyClusterDescription         item  = new MyClusterDescription {
                    AABB           = bbox,
                    DynamicObjects = source.Where <MyObjectData>(delegate(MyObjectData x) {
                        if (x.ActivationHandler != null)
                        {
                            return(!x.ActivationHandler.IsStaticForCluster);
                        }
                        return(true);
                    }).ToList <MyObjectData>(),
                    StaticObjects = (from x in source
                                     where (x.ActivationHandler != null) && x.ActivationHandler.IsStaticForCluster
                                     select x).ToList <MyObjectData>()
                };
                stack.Push(item);
                List <MyObjectData> list2 = (from x in item.StaticObjects
                                             where x.Cluster != null
                                             select x).ToList <MyObjectData>();
                int count = item.StaticObjects.Count;
                while (stack.Count > 0)
                {
                    MyClusterDescription description2 = stack.Pop();
                    if (description2.DynamicObjects.Count != 0)
                    {
                        BoundingBoxD xd2 = BoundingBoxD.CreateInvalid();
                        for (int i = 0; i < description2.DynamicObjects.Count; i++)
                        {
                            MyObjectData data2    = description2.DynamicObjects[i];
                            BoundingBoxD inflated = data2.AABB.GetInflated((Vector3)(IdealClusterSize / 2f));
                            xd2.Include(inflated);
                        }
                        BoundingBoxD xd4  = xd2;
                        Vector3D     max  = xd2.Max;
                        int          num5 = xd2.Size.AbsMaxComponent();
                        switch (num5)
                        {
                        case 0:
                            description2.DynamicObjects.Sort(AABBComparerX.Static);
                            break;

                        case 1:
                            description2.DynamicObjects.Sort(AABBComparerY.Static);
                            break;

                        case 2:
                            description2.DynamicObjects.Sort(AABBComparerZ.Static);
                            break;
                        }
                        bool flag2 = false;
                        if (xd2.Size.AbsMax() >= MaximumForSplit.AbsMax())
                        {
                            for (int j = 1; j < description2.DynamicObjects.Count; j++)
                            {
                                MyObjectData data3 = description2.DynamicObjects[j - 1];
                                MyObjectData data4 = description2.DynamicObjects[j];
                                BoundingBoxD xd5   = data3.AABB.GetInflated((Vector3)(IdealClusterSize / 2f));
                                if ((data4.AABB.GetInflated((Vector3)(IdealClusterSize / 2f)).Min.GetDim(num5) - xd5.Max.GetDim(num5)) > 0.0)
                                {
                                    flag2 = true;
                                    max.SetDim(num5, xd5.Max.GetDim(num5));
                                    break;
                                }
                            }
                        }
                        xd4.Max = max;
                        xd4.InflateToMinimum(IdealClusterSize);
                        MyClusterDescription description3 = new MyClusterDescription {
                            AABB           = xd4,
                            DynamicObjects = new List <MyObjectData>(),
                            StaticObjects  = new List <MyObjectData>()
                        };
                        foreach (MyObjectData data5 in description2.DynamicObjects.ToList <MyObjectData>())
                        {
                            if (xd4.Contains(data5.AABB) == ContainmentType.Contains)
                            {
                                description3.DynamicObjects.Add(data5);
                                description2.DynamicObjects.Remove(data5);
                            }
                        }
                        foreach (MyObjectData data6 in description2.StaticObjects.ToList <MyObjectData>())
                        {
                            switch (xd4.Contains(data6.AABB))
                            {
                            case ContainmentType.Contains:
                            case ContainmentType.Intersects:
                                description3.StaticObjects.Add(data6);
                                description2.StaticObjects.Remove(data6);
                                break;
                            }
                        }
                        description3.AABB = xd4;
                        if (description2.DynamicObjects.Count > 0)
                        {
                            BoundingBoxD xd7 = BoundingBoxD.CreateInvalid();
                            foreach (MyObjectData data7 in description2.DynamicObjects)
                            {
                                xd7.Include(data7.AABB.GetInflated(MinimumDistanceFromBorder));
                            }
                            xd7.InflateToMinimum(IdealClusterSize);
                            MyClusterDescription description4 = new MyClusterDescription {
                                AABB           = xd7,
                                DynamicObjects = description2.DynamicObjects.ToList <MyObjectData>(),
                                StaticObjects  = description2.StaticObjects.ToList <MyObjectData>()
                            };
                            if (description4.AABB.Size.AbsMax() > (2f * IdealClusterSize.AbsMax()))
                            {
                                stack.Push(description4);
                            }
                            else
                            {
                                list.Add(description4);
                            }
                        }
                        if ((description3.AABB.Size.AbsMax() > (2f * IdealClusterSize.AbsMax())) && flag2)
                        {
                            stack.Push(description3);
                        }
                        else
                        {
                            list.Add(description3);
                        }
                    }
                }
                HashSet <MyCluster> set2 = new HashSet <MyCluster>();
                HashSet <MyCluster> set3 = new HashSet <MyCluster>();
                foreach (MyObjectData data8 in list2)
                {
                    if (data8.Cluster != null)
                    {
                        set2.Add(data8.Cluster);
                        this.RemoveObjectFromCluster(data8, true);
                    }
                }
                foreach (MyObjectData data9 in list2)
                {
                    if (data9.Cluster != null)
                    {
                        data9.ActivationHandler.FinishRemoveBatch(data9.Cluster.UserData);
                        data9.Cluster = null;
                    }
                }
                int num7 = 0;
                foreach (MyClusterDescription description7 in list)
                {
                    BoundingBoxD aABB    = description7.AABB;
                    MyCluster    cluster = this.CreateCluster(ref aABB);
                    foreach (MyObjectData data10 in description7.DynamicObjects)
                    {
                        if (data10.Cluster != null)
                        {
                            set2.Add(data10.Cluster);
                            this.RemoveObjectFromCluster(data10, true);
                        }
                    }
                    foreach (MyObjectData data11 in description7.DynamicObjects)
                    {
                        if (data11.Cluster != null)
                        {
                            data11.ActivationHandler.FinishRemoveBatch(data11.Cluster.UserData);
                            data11.Cluster = null;
                        }
                    }
                    foreach (MyCluster cluster2 in set2)
                    {
                        if (this.OnFinishBatch != null)
                        {
                            this.OnFinishBatch(cluster2.UserData);
                        }
                    }
                    foreach (MyObjectData data12 in description7.DynamicObjects)
                    {
                        this.AddObjectToCluster(cluster, data12.Id, true);
                    }
                    foreach (MyObjectData data13 in description7.StaticObjects)
                    {
                        if (cluster.AABB.Contains(data13.AABB) != ContainmentType.Disjoint)
                        {
                            this.AddObjectToCluster(cluster, data13.Id, true);
                            num7++;
                        }
                    }
                    set3.Add(cluster);
                }
                foreach (MyCluster cluster3 in set2)
                {
                    this.RemoveCluster(cluster3);
                }
                foreach (MyCluster cluster4 in set3)
                {
                    if (this.OnFinishBatch != null)
                    {
                        this.OnFinishBatch(cluster4.UserData);
                    }
                    foreach (ulong num8 in cluster4.Objects)
                    {
                        if (this.m_objectsData[num8].ActivationHandler != null)
                        {
                            this.m_objectsData[num8].ActivationHandler.FinishAddBatch();
                        }
                    }
                }
                if (this.OnClustersReordered != null)
                {
                    this.OnClustersReordered();
                }
            }
        }
        /// <summary>
        /// Performes a physics raycast
        /// It can be recursive (it calls CastDDA when it hits a grid).
        /// </summary>
        /// <param name="fromWorldPos"></param>
        /// <returns>Returns starting damage for current stack</returns>
        private MyRaycastDamageInfo CastPhysicsRay(Vector3D fromWorldPos)
        {
            Vector3D pos = Vector3D.Zero;
            IMyEntity hitEntity = null;

            var hitInfo = MyPhysics.CastRay(fromWorldPos, m_explosion.Center, MyPhysics.ExplosionRaycastLayer);
            if (hitInfo.HasValue)
            {
                hitEntity = (hitInfo.Value.HkHitInfo.Body.UserObject != null) ? ((MyPhysicsBody)hitInfo.Value.HkHitInfo.Body.UserObject).Entity : null;
                pos = hitInfo.Value.Position;
            }
            Vector3D direction = (m_explosion.Center - fromWorldPos);
            float lengthToCenter = (float)direction.Length();
            direction.Normalize();

            var grid = (hitEntity as MyCubeGrid);
            if (grid == null)
            {
                MyCubeBlock hitBlock = hitEntity as MyCubeBlock;
                if (hitBlock != null)
                {
                    grid = hitBlock.CubeGrid;
                }
            }
            if (grid != null)
            {
                //Try advancing the point to find the intersected block
                //If the block is a cube, this is necessary because the raycast will return a point somewhere outside the cube
                //If the block is not a full cube (slope, special block), the raycast can return inside the cube
                //It advances 4 times, each time one 8th the grid size
                for (int i = 0; i < 5; i++)
                {
                    Vector3D localPos = Vector3D.Transform(pos, grid.PositionComp.WorldMatrixNormalizedInv) / grid.GridSize;
                    Vector3I gridPos = Vector3I.Round(localPos);
                    var cubeBlock = grid.GetCubeBlock(gridPos);
                    if (cubeBlock != null)
                    {
                        if (m_castBlocks.Contains(cubeBlock))
                        {
                            //This shouldn't happen
                            //There is a corner case where the explosion position is inside the empty cell, but this should be handleded somewhere higher
                            System.Diagnostics.Debug.Fail("Raycast failed!");
                            DrawRay(fromWorldPos, pos, Color.Red);
                            return new MyRaycastDamageInfo(0f, lengthToCenter);
                        }
                        else
                        {
                            if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                                DrawRay(fromWorldPos, pos, Color.Blue);
                            return CastDDA(cubeBlock);
                        }
                    }
                    pos += direction * grid.GridSize / 8f;
                }
                //We hit a grid but were unable to find the hit cube. Send another raycast
                //Ideally, we would want to get the cube in all cases, but it also has to be fast
                //We need to check if the explosion center is between the initial start position (fromWorldPos) and the new one (pos)

                Vector3D min = new Vector3D(Math.Min(fromWorldPos.X, pos.X), Math.Min(fromWorldPos.Y, pos.Y), Math.Min(fromWorldPos.Z, pos.Z));
                Vector3D max = new Vector3D(Math.Max(fromWorldPos.X, pos.X), Math.Max(fromWorldPos.Y, pos.Y), Math.Max(fromWorldPos.Z, pos.Z));

                BoundingBoxD boundingBox = new BoundingBoxD(min, max);
                if (boundingBox.Contains(m_explosion.Center) == ContainmentType.Contains)
                {
                    return new MyRaycastDamageInfo(m_explosionDamage, lengthToCenter);
                }

                stackOverflowGuard++;
                if (stackOverflowGuard > MAX_PHYSICS_RECURSION_COUNT)
                {
                    System.Diagnostics.Debug.Fail("Potential stack overflow!");
                    if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                        DrawRay(fromWorldPos, pos, Color.Red);
                    return new MyRaycastDamageInfo(0f, lengthToCenter);
                }
                else
                {
                    if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                        DrawRay(fromWorldPos, pos, Color.White);
                    return CastPhysicsRay(pos);
                }
            }
            else if (hitInfo.HasValue)
            {
                //Something was hit, but it wasn't a grid. This needs to be handled somehow
                if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                    DrawRay(fromWorldPos, pos, Color.Violet);
                return new MyRaycastDamageInfo(0, lengthToCenter);
            }

            //Nothing was hit, so we can assume the there was nothing blocking the explosion
            if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                DrawRay(fromWorldPos, pos, Color.Salmon);
            return new MyRaycastDamageInfo(m_explosionDamage, lengthToCenter);
        }
        private new bool TestPlacement()
        {
            bool retval = true;

            m_touchingGrids.Clear();

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

                m_touchingGrids.Add(null);

                if (MyCubeBuilder.Static.DynamicMode)
                {
                    if (!m_dynamicBuildAllowed)
                    {
                        var settings = m_settings.GetGridPlacementSettings(grid, false);

                        BoundingBoxD localAabb   = (BoundingBoxD)grid.PositionComp.LocalAABB;
                        MatrixD      worldMatrix = grid.WorldMatrix;

                        if (MyFakes.ENABLE_VOXEL_MAP_AABB_CORNER_TEST)
                        {
                            retval = retval && MyCubeGrid.TestPlacementVoxelMapOverlap(null, ref settings, ref localAabb, ref worldMatrix);
                        }

                        retval = retval && MyCubeGrid.TestPlacementArea(grid, false, ref settings, localAabb, true);

                        if (!retval)
                        {
                            break;
                        }

                        //foreach (var block in grid.GetBlocks())
                        //{
                        //    Vector3 minLocal = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                        //    Vector3 maxLocal = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                        //    BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal);
                        //    retval &= MyCubeGrid.TestPlacementArea(grid, false, ref settings, aabbLocal, true);
                        //    if (!retval)
                        //        break;
                        //}
                    }
                }
                else
                { //not dynamic building mode
                    if (i == 0 && m_hitEntity is MyCubeGrid && IsSnapped && SnapMode == MyGridPlacementSettings.SnapMode.Base6Directions)
                    {
                        var settings = grid.GridSizeEnum == MyCubeSize.Large ? MyPerGameSettings.BuildingSettings.LargeStaticGrid : MyPerGameSettings.BuildingSettings.SmallStaticGrid;

                        var hitGrid = m_hitEntity as MyCubeGrid;

                        if (hitGrid.GridSizeEnum == MyCubeSize.Small && grid.GridSizeEnum == MyCubeSize.Large)
                        {
                            retval = false;
                            break;
                        }

                        bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && grid.GridSizeEnum == MyCubeSize.Small;

                        if (MyFakes.ENABLE_STATIC_SMALL_GRID_ON_LARGE /*&& grid.IsStatic*/ && smallOnLargeGrid)
                        {
                            if (!hitGrid.IsStatic)
                            {
                                retval = false;
                                break;
                            }

                            foreach (var block in grid.CubeBlocks)
                            {
                                if (block.FatBlock is MyCompoundCubeBlock)
                                {
                                    MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                                    foreach (var blockInCompound in compoundBlock.GetBlocks())
                                    {
                                        retval = retval && TestBlockPlacement(blockInCompound, ref settings);
                                        if (!retval)
                                        {
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    retval = retval && TestBlockPlacement(block, ref settings);
                                }

                                if (!retval)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            retval = retval && TestGridPlacementOnGrid(grid, ref settings, hitGrid);
                        }
                    }
                    else
                    {
                        // Check with grid settings
                        {
                            MyCubeGrid touchingGrid = null;
                            var        settings     = i == 0 ? (grid.GridSizeEnum == MyCubeSize.Large ? MyPerGameSettings.BuildingSettings.LargeStaticGrid : MyPerGameSettings.BuildingSettings.SmallStaticGrid)
                                : MyPerGameSettings.BuildingSettings.GetGridPlacementSettings(grid);

                            if (grid.IsStatic)
                            {
                                if (i == 0)
                                {
                                    Matrix orientation = grid.WorldMatrix.GetOrientation();
                                    retval = retval && MyCubeBuilder.CheckValidBlocksRotation(orientation, grid);
                                }

                                foreach (var block in grid.CubeBlocks)
                                {
                                    if (block.FatBlock is MyCompoundCubeBlock)
                                    {
                                        MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                                        foreach (var blockInCompound in compoundBlock.GetBlocks())
                                        {
                                            MyCubeGrid touchingGridLocal = null;
                                            retval = retval && TestBlockPlacementNoAABBInflate(blockInCompound, ref settings, out touchingGridLocal);

                                            if (retval && touchingGridLocal != null && touchingGrid == null)
                                            {
                                                touchingGrid = touchingGridLocal;
                                            }

                                            if (!retval)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        MyCubeGrid touchingGridLocal = null;
                                        retval = retval && TestBlockPlacementNoAABBInflate(block, ref settings, out touchingGridLocal);

                                        if (retval && touchingGridLocal != null && touchingGrid == null)
                                        {
                                            touchingGrid = touchingGridLocal;
                                        }
                                    }

                                    if (!retval)
                                    {
                                        break;
                                    }
                                }

                                if (retval && touchingGrid != null)
                                {
                                    m_touchingGrids[i] = touchingGrid;
                                }
                            }
                            else
                            {
                                foreach (var block in grid.CubeBlocks)
                                {
                                    Vector3      minLocal  = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                                    Vector3      maxLocal  = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                                    BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal);
                                    retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settings, aabbLocal, false);

                                    if (!retval)
                                    {
                                        break;
                                    }
                                }

                                m_touchingGrids[i] = null;
                            }
                        }

                        // Check connectivity with touching grid
                        if (retval && m_touchingGrids[i] != null)
                        {
                            var settings = grid.GridSizeEnum == MyCubeSize.Large ? MyPerGameSettings.BuildingSettings.LargeStaticGrid : MyPerGameSettings.BuildingSettings.SmallStaticGrid;
                            retval = retval && TestGridPlacementOnGrid(grid, ref settings, m_touchingGrids[i]);
                        }

                        // Check with paste settings only first grid
                        {
                            if (retval && i == 0)
                            {
                                bool smallStaticGrid = grid.GridSizeEnum == MyCubeSize.Small && grid.IsStatic;
                                if (smallStaticGrid || !grid.IsStatic)
                                {
                                    var  settings    = i == 0 ? m_settings.GetGridPlacementSettings(grid, false) : MyPerGameSettings.BuildingSettings.SmallStaticGrid;
                                    bool localRetVal = true;

                                    foreach (var block in grid.CubeBlocks)
                                    {
                                        Vector3      minLocal       = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                                        Vector3      maxLocal       = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                                        BoundingBoxD blockLocalAABB = new BoundingBoxD(minLocal, maxLocal);

                                        localRetVal = localRetVal && MyCubeGrid.TestPlacementArea(grid, false, ref settings, blockLocalAABB, false);
                                        if (!localRetVal)
                                        {
                                            break;
                                        }
                                    }

                                    retval &= !localRetVal;
                                }
                                else if (m_touchingGrids[i] == null)
                                {
                                    var settings = m_settings.GetGridPlacementSettings(grid, i == 0 ? true : grid.IsStatic);

                                    MyCubeGrid touchingGridLocal = null;

                                    bool localRetVal = false;
                                    foreach (var block in grid.CubeBlocks)
                                    {
                                        if (block.FatBlock is MyCompoundCubeBlock)
                                        {
                                            MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                                            foreach (var blockInCompound in compoundBlock.GetBlocks())
                                            {
                                                localRetVal |= TestBlockPlacementNoAABBInflate(blockInCompound, ref settings, out touchingGridLocal);
                                                if (localRetVal)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            localRetVal |= TestBlockPlacementNoAABBInflate(block, ref settings, out touchingGridLocal);
                                        }

                                        if (localRetVal)
                                        {
                                            break;
                                        }
                                    }

                                    retval &= localRetVal;
                                }
                            }
                        }
                    }
                }

                BoundingBoxD aabb = (BoundingBoxD)grid.PositionComp.LocalAABB;
                MatrixD      invGridWorlMatrix = grid.PositionComp.WorldMatrixNormalizedInv;

                // Character collisions.
                if (MySector.MainCamera != null)
                {
                    Vector3D cameraPos = Vector3D.Transform(MySector.MainCamera.Position, invGridWorlMatrix);
                    retval = retval && aabb.Contains(cameraPos) != ContainmentType.Contains;
                }

                if (retval)
                {
                    m_tmpCollisionPoints.Clear();
                    MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints);
                    foreach (var pt in m_tmpCollisionPoints)
                    {
                        Vector3D ptLocal = Vector3D.Transform(pt, invGridWorlMatrix);
                        retval = retval && aabb.Contains(ptLocal) != ContainmentType.Contains;
                        if (!retval)
                        {
                            break;
                        }
                    }
                }

                if (!retval)
                {
                    break;
                }
            }

            return(retval);
        }
        public bool PointsAABBIntersectsGizmo(List<Vector3D> points, MyGizmoSpaceEnum gizmo, ref MatrixD invGridWorldMatrix, float gridSize, float inflate = 0.0f, bool onVoxel = false, bool dynamicMode = false)
        {
            MatrixD m = new MatrixD();
            BoundingBoxD gizmoBox = new BoundingBoxD();
            GetGizmoPointTestVariables(ref invGridWorldMatrix, gridSize, out gizmoBox, out m, gizmo, inflate: inflate, onVoxel: onVoxel, dynamicMode: dynamicMode);

            BoundingBoxD pointsBox = BoundingBoxD.CreateInvalid();
            foreach (var point in points)
            {
                Vector3D localPoint = Vector3D.Transform(point, m);

                if (gizmoBox.Contains(localPoint) == ContainmentType.Contains)
                    return true;

                pointsBox.Include(localPoint);
            }

            return pointsBox.Intersects(ref gizmoBox);
        }
Example #8
0
        private Vector3D?FindSuitableJumpLocationSpace(Vector3D desiredLocation)
        {
            List <MyObjectSeed> m_objectsInRange   = new List <MyObjectSeed>();
            List <BoundingBoxD> m_obstaclesInRange = new List <BoundingBoxD>();
            List <MyEntity>     m_entitiesInRange  = new List <MyEntity>();


            BoundingSphereD Inflated = SphereD;

            Inflated.Radius *= 1.5;
            Inflated.Center  = desiredLocation;

            Vector3D vector3D = desiredLocation;

            MyProceduralWorldGenerator.Static.OverlapAllAsteroidSeedsInSphere(Inflated, m_objectsInRange);
            foreach (MyObjectSeed item3 in m_objectsInRange)
            {
                m_obstaclesInRange.Add(item3.BoundingVolume);
            }
            m_objectsInRange.Clear();

            MyProceduralWorldGenerator.Static.GetAllInSphere <MyStationCellGenerator>(Inflated, m_objectsInRange);
            foreach (MyObjectSeed item4 in m_objectsInRange)
            {
                MyStation myStation = item4.UserData as MyStation;
                if (myStation != null)
                {
                    BoundingBoxD item = new BoundingBoxD(myStation.Position - MyStation.SAFEZONE_SIZE, myStation.Position + MyStation.SAFEZONE_SIZE);
                    if (item.Contains(vector3D) != 0)
                    {
                        m_obstaclesInRange.Add(item);
                    }
                }
            }
            m_objectsInRange.Clear();


            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref Inflated, m_entitiesInRange);
            foreach (MyEntity item5 in m_entitiesInRange)
            {
                if (!(item5 is MyPlanet))
                {
                    m_obstaclesInRange.Add(item5.PositionComp.WorldAABB.GetInflated(Inflated.Radius));
                }
            }

            int          num          = 10;
            int          num2         = 0;
            BoundingBoxD?boundingBoxD = null;
            bool         flag         = false;
            bool         flag2        = false;

            while (num2 < num)
            {
                num2++;
                flag = false;
                foreach (BoundingBoxD item6 in m_obstaclesInRange)
                {
                    ContainmentType containmentType = item6.Contains(vector3D);
                    if (containmentType == ContainmentType.Contains || containmentType == ContainmentType.Intersects)
                    {
                        if (!boundingBoxD.HasValue)
                        {
                            boundingBoxD = item6;
                        }
                        boundingBoxD = boundingBoxD.Value.Include(item6);
                        boundingBoxD = boundingBoxD.Value.Inflate(1.0);
                        vector3D     = ClosestPointOnBounds(boundingBoxD.Value, vector3D);
                        flag         = true;
                        break;
                    }
                }
                if (!flag)
                {
                    flag2 = true;
                    break;
                }
            }
            m_obstaclesInRange.Clear();
            m_entitiesInRange.Clear();
            m_objectsInRange.Clear();
            if (flag2)
            {
                return(vector3D);
            }
            return(null);
        }
Example #9
0
        public bool ExtractStationIntersect(IMainView mainViewModel, bool tightIntersection)
        {
            // Make a shortlist of station Entities in the bounding box of the asteroid.
            var asteroidWorldAABB = new BoundingBoxD((Vector3D)ContentBounds.Min + PositionAndOrientation.Value.Position, (Vector3D)ContentBounds.Max + PositionAndOrientation.Value.Position);
            var stations          = mainViewModel.GetIntersectingEntities(asteroidWorldAABB).Where(e => e.ClassType == ClassType.LargeStation).Cast <StructureCubeGridModel>().ToList();

            if (stations.Count == 0)
            {
                return(false);
            }

            var modified   = false;
            var sourceFile = SourceVoxelFilepath ?? VoxelFilepath;
            var asteroid   = new MyVoxelMap();

            asteroid.Load(sourceFile);

            var total = stations.Sum(s => s.CubeGrid.CubeBlocks.Count);

            mainViewModel.ResetProgress(0, total);

            // Search through station entities cubes for intersection with this voxel.
            foreach (var station in stations)
            {
                var quaternion = station.PositionAndOrientation.Value.ToQuaternion();

                foreach (var cube in station.CubeGrid.CubeBlocks)
                {
                    mainViewModel.IncrementProgress();

                    var definition = SpaceEngineersApi.GetCubeDefinition(cube.TypeId, station.CubeGrid.GridSizeEnum, cube.SubtypeName);

                    var orientSize    = definition.Size.Transform(cube.BlockOrientation).Abs();
                    var min           = cube.Min.ToVector3() * station.CubeGrid.GridSizeEnum.ToLength();
                    var max           = (cube.Min + orientSize) * station.CubeGrid.GridSizeEnum.ToLength();
                    var p1            = Vector3D.Transform(min, quaternion) + station.PositionAndOrientation.Value.Position - (station.CubeGrid.GridSizeEnum.ToLength() / 2);
                    var p2            = Vector3D.Transform(max, quaternion) + station.PositionAndOrientation.Value.Position - (station.CubeGrid.GridSizeEnum.ToLength() / 2);
                    var cubeWorldAABB = new BoundingBoxD(Vector3.Min(p1, p2), Vector3.Max(p1, p2));

                    // find worldAABB of block.
                    if (asteroidWorldAABB.Intersects(cubeWorldAABB))
                    {
                        Vector3I block;
                        var      cacheSize = new Vector3I(64);
                        Vector3D position  = PositionAndOrientation.Value.Position;

                        // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue.
                        for (block.Z = 0; block.Z < asteroid.Storage.Size.Z; block.Z += 64)
                        {
                            for (block.Y = 0; block.Y < asteroid.Storage.Size.Y; block.Y += 64)
                            {
                                for (block.X = 0; block.X < asteroid.Storage.Size.X; block.X += 64)
                                {
                                    var cache = new MyStorageData();
                                    cache.Resize(cacheSize);
                                    // LOD1 is not detailed enough for content information on asteroids.
                                    Vector3I maxRange = block + cacheSize - 1;
                                    asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, block, maxRange);

                                    bool     changed = false;
                                    Vector3I p;
                                    for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z)
                                    {
                                        for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y)
                                        {
                                            for (p.X = 0; p.X < cacheSize.X; ++p.X)
                                            {
                                                BoundingBoxD    voxelCellBox = new BoundingBoxD(position + p + block, position + p + block + 1);
                                                ContainmentType contains     = cubeWorldAABB.Contains(voxelCellBox);

                                                // TODO: finish tightIntersection. Will require high interpretation of voxel content volumes.

                                                if (contains == ContainmentType.Contains || contains == ContainmentType.Intersects)
                                                {
                                                    cache.Content(ref p, 0);
                                                    changed = true;
                                                }
                                            }
                                        }
                                    }

                                    if (changed)
                                    {
                                        asteroid.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, block, maxRange);
                                        modified = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            mainViewModel.ClearProgress();

            if (modified)
            {
                var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                asteroid.Save(tempfilename);
                // replaces the existing asteroid file, as it is still the same size and dimentions.
                UpdateNewSource(asteroid, tempfilename);
                MaterialAssets = null;
                InitializeAsync();
            }
            return(modified);
        }
Example #10
0
        public static unsafe void DisableItemsInAabb(this MyEnvironmentSector sector, ref BoundingBoxD aabb)
        {
            if (sector.DataView == null)
                return;

            aabb.Translate(-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 && aabb.Contains(items[i].Position) != ContainmentType.Disjoint)
                            logicalSector.EnableItem(i, false);
                    }
            }
        }
        private new bool TestPlacement()
        {
            bool retval = true;

            m_touchingGrids.Clear();

            for (int i = 0; i < PreviewGrids.Count; ++i)
            {
                var grid     = PreviewGrids[i];
                var settings = m_settings.GetGridPlacementSettings(grid.GridSizeEnum);

                m_touchingGrids.Add(null);

                if (MySession.Static.SurvivalMode && !MyCubeBuilder.SpectatorIsBuilding && !MySession.Static.IsAdminModeEnabled(Sync.MyId))
                {
                    if (i == 0 && MyCubeBuilder.CameraControllerSpectator)
                    {
                        m_visible = false;
                        return(false);
                    }

                    if (i == 0 && !MyCubeBuilder.Static.DynamicMode)
                    {
                        MatrixD invMatrix = grid.PositionComp.WorldMatrixNormalizedInv;
                        if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invMatrix, (BoundingBoxD)grid.PositionComp.LocalAABB, grid.GridSize, MyCubeBuilder.IntersectionDistance))
                        {
                            m_visible = false;
                            return(false);
                        }
                    }

                    /*if (!MySession.Static.SimpleSurvival && MySession.Static.ControlledEntity is MyCharacter)
                     * {
                     *  foreach (var block in grid.GetBlocks())
                     *  {
                     *      retval &= (MySession.Static.ControlledEntity as MyCharacter).CanStartConstruction(block.BlockDefinition);
                     *      if (!retval)
                     *          break;
                     *  }
                     * }
                     *
                     * if (i == 0 && MySession.Static.SimpleSurvival)
                     * {
                     *  retval = retval && MyCubeBuilder.Static.CanBuildBlockSurvivalTime();
                     * }*/

                    if (!retval)
                    {
                        return(false);
                    }
                }

                if (MyCubeBuilder.Static.DynamicMode)
                {
                    // if (!m_dynamicBuildAllowed)
                    //  {
                    var settingsLocal = grid.GridSizeEnum == MyCubeSize.Large ? m_settings.LargeGrid :
                                        m_settings.SmallGrid;
                    bool anyBlockVoxelHit = false;
                    foreach (var block in grid.GetBlocks())
                    {
                        Vector3      minLocal  = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                        Vector3      maxLocal  = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                        BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal);
                        if (!anyBlockVoxelHit)
                        {
                            anyBlockVoxelHit = TestVoxelPlacement(block, ref settings, true);
                        }
                        retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, aabbLocal, true, testVoxel: false);
                        if (!retval)
                        {
                            break;
                        }
                    }

                    retval = retval && anyBlockVoxelHit;
                    // }
                }
                else if (i == 0 && m_hitEntity is MyCubeGrid && IsSnapped /* && SnapMode == SnapMode.Base6Directions*/)
                {
                    var hitGrid       = m_hitEntity as MyCubeGrid;
                    var settingsLocal = m_settings.GetGridPlacementSettings(hitGrid.GridSizeEnum, hitGrid.IsStatic);

                    bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && grid.GridSizeEnum == MyCubeSize.Small;

                    if (smallOnLargeGrid)
                    {
                        retval = retval && MyCubeGrid.TestPlacementArea(grid, ref settings, (BoundingBoxD)grid.PositionComp.LocalAABB, false);
                    }
                    else
                    {
                        retval = retval && TestGridPlacementOnGrid(grid, ref settingsLocal, hitGrid);
                    }

                    m_touchingGrids.Clear();
                    m_touchingGrids.Add(hitGrid);
                }
                else if (i == 0 && m_hitEntity is MyVoxelMap)
                {
                    bool anyBlockVoxelHit = false;
                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock is MyCompoundCubeBlock)
                        {
                            MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                            foreach (var blockInCompound in compoundBlock.GetBlocks())
                            {
                                if (!anyBlockVoxelHit)
                                {
                                    anyBlockVoxelHit = TestVoxelPlacement(blockInCompound, ref settings, false);
                                }
                                retval = retval && TestBlockPlacementArea(blockInCompound, ref settings, false, false);
                                if (!retval)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (!anyBlockVoxelHit)
                            {
                                anyBlockVoxelHit = TestVoxelPlacement(block, ref settings, false);
                            }
                            retval = retval && TestBlockPlacementArea(block, ref settings, false, false);
                        }

                        if (!retval)
                        {
                            break;
                        }
                    }

                    retval = retval && anyBlockVoxelHit;

                    Debug.Assert(i == 0);
                    m_touchingGrids[i] = DetectTouchingGrid();
                }
                else
                {
                    var settingsLocal = m_settings.GetGridPlacementSettings(grid.GridSizeEnum, grid.IsStatic && !MyCubeBuilder.Static.DynamicMode);
                    retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, (BoundingBoxD)grid.PositionComp.LocalAABB, false);
                }

                BoundingBoxD aabb = (BoundingBoxD)grid.PositionComp.LocalAABB;
                MatrixD      invGridWorlMatrix = grid.PositionComp.WorldMatrixNormalizedInv;

                // Character collisions.
                if (MySector.MainCamera != null)
                {
                    Vector3D cameraPos = Vector3D.Transform(MySector.MainCamera.Position, invGridWorlMatrix);
                    retval = retval && aabb.Contains(cameraPos) != ContainmentType.Contains;
                }

                if (retval)
                {
                    m_tmpCollisionPoints.Clear();
                    MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints);
                    foreach (var pt in m_tmpCollisionPoints)
                    {
                        Vector3D ptLocal = Vector3D.Transform(pt, invGridWorlMatrix);
                        retval = retval && aabb.Contains(ptLocal) != ContainmentType.Contains;
                        if (!retval)
                        {
                            break;
                        }
                    }
                }
            }

            return(retval);
        }
Example #12
0
        /// <summary>
        /// Returns true if the given small block connects to large one.
        /// </summary>
        /// <param name="smallBlock">small block</param>
        /// <param name="smallBlockWorldAabb">small block world AABB</param>
        /// <param name="largeBlock">large block</param>
        /// <param name="largeBlockWorldAabb">large block wotld AABB</param>
        /// <returns>true when connected</returns>
        private bool SmallBlockConnectsToLarge(MySlimBlock smallBlock, ref BoundingBoxD smallBlockWorldAabb, MySlimBlock largeBlock, ref BoundingBoxD largeBlockWorldAabb)
        {
            Debug.Assert(smallBlock.BlockDefinition.CubeSize == MyCubeSize.Small);
            Debug.Assert(largeBlock.BlockDefinition.CubeSize == MyCubeSize.Large);
            Debug.Assert(!(smallBlock.FatBlock is MyCompoundCubeBlock));
            Debug.Assert(!(largeBlock.FatBlock is MyCompoundCubeBlock));

            BoundingBoxD smallBlockWorldAabbReduced = smallBlockWorldAabb;

            smallBlockWorldAabbReduced.Inflate(-smallBlock.CubeGrid.GridSize / 4);

            // Small block aabb penetrates large block aabb (large timbers).
            bool penetratesAabbs = largeBlockWorldAabb.Contains(smallBlockWorldAabbReduced) == ContainmentType.Intersects;

            if (!penetratesAabbs)
            {
                Vector3D centerToCenter = smallBlockWorldAabb.Center - largeBlockWorldAabb.Center;
                Vector3I addDir         = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(centerToCenter));
                // Check small grid mount points
                Quaternion smallBlockRotation;
                smallBlock.Orientation.GetQuaternion(out smallBlockRotation);
                smallBlockRotation = Quaternion.CreateFromRotationMatrix(smallBlock.CubeGrid.WorldMatrix) * smallBlockRotation;
                if (!MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(largeBlock.CubeGrid, smallBlock.BlockDefinition, ref smallBlockRotation, ref addDir))
                {
                    return(false);
                }
            }

            BoundingBoxD smallBlockWorldAabbInflated = smallBlockWorldAabb;

            smallBlockWorldAabbInflated.Inflate(2 * smallBlock.CubeGrid.GridSize / 3);

            // Trim small block aabb with large block aabb.
            BoundingBoxD intersectedBox       = smallBlockWorldAabbInflated.Intersect(largeBlockWorldAabb);
            Vector3D     intersectedBoxCenter = intersectedBox.Center;
            HkShape      shape = new HkBoxShape((Vector3)intersectedBox.HalfExtents);

            Quaternion largeRotation;

            largeBlock.Orientation.GetQuaternion(out largeRotation);
            largeRotation = Quaternion.CreateFromRotationMatrix(largeBlock.CubeGrid.WorldMatrix) * largeRotation;
            Vector3D largeTranslation;

            largeBlock.ComputeWorldCenter(out largeTranslation);

            bool result = false;

            try
            {
                if (largeBlock.FatBlock != null)
                {
                    MyModel model = largeBlock.FatBlock.Model;
                    if (model != null)
                    {
                        HkShape[] shapes = model.HavokCollisionShapes;
                        if (shapes == null || shapes.Length == 0)
                        {
                            return(false);
                        }

                        for (int i = 0; i < shapes.Length; ++i)
                        {
                            result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapes[i], ref largeTranslation, ref largeRotation);
                            if (result)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        HkShape shapeLarge = new HkBoxShape(largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize / 2);

                        result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapeLarge, ref largeTranslation, ref largeRotation);

                        shapeLarge.RemoveReference();
                    }
                }
                else
                {
                    HkShape shapeLarge = new HkBoxShape(largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize / 2);

                    result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapeLarge, ref largeTranslation, ref largeRotation);

                    shapeLarge.RemoveReference();
                }
            }
            finally
            {
                shape.RemoveReference();
            }

            return(result);
        }
Example #13
0
        private bool TestPlacement()
        {
            bool retval = true;

            for (int i = 0; i < PreviewGrids.Count; ++i)
            {
                var grid     = PreviewGrids[i];
                var settings = m_settings.GetGridPlacementSettings(grid);

                if (MySession.Static.SurvivalMode && !MyCubeBuilder.DeveloperSpectatorIsBuilding)
                {
                    if (i == 0 && !MyCubeBuilder.Static.DynamicMode)
                    {
                        MatrixD invMatrix = grid.PositionComp.WorldMatrixNormalizedInv;
                        if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invMatrix, (BoundingBoxD)grid.PositionComp.LocalAABB, grid.GridSize, MyCubeBuilder.Static.IntersectionDistance) ||
                            MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator)
                        {
                            m_visible = false;
                            return(false);
                        }
                    }

                    if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter)
                    {
                        foreach (var block in grid.GetBlocks())
                        {
                            retval &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(block.BlockDefinition);
                            if (!retval)
                            {
                                break;
                            }
                        }
                    }

                    if (i == 0 && MySession.Static.SimpleSurvival)
                    {
                        retval = retval && MyCubeBuilder.Static.CanBuildBlockSurvivalTime();
                    }

                    if (!retval)
                    {
                        return(false);
                    }
                }

                if (MyCubeBuilder.Static.DynamicMode)
                {
                    if (!m_dynamicBuildAllowed)
                    {
                        var settingsLocal = grid.GridSizeEnum == MyCubeSize.Large ? MyPerGameSettings.PastingSettings.LargeGrid : MyPerGameSettings.PastingSettings.SmallGrid;

                        foreach (var block in grid.GetBlocks())
                        {
                            Vector3      minLocal  = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                            Vector3      maxLocal  = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                            BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal);
                            retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, aabbLocal, true);
                        }
                    }
                }
                else if (i == 0 && m_hitEntity is MyCubeGrid && IsSnapped && SnapMode == MyGridPlacementSettings.SnapMode.Base6Directions)
                {
                    var hitGrid = m_hitEntity as MyCubeGrid;

                    bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && grid.GridSizeEnum == MyCubeSize.Small;

                    if (smallOnLargeGrid)
                    {
                        retval = retval && MyCubeGrid.TestPlacementArea(grid, ref settings, (BoundingBoxD)grid.PositionComp.LocalAABB, false /*, hitGrid*/);
                    }
                    else
                    {
                        retval = retval && TestGridPlacementOnGrid(grid, ref settings, hitGrid);
                    }
                }
                else if (i == 0 && m_hitEntity is MyVoxelMap)
                {
                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock is MyCompoundCubeBlock)
                        {
                            MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                            foreach (var blockInCompound in compoundBlock.GetBlocks())
                            {
                                retval = retval && TestBlockPlacementArea(blockInCompound, ref settings, false);
                                if (!retval)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            retval = retval && TestBlockPlacementArea(block, ref settings, false);
                        }

                        if (!retval)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    var settingsLocal = m_settings.GetGridPlacementSettings(grid, grid.IsStatic && !MyCubeBuilder.Static.DynamicMode);
                    retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, (BoundingBoxD)grid.PositionComp.LocalAABB, false);
                }

                BoundingBoxD aabb = (BoundingBoxD)grid.PositionComp.LocalAABB;
                MatrixD      invGridWorlMatrix = grid.PositionComp.GetWorldMatrixNormalizedInv();

                // Character collisions.
                if (MySector.MainCamera != null)
                {
                    Vector3D cameraPos = Vector3D.Transform(MySector.MainCamera.Position, invGridWorlMatrix);
                    retval = retval && aabb.Contains(cameraPos) != ContainmentType.Contains;
                }

                if (retval)
                {
                    m_tmpCollisionPoints.Clear();
                    MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints);
                    foreach (var pt in m_tmpCollisionPoints)
                    {
                        Vector3D ptLocal = Vector3D.Transform(pt, invGridWorlMatrix);
                        retval = retval && aabb.Contains(ptLocal) != ContainmentType.Contains;
                        if (!retval)
                        {
                            break;
                        }
                    }
                }
            }

            return(retval);
        }
        public bool PointInsideGizmo(Vector3D point, MyGizmoSpaceEnum gizmo, ref MatrixD invGridWorldMatrix, float gridSize, float inflate = 0.0f, bool onVoxel = false)
        {
            MatrixD m = new MatrixD();
            BoundingBoxD gizmoBox = new BoundingBoxD();
            GetGizmoPointTestVariables(ref invGridWorldMatrix, gridSize, out gizmoBox, out m, gizmo, inflate: inflate, onVoxel: onVoxel);

            Vector3D localPoint = Vector3D.Transform(point, m);

            return gizmoBox.Contains(localPoint) == ContainmentType.Contains;
        }
Example #15
0
        /// <summary>
        /// Performes a physics raycast
        /// It can be recursive (it calls CastDDA when it hits a grid).
        /// </summary>
        /// <param name="fromWorldPos"></param>
        /// <returns>Returns starting damage for current stack</returns>
        private MyRaycastDamageInfo CastPhysicsRay(Vector3D fromWorldPos)
        {
            Vector3D  pos       = Vector3D.Zero;
            IMyEntity hitEntity = null;

            var hitInfo = MyPhysics.CastRay(fromWorldPos, m_explosion.Center, MyPhysics.ExplosionRaycastLayer);

            if (hitInfo.HasValue)
            {
                hitEntity = (hitInfo.Value.HkHitInfo.Body.UserObject != null) ? ((MyPhysicsBody)hitInfo.Value.HkHitInfo.Body.UserObject).Entity : null;
                pos       = hitInfo.Value.Position;
            }
            Vector3D direction      = (m_explosion.Center - fromWorldPos);
            float    lengthToCenter = (float)direction.Length();

            direction.Normalize();

            var grid = (hitEntity as MyCubeGrid);

            if (grid == null)
            {
                MyCubeBlock hitBlock = hitEntity as MyCubeBlock;
                if (hitBlock != null)
                {
                    grid = hitBlock.CubeGrid;
                }
            }
            if (grid != null)
            {
                //Try advancing the point to find the intersected block
                //If the block is a cube, this is necessary because the raycast will return a point somewhere outside the cube
                //If the block is not a full cube (slope, special block), the raycast can return inside the cube
                //It advances 4 times, each time one 8th the grid size
                for (int i = 0; i < 5; i++)
                {
                    Vector3D localPos  = Vector3D.Transform(pos, grid.PositionComp.WorldMatrixNormalizedInv) / grid.GridSize;
                    Vector3I gridPos   = Vector3I.Round(localPos);
                    var      cubeBlock = grid.GetCubeBlock(gridPos);
                    if (cubeBlock != null)
                    {
                        if (m_castBlocks.Contains(cubeBlock))
                        {
                            //This shouldn't happen
                            //There is a corner case where the explosion position is inside the empty cell, but this should be handleded somewhere higher
                            System.Diagnostics.Debug.Fail("Raycast failed!");
                            DrawRay(fromWorldPos, pos, Color.Red);
                            return(new MyRaycastDamageInfo(0f, lengthToCenter));
                        }
                        else
                        {
                            if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                            {
                                DrawRay(fromWorldPos, pos, Color.Blue);
                            }
                            return(CastDDA(cubeBlock));
                        }
                    }
                    pos += direction * grid.GridSize / 8f;
                }
                //We hit a grid but were unable to find the hit cube. Send another raycast
                //Ideally, we would want to get the cube in all cases, but it also has to be fast
                //We need to check if the explosion center is between the initial start position (fromWorldPos) and the new one (pos)

                Vector3D min = new Vector3D(Math.Min(fromWorldPos.X, pos.X), Math.Min(fromWorldPos.Y, pos.Y), Math.Min(fromWorldPos.Z, pos.Z));
                Vector3D max = new Vector3D(Math.Max(fromWorldPos.X, pos.X), Math.Max(fromWorldPos.Y, pos.Y), Math.Max(fromWorldPos.Z, pos.Z));

                BoundingBoxD boundingBox = new BoundingBoxD(min, max);
                if (boundingBox.Contains(m_explosion.Center) == ContainmentType.Contains)
                {
                    return(new MyRaycastDamageInfo(m_explosionDamage, lengthToCenter));
                }

                stackOverflowGuard++;
                if (stackOverflowGuard > MAX_PHYSICS_RECURSION_COUNT)
                {
                    System.Diagnostics.Debug.Fail("Potential stack overflow!");
                    if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                    {
                        DrawRay(fromWorldPos, pos, Color.Red);
                    }
                    return(new MyRaycastDamageInfo(0f, lengthToCenter));
                }
                else
                {
                    if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                    {
                        DrawRay(fromWorldPos, pos, Color.White);
                    }
                    return(CastPhysicsRay(pos));
                }
            }
            else if (hitInfo.HasValue)
            {
                //Something was hit, but it wasn't a grid. This needs to be handled somehow
                if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                {
                    DrawRay(fromWorldPos, pos, Color.Violet);
                }
                return(new MyRaycastDamageInfo(0, lengthToCenter));
            }

            //Nothing was hit, so we can assume the there was nothing blocking the explosion
            if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
            {
                DrawRay(fromWorldPos, pos, Color.Salmon);
            }
            return(new MyRaycastDamageInfo(m_explosionDamage, lengthToCenter));
        }
 private static bool IsInCell(ref BoundingBoxD cellbox, ref BoundingSphereD asteroid)
 {
     return cellbox.Contains(asteroid) != ContainmentType.Disjoint;
 }
Example #17
0
 private static bool IsInCell(ref BoundingBoxD cellbox, ref BoundingSphereD asteroid)
 {
     return(cellbox.Contains(asteroid) != ContainmentType.Disjoint);
 }