static BoundingBoxD GetEntityAABB(MyEntity entity)
        {
            BoundingBoxD bbox = entity.PositionComp.WorldAABB;

            //Include entity velocity to be able to hit fast moving objects
            if (entity.Physics != null)
            {
                bbox = bbox.Include(entity.WorldMatrix.Translation + entity.Physics.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * 5);
            }

            return(bbox);
        }
示例#2
0
        public void UpdateAABB()
        {
            var startPos = Grids.First().PositionComp.GetPosition();
            var box      = new BoundingBoxD(startPos, startPos);

            foreach (var aabb in Grids.Select(g => g.PositionComp.WorldAABB))
            {
                box.Include(aabb);
            }

            WorldAABB = box;
        }
示例#3
0
        public BoundingBoxD GetMechnicalGroupAabb()
        {
            BoundingBoxD worldAabb = new BoundingBoxD();

            lock (SubLock) {
                foreach (var sub in ShieldComp.SubGrids)
                {
                    worldAabb.Include(sub.PositionComp.WorldAABB);
                }
            }

            return(worldAabb);
        }
        public static BoundingBoxD AdjustAABBByVelocity(BoundingBoxD aabb, Vector3 velocity, float inflate = 1.1f)
        {
            if (velocity.LengthSquared() > 0.001f)
            {
                velocity.Normalize();
            }
            aabb.Inflate((double)inflate);
            BoundingBoxD box = aabb;

            box += (BoundingBoxD)((velocity * 2000f) * inflate);
            aabb.Include(box);
            return(aabb);
        }
示例#5
0
        void UpdateBoundingFrustum()
        {
            //  Update frustum
            BoundingFrustum.Matrix    = ViewProjectionMatrix;
            BoundingFrustumFar.Matrix = ViewProjectionMatrixFar;

            //  Update bounding box
            BoundingBox = BoundingBoxD.CreateInvalid();
            BoundingBox.Include(ref BoundingFrustum);

            //  Update bounding sphere
            BoundingSphere = MyUtils.GetBoundingSphereFromBoundingBox(ref BoundingBox);
        }
示例#6
0
        private void PerformJump(Vector3D jumpTarget)
        {
            m_jumpDirection = jumpTarget - m_grid.WorldMatrix.Translation;

            MyParticleEffect effect;

            if (MyParticlesManager.TryCreateParticleEffect(53, out effect))
            {
                effect.WorldMatrix = MatrixD.CreateFromTransformScale(Quaternion.Identity, m_grid.WorldMatrix.Translation, Vector3D.One);
                effect.UserScale   = (float)m_grid.PositionComp.WorldAABB.HalfExtents.AbsMax() / 25f;
                effect.AutoDelete  = true;
            }

            BoundingBoxD aggregateBox = m_grid.PositionComp.WorldAABB;

            foreach (var grid in m_shipInfo.Keys)
            {
                aggregateBox.Include(grid.PositionComp.WorldAABB);
            }
            MyPhysics.Clusters.EnsureClusterSpace(aggregateBox + m_jumpDirection);

            bool updateSpectator = false;

            if (IsLocalCharacterAffectedByJump())
            {
                updateSpectator = true;
            }

            if (updateSpectator)
            {
                MyThirdPersonSpectator.Static.ResetPosition(0.0, null);
                MyThirdPersonSpectator.Static.ResetDistance();
                MyThirdPersonSpectator.Static.RecalibrateCameraPosition();
            }

            m_jumped = true;

            foreach (var grid in m_shipInfo.Keys)
            {
                MatrixD gridMatrix = grid.WorldMatrix;
                gridMatrix.Translation = grid.WorldMatrix.Translation + m_jumpDirection;
                grid.WorldMatrix       = gridMatrix;
            }

            if (updateSpectator)
            {
                MyThirdPersonSpectator.Static.ResetPosition(0.0, null);
                MyThirdPersonSpectator.Static.ResetDistance();
                MyThirdPersonSpectator.Static.RecalibrateCameraPosition();
            }
        }
示例#7
0
        public static BoundingBoxD GetWorldAABB(this MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group group)
        {
            var grids = group.Nodes.Select(n => n.NodeData);

            var startPos = grids.First().PositionComp.GetPosition();
            var box      = new BoundingBoxD(startPos, startPos);

            foreach (var aabb in grids.Select(g => g.PositionComp.WorldAABB))
            {
                box.Include(aabb);
            }

            return(box);
        }
        protected void UpdateRenderObject()
        {
            m_actualWorldAABB = BoundingBoxD.CreateInvalid();

            for (int i = 1; i < Model.Bones.Length; i++)
            {
                Vector3D p1 = Vector3D.Transform(Bones[i].Parent.AbsoluteTransform.Translation, WorldMatrix);
                Vector3D p2 = Vector3D.Transform(Bones[i].AbsoluteTransform.Translation, WorldMatrix);

                m_actualWorldAABB.Include(ref p1);
                m_actualWorldAABB.Include(ref p2);
            }

            ContainmentType containmentType;

            m_aabb.Contains(ref m_actualWorldAABB, out containmentType);
            if (containmentType != ContainmentType.Contains)
            {
                m_actualWorldAABB.Inflate(0.5f);
                MatrixD worldMatrix = WorldMatrix;
                VRageRender.MyRenderProxy.UpdateRenderObject(Render.RenderObjectIDs[0], ref worldMatrix, false, m_actualWorldAABB);
                m_aabb = m_actualWorldAABB;
            }
        }
示例#9
0
        private static void CalculateAABB(ref BoundingBoxD bbox, out float scaleZ, out float scaleXY, ref Vector3D position, ref Vector3D direction, ref Vector3D up, float reflectorConeMaxAngleCos, float reflectorRange)
        {
            scaleZ  = 1;
            scaleXY = 1;
            float cosAngle = 1 - reflectorConeMaxAngleCos;

            scaleZ = reflectorRange;
            // Calculate cone side (hypotenuse of triangle)
            float side = reflectorRange / cosAngle;

            // Calculate cone bottom scale (Pythagoras theorem)
            scaleXY = (float)System.Math.Sqrt(side * side - reflectorRange * reflectorRange) * 2;

            if (scaleXY == 0)
            {
                scaleXY = 1;
            }

            up = MyUtils.Normalize(up);
            Vector3 coneSideDirection = Vector3.Cross(up, direction);

            coneSideDirection = MyUtils.Normalize(coneSideDirection);
            Vector3D coneCenter = position + direction * scaleZ;
            Vector3D pt1        = coneCenter + coneSideDirection * scaleXY / 2 + up * scaleXY / 2;
            Vector3D pt2        = coneCenter - coneSideDirection * scaleXY / 2 + up * scaleXY / 2;
            Vector3D pt3        = coneCenter + coneSideDirection * scaleXY / 2 - up * scaleXY / 2;
            Vector3D pt4        = coneCenter - coneSideDirection * scaleXY / 2 - up * scaleXY / 2;

            bbox = BoundingBoxD.CreateInvalid();
            bbox = bbox.Include(ref position);
            //bbox = bbox.Include(ref coneCenter);
            bbox = bbox.Include(ref pt1);
            bbox = bbox.Include(ref pt2);
            bbox = bbox.Include(ref pt3);
            bbox = bbox.Include(ref pt4);
        }
示例#10
0
        public BoundingBoxD GetEntityAABB(AABBEntity entity)
        {
            BoundingBoxD bbox = entity.BoundingBox;

            //Include entity velocity to be able to hit fast moving objects
            if (entity.WorldTranslation != null && entity.LinearVelocity != null)
            {
                bbox = bbox.Include(
                    entity.WorldTranslation +
                    entity.LinearVelocity *
                    MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * 5
                    );
            }

            return(bbox);
        }
示例#11
0
        public override void UpdateWorldAABB()
        {
            CulledObjects.GetAll(m_list, true);

            m_localAABB = BoundingBoxD.CreateInvalid();


            foreach (var element in m_list)
            {
                m_localAABB = m_localAABB.Include(element.WorldAABB);
            }

            m_aabb = m_localAABB.Transform(ref m_worldMatrix);

            base.UpdateWorldAABB();
        }
        public override void UpdateWorldAABB()
        {
            CulledObjects.GetAll(m_list, true);

            m_localAABB = BoundingBoxD.CreateInvalid();
            

            foreach (var element in m_list)
            {
                m_localAABB = m_localAABB.Include(element.WorldAABB);
            }

            m_aabb = m_localAABB.Transform(ref m_worldMatrix);

            base.UpdateWorldAABB();
        }
        public void Init(IMyEnvironmentOwner owner, ref MyEnvironmentSectorParameters parameters)
        {
            // Copy parameters in
            SectorCenter = parameters.Center;

            Bounds = parameters.Bounds;

            m_dataRange = parameters.DataRange;

            m_environment = (MyProceduralEnvironmentDefinition)parameters.Environment;

            EnvironmentDefinition = parameters.Environment;

            m_owner = owner;

            m_provider = parameters.Provider;

            // Compute appropriate render origin.
            Vector3D center = parameters.Center;

            owner.ProjectPointToSurface(ref center);

            if (!Engine.Platform.Game.IsDedicated)
            {
                m_render = new MyInstancedRenderSector(string.Format("{0}:Sector({1:X})", owner, parameters.SectorId), MatrixD.CreateTranslation(center));
            }

            SectorId = parameters.SectorId;

            BoundingBoxD worldBounds = BoundingBoxD.CreateInvalid();

            for (int i = 0; i < 8; ++i)
            {
                worldBounds.Include(Bounds[i]);
            }

            // Entity stuff
            PositionComp.SetPosition(parameters.Center);
            PositionComp.WorldAABB = worldBounds;

            // Add missing stuff
            AddDebugRenderComponent(new MyDebugRenderComponentEnvironmentSector(this));
            GameLogic = new MyNullGameLogicComponent();
            Save      = false;

            IsClosed = false;
        }
示例#14
0
        private BoundingBoxD GetAggregateBBox()
        {
            if (m_grid.MarkedForClose)
            {
                return(BoundingBoxD.CreateInvalid());
            }
            BoundingBoxD bbox = m_grid.PositionComp.WorldAABB;

            foreach (var grid in m_connectedGrids)
            {
                if (grid.PositionComp != null)
                {
                    bbox.Include(grid.PositionComp.WorldAABB);
                }
            }
            return(bbox);
        }
