- triangulation_source_code.zip
- Triangulation Source Code
- FarseerPhysics2.0.1OnlyForXNA
- MainDemo
- bin
- Content
- bin
- x86
- Debug
- Content.contentproj
- Content.contentproj.vspscc
- Fonts
- detailsFont.spritefont
- diagnosticFont.spritefont
- frameRateCounterFont.spritefont
- gamefont.spritefont
- menufont.spritefont
- statusFont.spritefont
- Pen.png
- Demo
- MainDemo
- PhysicsHelper
- DrawingSystem
- FarseerPhysicsGame.cs
- Game.ico
- GameThumbnail.png
- PhysicsSimulatorView.cs
- Program.cs
- Properties
- ScreenSystem
- Triangulation.csproj
- Triangulation.csproj.Debug.cachefile
- Triangulation.suo
- MechOrganic.suo
- Triangulation.sln
- Triangulation.suo
- demo.zip
- Demo
- Content
- Fonts
- detailsFont.xnb
- diagnosticFont.xnb
- frameRateCounterFont.xnb
- gamefont.xnb
- menufont.xnb
- statusFont.xnb
- Pen.xnb
- FarseerProject.dll
- Triangulation.exe
|
using System;
using System.Collections.Generic;
using System.Threading;
using FarseerGames.FarseerPhysics;
using Microsoft.Xna.Framework;
namespace FarseerGames.Triangulation.GamePlay.PhysicsHelper
{
public class PhysicsProcessor : IDisposable
{
// POINT OF INTEREST
// The simulator what will be used by the processor
// POINT OF INTEREST
// Use this to signal the termination of the physics thread. volatile is a simple syncronisation
// specifier.
private volatile bool _doExit;
private bool _forceSingleThreaded;
// POINT OF INTEREST
// This is a package holding all the information to update the simulator like time and game related stuff
// POINT OF INTEREST
// This is signaled when the thread is not updating. the code using this to determine
// if the thread is not using the simulator /so it can be disposed/.
private ManualResetEvent _idleEvent = new ManualResetEvent(true);
private IterateParam _iterateParam;
// POINT OF INTEREST
// The links the physics thread needs to syncronise after the updates
private List<ObjectLinker> _linkList = new List<ObjectLinker>();
private PhysicsSimulator _physicsSimulator;
private AutoResetEvent _processEvent = new AutoResetEvent(false);
private bool _useMultiThreading;
public PhysicsProcessor(PhysicsSimulator physicsSimulator)
{
_physicsSimulator = physicsSimulator;
}
#region IDisposable Members
public void Dispose()
{
// POINT OF INTEREST
// Signal the phyisics thread to exit, reset the iteration params and signal the
// physics thread so it will exit
_doExit = true;
_iterateParam = new IterateParam(new GameTime());
_processEvent.Set();
}
#endregion
// POINT OF INTEREST
// This is the entry point for the physics thread, like the Main function for it
public void StartThinking()
{
#if XBOX
// POINT OF INTEREST
// On the Xbox360, we need to specify the hardware threads /CPUs/ for the physics
// thread. It is going to run on the fourth HW thread /it is almost fully idle/
Thread.CurrentThread.SetProcessorAffinity( new int[] { 4 } );
useMultiThreading = true;
#else
// POINT OF INTEREST
// Use multithreading only if there is more than one processor to use
_useMultiThreading = Environment.ProcessorCount > 1;
#endif
// POINT OF INTEREST
// The main loop for the physics thread. Update the simulator until told to exit.
// Between each update, it is going to wait until the main thread it to update,
// so the updates are going to happen while the main thread doing something else,
// like drawing, etc.
while (!_doExit)
{
_processEvent.WaitOne();
Think();
}
}
// POINT OF INTEREST
// This is to signal the physics thread to update the simulator. Iterate is
// going to be called on the main thread. This is not going to update the
// simulator, just send the signal to the other thread to get the job done.
public void Iterate(GameTime gameTime, bool forceSingleThreaded)
{
// POINT OF INTEREST
// If the simulation can not be syncronied we force the PhysicsProcessor to do the
// physics update on this thread /the main thread/.
_forceSingleThreaded = forceSingleThreaded;
// POINT OF INTEREST
// Fill the iterate params with all the needed info and signal the physics thread
// to iterate the simulator
_iterateParam = new IterateParam(gameTime);
_processEvent.Set();
// POINT OF INTEREST
// If there is no multithreading enabled /only one HW threads/, or the application
// disabled it manually /DebugView/, do the update on this thread.
if (!_useMultiThreading || forceSingleThreaded)
{
DoThinkPhysics();
}
}
// POINT OF INTEREST
// This blocks the caller thread until the physics thread becomes idle /finished the
// current frame/
public void BlockUntilIdle()
{
_idleEvent.WaitOne();
}
// POINT OF INTEREST
// Register a link to get it syncronised after each update
public void AddLink(ObjectLinker link)
{
_linkList.Add(link);
}
// POINT OF INTEREST
// This is going to be called by the physics thread. Updates the physics simulator.
private void Think()
{
// POINT OF INTEREST
// Updates the simulator if neccessary
if (_useMultiThreading && !_forceSingleThreaded)
{
DoThinkPhysics();
}
// POINT OF INTEREST
// After an update turn off the forced single threading. It is turned off every frame.
_forceSingleThreaded = false;
}
// POINT OF INTEREST
// This is doing the actual physics update. It can be called on both threads. When there are
// more HW threads present in the system /and the multithreaded processing isn't forced off/
// it is going to be called by the physics thread, while the main thread is drawing.
// Otherwise it is going to be called on the main thread, so there is no speed gain.
private void DoThinkPhysics()
{
// POINT OF INTEREST
// Unsignal the idle signal while working.
_idleEvent.Reset();
// POINT OF INTEREST
// Linit the frame rate to 100ms. This is going to cause a slowdown in the simulator when
// the framerate drops below 10FPS. But I think the lagg is more frustrating than the
// slowdown. I prefer a little slowdown, instead of dying between two frames.
_physicsSimulator.Update(Math.Min(_iterateParam.GameTime.ElapsedGameTime.Milliseconds, 100)*.001f);
// POINT OF INTEREST
// Done updating, now syncronise the links
SyncronizeLinks();
// POINT OF INTEREST
// The physics thread is idle again
_idleEvent.Set();
}
// POINT OF INTEREST
// Syncronise the link. It is going to be called after each physics update.
private void SyncronizeLinks()
{
foreach (ObjectLinker link in _linkList)
{
link.Syncronize();
}
}
#region Nested type: IterateParam
private struct IterateParam
{
private GameTime _gameTime;
public IterateParam(GameTime gameTime)
{
_gameTime = gameTime;
}
public GameTime GameTime
{
get { return _gameTime; }
}
} ;
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.