示例#1
0
        /// <summary>
        /// Applies buoyancy forces to appropriate objects.
        /// Called automatically when needed by the owning Space.
        /// </summary>
        /// <param name="dt">Time since last frame in physical logic.</param>
        void IDuringForcesUpdateable.Update(float dt)
        {
            QueryAccelerator.GetEntries(boundingBox, broadPhaseEntries);
            //TODO: Could integrate the entire thing into the collision detection pipeline.  Applying forces
            //in the collision detection pipeline isn't allowed, so there'd still need to be an Updateable involved.
            //However, the broadphase query would be eliminated and the raycasting work would be automatically multithreaded.

            this.dt = dt;

            //Don't always multithread.  For small numbers of objects, the overhead of using multithreading isn't worth it.
            //Could tune this value depending on platform for better performance.
            if (broadPhaseEntries.Count > 30 && ParallelLooper != null && ParallelLooper.ThreadCount > 1)
            {
                ParallelLooper.ForLoop(0, broadPhaseEntries.Count, analyzeCollisionEntryDelegate);
            }
            else
            {
                for (int i = 0; i < broadPhaseEntries.Count; i++)
                {
                    AnalyzeEntry(i);
                }
            }

            broadPhaseEntries.Clear();
        }
示例#2
0
        protected Demo(DemosGame game)
        {
            Game           = game;
            parallelLooper = new ParallelLooper();
            //This section lets the engine know that it can make use of multithreaded systems
            //by adding threads to its thread pool.
#if XBOX360
            parallelLooper.AddThread(delegate { Thread.CurrentThread.SetProcessorAffinity(new[] { 1 }); });
            parallelLooper.AddThread(delegate { Thread.CurrentThread.SetProcessorAffinity(new[] { 3 }); });
            parallelLooper.AddThread(delegate { Thread.CurrentThread.SetProcessorAffinity(new[] { 4 }); });
            parallelLooper.AddThread(delegate { Thread.CurrentThread.SetProcessorAffinity(new[] { 5 }); });
#else
            if (Environment.ProcessorCount > 1)
            {
                for (int i = 0; i < Environment.ProcessorCount; i++)
                {
                    parallelLooper.AddThread();
                }
            }
#endif

            Space = new Space(parallelLooper);


            game.Camera.LockedUp      = Vector3.Up;
            game.Camera.ViewDirection = new Vector3(0, 0, -1);
        }
示例#3
0
        protected override void UpdateMultithreaded()
        {
#if PROFILE
            startPairs = Stopwatch.GetTimestamp();
#endif

            ParallelLooper.ForLoop(0, broadPhaseOverlaps.Count, updateBroadPhaseOverlapDelegate);

#if PROFILE
            endPairs = Stopwatch.GetTimestamp();
#endif

            //Remove stale objects BEFORE adding new objects. This ensures that simulation islands which will be activated
            //by new narrow phase pairs will not be momentarily considered stale.
            //(The RemoveStale only considers islands that are active to be potentially stale.)
            //If that happened, all the pairs would be remove and immediately recreated. Very wasteful!
            RemoveStaleOverlaps();
#if PROFILE
            endStale = Stopwatch.GetTimestamp();
#endif
            //This sets NeedsUpdate to true for all new objects, ensuring that they are considered for staleness next time.
            AddNewNarrowPhaseObjects();

#if PROFILE
            endFlushNew = Stopwatch.GetTimestamp();
#endif
        }
        protected override void UpdateMultithreaded()
        {
            FlushSplits();

            ParallelLooper.ForLoop(0, simulationIslandMembers.Count, multithreadedCandidacyLoopDelegate);

            DeactivateObjects();
        }
示例#5
0
 protected override void UpdateMultithreaded()
 {
     ParallelLooper.ForLoop(0, solverUpdateables.Count, multithreadedPrestepDelegate);
     //By performing all velocity modifications after the prestep, the prestep is free to read velocities consistently.
     //If the exclusive update was performed in the same call as the prestep, the velocities would enter inconsistent states based on update order.
     ParallelLooper.ForLoop(0, solverUpdateables.Count, multithreadedExclusiveUpdateDelegate);
     ++PermutationMapper.PermutationIndex;
     ParallelLooper.ForLoop(0, iterationLimit * solverUpdateables.Count, multithreadedIterationDelegate);
 }
        internal ParallelLoopWorker(ParallelLooper manager, Action threadStart)
        {
            this.manager     = manager;
            this.threadStart = threadStart;

            getToWork = new AutoResetEvent(false);

            thread = new Thread(Work)
            {
                IsBackground = true
            };
            thread.Start();
        }