示例#15
0
        private void PerformJump(Vector3D jumpTarget)
        {
            m_updateEffectPosition = false;
            m_jumpDirection        = jumpTarget - m_grid.WorldMatrix.Translation;

            BoundingBoxD aggregateBox = m_grid.PositionComp.WorldAABB;

            foreach (var grid in m_shipInfo.Keys)
            {
                aggregateBox.Include(grid.PositionComp.WorldAABB);
            }

            MyPhysics.EnsurePhysicsSpace(aggregateBox + m_jumpDirection);

            bool updateSpectator = false;

            if (IsLocalCharacterAffectedByJump())
            {
                updateSpectator = true;
            }

            if (updateSpectator)
            {
                MyThirdPersonSpectator.Static.ResetViewerAngle(null);
                MyThirdPersonSpectator.Static.ResetViewerDistance();
                MyThirdPersonSpectator.Static.RecalibrateCameraPosition();
            }

            m_jumped = true;

            foreach (var grid in m_shipInfo.Keys)
            {
                MatrixD gridMatrix = grid.WorldMatrix;
                gridMatrix.Translation = grid.WorldMatrix.Translation + m_jumpDirection;
                grid.WorldMatrix       = gridMatrix;
            }

            if (updateSpectator)
            {
                MyThirdPersonSpectator.Static.ResetViewerAngle(null);
                MyThirdPersonSpectator.Static.ResetViewerDistance();
                MyThirdPersonSpectator.Static.RecalibrateCameraPosition();
            }
        }
        static void SendOutputMessages()
        {
            foreach (var q in m_cullQuery.FrustumQueries)
            {
                foreach (var proxy in q.List)
                {
                    // all should have same parent
                    if (proxy.Proxies.Length > 0)
                    {
                        MyRenderProxy.VisibleObjectsWrite.Add(proxy.Proxies[0].Parent.m_owner.ID);
                    }
                }
            }

            // TODO: just for now
            foreach (var h in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                if (true)
                {
                    BoundingBoxD bb = BoundingBoxD.CreateInvalid();

                    foreach (var child in h.m_children)
                    {
                        if (child.m_visible)
                        {
                            bb.Include(child.Aabb);
                        }
                    }

                    if (MyEnvironment.ViewFrustumClippedD.Contains(bb) != VRageMath.ContainmentType.Disjoint)
                    {
                        MyRenderProxy.VisibleObjectsWrite.Add(h.m_owner.ID);
                    }
                }
            }

            foreach (var id in MyClipmapFactory.ClipmapByID.Keys)
            {
                MyRenderProxy.VisibleObjectsWrite.Add(id);
            }
        }
示例#17
0
        public void MoveObject(ulong id, BoundingBoxD oldAabb, BoundingBoxD aabb, Vector3 velocity)
        {
            System.Diagnostics.Debug.Assert(id != CLUSTERED_OBJECT_ID_UNITIALIZED, "Unitialized object in cluster!");

            MyObjectData objectData;

            if (m_objectsData.TryGetValue(id, out objectData))
            {
                System.Diagnostics.Debug.Assert(!objectData.ActivationHandler.IsStaticForCluster, "Cannot move static object!");

                var oldAABB = objectData.AABB;
                m_objectsData[id].AABB = aabb;

                BoundingBoxD originalAABB = aabb;
                Vector3      velocityDir  = Vector3.Normalize(velocity);

                BoundingBoxD extendedAABB = aabb.Include(aabb.Center + velocityDir * 2000);
                //                BoundingBoxD newClusterAABB = aabb.Include(aabb.Center + velocityDir * IdealClusterSize / 2);

                System.Diagnostics.Debug.Assert(m_clusters.Contains(objectData.Cluster));

                if (objectData.Cluster.AABB.Contains(extendedAABB) != ContainmentType.Contains && !SingleCluster.HasValue)
                {
                    ReorderClusters(originalAABB.Include(oldAABB), id);
                }

                System.Diagnostics.Debug.Assert(m_objectsData[id].Cluster.AABB.Contains(objectData.AABB) == ContainmentType.Contains || SingleCluster.HasValue, "Inconsistency in clusters");
            }

            //foreach (var ob in m_objectsData)
            //{
            //    if (ob.Value.ActivationHandler.IsStatic && ob.Value.Cluster != null)
            //        System.Diagnostics.Debug.Assert(ob.Value.Cluster.AABB.Contains(ob.Value.AABB) != ContainmentType.Disjoint, "Inconsistency in clusters");
            //    else
            //      if (!ob.Value.ActivationHandler.IsStatic)
            //        System.Diagnostics.Debug.Assert(ob.Value.Cluster.AABB.Contains(ob.Value.AABB) == ContainmentType.Contains, "Inconsistency in clusters");
            //}
        }
        public void TestVoxelNavmeshTriangle(ref Vector3D a, ref Vector3D b, ref Vector3D c, List<MyCubeGrid> gridsToTest, List<MyGridPathfinding.CubeId> linkCandidatesOutput, out bool intersecting)
        {
            ProfilerShort.Begin("TestVoxelNavmeshTriangle");

            ProfilerShort.Begin("Triangle-obstacle tests");
            Vector3D s = (a + b + c) / 3.0;
            if (m_obstacles.IsInObstacle(s))
            {
                intersecting = true;
                ProfilerShort.End();
                ProfilerShort.End();
                return;
            }
            ProfilerShort.End();

            BoundingBoxD triBB;
            Vector3D aLocal, bLocal, cLocal, gLocal;
            Vector3D g = Vector3D.Zero;
            if (MyPerGameSettings.NavmeshPresumesDownwardGravity)
            {
                g = Vector3.Down * 2.0f;
            }

            m_tmpLinkCandidates.Clear();

            intersecting = false;
            foreach (var grid in gridsToTest)
            {
                MatrixD mat = grid.PositionComp.WorldMatrixNormalizedInv;

                Vector3D.Transform(ref a, ref mat, out aLocal);
                Vector3D.Transform(ref b, ref mat, out bLocal);
                Vector3D.Transform(ref c, ref mat, out cLocal);
                Vector3D.TransformNormal(ref g, ref mat, out gLocal);

                triBB = new BoundingBoxD(Vector3D.MaxValue, Vector3D.MinValue);
                triBB.Include(ref aLocal, ref bLocal, ref cLocal);
                
                Vector3I min = grid.LocalToGridInteger(triBB.Min);
                Vector3I max = grid.LocalToGridInteger(triBB.Max);
                Vector3I pos = min - Vector3I.One;
                Vector3I max2 = max + Vector3I.One;
                for (var it = new Vector3I_RangeIterator(ref pos, ref max2); it.IsValid(); it.GetNext(out pos))
                {
                    if (grid.GetCubeBlock(pos) != null)
                    {
                        Vector3 largeMin = (pos - Vector3.One) * grid.GridSize;
                        Vector3 largeMax = (pos + Vector3.One) * grid.GridSize;
                        Vector3 smallMin = (pos - Vector3.Half) * grid.GridSize;
                        Vector3 smallMax = (pos + Vector3.Half) * grid.GridSize;
                        BoundingBoxD largeBb = new BoundingBoxD(largeMin, largeMax);
                        BoundingBoxD bb = new BoundingBoxD(smallMin, smallMax);

                        largeBb.Include(largeMin + gLocal);
                        largeBb.Include(largeMax + gLocal);
                        bb.Include(smallMin + gLocal);
                        bb.Include(smallMax + gLocal);

                        ProfilerShort.Begin("Triangle intersection tests");
                        if (largeBb.IntersectsTriangle(ref aLocal, ref bLocal, ref cLocal))
                        {
                            if (bb.IntersectsTriangle(ref aLocal, ref bLocal, ref cLocal))
                            {
                                intersecting = true;
                                ProfilerShort.End();
                                break;
                            }
                            else
                            {
                                int dx = Math.Min(Math.Abs(min.X - pos.X), Math.Abs(max.X - pos.X));
                                int dy = Math.Min(Math.Abs(min.Y - pos.Y), Math.Abs(max.Y - pos.Y));
                                int dz = Math.Min(Math.Abs(min.Z - pos.Z), Math.Abs(max.Z - pos.Z));
                                if ((dx + dy + dz) < 3)
                                    m_tmpLinkCandidates.Add(new MyGridPathfinding.CubeId() { Grid = grid, Coords = pos });
                            }
                        }
                        ProfilerShort.End();
                    }
                }

                if (intersecting) break;
            }

            if (!intersecting)
            {
                for (int i = 0; i < m_tmpLinkCandidates.Count; ++i)
                {
                    linkCandidatesOutput.Add(m_tmpLinkCandidates[i]);
                }
            }
            m_tmpLinkCandidates.Clear();

            ProfilerShort.End();
        }
