예제 #1
0
        /// <summary>
        /// Adding rigid body recursively to check for constraint connections and make sure that its only in 1 island
        /// </summary>
        private void AddRigidBody(MyRigidBody rbo, MyRigidBody secondRigidBody,MyRigidBodyIsland addIsland)
        {
            if(rbo.IsStatic())
            {
                rbo.PutToSleep();
                return;
            }

            if (!m_proccesedList.Add(rbo))
                return;

            // add rigid bodies to island recursively
            int numInteractions = 0;

            for (int j = 0; j < rbo.GetRBElementList().Count; j++)
            {
                MyRBElement el = rbo.GetRBElementList()[j];
                numInteractions += el.GetRBElementInteractions().Count;
                
                for (int k = 0; k < el.GetRBElementInteractions().Count; k++)
                {
                    if (addIsland == null && !rbo.IsStatic())
                    {
                        addIsland = m_islandsPool.Allocate();
                        addIsland.Clear();
                        addIsland.IterationCount = 0;
                        addIsland.AddRigidBody(rbo);

                        m_islands.Add(addIsland);                        
                    }
                    else
                    {
                        if(!rbo.IsStatic())
                        {
                            addIsland.AddRigidBody(rbo);
                        }
                    }

                    MyRBElementInteraction intr = el.GetRBElementInteractions()[k];

                    if(intr.GetRigidBody1() != rbo && intr.GetRigidBody2() != secondRigidBody)
                    {
                        AddRigidBody(intr.GetRigidBody1(),rbo,addIsland);
                    }

                    if (intr.GetRigidBody2() != rbo && intr.GetRigidBody1() != secondRigidBody)
                    {
                        AddRigidBody(intr.GetRigidBody2(), rbo, addIsland);
                    }
                }
            }

            // isolated rbo
            if (numInteractions == 0 && !rbo.IsStatic())
            {
                MyRigidBodyIsland island = m_islandsPool.Allocate();
                island.Clear();
                island.IterationCount = 0;
                island.AddRigidBody(rbo);

                m_islands.Add(island);
            }
        }
        /// <summary>
        /// Adding rigid body recursively to check for constraint connections and make sure that its only in 1 island
        /// </summary>
        private void AddRigidBody(MyRigidBody rbo, MyRigidBody secondRigidBody, MyRigidBodyIsland addIsland)
        {
            if (rbo.IsStatic())
            {
                rbo.PutToSleep();
                return;
            }

            if (!m_proccesedList.Add(rbo))
            {
                return;
            }

            // add rigid bodies to island recursively
            int numInteractions = 0;

            for (int j = 0; j < rbo.GetRBElementList().Count; j++)
            {
                MyRBElement el = rbo.GetRBElementList()[j];
                numInteractions += el.GetRBElementInteractions().Count;

                for (int k = 0; k < el.GetRBElementInteractions().Count; k++)
                {
                    if (addIsland == null && !rbo.IsStatic())
                    {
                        addIsland = m_islandsPool.Allocate();
                        addIsland.Clear();
                        addIsland.IterationCount = 0;
                        addIsland.AddRigidBody(rbo);

                        m_islands.Add(addIsland);
                    }
                    else
                    {
                        if (!rbo.IsStatic())
                        {
                            addIsland.AddRigidBody(rbo);
                        }
                    }

                    MyRBElementInteraction intr = el.GetRBElementInteractions()[k];

                    if (intr.GetRigidBody1() != rbo && intr.GetRigidBody2() != secondRigidBody)
                    {
                        AddRigidBody(intr.GetRigidBody1(), rbo, addIsland);
                    }

                    if (intr.GetRigidBody2() != rbo && intr.GetRigidBody1() != secondRigidBody)
                    {
                        AddRigidBody(intr.GetRigidBody2(), rbo, addIsland);
                    }
                }
            }

            // isolated rbo
            if (numInteractions == 0 && !rbo.IsStatic())
            {
                MyRigidBodyIsland island = m_islandsPool.Allocate();
                island.Clear();
                island.IterationCount = 0;
                island.AddRigidBody(rbo);

                m_islands.Add(island);
            }
        }
        /// <summary>
        /// Checks the sleep state of rigids and decides if its possible to sleep the whole island
        /// </summary>
        private void UpdateSleepState()
        {
            //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("GetIslands");

            List <MyRigidBodyIsland> islands = MyPhysics.physicsSystem.GetRigidBodyModule().GetRigidBodyIslandGeneration().GetIslands();

            float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;

            //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Loop Islands");

            int count = 0;

            for (int i = 0; i < islands.Count; i++)
            {
                MyRigidBodyIsland island = islands[i];
                bool canDeactivate       = true;

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Loop Rigids");

                for (int j = 0; j < island.GetRigids().Count; j++)
                {
                    count++;

                    MyRigidBody rbo = island.GetRigids()[j];
                    if (rbo.IsStatic())
                    {
                        rbo.PutToSleep();
                        MyPhysics.physicsSystem.GetRigidBodyModule().RemoveActiveRigid(rbo);
                    }
                    else
                    {
                        //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MoveVolumeFast");

                        foreach (var el in rbo.GetRBElementList())
                        {
                            m_Broadphase.MoveVolumeFast(el);
                        }

                        //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                        //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("NotifyMotionHandler");

                        if (rbo.NotifyMotionHandler != null)
                        {
                            rbo.NotifyMotionHandler.OnMotion(rbo, dt);
                        }

                        //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                    }

                    // dynamic rigids use different approach
                    if (!rbo.CanDeactivate())
                    {
                        canDeactivate = false;
                    }
                }

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("canDeactivate");
                // check if all are asleep
                if (canDeactivate)
                {
                    foreach (var rbo in island.GetRigids())
                    {
                        rbo.PutToSleep();
                        MyPhysics.physicsSystem.GetRigidBodyModule().RemoveActiveRigid(rbo);
                    }
                }
                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
            //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().ProfileCustomValue("UpdateSleepState", count);
        }