示例#7
0
        //Default Constructor
        public ServerPhysics()
        {
            //Run extra threads if they are available
            ParallelLooper = new ParallelLooper();
            if (Environment.ProcessorCount > 1)
            {
                for (int i = 0; i < Environment.ProcessorCount; i++)
                {
                    ParallelLooper.AddThread();
                }
            }
            Globals.space = new Space(ParallelLooper);

            //Set the gravity force in the physics simulation
            Globals.space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);

            //Load in the terrain mesh collsion data to use as the base of the game simulation
        }
        protected override void UpdateMultithreaded()
        {
            //Go through the list of all updateables which do not permit motion clamping.
            //Since these do not care about CCD, just update them as if they were discrete.
            //In addition, go through the remaining non-discrete objects and perform their prestep.
            //This usually involves updating their angular motion, but not their linear motion.
            int count = discreteUpdateables.Count + passiveUpdateables.Count + continuousUpdateables.Count;

            ParallelLooper.ForLoop(0, count, preUpdate);

            //Now go through the list of all full CCD objects.  These are responsible
            //for determining the TOI of collision pairs, if existent.
            if (continuousUpdateables.Count > MultithreadingThreshold)
            {
                ParallelLooper.ForLoop(0, continuousUpdateables.Count, updateTimeOfImpact);
            }
            else
            {
                for (int i = 0; i < continuousUpdateables.Count; i++)
                {
                    UpdateTimeOfImpact(i);
                }
            }

            //The TOI's are now computed, so we can integrate all of the CCD or allow-motionclampers
            //to their new positions.
            count = passiveUpdateables.Count + continuousUpdateables.Count;
            if (count > MultithreadingThreshold)
            {
                ParallelLooper.ForLoop(0, count, updateContinuous);
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    UpdateContinuousItem(i);
                }
            }

            //The above process is the same as the UpdateSingleThreaded version, but
            //it doesn't always use multithreading.  Sometimes, a simulation can have
            //very few continuous objects.  In this case, there's no point in having the
            //multithreaded overhead.
        }
示例#9
0
 /// <summary>
 /// Applies forces specified by the given calculation delegate to bodies in the volume.
 /// Called automatically when needed by the owning Space.
 /// </summary>
 /// <param name="dt">Time since the last frame in simulation seconds.</param>
 void IDuringForcesUpdateable.Update(float dt)
 {
     PreUpdate();
     affectedEntities = Shape.GetPossiblyAffectedEntities();
     if (AllowMultithreading && ParallelLooper != null && ParallelLooper.ThreadCount > 1)
     {
         currentTimestep = dt;
         ParallelLooper.ForLoop(0, affectedEntities.Count, subfunction);
     }
     else
     {
         currentTimestep = dt;
         //No multithreading, so do it directly.
         int count = affectedEntities.Count;
         for (int i = 0; i < count; i++)
         {
             CalculateImpulsesSubfunction(i);
         }
     }
 }
示例#10
0
 protected override void UpdateMultithreaded()
 {
     Vector3.Multiply(ref gravity, timeStepSettings.TimeStepDuration, out gravityDt);
     ParallelLooper.ForLoop(0, dynamicObjects.Count, multithreadedLoopBodyDelegate);
 }
示例#11
0
 protected override void UpdateMultithreaded()
 {
     ParallelLooper.ForLoop(0, manager.entities.Count, multithreadedWithReadBuffersDelegate);
     FlipBuffers();
 }
示例#12
0
 protected override void UpdateMultithreaded()
 {
     ParallelLooper.ForLoop(0, entries.Count, multithreadedLoopBodyDelegate);
 }