示例#19
0
        /// <summary>
        /// Adds environment item to internal collections. Creates render and physics data.
        /// </summary>
        /// <returns>True if successfully added, otherwise false.</returns>
        private bool AddItem(
            MyEnvironmentItemDefinition itemDefinition,
            ref MatrixD worldMatrix,
            ref BoundingBoxD aabbWorld,
            HkStaticCompoundShape sectorRootShape,
            Dictionary <MyStringHash, HkShape> subtypeIdToShape,
            int localModelId = MAIN_MODEL_LOCAL_ID)
        {
            if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS)
            {
                return(true);
            }

            Debug.Assert(m_definition.ContainsItemDefinition(itemDefinition),
                         String.Format("Environment item with definition '{0}' not found in class '{1}'", itemDefinition.Id, m_definition.Id));
            if (!m_definition.ContainsItemDefinition(itemDefinition))
            {
                return(false);
            }

            if (itemDefinition.Model == null)
            {
                return(false);
            }

            //MyDefinitionId defId = new MyDefinitionId(envItemObjectBuilderType, subtypeId.ToString());
            int    modelId   = MyEnvironmentItems.GetModelId(itemDefinition.Id.SubtypeId, localModelId);
            string modelName = MyModel.GetById(modelId);

            MyModel model = MyModels.GetModelOnlyData(modelName);

            if (model == null)
            {
                //Debug.Fail(String.Format("Environment item model of '{0}' not found, skipping the item...", itemDefinition.Id));
                return(false);
            }

            CheckModelConsistency(itemDefinition);

            int localId = worldMatrix.Translation.GetHashCode();

            MyEnvironmentItemData data = new MyEnvironmentItemData()
            {
                Id               = localId,
                SubtypeId        = itemDefinition.Id.SubtypeId,
                Transform        = new MyTransformD(ref worldMatrix),
                Enabled          = true,
                SectorInstanceId = -1,
                ModelId          = modelId,
            };

            //Preload split planes
            //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName);

            aabbWorld.Include(model.BoundingBox.Transform(worldMatrix));

            MatrixD transform = data.Transform.TransformMatrix;

            Vector3I            sectorId = MyEnvironmentSector.GetSectorId(transform.Translation - CellsOffset, m_definition.SectorSize);
            MyEnvironmentSector sector;

            if (!m_sectors.TryGetValue(sectorId, out sector))
            {
                sector = new MyEnvironmentSector(sectorId, sectorId * m_definition.SectorSize + CellsOffset);
                m_sectors.Add(sectorId, sector);
            }

            // Adds instance of the given model. Local matrix specified might be changed internally in renderer.

            MatrixD sectorOffset = MatrixD.CreateTranslation(-sectorId * m_definition.SectorSize - CellsOffset);
            Matrix  transformL   = (Matrix)(transform * sectorOffset);

            data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, data.ModelId, localId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance);

            int physicsShapeInstanceId;

            if (AddPhysicsShape(data.SubtypeId, model, ref transform, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId))
            {
                // Map to data index - note that itemData is added after this to its list!
                m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = localId;
                m_localIdToPhysicsShapeInstanceId[localId] = physicsShapeInstanceId;
            }

            data.Transform = new MyTransformD(transform);

            if (m_itemsData.ContainsKey(localId))
            {
                //Debug.Fail("More items on same place! " + transform.Translation.ToString());
            }
            else
            {
                m_itemsData.Add(localId, data);
            }

            if (ItemAdded != null)
            {
                ItemAdded(this,
                          new ItemInfo()
                {
                    LocalId   = localId,
                    SubtypeId = data.SubtypeId,
                    Transform = data.Transform,
                });
            }

            return(true);
        }
        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();
                }
            }
        }
示例#21
0
        void DrawBlockSelection(IMySlimBlock block, SelectionState state, bool primarySelection = false)
        {
            IMyCubeGrid           grid = block.CubeGrid;
            MyCubeBlockDefinition def  = (MyCubeBlockDefinition)block.BlockDefinition;

            Color color = (state == SelectionState.InvalidButMirrorValid ? Color.Yellow : (state == SelectionState.Valid ? Color.Green : Color.Red));

            MatrixD      worldMatrix;
            BoundingBoxD localBB;

            #region Compute box
            MyCubeBlock fatBlock = block.FatBlock as MyCubeBlock;
            if (fatBlock != null)
            {
                worldMatrix = fatBlock.PositionComp.WorldMatrixRef;

                if (Main.Tick % (Constants.TICKS_PER_SECOND / 4) == 0 || !LocalBBCache.TryGetValue(block, out localBB))
                {
                    BoundingBox localAABB = fatBlock.PositionComp.LocalAABB;
                    localBB = new BoundingBoxD(localAABB.Min, localAABB.Max);

                    #region Subpart localBB inclusion
                    if (fatBlock.Subparts != null)
                    {
                        MatrixD transformToBlockLocal = fatBlock.PositionComp.WorldMatrixInvScaled;

                        foreach (VRage.Game.Entity.MyEntitySubpart s1 in fatBlock.Subparts.Values)
                        {
                            MyOrientedBoundingBoxD obbS1 = new MyOrientedBoundingBoxD(s1.PositionComp.LocalAABB, s1.PositionComp.WorldMatrixRef);
                            obbS1.GetCorners(Corners, 0);

                            for (int i = 0; i < Corners.Length; i++)
                            {
                                Vector3D corner = Corners[i];
                                localBB.Include(Vector3D.Transform(corner, transformToBlockLocal));
                            }

                            if (s1.Subparts != null)
                            {
                                foreach (VRage.Game.Entity.MyEntitySubpart s2 in s1.Subparts.Values)
                                {
                                    MyOrientedBoundingBoxD obbS2 = new MyOrientedBoundingBoxD(s2.PositionComp.LocalAABB, s2.PositionComp.WorldMatrixRef);
                                    obbS2.GetCorners(Corners, 0);

                                    for (int i = 0; i < Corners.Length; i++)
                                    {
                                        Vector3D corner = Corners[i];
                                        localBB.Include(Vector3D.Transform(corner, transformToBlockLocal));
                                    }

                                    if (s2.Subparts != null)
                                    {
                                        foreach (VRage.Game.Entity.MyEntitySubpart s3 in s2.Subparts.Values)
                                        {
                                            MyOrientedBoundingBoxD obbS3 = new MyOrientedBoundingBoxD(s3.PositionComp.LocalAABB, s3.PositionComp.WorldMatrixRef);
                                            obbS3.GetCorners(Corners, 0);

                                            for (int i = 0; i < Corners.Length; i++)
                                            {
                                                Vector3D corner = Corners[i];
                                                localBB.Include(Vector3D.Transform(corner, transformToBlockLocal));
                                            }

                                            if (s3.Subparts != null)
                                            {
                                                foreach (VRage.Game.Entity.MyEntitySubpart s4 in s3.Subparts.Values)
                                                {
                                                    MyOrientedBoundingBoxD obbS4 = new MyOrientedBoundingBoxD(s4.PositionComp.LocalAABB, s4.PositionComp.WorldMatrixRef);
                                                    obbS4.GetCorners(Corners, 0);

                                                    for (int i = 0; i < Corners.Length; i++)
                                                    {
                                                        Vector3D corner = Corners[i];
                                                        localBB.Include(Vector3D.Transform(corner, transformToBlockLocal));
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    LocalBBCache[block] = localBB;
                }
            }
            else
            {
                Matrix localMatrix;
                block.Orientation.GetMatrix(out localMatrix);
                localMatrix.Translation = new Vector3(block.Position) * grid.GridSize;
                worldMatrix             = localMatrix * grid.WorldMatrix;

                Vector3 halfSize = def.Size * (grid.GridSize * 0.5f);
                localBB = new BoundingBoxD(-halfSize, halfSize);
            }
            #endregion

            localBB.Inflate((grid.GridSizeEnum == MyCubeSize.Large ? 0.1 : 0.03));
            float lineWidth;

            if (primarySelection)
            {
                lineWidth = (grid.GridSizeEnum == MyCubeSize.Large ? 0.02f : 0.016f);
            }
            else
            {
                lineWidth = (grid.GridSizeEnum == MyCubeSize.Large ? 0.25f : 0.1f); // thicker mirrored selections to see better in distance
            }
            DrawSelectionLines(ref worldMatrix, ref localBB, color, lineWidth);
        }
示例#22
0
        public void MoveObject(ulong id, BoundingBoxD oldAabb, BoundingBoxD aabb, Vector3 velocity)
        {
            System.Diagnostics.Debug.Assert(id != CLUSTERED_OBJECT_ID_UNITIALIZED, "Unitialized object in cluster!");

            MyObjectData objectData;

            if (m_objectsData.TryGetValue(id, out objectData))
            {
                System.Diagnostics.Debug.Assert(!objectData.ActivationHandler.IsStaticForCluster, "Cannot move static object!");

                var oldAABB = objectData.AABB;
                m_objectsData[id].AABB = aabb;

                BoundingBoxD originalAABB = aabb;
                Vector3      velocityDir  = velocity;

                if (velocity.LengthSquared() > 0.001f)
                {
                    velocityDir = Vector3.Normalize(velocity);
                }

                BoundingBoxD extendedAABB = aabb.Include(aabb.Center + velocityDir * 2000);
                //                BoundingBoxD newClusterAABB = aabb.Include(aabb.Center + velocityDir * IdealClusterSize / 2);

                originalAABB.InflateToMinimum(IdealClusterSize);

                System.Diagnostics.Debug.Assert(m_clusters.Contains(objectData.Cluster));

                var newContainmentType = objectData.Cluster.AABB.Contains(extendedAABB);
                if (newContainmentType != ContainmentType.Contains && !SingleCluster.HasValue)
                {
                    if (newContainmentType == ContainmentType.Disjoint)
                    { //Probably caused by teleport
                        m_clusterTree.OverlapAllBoundingBox(ref extendedAABB, m_returnedClusters);
                        if ((m_returnedClusters.Count == 1) && (m_returnedClusters[0].AABB.Contains(extendedAABB) == ContainmentType.Contains))
                        { //Just move object from one cluster to another
                            var oldCluster = objectData.Cluster;
                            RemoveObjectFromCluster(objectData, false);
                            if (oldCluster.Objects.Count == 0)
                            {
                                RemoveCluster(oldCluster);
                            }

                            AddObjectToCluster(m_returnedClusters[0], objectData.Id, false);
                        }
                        else
                        {
                            ReorderClusters(originalAABB.Include(oldAABB), id);
                        }
                    }
                    else
                    {
                        ReorderClusters(originalAABB.Include(oldAABB), id);
                    }
                }

                System.Diagnostics.Debug.Assert(m_objectsData[id].Cluster.AABB.Contains(objectData.AABB) == ContainmentType.Contains || SingleCluster.HasValue, "Inconsistency in clusters");
            }

            //foreach (var ob in m_objectsData)
            //{
            //    if (ob.Value.ActivationHandler.IsStatic && ob.Value.Cluster != null)
            //        System.Diagnostics.Debug.Assert(ob.Value.Cluster.AABB.Contains(ob.Value.AABB) != ContainmentType.Disjoint, "Inconsistency in clusters");
            //    else
            //      if (!ob.Value.ActivationHandler.IsStatic)
            //        System.Diagnostics.Debug.Assert(ob.Value.Cluster.AABB.Contains(ob.Value.AABB) == ContainmentType.Contains, "Inconsistency in clusters");
            //}
        }
示例#23
0
        public bool Update()
        {
            if (!Enabled)
            {
                return(AutoDelete); //efect is not enabled at all and must be deleted
            }
            System.Diagnostics.Debug.Assert(WorldMatrix != MatrixD.Zero, "Effect world matrix was not set!");

            if (!m_isPreloading && !m_wasPreloaded && m_preload > 0)
            {
                m_isPreloading = true;

                // TODO: Optimize (preload causes lags, depending on preload size, it's from 0 ms to 85 ms)
                while (m_elapsedTime < m_preload)
                {
                    Update();
                }

                m_isPreloading = false;
                m_wasPreloaded = true;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleEffect-Update");

            if (!m_isPreloading && IsInFrustum)
            {
                MyPerformanceCounter.PerCameraDrawWrite.ParticleEffectsDrawn++;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleEffect-UpdateGen");

            m_elapsedTime += MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            //m_distance = MySector.MainCamera.GetDistanceWithFOV(WorldMatrix.Translation) / (100.0f); //precalculate for LODs
            m_distance       = (float)Vector3D.Distance(MyTransparentGeometry.Camera.Translation, WorldMatrix.Translation) / (100.0f); //precalculate for LODs
            m_particlesCount = 0;
            m_birthRate      = 0;
            m_AABB           = BoundingBoxD.CreateInvalid();


            //if (CalculateDeltaMatrix)
            //{
            //DeltaMatrix = Matrix.Invert(m_lastWorldMatrix) * m_worldMatrix;
            //}


            if (Velocity != Vector3.Zero)
            {
                var position = m_worldMatrix.Translation;
                position.X   += Velocity.X * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                position.Y   += Velocity.Y * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                position.Z   += Velocity.Z * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                m_worldMatrix = MatrixD.CreateWorld(position, Vector3D.Normalize(Velocity), m_worldMatrix.Up);
            }

            //if (RenderCounter == 0 || ((MyRender.RenderCounter - RenderCounter) < FRAMES_TO_SKIP)) //more than FRAMES_TO_SKIP frames consider effect as invisible
            {
                foreach (MyParticleGeneration generation in m_generations)
                {
                    generation.EffectMatrix = WorldMatrix;
                    generation.Update();
                    m_particlesCount += generation.GetParticlesCount();
                    m_birthRate      += generation.GetBirthRate();

                    BoundingBoxD bbox = generation.GetAABB();
                    m_AABB = m_AABB.Include(ref bbox);
                }


                if (m_particlesCount > 0)
                {
                    m_hasShownSomething = true;
                }

                //TODO
                IsInFrustum = true; // MySector.MainCamera.IsInFrustum(ref m_AABB);
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            m_lastWorldMatrix = m_worldMatrix;

            if (((m_particlesCount == 0 && HasShownSomething()) ||
                 (m_particlesCount == 0 && m_birthRate == 0.0f)) &&
                AutoDelete && !m_isPreloading)
            {   //Effect was played and has to be deleted
                return(true);
            }

            if (!m_isPreloading && OnUpdate != null)
            {
                OnUpdate(this, null);
            }

            return(false);
        }
        public bool Update()
        {
            if (!Enabled)
                return AutoDelete; //efect is not enabled at all and must be deleted
            if (WorldMatrix == MatrixD.Zero)
                return true;

            System.Diagnostics.Debug.Assert(WorldMatrix != MatrixD.Zero, "Effect world matrix was not set!");

            if (!m_isPreloading && !m_wasPreloaded && m_preload > 0)
            {
                m_isPreloading = true;

                // TODO: Optimize (preload causes lags, depending on preload size, it's from 0 ms to 85 ms)
                while (m_elapsedTime < m_preload)
                {
                    Update();
                }

                m_isPreloading = false;
                m_wasPreloaded = true;
            }


            if (MyParticlesManager.CalculateGravityInPoint != null && m_updateCounter == 0)
                Gravity = MyParticlesManager.CalculateGravityInPoint(WorldMatrix.Translation);

            m_updateCounter++;

            if (m_updateCounter > GRAVITY_UPDATE_DELAY)
            {
                m_updateCounter = 0;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleEffect-Update");

            if (!m_isPreloading)
            {
                MyPerformanceCounter.PerCameraDrawWrite.ParticleEffectsDrawn++;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleEffect-UpdateGen");

            m_elapsedTime += VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            //m_distance = MySector.MainCamera.GetDistanceWithFOV(WorldMatrix.Translation) / (100.0f); //precalculate for LODs
            m_distance = (float)Vector3D.Distance(MyTransparentGeometry.Camera.Translation, WorldMatrix.Translation) / (100.0f); //precalculate for LODs
            m_particlesCount = 0;
            m_birthRate = 0;
            m_AABB = BoundingBoxD.CreateInvalid();

            if (Velocity != Vector3.Zero)
            {
                var position = m_worldMatrix.Translation;
                position.X += Velocity.X * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                position.Y += Velocity.Y * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                position.Z += Velocity.Z * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                m_worldMatrix = MatrixD.CreateWorld(position, Vector3D.Normalize(Velocity), m_worldMatrix.Up);
            }

            foreach (MyParticleGeneration generation in m_generations)
            {
                generation.EffectMatrix = WorldMatrix;
                generation.Update();
                m_particlesCount += generation.GetParticlesCount();
                m_birthRate += generation.GetBirthRate();

                BoundingBoxD bbox = generation.GetAABB();
                m_AABB = m_AABB.Include(ref bbox);
            }


            if (m_particlesCount > 0)
                m_hasShownSomething = true;
 
            foreach (var particleLight in m_particleLights)
            {
                particleLight.Update();
            }



            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            m_lastWorldMatrix = m_worldMatrix;

            if (((m_particlesCount == 0 && HasShownSomething())
                || (m_particlesCount == 0 && m_birthRate == 0.0f))
                && AutoDelete && !m_isPreloading)
            {   //Effect was played and has to be deleted
                return true;
            }

            if (!m_isPreloading && OnUpdate != null)
                OnUpdate(this, null);

            return false;
        }
        private void CreateParticle(Vector3D interpolatedEffectPosition)
        {
            MyAnimatedParticle particle = MyTransparentGeometry.AddAnimatedParticle();

            if (particle == null)
            {
                return;
            }

            particle.Type = (MyParticleTypeEnum)ParticleType.GetValue <int>();

            MyUtils.AssertIsValid(m_effect.WorldMatrix);

            Vector3D startOffset;

            m_emitter.CalculateStartPosition(m_effect.GetElapsedTime(), MatrixD.CreateWorld(interpolatedEffectPosition, m_effect.WorldMatrix.Forward, m_effect.WorldMatrix.Up), m_effect.UserEmitterScale * m_effect.UserScale, out startOffset, out particle.StartPosition);

            Vector3D particlePosition = particle.StartPosition;

            m_AABB = m_AABB.Include(ref particlePosition);

            Life.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Life);
            float lifeVar = LifeVar;

            if (lifeVar > 0)
            {
                particle.Life = MathHelper.Max(MyUtils.GetRandomFloat(particle.Life - lifeVar, particle.Life + lifeVar), 0.1f);
            }

            Vector3 vel;

            Velocity.GetInterpolatedValue <Vector3>(m_effect.GetElapsedTime(), out vel);
            vel.X            *= m_effect.UserScale;
            vel.Y            *= m_effect.UserScale;
            vel.Z            *= m_effect.UserScale;
            particle.Velocity = vel;

            if (VelocityDir == MyVelocityDirEnum.FromEmitterCenter)
            {
                if (!MyUtils.IsZero(startOffset - particle.StartPosition))
                {
                    float length = particle.Velocity.Length();
                    particle.Velocity = MyUtils.Normalize(particle.StartPosition - (Vector3D)startOffset) * length;
                }
            }
            particle.Velocity = Vector3D.TransformNormal(particle.Velocity, GetEffect().WorldMatrix);

            Angle.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Angle);
            float angleVar = AngleVar;

            if (angleVar > 0)
            {
                particle.Angle = MyUtils.GetRandomFloat(particle.Angle - AngleVar, particle.Angle + AngleVar);
            }

            RotationSpeed.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.RotationSpeed);
            float rotationSpeedVar = RotationSpeedVar;

            if (rotationSpeedVar > 0)
            {
                particle.RotationSpeed = MyUtils.GetRandomFloat(particle.RotationSpeed - RotationSpeedVar, particle.RotationSpeed + RotationSpeedVar);
            }

            float radiusVar;

            RadiusVar.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out radiusVar);
            float lodRadius = 1.0f;

            if (GetEffect().EnableLods)
            {
                LODRadius.GetInterpolatedValue <float>(GetEffect().Distance, out lodRadius);
            }

            Radius.GetInterpolatedKeys(m_effect.GetElapsedTime(),
                                       radiusVar,
                                       (EnableCustomRadius.GetValue <bool>() ? m_effect.UserRadiusMultiplier : 1.0f)
                                       * lodRadius
                                       * GetEffect().UserScale,
                                       particle.Radius);

            if (particle.Type != MyParticleTypeEnum.Point)
            {
                Thickness.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Thickness);
            }

            particle.Thickness *= lodRadius;

            float colorVar;

            ColorVar.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out colorVar);
            Color.GetInterpolatedKeys(m_effect.GetElapsedTime(), colorVar, 1.0f, particle.Color);

            Material.GetInterpolatedKeys(m_effect.GetElapsedTime(), 0, 1.0f, particle.Material);

            particle.Flags  = 0;
            particle.Flags |= BlendTextures.GetValue <bool>() ? MyAnimatedParticle.ParticleFlags.BlendTextures : 0;
            particle.Flags |= GetEffect().IsInFrustum ? MyAnimatedParticle.ParticleFlags.IsInFrustum : 0;

            particle.Start(this);

            m_particles.Add(particle);
        }
示例#26
0
 private void CalcBox()
 {
     m_boundingBox = new BoundingBoxD();
     m_boundingBox.Include(m_line.From);
     m_boundingBox.Include(m_line.To);
     m_calculatedBox = true;
 }
示例#27
0
        public bool Intersects(ref BoundingSphereD localSphere)
        {
            MyPrecalcComponent.AssertUpdateThread();

            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBoxD sphereBoundingBox = BoundingBoxD.CreateInvalid();

            sphereBoundingBox.Include(ref localSphere);
            Vector3I cellCoordMin, cellCoordMax;

            {
                Vector3D minD = sphereBoundingBox.Min;
                Vector3D maxD = sphereBoundingBox.Max;
                MyVoxelCoordSystems.LocalPositionToGeometryCellCoord(ref minD, out cellCoordMin);
                MyVoxelCoordSystems.LocalPositionToGeometryCellCoord(ref maxD, out cellCoordMax);
            }

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            ClampCellCoord(ref cellCoordMin);
            ClampCellCoord(ref cellCoordMax);

            MyCellCoord cell = new MyCellCoord();

            for (cell.CoordInLod.X = cellCoordMin.X; cell.CoordInLod.X <= cellCoordMax.X; cell.CoordInLod.X++)
            {
                for (cell.CoordInLod.Y = cellCoordMin.Y; cell.CoordInLod.Y <= cellCoordMax.Y; cell.CoordInLod.Y++)
                {
                    for (cell.CoordInLod.Z = cellCoordMin.Z; cell.CoordInLod.Z <= cellCoordMax.Z; cell.CoordInLod.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox cellBoundingBox;
                        MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref cell.CoordInLod, out cellBoundingBox);
                        if (cellBoundingBox.Intersects(ref localSphere) == false)
                        {
                            continue;
                        }

                        //  Get cell from cache. If not there, precalc it and store in the cache.
                        //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                        CellData cachedData = GetCell(ref cell);

                        if (cachedData == null)
                        {
                            continue;
                        }

                        for (int i = 0; i < cachedData.VoxelTrianglesCount; i++)
                        {
                            MyVoxelTriangle voxelTriangle = cachedData.VoxelTriangles[i];

                            MyTriangle_Vertexes triangle;
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangle.Vertex0);
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangle.Vertex1);
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangle.Vertex2);

                            BoundingBox localTriangleAABB = BoundingBox.CreateInvalid();
                            localTriangleAABB.Include(ref triangle.Vertex0);
                            localTriangleAABB.Include(ref triangle.Vertex1);
                            localTriangleAABB.Include(ref triangle.Vertex2);

                            //  First test intersection of triangle's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                            if (localTriangleAABB.Intersects(ref localSphere))
                            {
                                PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                                if (MyUtils.GetSphereTriangleIntersection(ref localSphere, ref trianglePlane, ref triangle) != null)
                                {
                                    //  If intersection found - we are finished. We don't need to look for more.
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
示例#28
0
        /// <summary>
        /// Adds environment item to internal collections. Creates render and physics data. 
        /// </summary>
        /// <returns>True if successfully added, otherwise false.</returns>
        private bool AddItem(
            MyEnvironmentItemDefinition itemDefinition, 
            ref MatrixD worldMatrix, 
            ref BoundingBoxD aabbWorld,
            HkStaticCompoundShape sectorRootShape, 
            Dictionary<MyStringHash, HkShape> subtypeIdToShape,
            int localModelId = MAIN_MODEL_LOCAL_ID)
        {
            if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS)
                return true;

            Debug.Assert(m_definition.ContainsItemDefinition(itemDefinition),
                String.Format("Environment item with definition '{0}' not found in class '{1}'", itemDefinition.Id, m_definition.Id));
            if (!m_definition.ContainsItemDefinition(itemDefinition))
            {
                return false;
            }

            if (itemDefinition.Model == null)
                return false;

            //MyDefinitionId defId = new MyDefinitionId(envItemObjectBuilderType, subtypeId.ToString());
            int modelId = MyEnvironmentItems.GetModelId(itemDefinition.Id.SubtypeId, localModelId);
            string modelName = MyModel.GetById(modelId);

            MyModel model = MyModels.GetModelOnlyData(modelName);
            if (model == null)
            {
                //Debug.Fail(String.Format("Environment item model of '{0}' not found, skipping the item...", itemDefinition.Id));
                return false;
            }

            CheckModelConsistency(itemDefinition);

            int localId = worldMatrix.Translation.GetHashCode();

            MyEnvironmentItemData data = new MyEnvironmentItemData()
            {
                Id = localId,
                SubtypeId = itemDefinition.Id.SubtypeId,
                Transform = new MyTransformD(ref worldMatrix),
                Enabled = true,
                SectorInstanceId = -1,
                ModelId = modelId,
            };

            //Preload split planes
            //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName); 

            aabbWorld.Include(model.BoundingBox.Transform(worldMatrix));

            MatrixD transform = data.Transform.TransformMatrix;

            Vector3I sectorId = MyEnvironmentSector.GetSectorId(transform.Translation - CellsOffset, m_definition.SectorSize);
            MyEnvironmentSector sector;
            if (!m_sectors.TryGetValue(sectorId, out sector))
            {
                sector = new MyEnvironmentSector(sectorId, sectorId * m_definition.SectorSize + CellsOffset);
                m_sectors.Add(sectorId, sector);
            }

            // Adds instance of the given model. Local matrix specified might be changed internally in renderer.

            MatrixD sectorOffset = MatrixD.CreateTranslation(-sectorId * m_definition.SectorSize - CellsOffset);
            Matrix transformL = (Matrix)(transform * sectorOffset);
            data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, data.ModelId, localId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance);

            int physicsShapeInstanceId;

            if (AddPhysicsShape(data.SubtypeId, model, ref transform, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId))
            {
                // Map to data index - note that itemData is added after this to its list!
                m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = localId;
                m_localIdToPhysicsShapeInstanceId[localId] = physicsShapeInstanceId;
            }

            data.Transform = new MyTransformD(transform);

            if (m_itemsData.ContainsKey(localId))
            {
                //Debug.Fail("More items on same place! " + transform.Translation.ToString());
            }
            else
            {
                m_itemsData.Add(localId, data);
            }

            if (ItemAdded != null)
            {
                ItemAdded(this,
                    new ItemInfo()
                    {
                        LocalId = localId,
                        SubtypeId = data.SubtypeId,
                        Transform = data.Transform,
                    });
            }

            return true;
        }
示例#29
0
        public static void DebugDrawClusters()
        {
            if (Clusters == null)
            {
                return;
            }

            double  previewScale  = 2000;
            MatrixD previewMatrix = MatrixD.CreateWorld(DebugDrawClustersMatrix.Translation + previewScale * DebugDrawClustersMatrix.Forward, Vector3D.Forward, Vector3D.Up);

            m_resultWorlds.Clear();

            Clusters.GetAll(m_resultWorlds);

            BoundingBoxD totalBox = BoundingBoxD.CreateInvalid();

            foreach (var res in m_resultWorlds)
            {
                totalBox = totalBox.Include(res.AABB);
            }

            double maxAxis = totalBox.Size.AbsMax();
            //double scaleAxis = 0.057142857142857141;
            double scaleAxis = previewScale / maxAxis;

            //Vector3D scale = new Vector3D(totalBox.Size.X * scaleAxis, totalBox.Size.Y * scaleAxis, totalBox.Size.Z * scaleAxis);

            Vector3D center = totalBox.Center;

            totalBox.Min -= center;
            totalBox.Max -= center;

            {
                BoundingBoxD           scaledBox = new BoundingBoxD(totalBox.Min * scaleAxis * 1.02f, totalBox.Max * scaleAxis * 1.02f);
                MyOrientedBoundingBoxD oriented  = new MyOrientedBoundingBoxD(scaledBox, previewMatrix);
                MyRenderProxy.DebugDrawOBB(oriented, Vector3.Up, 1, false, false);

                MyRenderProxy.DebugDrawAxis(previewMatrix, 50, false);

                if (MySession.Static != null)
                {
                    foreach (var player in Sandbox.Game.Multiplayer.Sync.Players.GetOnlinePlayers())
                    {
                        if (player.Character != null)
                        {
                            var playerPos = Vector3D.Transform((player.Character.PositionComp.GetPosition() - center) * scaleAxis, previewMatrix);
                            MyRenderProxy.DebugDrawSphere(playerPos, 10, Vector3.One, 1, false);
                        }
                    }
                }
            }

            Clusters.GetAllStaticObjects(m_clusterStaticObjects);
            foreach (var staticBB in m_clusterStaticObjects)
            {
                BoundingBoxD scaledBox = new BoundingBoxD((staticBB.Min - center) * scaleAxis, (staticBB.Max - center) * scaleAxis);

                MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix);

                MyRenderProxy.DebugDrawOBB(oriented, Color.Blue, 1, false, false);
            }

            foreach (var res in m_resultWorlds)
            {
                BoundingBoxD scaledBox = new BoundingBoxD((res.AABB.Min - center) * scaleAxis, (res.AABB.Max - center) * scaleAxis);

                MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix);

                MyRenderProxy.DebugDrawOBB(oriented, Vector3.One, 1, false, false);

                foreach (var rb in ((HkWorld)res.UserData).CharacterRigidBodies)
                {
                    Vector3D rbCenter = res.AABB.Center + rb.Position;
                    rbCenter = (rbCenter - center) * scaleAxis;
                    rbCenter = Vector3D.Transform(rbCenter, previewMatrix);

                    Vector3D velocity = rb.LinearVelocity;
                    velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10;
                    MyRenderProxy.DebugDrawLine3D(rbCenter, rbCenter + velocity, Color.Blue, Color.White, false);
                }

                foreach (var rb in ((HkWorld)res.UserData).RigidBodies)
                {
                    MyOrientedBoundingBoxD rbbb = new MyOrientedBoundingBoxD((BoundingBoxD)rb.GetEntity().LocalAABB, rb.GetEntity().WorldMatrix);
                    rbbb.Center      = (rbbb.Center - center) * scaleAxis;
                    rbbb.HalfExtent *= scaleAxis;
                    rbbb.Transform(previewMatrix);
                    MyRenderProxy.DebugDrawOBB(rbbb, Color.Yellow, 1, false, false);

                    //BoundingBoxD rbaa = rb.GetEntity().WorldAABB;
                    //rbaa.Min = (rbaa.Min - center) * scaleAxis;
                    //rbaa.Max = (rbaa.Max - center) * scaleAxis;
                    //MyRenderProxy.DebugDrawAABB(rbaa, new Vector3(0.8f, 0.8f, 0.8f), 1, 1, false);

                    Vector3D velocity = rb.LinearVelocity;
                    velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10;
                    MyRenderProxy.DebugDrawLine3D(rbbb.Center, rbbb.Center + velocity, Color.Red, Color.White, false);

                    if (velocity.Length() > 1)
                    {
                        BoundingBoxD           ideal    = new BoundingBoxD(rb.GetEntity().WorldAABB.Center - MyHavokCluster.IdealClusterSize / 2, rb.GetEntity().WorldAABB.Center + MyHavokCluster.IdealClusterSize / 2);
                        MyOrientedBoundingBoxD idealObb = new MyOrientedBoundingBoxD(ideal, MatrixD.Identity);
                        idealObb.Center      = (ideal.Center - center) * scaleAxis;
                        idealObb.HalfExtent *= scaleAxis;
                        idealObb.Transform(previewMatrix);
                        MyRenderProxy.DebugDrawOBB(idealObb, new Vector3(0, 0, 1), 1, false, false);
                    }
                }
            }
        }
        public override IMyReplicable GetDependency()
        {
            if (m_physicsSync == null || Grid.IsStatic)
            {
                return(null);
            }

            MyCubeGrid master = MyGridPhysicsStateGroup.GetMasterGrid(Grid);

            if (master != Grid)
            {
                return(MyExternalReplicable.FindByObject(master));
            }

            BoundingBoxD box   = Grid.PositionComp.WorldAABB;
            var          group = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(Grid);

            if (group != null)
            {
                foreach (var node in group.Nodes)
                {
                    box.Include(node.NodeData.PositionComp.WorldAABB);
                }
            }

            if (m_foundEntities == null)
            {
                m_foundEntities = new List <MyEntity>();
            }

            m_foundEntities.Clear();

            MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_foundEntities);

            float      maxRadius   = 0;
            MyCubeGrid biggestGrid = null;

            foreach (var entity in m_foundEntities)
            {
                MyCubeGrid grid = entity as MyCubeGrid;

                if (grid != null)
                {
                    // Dont check for projections
                    if (grid.Projector != null)
                    {
                        continue;
                    }

                    var rad = grid.PositionComp.LocalVolume.Radius;
                    if (rad > maxRadius || (rad == maxRadius && (biggestGrid == null || grid.EntityId > biggestGrid.EntityId)))
                    {
                        maxRadius   = rad;
                        biggestGrid = grid;
                    }
                }
            }

            if (biggestGrid != null && biggestGrid != Grid)
            {
                return(MyExternalReplicable.FindByObject(biggestGrid));
            }

            return(null);
        }
        private static void GetSafeBoundingBoxForPlayers(Vector3D start, double spawnDistance, out BoundingBoxD output)
        {
            double tolerance = 10.0f;
            BoundingSphereD sphere = new BoundingSphereD(start, tolerance);

            var players = MySession.Static.Players.GetOnlinePlayers();
            bool tryIncludeOtherPlayers = true;

            // We have to try adding other players until the bounding sphere stays the same
            while (tryIncludeOtherPlayers)
            {
                tryIncludeOtherPlayers = false;
                foreach (var player in players)
                {
                    Vector3D playerPosition = player.GetPosition();
                    double distanceFromSphere = (sphere.Center - playerPosition).Length() - sphere.Radius;

                    if (distanceFromSphere <= 0.0) continue;
                    if (distanceFromSphere > spawnDistance * 2.0f) continue;

                    sphere.Include(new BoundingSphereD(playerPosition, tolerance));
                    tryIncludeOtherPlayers = true;
                }
            }

            sphere.Radius += spawnDistance;
            output = new BoundingBoxD(sphere.Center - new Vector3D(sphere.Radius), sphere.Center + new Vector3D(sphere.Radius));

            var entities = MyEntities.GetEntitiesInAABB(ref output);
            foreach (var entity in entities)
            {
                if (entity is MyCubeGrid)
                {
                    var cubeGrid = entity as MyCubeGrid;
                    if (cubeGrid.IsStatic)
                    {
                        Vector3D gridPosition = cubeGrid.PositionComp.GetPosition();

                        // If grid is close to picked player we need to include it's "safe" bounding box for spawning ships,
                        // so cargo ships don't spawn near it.

                        output.Include(new BoundingBoxD(new Vector3D(gridPosition - spawnDistance), new Vector3D(gridPosition + spawnDistance)));
                    }
                }
            }
            entities.Clear();
        }
示例#32
0
        void UpdateBoundingFrustum()
        {
            //  Update frustum
            BoundingFrustum.Matrix = ViewProjectionMatrix;

            //  Update bounding box
            BoundingBox = BoundingBoxD.CreateInvalid();
            BoundingBox.Include(ref BoundingFrustum);

            //  Update bounding sphere
            BoundingSphere = MyUtils.GetBoundingSphereFromBoundingBox(ref BoundingBox);
        }
示例#33
0
        public bool Update()
        {
            if (!Enabled)
                return AutoDelete; //efect is not enabled at all and must be deleted

            System.Diagnostics.Debug.Assert(WorldMatrix != MatrixD.Zero, "Effect world matrix was not set!");

            if (!m_isPreloading && !m_wasPreloaded && m_preload > 0)
            {
                m_isPreloading = true;

                // TODO: Optimize (preload causes lags, depending on preload size, it's from 0 ms to 85 ms)
                while (m_elapsedTime < m_preload)
                {
                    Update();
                }

                m_isPreloading = false;
                m_wasPreloaded = true;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleEffect-Update");

            if (!m_isPreloading && IsInFrustum)
            {
                MyPerformanceCounter.PerCameraDrawWrite.ParticleEffectsDrawn++;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleEffect-UpdateGen");

            m_elapsedTime += MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            //m_distance = MySector.MainCamera.GetDistanceWithFOV(WorldMatrix.Translation) / (100.0f); //precalculate for LODs
            m_distance = (float)Vector3D.Distance(MyTransparentGeometry.Camera.Translation, WorldMatrix.Translation) / (100.0f); //precalculate for LODs
            m_particlesCount = 0;
            m_birthRate = 0;
            m_AABB = BoundingBoxD.CreateInvalid();


            //if (CalculateDeltaMatrix)
            //{
                //DeltaMatrix = Matrix.Invert(m_lastWorldMatrix) * m_worldMatrix;
            //}
           

            if (Velocity != Vector3.Zero)
            {
                var position = m_worldMatrix.Translation;
                position.X += Velocity.X * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                position.Y += Velocity.Y * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                position.Z += Velocity.Z * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                m_worldMatrix = MatrixD.CreateWorld(position, Vector3D.Normalize(Velocity), m_worldMatrix.Up);
            }

            //if (RenderCounter == 0 || ((MyRender.RenderCounter - RenderCounter) < FRAMES_TO_SKIP)) //more than FRAMES_TO_SKIP frames consider effect as invisible
            {
                foreach (MyParticleGeneration generation in m_generations)
                {
                    generation.EffectMatrix = WorldMatrix;
                    generation.Update();
                    m_particlesCount += generation.GetParticlesCount();
                    m_birthRate += generation.GetBirthRate();

                    BoundingBoxD bbox = generation.GetAABB();
                    m_AABB = m_AABB.Include(ref bbox);
                }


                if (m_particlesCount > 0)
                    m_hasShownSomething = true;

                //TODO
                IsInFrustum = true; // MySector.MainCamera.IsInFrustum(ref m_AABB);
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            m_lastWorldMatrix = m_worldMatrix;

            if (((m_particlesCount == 0 && HasShownSomething())
                || (m_particlesCount == 0 && m_birthRate == 0.0f))
                && AutoDelete && !m_isPreloading)
            {   //Effect was played and has to be deleted
                return true;
            }

            if (!m_isPreloading && OnUpdate != null)
                OnUpdate(this, null);

            return false;
        }
        private void UpdateParticlesLife()
        {
            int counter = 0;

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-UpdateParticlesLife");

            MyParticleGeneration inheritedGeneration      = null;
            Vector3D             previousParticlePosition = m_effect.WorldMatrix.Translation;
            float particlesToCreate = 0;

            m_AABB = BoundingBoxD.CreateInvalid();
            m_AABB = m_AABB.Include(ref previousParticlePosition);

            if (OnDie.GetValue <int>() != -1)
            {
                inheritedGeneration = GetInheritedGeneration(OnDie.GetValue <int>());

                if (inheritedGeneration == null)
                {
                    OnDie.SetValue(-1);
                }
                else
                {
                    inheritedGeneration.IsInherited = true;
                    particlesToCreate = inheritedGeneration.m_particlesToCreate;
                }
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-Update01");

            Vector3D previousTrail0 = previousParticlePosition;
            Vector3D previousTrail1 = previousParticlePosition;

            using (ParticlesLock.AcquireExclusiveUsing())
            {
                while (counter < m_particles.Count)
                {
                    float motionInheritance;
                    MotionInheritance.GetInterpolatedValue(m_effect.GetElapsedTime(), out motionInheritance);

                    MyAnimatedParticle particle = m_particles[counter];

                    if (motionInheritance > 0)
                    {
                        m_effect.CalculateDeltaMatrix = true;
                    }

                    if (particle.Update())
                    {
                        if (motionInheritance > 0)
                        {
                            var delta = m_effect.GetDeltaMatrix();
                            particle.AddMotionInheritance(ref motionInheritance, ref delta);
                        }

                        if (counter == 0)
                        {
                            previousParticlePosition = particle.ActualPosition;
                            previousTrail0           = particle.Quad.Point1;
                            previousTrail1           = particle.Quad.Point2;
                            particle.Quad.Point0     = particle.ActualPosition;
                            particle.Quad.Point2     = particle.ActualPosition;
                        }

                        counter++;


                        if (particle.Type == MyParticleTypeEnum.Trail)
                        {
                            if (particle.ActualPosition == previousParticlePosition)
                            {
                                particle.Quad.Point0 = particle.ActualPosition;
                                particle.Quad.Point1 = particle.ActualPosition;
                                particle.Quad.Point2 = particle.ActualPosition;
                                particle.Quad.Point3 = particle.ActualPosition;
                            }
                            else
                            {
                                MyPolyLineD polyLine = new MyPolyLineD();
                                polyLine.Thickness = particle.Thickness;
                                polyLine.Point0    = particle.ActualPosition;
                                polyLine.Point1    = previousParticlePosition;

                                Vector3D direction           = polyLine.Point1 - polyLine.Point0;
                                Vector3D normalizedDirection = MyUtils.Normalize(polyLine.Point1 - polyLine.Point0);

                                polyLine.LineDirectionNormalized = normalizedDirection;
                                var camPos = MyTransparentGeometry.Camera.Translation;
                                MyUtils.GetPolyLineQuad(out particle.Quad, ref polyLine, camPos);

                                particle.Quad.Point0 = previousTrail0 + direction * 0.15f;
                                particle.Quad.Point3 = previousTrail1 + direction * 0.15f;
                                previousTrail0       = particle.Quad.Point1;
                                previousTrail1       = particle.Quad.Point2;
                            }
                        }

                        previousParticlePosition = particle.ActualPosition;

                        m_AABB         = m_AABB.Include(ref previousParticlePosition);
                        particle.Flags = GetEffect().IsInFrustum ? particle.Flags | MyAnimatedParticle.ParticleFlags.IsInFrustum : particle.Flags & ~MyAnimatedParticle.ParticleFlags.IsInFrustum;
                        continue;
                    }

                    if (inheritedGeneration != null)
                    {
                        inheritedGeneration.m_particlesToCreate = particlesToCreate;
                        inheritedGeneration.EffectMatrix        = MatrixD.CreateWorld(particle.ActualPosition, Vector3D.Normalize(particle.Velocity), Vector3D.Cross(Vector3D.Left, particle.Velocity));
                        inheritedGeneration.UpdateParticlesCreation();
                    }

                    m_particles.Remove(particle);
                    MyTransparentGeometry.DeallocateAnimatedParticle(particle);
                }
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
示例#35
0
        public void TestVoxelNavmeshTriangle(ref Vector3D a, ref Vector3D b, ref Vector3D c, List <MyCubeGrid> gridsToTest, List <MyGridPathfinding.CubeId> linkCandidatesOutput, out bool intersecting)
        {
            ProfilerShort.Begin("TestVoxelNavmeshTriangle");

            ProfilerShort.Begin("Triangle-obstacle tests");
            Vector3D s = (a + b + c) / 3.0;

            if (m_obstacles.IsInObstacle(s))
            {
                intersecting = true;
                ProfilerShort.End();
                ProfilerShort.End();
                return;
            }
            ProfilerShort.End();

            BoundingBoxD triBB;
            Vector3D     aLocal, bLocal, cLocal, gLocal;
            Vector3D     g = Vector3D.Zero;

            if (MyPerGameSettings.NavmeshPresumesDownwardGravity)
            {
                g = Vector3.Down * 2.0f;
            }

            m_tmpLinkCandidates.Clear();

            intersecting = false;
            foreach (var grid in gridsToTest)
            {
                MatrixD mat = grid.PositionComp.WorldMatrixNormalizedInv;

                Vector3D.Transform(ref a, ref mat, out aLocal);
                Vector3D.Transform(ref b, ref mat, out bLocal);
                Vector3D.Transform(ref c, ref mat, out cLocal);
                Vector3D.TransformNormal(ref g, ref mat, out gLocal);

                triBB = new BoundingBoxD(Vector3D.MaxValue, Vector3D.MinValue);
                triBB.Include(ref aLocal, ref bLocal, ref cLocal);

                Vector3I min  = grid.LocalToGridInteger(triBB.Min);
                Vector3I max  = grid.LocalToGridInteger(triBB.Max);
                Vector3I pos  = min - Vector3I.One;
                Vector3I max2 = max + Vector3I.One;
                for (var it = new Vector3I_RangeIterator(ref pos, ref max2); it.IsValid(); it.GetNext(out pos))
                {
                    if (grid.GetCubeBlock(pos) != null)
                    {
                        Vector3      largeMin = (pos - Vector3.One) * grid.GridSize;
                        Vector3      largeMax = (pos + Vector3.One) * grid.GridSize;
                        Vector3      smallMin = (pos - Vector3.Half) * grid.GridSize;
                        Vector3      smallMax = (pos + Vector3.Half) * grid.GridSize;
                        BoundingBoxD largeBb  = new BoundingBoxD(largeMin, largeMax);
                        BoundingBoxD bb       = new BoundingBoxD(smallMin, smallMax);

                        largeBb.Include(largeMin + gLocal);
                        largeBb.Include(largeMax + gLocal);
                        bb.Include(smallMin + gLocal);
                        bb.Include(smallMax + gLocal);

                        ProfilerShort.Begin("Triangle intersection tests");
                        if (largeBb.IntersectsTriangle(ref aLocal, ref bLocal, ref cLocal))
                        {
                            if (bb.IntersectsTriangle(ref aLocal, ref bLocal, ref cLocal))
                            {
                                intersecting = true;
                                ProfilerShort.End();
                                break;
                            }
                            else
                            {
                                int dx = Math.Min(Math.Abs(min.X - pos.X), Math.Abs(max.X - pos.X));
                                int dy = Math.Min(Math.Abs(min.Y - pos.Y), Math.Abs(max.Y - pos.Y));
                                int dz = Math.Min(Math.Abs(min.Z - pos.Z), Math.Abs(max.Z - pos.Z));
                                if ((dx + dy + dz) < 3)
                                {
                                    m_tmpLinkCandidates.Add(new MyGridPathfinding.CubeId()
                                    {
                                        Grid = grid, Coords = pos
                                    });
                                }
                            }
                        }
                        ProfilerShort.End();
                    }
                }

                if (intersecting)
                {
                    break;
                }
            }

            if (!intersecting)
            {
                for (int i = 0; i < m_tmpLinkCandidates.Count; ++i)
                {
                    linkCandidatesOutput.Add(m_tmpLinkCandidates[i]);
                }
            }
            m_tmpLinkCandidates.Clear();

            ProfilerShort.End();
        }
示例#36
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();
                    }
                }
            }
        }
示例#37
0
        public void TestVoxelNavmeshTriangle(ref Vector3D a, ref Vector3D b, ref Vector3D c, List <MyCubeGrid> gridsToTest, List <MyGridPathfinding.CubeId> linkCandidatesOutput, out bool intersecting)
        {
            Vector3D point = ((a + b) + c) / 3.0;

            if (this.m_obstacles.IsInObstacle(point))
            {
                intersecting = true;
                return;
            }
            Vector3D zero = Vector3D.Zero;

            if (MyPerGameSettings.NavmeshPresumesDownwardGravity)
            {
                zero = Vector3.Down * 2f;
            }
            m_tmpLinkCandidates.Clear();
            intersecting = false;
            using (List <MyCubeGrid> .Enumerator enumerator = gridsToTest.GetEnumerator())
            {
                goto TR_0016;
TR_0008:
                if (intersecting)
                {
                    goto TR_0006;
                }
TR_0016:
                while (true)
                {
                    if (enumerator.MoveNext())
                    {
                        Vector3D   vectord2;
                        Vector3D   vectord3;
                        Vector3D   vectord4;
                        Vector3D   vectord5;
                        MyCubeGrid current = enumerator.Current;
                        MatrixD    worldMatrixNormalizedInv = current.PositionComp.WorldMatrixNormalizedInv;
                        Vector3D.Transform(ref a, ref worldMatrixNormalizedInv, out vectord2);
                        Vector3D.Transform(ref b, ref worldMatrixNormalizedInv, out vectord3);
                        Vector3D.Transform(ref c, ref worldMatrixNormalizedInv, out vectord4);
                        Vector3D.TransformNormal(ref zero, ref worldMatrixNormalizedInv, out vectord5);
                        BoundingBoxD xd = new BoundingBoxD(Vector3D.MaxValue, Vector3D.MinValue);
                        xd.Include(ref vectord2, ref vectord3, ref vectord4);
                        Vector3I vectori  = current.LocalToGridInteger((Vector3)xd.Min);
                        Vector3I vectori2 = current.LocalToGridInteger((Vector3)xd.Max);
                        Vector3I start    = vectori - Vector3I.One;
                        Vector3I end      = (Vector3I)(vectori2 + Vector3I.One);
                        Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref start, ref end);
                        while (iterator.IsValid())
                        {
                            if (current.GetCubeBlock(start) != null)
                            {
                                Vector3      min     = (Vector3)((start - Vector3.One) * current.GridSize);
                                Vector3      max     = (start + Vector3.One) * current.GridSize;
                                Vector3      vector3 = (Vector3)((start - Vector3.Half) * current.GridSize);
                                Vector3      vector4 = (start + Vector3.Half) * current.GridSize;
                                BoundingBoxD xd3     = new BoundingBoxD(min, max);
                                BoundingBoxD xd4     = new BoundingBoxD(vector3, vector4);
                                xd3.Include(min + vectord5);
                                xd3.Include(max + vectord5);
                                xd4.Include(vector3 + vectord5);
                                xd4.Include(vector4 + vectord5);
                                if (xd3.IntersectsTriangle(ref vectord2, ref vectord3, ref vectord4))
                                {
                                    if (xd4.IntersectsTriangle(ref vectord2, ref vectord3, ref vectord4))
                                    {
                                        intersecting = true;
                                        break;
                                    }
                                    int num3 = Math.Min(Math.Abs((int)(vectori.Z - start.Z)), Math.Abs((int)(vectori2.Z - start.Z)));
                                    if (((Math.Min(Math.Abs((int)(vectori.X - start.X)), Math.Abs((int)(vectori2.X - start.X))) + Math.Min(Math.Abs((int)(vectori.Y - start.Y)), Math.Abs((int)(vectori2.Y - start.Y)))) + num3) < 3)
                                    {
                                        MyGridPathfinding.CubeId item = new MyGridPathfinding.CubeId {
                                            Grid   = current,
                                            Coords = start
                                        };
                                        m_tmpLinkCandidates.Add(item);
                                    }
                                }
                            }
                            iterator.GetNext(out start);
                        }
                    }
                    else
                    {
                        goto TR_0006;
                    }
                    break;
                }
                goto TR_0008;
            }
TR_0006:
            if (!intersecting)
            {
                for (int i = 0; i < m_tmpLinkCandidates.Count; i++)
                {
                    linkCandidatesOutput.Add(m_tmpLinkCandidates[i]);
                }
            }
            m_tmpLinkCandidates.Clear();
        }
示例#38
0
        /// <summary>
        /// Adds environment item to internal collections. Creates render and physics data. 
        /// </summary>
        /// <returns>True if successfully added, otherwise false.</returns>
        private bool AddItem(
            MyEnvironmentItemDefinition itemDefinition, 
            ref MatrixD worldMatrix, 
            ref BoundingBoxD aabbWorld, bool silentOverlaps = false)
        {
            if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS)
                return true;

            Debug.Assert(m_definition.ContainsItemDefinition(itemDefinition),
                String.Format("Environment item with definition '{0}' not found in class '{1}'", itemDefinition.Id, m_definition.Id));
            if (!m_definition.ContainsItemDefinition(itemDefinition))
            {
                return false;
            }

            if (itemDefinition.Model == null)
                return false;

            //MyDefinitionId defId = new MyDefinitionId(envItemObjectBuilderType, subtypeId.ToString());
            int modelId = MyEnvironmentItems.GetModelId(itemDefinition.Id.SubtypeId);
            string modelName = MyModel.GetById(modelId);

            MyModel model = MyModels.GetModelOnlyData(modelName);
            if (model == null)
            {
                //Debug.Fail(String.Format("Environment item model of '{0}' not found, skipping the item...", itemDefinition.Id));
                return false;
            }

            CheckModelConsistency(itemDefinition);

            int localId = worldMatrix.Translation.GetHashCode();

            if (m_itemsData.ContainsKey(localId))
            {
                if (!silentOverlaps)
                {
                    Debug.Fail("More items on same place! " + worldMatrix.Translation.ToString());
                    MyLog.Default.WriteLine("WARNING: items are on the same place.");
                }
                return false;
            }

            MyEnvironmentItemData data = new MyEnvironmentItemData()
            {
                Id = localId,
                SubtypeId = itemDefinition.Id.SubtypeId,
                Transform = new MyTransformD(ref worldMatrix),
                Enabled = true,
                SectorInstanceId = -1,
                Model = model,
            };

            //Preload split planes
            //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName); 

            aabbWorld.Include(model.BoundingBox.Transform(worldMatrix));

            MatrixD transform = data.Transform.TransformMatrix;
            float sectorSize = MyFakes.ENVIRONMENT_ITEMS_ONE_INSTANCEBUFFER ? 20000 : m_definition.SectorSize;

            Vector3I sectorId = MyEnvironmentSector.GetSectorId(transform.Translation - CellsOffset, sectorSize);
            MyEnvironmentSector sector;
            if (!m_sectors.TryGetValue(sectorId, out sector))
            {
                sector = new MyEnvironmentSector(sectorId, sectorId * sectorSize + CellsOffset);
                m_sectors.Add(sectorId, sector);
            }

            // Adds instance of the given model. Local matrix specified might be changed internally in renderer.

            MatrixD sectorOffsetInv = MatrixD.CreateTranslation(-sectorId * sectorSize - CellsOffset);
            Matrix transformL = (Matrix)(data.Transform.TransformMatrix * sectorOffsetInv);

            data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, modelId, localId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance);
            data.Transform = new MyTransformD(transform);
            m_itemsData.Add(localId, data);

            if (ItemAdded != null)
            {
                ItemAdded(this,
                    new ItemInfo()
                    {
                        LocalId = localId,
                        SubtypeId = data.SubtypeId,
                        Transform = data.Transform,
                    });
            }

            return true;
        }
        private static void CalculateAABB(ref BoundingBoxD bbox, out float scaleZ, out float scaleXY, ref Vector3D position, ref Vector3D direction, ref Vector3D up, float reflectorConeMaxAngleCos, float reflectorRange)
        {
            scaleZ = 1;
            scaleXY = 1;
            float cosAngle = 1 - reflectorConeMaxAngleCos;
            scaleZ = reflectorRange;
            // Calculate cone side (hypotenuse of triangle)
            float side = reflectorRange / cosAngle;
            // Calculate cone bottom scale (Pythagoras theorem)
            scaleXY = (float)System.Math.Sqrt(side * side - reflectorRange * reflectorRange) * 2;

            if (scaleXY == 0)
                scaleXY = 1;

            up = MyUtils.Normalize(up);
            Vector3 coneSideDirection = Vector3.Cross(up, direction);
            coneSideDirection = MyUtils.Normalize(coneSideDirection);
            Vector3D coneCenter = position + direction * scaleZ;
            Vector3D pt1 = coneCenter + coneSideDirection * scaleXY / 2 + up * scaleXY / 2;
            Vector3D pt2 = coneCenter - coneSideDirection * scaleXY / 2 + up * scaleXY / 2;
            Vector3D pt3 = coneCenter + coneSideDirection * scaleXY / 2 - up * scaleXY / 2;
            Vector3D pt4 = coneCenter - coneSideDirection * scaleXY / 2 - up * scaleXY / 2;

            bbox = BoundingBoxD.CreateInvalid();
            bbox = bbox.Include(ref position);
            //bbox = bbox.Include(ref coneCenter);
            bbox = bbox.Include(ref pt1);
            bbox = bbox.Include(ref pt2);
            bbox = bbox.Include(ref pt3);
            bbox = bbox.Include(ref pt4);
        }
示例#40
0
        /// <summary>
        /// Handles camera collisions with environment
        /// </summary>
        /// <param name="controlledEntity"></param>
        /// <param name="shakeActive"></param>
        /// <param name="headPosition"></param>
        /// <param name="headDirection"></param>
        /// <returns>False if no correct position was found</returns>
        private bool HandleIntersection(MyEntity controlledEntity, MyOrientedBoundingBoxD safeOBB, bool requireRaycast, bool shakeActive, Vector3D headPosition, Vector3 headDirection)
        {
            var line = new LineD(m_target, m_position);

            var      safeOBBLine = new LineD(line.From, line.From + line.Direction * 2 * safeOBB.HalfExtent.Length());
            Vector3D castStartSafe;

            {
                MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeOBB.Center, safeOBB.HalfExtent + 2 * CAMERA_RADIUS, safeOBB.Orientation);
                double?safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine);
                if (!safeIntersection.HasValue)
                {
                    safeIntersection = safeOBB.HalfExtent.Length();
                }
                double safeDistance = safeIntersection.Value;
                castStartSafe = line.From + line.Direction * safeDistance;
            }

            {
                double?unsafeIntersection = safeOBB.Intersects(ref safeOBBLine);
                if (!requireRaycast && unsafeIntersection.HasValue)
                {
                    var castStartUnsafe = line.From + line.Direction * unsafeIntersection.Value;
                    var castEndUnsafe   = castStartSafe + line.Direction;
                    // short raycast, not causing problems with asteroids generating geometry
                    Physics.MyPhysics.CastRay(castStartUnsafe, castEndUnsafe, m_raycastList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                    if (!IsRaycastOK(m_raycastList))
                    {
                        return(false);
                    }
                }
            }

            if (requireRaycast)
            {
                // short raycast, not causing problems with asteroids generating geometry
                Physics.MyPhysics.CastRay(line.From, castStartSafe + line.Direction, m_raycastList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                if (!IsRaycastOK(m_raycastList))
                {
                    return(false);
                }
            }

            HkShape shape = new HkSphereShape(CAMERA_RADIUS);

            try
            {
                // small shape, not causing problems with asteroids generating geometry
                Physics.MyPhysics.GetPenetrationsShape(shape, ref castStartSafe, ref Quaternion.Identity, m_rigidList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                if (m_rigidList.Count > 0)
                {
                    bool sameGrid = false;
                    if (MySession.Static.ControlledEntity != null && m_rigidList[0].Body != null)
                    {
                        sameGrid = m_rigidList[0].GetCollisionEntity() == MySession.Static.ControlledEntity;
                    }

                    if (sameGrid)
                    {
                        castStartSafe += line.Direction;
                    }
                }

                var  shapeCastLine = new LineD(castStartSafe, m_position);
                uint steps         = 1;
                uint stepIdx       = 0;
                if (shapeCastLine.Length > SHAPE_CAST_STEP)
                {
                    steps = (uint)Math.Ceiling(shapeCastLine.Length / SHAPE_CAST_STEP);
                    if (steps >= SHAPE_CAST_MAX_STEP_COUNT)
                    {
                        steps = SHAPE_CAST_MAX_STEP_COUNT - 1;
                    }
                    stepIdx = m_updateCount % steps;
                    m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity;

                    Vector3D step = shapeCastLine.Direction * (shapeCastLine.Length / steps);
                    shapeCastLine = new LineD(castStartSafe + stepIdx * step, castStartSafe + (stepIdx + 1) * step);
                }

                if (false)
                {
                    BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
                    bbox.Include(new BoundingSphereD(shapeCastLine.From, CAMERA_RADIUS));
                    bbox.Include(new BoundingSphereD(shapeCastLine.To, CAMERA_RADIUS));
                    VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Color.Crimson, 1f, 1f, true);
                }

                var matrix = MatrixD.CreateTranslation(shapeCastLine.From);
                HkContactPointData?cpd;
                if (controlledEntity.Physics != null && controlledEntity.GetPhysicsBody().CharacterProxy != null)
                {
                    cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, MyPhysics.CollisionLayers.CharacterCollisionLayer, 0.0f);
                }
                else
                {
                    cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, MyPhysics.CollisionLayers.DefaultCollisionLayer, 0.0f);
                }
                if (cpd.HasValue)
                {
                    var point = shapeCastLine.From + shapeCastLine.Direction * shapeCastLine.Length * cpd.Value.DistanceFraction;
                    m_lastShapeCastDistance[stepIdx] = (float)(castStartSafe - point).Length();
                }
                else
                {
                    m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity;
                }


                float?dist = null;
                for (int i = 0; i < steps; ++i)
                {
                    if (m_lastShapeCastDistance[i] != float.PositiveInfinity)
                    {
                        dist = Math.Min(m_lastShapeCastDistance[i], dist ?? float.PositiveInfinity);
                    }
                }

                if (dist.HasValue)
                {
                    if (dist == 0.0f)
                    {
                        return(false);
                    }
                    else
                    {
                        m_positionSafe = castStartSafe + shapeCastLine.Direction * dist.Value;
                    }
                }
                else
                {
                    m_positionSafe = m_position;
                }
                return(true);
            }
            finally
            {
                shape.RemoveReference();
            }
        }
示例#41
0
        protected void UpdateRenderObject()
        {
            m_actualWorldAABB = BoundingBoxD.CreateInvalid();

            if (AnimationController.CharacterBones != null)
            for (int i = 1; i < Model.Bones.Length; i++)
            {
                Vector3D p1 = Vector3D.Transform(AnimationController.CharacterBones[i].Parent.AbsoluteTransform.Translation, WorldMatrix);
                Vector3D p2 = Vector3D.Transform(AnimationController.CharacterBones[i].AbsoluteTransform.Translation, WorldMatrix);

                m_actualWorldAABB.Include(ref p1);
                m_actualWorldAABB.Include(ref p2);
            }

            ContainmentType containmentType;
            m_aabb.Contains(ref m_actualWorldAABB, out containmentType);
            if (containmentType != ContainmentType.Contains)
            {
                m_actualWorldAABB.Inflate(0.5f);
                MatrixD worldMatrix = WorldMatrix;
                VRageRender.MyRenderProxy.UpdateRenderObject(Render.RenderObjectIDs[0], ref worldMatrix, false, m_actualWorldAABB);
                m_aabb = m_actualWorldAABB;
            }
        }