示例#13
0
        //public ServerEntity WaypointTest;

        public WorldSimulator(WorldRenderer game)
        {
            Game           = game;
            parallelLooper = new ParallelLooper();
            if (Environment.ProcessorCount > 1)
            {
                for (int i = 0; i < Environment.ProcessorCount; i++)
                {
                    parallelLooper.AddThread();
                }
            }
            Globals.space             = new Space(parallelLooper);
            game.Camera.LockedUp      = Vector3.Up;
            game.Camera.ViewDirection = new Vector3(0, -1.5f, 1);
            game.Camera.Position      = new Vector3(-19.55f, 39.25f, -10.35f);
            ServerCamera = new FreeCamera(100, game.Camera, game);

            //Add some force of gravity to the simulation
            Globals.space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);


            //Load the world terrain mesh data
            Vector3[] TerrainVertices;
            int[]     TerrainIndices;
            Model     TerrainCollision = Globals.game.Content.Load <Model>("LowDetailTerrain");

            ModelDataExtractor.GetVerticesAndIndicesFromModel(TerrainCollision, out TerrainVertices, out TerrainIndices);
            StaticMesh TerrainMesh = new StaticMesh(TerrainVertices, TerrainIndices, new AffineTransform(new Vector3(0, 0, 0)));

            Globals.TerrainVerts = TerrainVertices;
            Globals.TerrainInds  = TerrainIndices;
            Globals.space.Add(TerrainMesh);
            Globals.game.ModelDrawer.Add(TerrainMesh);

            //Create a new mesh node object for each unique location in the navigation mesh
            for (int i = 0; i < Globals.TerrainVerts.Length; i++)
            {
                //Dont create mesh nodes at locations already been used
                if (!NavMeshNodes.IsLocationAvailable(Globals.TerrainVerts[i]))
                {
                    continue;
                }

                //Add a new mesh node object to every other space in the terrain verts that we find to be available
                NavMeshNodes.AddNode(new NavMeshNode(Globals.TerrainVerts[i]));
            }

            //Now sort all of the mesh nodes into a dictionary sorted by their index in the level
            //Start with the first column of mesh nodes
            for (int i = 1; i < 10; i++)
            {
                Vector2     MeshIndex     = new Vector2(i, 1);
                int         MeshNodeIndex = (i - 1) * 2;
                NavMeshNode MeshNode      = NavMeshNodes.MeshNodes[MeshNodeIndex];
                NavMeshDictionary.AddNode(MeshNode, MeshIndex);
            }
            //Then the second column of mesh nodes
            int CurrentNodeIndex = 1;

            for (int i = 1; i < 10; i++)
            {
                Vector2 MeshIndex = new Vector2(i, 2);
                int     NodeIndex = CurrentNodeIndex;
                CurrentNodeIndex += 2;
                NavMeshNode MeshNode = NavMeshNodes.MeshNodes[NodeIndex];
                MeshNode.NodeIndex = MeshIndex;
                NavMeshDictionary.AddNode(MeshNode, MeshIndex);
            }
            //Add the other remaining columns
            int ListIndex = 18;

            for (int Column = 3; Column < 10; Column++)
            {
                for (int j = 1; j < 10; j++)
                {
                    Vector2     MeshIndex = new Vector2(j, Column);
                    NavMeshNode MeshNode  = NavMeshNodes.MeshNodes[ListIndex];
                    MeshNode.NodeIndex = MeshIndex;
                    ListIndex++;
                    NavMeshDictionary.AddNode(MeshNode, MeshIndex);
                }
            }

            //Add two game entities into the scene, the first entity will pathfind its way to the 2nd entity
            PrincessFox    = new GameEntity(new Vector3(-17.74f, 2.15f, 10.54f));
            PrincessTarget = new GameEntity(new Vector3(-41.17f, 0.89f, 24.15f));
            //Figure out which node each of these entities is closest two, these will be the ends of the pathway
            NavMeshNode StartNode = NavMeshDictionary.MeshDictionary[new Vector2(3, 4)];
            NavMeshNode EndNode   = NavMeshDictionary.MeshDictionary[new Vector2(7, 8)];

            //Find our pathway between the two entities
            List <NavMeshNode> NodePath = AStarSearch.FindPath(StartNode, EndNode, new Vector2(9, 9));
            //Now assign this path to the princess fox entity and have her navigate along to reach her target
        }