Codesnippet: Poor man’s benchmark, or quickly timing things in C#

For a project I’m working on I had to do some quick timing. Now manually working with DateTimes and TimeSpans isn’t hard but I had to do a lot (e.g. more than 3) timings inside a bigger process and I wanted to know both the time the entire process took as the time parts of the process ate up. For this I created a handy StopWatch class which uses a stack to store different date times so you can easily do nested timing with very little code. This is nothing revolutionary but I thought I’d share it anyway. Its those little things that safe some time that are the nicest!

/// <summary>
/// Always accesible timing apparatus
/// </summary>
public static class StopWatch
{
	private static Stack<DateTime> timers;

	static StopWatch()
	{
		timers = new Stack<DateTime>(0);
	}


	/// <summary>
	/// Pushes the current DateTime onto the stack of timers
	/// </summary>
	public static void Push()
	{
		timers.Push(DateTime.Now);
	}

	/// <summary>
	/// Pops the top DateTime from the stack of timers,
	/// returns the TimeSpan between when the last Push and now
	/// </summary>        
	public static TimeSpan Pop()
	{
		if(timers.Count > 0)
		{
			DateTime start = timers.Pop();
			return DateTime.Now - start;
		}
		else
		{
			throw new Exception("Trying to pop while the stack is empty");
		}
	} 

	/// <summary>
	/// Calls Pop(), then prints the text "StopWatch: {totalSeconds} \n"
	/// directly to console.
	/// </summary>
	public static void PopAndPrint()
	{            
		Console.Out.WriteLine("StopWatch: " + Pop().TotalSeconds);
	}
	
	/// <summary>
	/// Returns the TimeSpan between the last Push and now
	/// without popping the TimeSpan from the stack of timers
	/// </summary>        
	public static TimeSpan Peek()
	{
		if(timers.Count > 0)
		{
			DateTime start = timers.Peek();
			return DateTime.Now - start;
		}
		else
		{
			throw new Exception("Trying to peek while the stack is empty");
		}
	}

Usage

static void Main(string[] args)
{
	// Measure the entire process
	StopWatch.Push();
	{
		// Measure subtask            
		StopWatch.Push();
		
		// Subtask took:
		StopWatch.PopAndPrint();
	}
	// Entire process took:
	StopWatch.PopAndPrint();
}

Output

StopWatch: 0.0010001
StopWatch: 0.0020001
04
Jun 2014
COMMENTS No Comments

2D Lighting and Shadows Preview

While I’m finishing up my master’s degree studying Navigational Meshes and Path Finding I spent some of my free time with a friend developing a prototype for a game. Because we’ve been working on this for a while I thought it would be time to spice up the graphics a bit. During the last two weeks I developed a cool looking 2D lighting and shadowing technique that is much akin to deferred rendering.

I hope I can find the time to convert my test-code into a tutorial but for now you’ll just have to make due with this awesome videos, a few references and the source code (C# / XNA)

(Or follow this link for the 720p version)

References:

Red BloB Games on 2D Visibility

Catalin Zima on 2D lighting and smooth shadows

Source Code:

Available here

27
Feb 2014
CATEGORY

Blog, Programming, XNA

COMMENTS 1 Comment

Building SDL on Windows for use with Haskell / Cabal

If, like me, you wish to perform graphical operations with Haskell you need a library like SDL. Unfortunately most of the Haskell world resides in Linux so it is pretty hard to find good guides for Windows. This guide describes my endeavor to get things working.

I’ll assume that you have nothing installed yet, so you might be able to skip some of these steps.

1. Install the Haskell Platform

You can get it from http://www.haskell.org/platform/ and it will include most of what you will need to work with Haskell on Windows (or any other platform). Installation is as easy as double clicking the installer.

2. Install the MinGW-MSYS tool chain

In order for Cabal (a distribution-manager like apt-get but then just for Haskell) to be able to build packages that have no native Windows libraries we need a Linux like tool chain for Windows.

  • Download the MinGW installer from http://www.mingw.org/wiki/Getting_Started (in the middle of the page there is a blue link to  mingw-get-setup.exe)
  • Run the installer, for legacy reasons install it in a path that does not contain spaces. I’ll asume for now that you’ve installed it in C:\MinGW
  • During the end of the installation a package manager will show. Install the meta package MSYS and click apply changes in the menu.
  • Add C:\MinGW\bin\, C:\MinGW\, and C:\MinGW\msys\1.0\bin\ to the PATH environment variable

3. Install the SDL development libraries

Now we need to install the SDL development libraries and add them to the PATH variable so that the Haskell implementation can link and build.

  • Download the SDL-devel-1.2.15-mingw32.tar.gz archive from http://www.libsdl.org/download-1.2.php and extract. I’ll assume it is located in C:\SDL
  • Add C:\SDL\, and C:\SDL\bin to the PATH environment variable

4. Build Haskell’s SDL implementation

Ok final steps!

  • Open a command prompt
  • Run  cabal install SDL –extra-include-dirs=C:\SDL\include –extra-lib-dirs=C:\SDL\lib
  • This operation should complete with the message ‘Installed SDL-0.6.5′

5. In Conclusion

Building things with Cabal is quite a hassle especially since it uses both the PATH variable and explicitly given paths to find all dependencies, error messages are not to clear either. I hope this guide helps you and saves you some time as it took me two days to get this exactly right. If you wish to see if all really works why not try building and running this little program, it is the reason why I went trough all the steps to get SDL working. (Just left-click and drag to create a rectange, middle click to change the color, and right click to finish the rectangle).

Note: I am aware that the Haskell Platform includes its own version of MinGW but it does not include the MSYS library which is vital under Windows. It is also not easy to modify the built in version of MinGW and according to the docs the build in version can live happily together with the stand alone version.

16
Jan 2014
CATEGORY

Programming

COMMENTS 4 Comments

LUA Syntax highlighting in Visual Studio 2012 and Visual Studio 2013 (Preview)

Lately I’ve been working a lot with LUA and C++ code. As usual I’ve been using Visual Studio and it hindered me that there was no syntax high-lighting and that on Google I couldn’t find any up to plug-in that worked in VS 2012/2013 (yeah I’m working on the cutting edge at the moment.

After a lot of searching I found this post, I then figured out that VSIX files are just plain zip files with XML and other data stored inside. After some tweaking I present you 2 Visual Studio plugins. One for 2012 and one for 2013 (preview) that adds proper syntax high-lighting.

Download the Visual Studio 2012 and 2013 Version (zipped)

(Update 2: Some users were still not able to download the files because the VSIX files were interpreted as XML, so I’ve uploaded a zip file instead that contains both files)

04
Sep 2013
CATEGORY

Blog, Programming

COMMENTS 5 Comments

Post-Complement Color Grading

A friend of mine was having problems implementing NVIDIA’s Post-Complement example. The example code was littered with unnecessary garbage, probably created by a cross-platform shader generator/compiler. So to make it more clear what the method does I quickly rewrote it and I thought I would share it. It took much more debugging than expected since apparently not all RGB2HSV converter code is equal. Luckily, in the end, everything seems to work.

So basically just dump the below code in a shader and call PostComplement before you return from the pixel shader to apply a form of colour grading that makes the guide colour pop-out by shifting colours that are close to the guide colour closer to it and colours that are far away from the guide colour to the complement of the guide colours. (Remember those Blue-Orangy movie posters, that’s basically what you can do with this effect if you make the guide colour orange).

Color Grading - Steve Mata
(Image by Total Commitment Games Effect at a not too subtle setting to clearly show the difference)

Note, the code is now tested and seems to work correctly, a previous version which was up for about 2 hours contained a nasty bug.

// Post Complement method
// http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_complements

// RGB to HSV and HSV to RGB methods
// from http://www.chilliant.com/rgb2hsv.html
float RGBCVtoHUE(in float3 RGB, in float C, in float V)
{
    float3 Delta = (V - RGB) / C;
    Delta.rgb -= Delta.brg;
    Delta.rgb += float3(2,4,6);
    // NOTE 1
    Delta.brg = step(V, RGB) * Delta.brg;
    float H;
    H = max(Delta.r, max(Delta.g, Delta.b));
    return frac(H / 6);
}

float3 RGBtoHSV(in float3 RGB)
{
    float3 HSV = 0;
    HSV.z = max(RGB.r, max(RGB.g, RGB.b));
    float M = min(RGB.r, min(RGB.g, RGB.b));
    float C = HSV.z - M;
    if (C != 0)
    {
        HSV.x = RGBCVtoHUE(RGB, C, HSV.z);
        HSV.y = C / HSV.z;
    }
    return HSV;
}

float3 HUEtoRGB(in float H)
{
    float R = abs(H * 6 - 3) - 1;
    float G = 2 - abs(H * 6 - 2);
    float B = 2 - abs(H * 6 - 4);
    return saturate(float3(R,G,B));
}

float3 HSVtoRGB(float3 HSV)
{
    float3 RGB = HUEtoRGB(HSV.x);
    return ((RGB - 1) * HSV.y + 1) * HSV.z;
}

float3 HSVComplement(float3 HSV)
{
    // X = Hue, so rotate it for the complement
    float3 complement = HSV;
    complement.x -= 0.5;
    if (complement.x < 0.0) { complement.x += 1.0; }
    return(complement);
}

// Lerps 2 hue values, since they are on a circle
// in HSV we need some weird code for that
float HueLerp(float h1, float h2, float v)
{
    float d = abs(h1 - h2);
    if(d <= 0.5)
    {
        return lerp(h1, h2, v);
    }
    else if(h1 < h2)
    {
        return frac(lerp((h1 + 1.0), h2, v));
    }
    else
    {
        return frac(lerp(h1, (h2 + 1.0), v));
    }
}

float3 PostComplement(float3 input)
{
    // Tweakable values
    float3 guide = float3(1.0f, 0.5f, 0.0f); // the RGB colour that you want to 'bring out'

    float amount = 0.5f; // influence how much a colour gets lerped toward the guide or complement

    // Correlation and Concentration together define a curve along which the colour grading is done
    // tweak these values to see the effects, I think correlation should be < 0.5f and concentration should     // be > 1.0f, but I havent double checked that math
    float correlation = 0.5f;
    float concentration = 2.0f;

    // Convert everything to HSV
    float3 input_hsv = RGBtoHSV(input);
    float3 hue_pole1 = RGBtoHSV(guide);
    float3 hue_pole2 = HSVComplement(hue_pole1);

    // Find the difference in hue, again hue is circular so keep it in a circle
    float dist1 = abs(input_hsv.x - hue_pole1.x); if (dist1 > 0.5) dist1 = 1.0 - dist1;
    float dist2 = abs(input_hsv.x - hue_pole2.x); if (dist2 > 0.5) dist2 = 1.0 - dist2;

    float descent = smoothstep(0, correlation, input_hsv.y);

    // *there was a version here that forced it 100% but I skipped implementing that*

    float3 output_hsv = input_hsv;
    // Check if we are closer to the guide or to the complement and color grade according
    if(dist1 < dist2)
    {
        // Bring the colour closer to the guide
        float c = descent * amount * (1.0 - pow((dist1 * 2.0), 1.0 / concentration));
        output_hsv.x = HueLerp(input_hsv.x, hue_pole1.x, c);
        output_hsv.y = lerp(input_hsv.y, hue_pole1.y, c);
    }
    else
    {
        // Bring the colour closer to the complement
        float c = descent * amount * (1.0 - pow((dist2 * 2.0), 1.0 / concentration));
        output_hsv.x = HueLerp(input_hsv.x, hue_pole2.x, c);
        output_hsv.y = lerp(input_hsv.y, hue_pole2.y, c);
    }

    float3 output_rgb = HSVtoRGB(output_hsv);
    return output_rgb;
}

GPU Based Path Tracer

Introduction

As some of you might have seen I’ve been working on a Path Tracer on the GPU. Path Tracing is ray tracing like technique that is (when done right) a physically correct simulation of light. Usually it is done on the CPU but since the work can be easily parallelized and GPUs are getting more powerful, and more programmable it is now feasible to let the GPU do the bulk of the work. I didn’t use Cuda or OpenCL just plain ‘simple’ DirectX 11 with pixel shaders written in HLSL doing most of the work.

Since it is an assignment (which is due in 40 minutes) I can’t share any source code with you. But I would like to show the video and tell you where you can find the resources to build your own.

Video

(Be sure to select the 720P version, but even then the compression has a hard time with the grainyness that path tracing produces. The actually generated image are grainy but look a lot better.)

Image Gallery

Images are clickable.

The Cornell Box Scene

The Cornell Box Scene

Reflectance show-case #1

Reflectance show-case #1

Reflectance show-case #2

Reflectance show-case #2

Reflectance show-case #3

Reflectance show-case #3

Different levels of reflectance

Different levels of reflectance

Depth of Field

Depth of Field

References

The Direct3D 11 Reference
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476079(v=vs.85).aspx

  • Main resource

Wolfram Math World
http://mathworld.wolfram.com/SpherePointPicking.html

  • Sphere Point Picking algorithm #2

GPU Gems 3
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch37.html

  • GPU random number generation

Colors, Effects, Code
http://www.colorseffectscode.com/Projects/GPUPathTracer.html

  • ‘Jitter’ idea for depth of field

The FW1 DirectX 11 Font Wrapper
http://fw1.codeplex.com/

  • This library is used for font rendering

Rastertek.com
http://www.rastertek.com/dx11tut22.html

  • Render Targets
  • Best practices (I recommend the entire tutorial series)

Fundamentals of Computer Graphics, 3rd edition, Peter Shirley & Steve Marschner, 2009
http://www.amazon.com/Fundamentals-Computer-Graphics-Peter-Shirley/dp/1568814690/

  • Miscellaneous math
  • View/Projection/Perspective transformations
  • Inverse transformations
21
Apr 2013
CATEGORY

Blog, Programming

COMMENTS No Comments

Farseer physics 3.3.1 and XNA: Platformer character

It took a while, but here I finaly present you the third and final part of the Farseer Physics 3.3.1 and XNA tutorial series!

Part 1 of this tutorial
Part 2 of this tutorial

In the last two tutorials I’ve told you how to set up Farseer with XNA and how bodies and joints work. We’re going to use the techniques from these tutorials to create a character for a platformer game, think Mario or Kirby or whatever your favorite platformer character is! It’s not too obvious how to create a character in Farseer. Just applying forces to a rectangular body works OK, but traveling slopes becomes really tricky in this case and the ability to stop moving instantly becomes even more hacky (usually done by pinning the character to the background with a joint). Because of that I will use a technique described by Bryan Dismas and Robert Dodd where we create a character by combining a motorized wheel and a rectangular with an axis joint and fixed angle joint (see the previous tutorial) to create a character.

Platformer character composition

Platformer character composition

So let’s start off. First things first. I made some small changes to the DrawablePhysicsObjects class to allow circular bodies. I also found a bug in the drawing (which only happens with circular bodies). So let’s add the following constructor to the DrawablePhysicsObjects class:

/// <summary>
/// Creates a circular drawable physics object
/// </summary>
/// <param name="world">The farseer simulation this object should be part of</param>
/// <param name="texture">The image that will be drawn at the place of the body</param>
/// <param name="diameter"> The diameter in pixels</param>
/// <param name="mass">The mass in kilograms</param>
public DrawablePhysicsObject(World world, Texture2D texture, float diameter, float mass)
{
    size = new Vector2(diameter, diameter);
    Body = BodyFactory.CreateCircle(world, (diameter / 2.0f) * CoordinateHelper.pixelToUnit, 1);

    Body.BodyType = BodyType.Dynamic;

    this.Size = size;
    this.texture = texture;
}

And to fix the drawing code replace the draw method in the DrawablePhysicsObject class with this one

public void Draw(SpriteBatch spriteBatch)
{            
	Rectangle destination = new Rectangle
	(
		(int)Position.X,
		(int)Position.Y,
		(int)Size.X,
		(int)Size.Y
	);

	spriteBatch.Draw(texture, destination, null, Color.White, Body.Rotation, new Vector2(texture.Width / 2.0f, texture.Height / 2.0f), SpriteEffects.None, 0);
}

Now we can start with the player character. Add a new class to your project called Player and add the following private fields and constructor

private DrawablePhysicsObject torso;
private DrawablePhysicsObject wheel;
private RevoluteJoint axis;

public Player(World world, Texture2D torsoTexture, Texture2D wheelTexture, Vector2 size, float mass, Vector2 startPosition)

As you can see the player is a composition of two DrawablePhysicsObjects: a torso and a wheel as mentioned above. The constructor is fairly standard, we need a texture for the torso and wheel. We need a size for the player, a mass and a start position. Let’s start implementing these details!

First, because the player is a composition, we need to calculate the sizes of the wheel and torso. We want the wheel to be just as wide as the player and to form the lower part of the body (note that this technique won’t work for characters that are wider than they are high!)

Vector2 torsoSize = new Vector2(size.X, size.Y - size.X / 2.0f);
float wheelSize = size.X;

// Create the torso
torso = new DrawablePhysicsObject(world, torsoTexture, torsoSize, mass / 2.0f);
torso.Position = startPosition;            
			
// Create the feet of the body
wheel = new DrawablePhysicsObject(world, wheelTexture, wheelSize, mass / 2.0f);
wheel.Position = torso.Position + new Vector2(0, torsoSize.Y / 2.0f);

Now we can start adding joints. We will use a Fixed Angle Joint to keep the torso straight up at all times and we use a Revolute Joint to move the wheel (feet) of the character.

// Create a joint to keep the torso upright
JointFactory.CreateFixedAngleJoint(world, torso.Body);

// Connect the feet to the torso
axis = JointFactory.CreateRevoluteJoint(world, torso.Body, wheel.Body, Vector2.Zero);
axis.CollideConnected = false;
            
axis.MotorEnabled = true;
axis.MotorSpeed = 0;
axis.MotorTorque = 3;
axis.MaxMotorTorque = 10;

Let’s also implement a draw function, which is extremely simple because we can use the drawing facilities of the two DrawablePhysicsObjects. Note that in a real game you would just draw one animated sprite over the entire player but for this tutorial this will suffice.

public void Draw(SpriteBatch spriteBatch)
{
	torso.Draw(spriteBatch);
	wheel.Draw(spriteBatch);
}

Great! Let’s go to game class, add a field for the player, load it, and make it visible!

public class Game1
{
	...
	
	Player player;
	
	...
	
	protected override void LoadContent()
	{
		...
		
		player = new Player
            (
                world,
                Content.Load<Texture2D>("Player"),
                Content.Load<Texture2D>("Wheel"),
                new Vector2(20, 75),
                100,
                new Vector2(430, 0)
            );     		
	}
	
	...
	
	protected override void Draw(GameTime gameTime)
	{
		...
		
		player.Draw(spriteBatch);
		
		...
	}
}

Ok. Run your game. If everything went well you will see your player character fall from the sky, land, and be pushed away by one of the paddles we added in the previous tutorial. You can see a body and a wheel and that they are connected. You will notice that the character keeps sliding a lot before it stands still when it’s pushed by the paddle. Based on your game this might be desirable or undesirable. You can control this behavior using the friction of the wheel. I don’t want the character to slide so much so I’ve added a bit of friction to the wheel by adding the following line in the constructor of player.

wheel.Body.Friction = 0.8f;

Higher values will stop the character from sliding at all.

Now to make the scene more interesting we will have to be able to control the player. Let’s first add movement and then later add jumping as well. Create the following enum:

public enum Movement
{
    Left,
    Right,
    Stop
}

Add the following code to your player class:

float speed = 3.0f;

...

public void Move(Movement movement)
{
	switch(movement)
	{
		case Movement.Left:
			axis.MotorSpeed = -MathHelper.TwoPi * speed;
			break;

		case Movement.Right:
			axis.MotorSpeed = MathHelper.TwoPi * speed;
			break;

		case Movement.Stop:                    
			axis.MotorSpeed = 0;
			break;
	}
}

Then go to the update function of your game class and add the following lines:

Run the game again. You should now be able to control your character. Remember that you can still press space to make some boxes fall from the sky, push them around a bit. Depending on how high you’ve set the friction of your wheel body and (max) torque of your revolute joint you might be able to push none, one or quite a few more!

Now the finishing touch is obviously jumping, and with just adding a bit of force we can get there. Add the following fields and method to the Player class:

private DateTime previousJump = DateTime.Now;   // time at which we previously jumped
private const float jumpInterval = 1.0f;        // in seconds
private Vector2 jumpForce = new Vector2(0, -1); // applied force when jumping

public void Jump()
{
	if ((DateTime.Now - previousJump).TotalSeconds >= jumpInterval)
	{
		torso.Body.ApplyLinearImpulse(ref jumpForce);
		previousJump = DateTime.Now;
	}
}

As you can see we do some management to keep track of when we last jumped. The jumping itself is done by adding impulse to the torso body and since the wheel is connected to the torso body we don’t need to do anything else. Simple right? Let’s hook this jump function up to the left control key by adding these last few lines to the Update function of your game class.

if (keyboardState.IsKeyDown(Keys.LeftControl) && !prevKeyboardState.IsKeyDown(Keys.LeftControl))
{
    player.Jump();
}

Et voila! We have a controllable player character which you can use in your very own platform game! Fire up your game and if you followed my instructions this is what you should end up with:

You can download the complete source code (includes everything from the previous two tutorials and this one) here

Fun trivia

  • I published (and wrote most) of this tutorial on my birthday, 25 now, yay!
  • In 2010 I got 2nd place on SgtConker’s Absolutely Fine tutorial contest writhing the Farseer 2.x version of this series
02
Jan 2013
COMMENTS 12 Comments

C# Asynchronous sockets revisited

Three years ago I wrote a quick code snippet explaining asynchronous sockets. Recently someone found a rather large bug in that code so I decided to rewrite the tutorial (it’s one of my more popular articles and people have long been asking for the source code, which I lost a few years ago. So this way I kill a bug and give people the source code all at once).

I would like to thank stackoverflow user Polity for notifying me of the problems.

The client

Let’s first start with the client. For this example I created a small console application. It reads lines from the console until it sees an empty line. The text is then converted to a byte[] using the UTF8-Encoding schema.  Meanwhile I create a socket and call the BeginConnect method to start the process of creating an asynchronous connection. Asynchronous in this regards means that the entire program can keep crushing while a separate thread setups up the connection and sends the data. To guide the setup and the sending of the data while the program is running several callbacks are used. One to finish the connection setup and one to send the actual data. Before the actual message is sent I first send 4 bytes to tell how long the message is going to be. (Not doing this caused a subtle bug in the previous version which assumed a message was done once the receive buffer of the server was not entirely filled).

The server

The server is also simple. There is one socket continuously accepting new connections. So in contrary to the previous version this version accepts multiple concurrent connections. Once a connection has been made a separate thread is spawned, implicitly, by using the asynchronous BeginAccept method. In a callback the connecting is accepted using a new socket so the server can keep listing for more connections on the old socket. For each connection a small state object is kept to do the bookkeeping. It stores the active socket, the buffer, and fields  with information about the amount of data we expect to receive and how much data we have indeed received. In the read callback the first 4 bytes are extracted so that we know how much data to accept. After that we keep using BeginReceive until all data has made it’s way to the server. Only then we reconstruct the message.

Note that I use the TCP protocol for the sockets so I know that the data will be complete and in-order.

The source code

I’ve created a Visual Studio 2012 solution with the above two projects in them. Everything is compiled using the .NET 4.5 framework. The example will probably also compile in .NET3.5 but I noticed some methods that I previously used were deprecated  in .NET4.5, so I’ve used alternatives that might no be available in .NET3.5 (should be trivial to fix).

You can find the source code here

09
Sep 2012
CATEGORY

Blog, Programming

COMMENTS 5 Comments

Farseer physics 3.3.1 and XNA: Joints

In the previous tutorial, which you can find here, we created static and dynamic bodies. In this second tutorial we are going to take a look at joints. Simply said a joint is used to make a connection between two bodies or a body and the background.  The place where a joint is attached is called the anchor. Usually a joint has two anchors. One placed on the first body and one placed on a second body or on the world itself. Farseer uses the following naming convention for this. If a joint is ‘fixed’ it provides a joint between a body and the background/world. If a joint is not fixed it is used to connect two separate bodies to each other. So a RevoluteJoint connects two bodies and a FixedRevoluteJoint connects a body and the background/world.

Overview of joints

There are quite a few types of joints in Farseer:

Standard joints

Angle joints

Keeps a body at a fixed angle from another body or the world.

Distance joints

Keeps a body at a fixed distance from another body or from an anchor in the world.

Friction joints

Applies translational and angular friction to a body.

Line joints

A line joint can best be seen as a spring. It linearly connects to bodies (or a body and the background) together and tries to keep them at a fixed distance. It does not limit relative rotations but it does limit translation over one axis. They can be a bit tricky to place since the mass of the bodies themselves already affects the distance between the two bodies so setting the ‘at rest’ state is a bit of trial and error. Note that Line Joints are a new addition to Farseer and are not available in Box2D.

Prismatic joints

Enforces that two bodies can only slide in a linear motion (one degree of freedom) with respect to each other. See http://en.wikipedia.org/wiki/Prismatic_joint

Revolute joints

The most standard joints. Allows a body to rotate around an implicit axis coming from the screen (Z-Axis). Can be used to connect a body to the background or to another body.  Can be motorized.

Slider joints

A sort of prismatic joint that doesn’t limit the bodies to just linear motion. Best described as a combination of a revolute joint and a prismatic joint. Note that Slider Joints are also not available in Box2D.

Weld joints

Connects two bodies together disallowing any form of relative rotation/translation.

More complex joints

Gear joints

Connects two revolute joints or a revolute joint and a prismatic joint. Simulates that they are connected by gears so if the body on the first revolute joint rotates the body on the second revolute joint will rotate in the opposite direction.

Pulley joints

Used to create a pulley system. (Two bodies both connected to a rope that runs over a pulley). Can be used to create sophisticated elevators.

If you would like to know more about the joints Farseer offers you can check the Box2D documentation here (Farseer is a C# implementation of Box2D, and although it’s growing slowly to become more than that the best place for documentation is still the Box2D website).

Refactoring last week’s example

After doing some coding I found that I need access to the world-to-screen and screen-to-world conversion methods for the joints and they are currently members of the DrawablePhysicsObject class. So before we start creating or own joints we must first refactor last week’s example.

Create this new helper class:

    public static class CoordinateHelper
    {
        // Because Farseer uses 1 unit = 1 meter we need to convert
        // between pixel coordinates and physics coordinates.
        // I've chosen to use the rule that 100 pixels is one meter.
        // We have to take care to convert between these two
        // coordinate-sets wherever we mix them!

        public const float unitToPixel = 100.0f;
        public const float pixelToUnit = 1 / unitToPixel;

        public static Vector2 ToScreen(Vector2 worldCoordinates)
        {
            return worldCoordinates * unitToPixel;
        }

        public static Vector2 ToWorld(Vector2 screenCoordinates)
        {
            return screenCoordinates * pixelToUnit;
        }
    }

And then update the DrawablePhysicsObject class to use the helper class.

Some setup

Last week we added a list to store all the boxes that we randomly spawn. This week we’re going to create ‘paddles’ connected by joints. To store the paddles we’re going to need another list. So open Game1.cs and add the following field:

List paddles;

Then add the following three lines to draw the paddles:

foreach (DrawablePhysicsObject paddle in paddles)
{
    paddle.Draw(spriteBatch);
}

I’ve also added another image to the content project called ‘Paddle.png’.

Adding some bodies and joints

Now to demonstrate how to use joints I’m going to create three paddles. The first paddle will just be a simple body connected with revolute joint to the background. This means that it can spin freely. The second paddle is almost the same, but it will be motorized, adding some interaction to the scene. Finally we combine two line joints to create a trampoline. After this you should have a basic understanding on how joints work in Farseer.

A simple revolute joint

Add the end of the LoadContent method initialize the list we use to store the paddles. Then after that add the following code to create the first paddle:

// Create a simple paddle which center is anchored
// in the background. It can rotate freely
DrawablePhysicsObject simplePaddle = new DrawablePhysicsObject
(
    world,
    Content.Load("Paddle"),
    new Vector2(128, 16),
    10
);

JointFactory.CreateFixedRevoluteJoint
(
    world,
    simplePaddle.body,
    CoordinateHelper.ToWorld(new Vector2(0, 0)),
    CoordinateHelper.ToWorld(new Vector2(GraphicsDevice.Viewport.Width / 2.0f - 150,
                                         GraphicsDevice.Viewport.Height - 300))
);

paddles.Add(simplePaddle);

As you can see we first create a simple body, just as in the previous tutorial. The body is 128 pixels wide and 16 pixels high (note that the constructor of the DrawablePhysicsObject converts these units to world coordinates). It has a mass of 10KG. Note that we don’t have to set the position of the body. This is implicitly done by the joint, which fixes the body on the background at the anchor positions.

Next we create the joint. The first argument is our physics simulation and is used to register our joint to the simulation. We then pass the body this joint should be applied to. Since this is a Fixed joint we don’t need to pass a second body. The joint will connect the first body to the world. We then have to give some coordinates. We pass the center of the body (0,0) and somewhere in our world. Note that we use the conversion methods to go from pixel to world coordinates. Also don’t forget the last line, where we add the paddle to our list of paddles, else it won’t show up for drawing.

You can now run the simulation. Again press space to drop crate, you will see that we’ve create a small paddle that rotates freely when hit by a crate.

A motorized joint

The motorized joint is very similar:

// Creates a motorized paddle which left side is anchored in the background
// it will rotate slowly but the motor is not set soo strong that
// it can push everything away.
DrawablePhysicsObject motorPaddle = new DrawablePhysicsObject
(
    world,
    Content.Load("Paddle"),
    new Vector2(128, 16),
    10
);

var j = JointFactory.CreateFixedRevoluteJoint
(
    world,
    motorPaddle.body,
    CoordinateHelper.ToWorld(new Vector2(-48, 0)),
    CoordinateHelper.ToWorld(new Vector2(GraphicsDevice.Viewport.Width / 2.0f,
                                         GraphicsDevice.Viewport.Height - 280))
);

// rotate 1/4 of a circle per second
j.MotorSpeed = MathHelper.PiOver2;
// have little torque (power) so it can push away a few blocks
j.MotorTorque = 3;
j.MotorEnabled = true;
j.MaxMotorTorque = 10;

paddles.Add(motorPaddle);

Again we create a body and a Fixed Revolute Joint. But this time we store the joint created by the joint factory in the variable j so that we can access the properties of the joint. The revolute joint exposes a few interesting properties. The most interesting one is to motorize it. We’ve set a motor speed of pi/2. This means that the every second the joint will rotate the connected body by pi/2 radians, or a 1/4 of a circle. We also have to set the torque to give the motor enough power to rotate the body and to keep rotating even when a few crates are blocking the paddle. We also set the max motor torque and enable the motor. Again in the last line we add the paddle to our list of paddles so that it will be drawn.

A trampoline

To create a trampoline we will use two Line Joints (a sort of springs) to connect a paddle to the ground. This way we create some sort of trampoline. Add the following code:

// Use two line joints (a sort of springs) to create a trampoline
DrawablePhysicsObject trampolinePaddle = new DrawablePhysicsObject
(
    world,
    Content.Load("Paddle"),
    new Vector2(128, 16),
    10
);

trampolinePaddle.Position = new Vector2(600, floor.Position.Y - 175);

var l = JointFactory.CreateLineJoint
(
    floor.body,
    trampolinePaddle.body,
    CoordinateHelper.ToWorld(trampolinePaddle.Position - new Vector2(64, 0)),
    Vector2.UnitY
);

l.CollideConnected = true;
l.Frequency = 2.0f;
l.DampingRatio = 0.05f;

var r = JointFactory.CreateLineJoint
(
    floor.body,
    trampolinePaddle.body,
    CoordinateHelper.ToWorld(trampolinePaddle.Position + new Vector2(64, 0)),
    Vector2.UnitY
);

r.CollideConnected = true;
r.Frequency = 2.0f;
r.DampingRatio = 0.05f;

world.AddJoint(l);
world.AddJoint(r);

paddles.Add(trampolinePaddle);

Now the creation of the body should look really familiar now. Note that this time we do have to set the position of the body. The line joint will try to keep the paddle and the ground at roughly the same position as the starting position from each other so it needs some initial position.

We create two joints, they are exactly the same, except for where they connect to the paddle. One is anchored on the left side of the paddle and one on the right side. So I will only explain the first line joint.

We start by passing the body of the first body the line joint should connect to, the floor. We then pass the body of the paddle. We tell the line joint to connect to the paddle at the given relative coordinates.  We then give the axis of freedom the line joint should offer. In our case the Y-Axis.

We also set some properties, CollideConnected  means that the paddle and the floor can collide with each other. Handy now but for a wheel inside a car you might want to keep this at the default, turned off, state. We also set a nice frequency and damping ratio. Finally we add the joints to the world. Don’t forget this step! Only Fixed joints are automatically added to the world. We also add the paddle to our list of paddles to draw.

You can now run the simulation again. Try to drop a few crates on the trampoline, you will see that it behaves quite nicely.

Conclusion

Joints in Farseer are fairly easy to use and can add a dynamicity lot to your scene. Try playing around with all different joints to get a feel from them. All joints in Farseer are created using a way similar as shown in this tutorial. In the next tutorial we will add a controllable character and create a small platformer.

06
Sep 2012
COMMENTS 11 Comments
TAGS

, , ,

Using JavaScript as a script engine in XNA/C#

A scripting engine is a useful component in any game-engine. It allows you to execute modified code (aka scripts) in real time while your game is running. This gives you immediate feedback, allows for easy debugging of scripts and gives you true rapid prototyping abilities.

Scripting engines are also easier to work with than a full blown programming language, an error in a script is easy to recover from and because the scripts aren’t compiled it’s easy for the script interpreter to give helpful debug information. Even better: you don’t have to compile the script and the game keeps running so immediately after you fix the bug in your script you can see the result.

Script engines gives opportunities for ‘other’-programmers (gameplay, leveldesign, animator, etc..), they might not wish to delve into the intricacies of the programming language and frameworks you’re using for the game engine but they will be more than willing to write some script to modify the behavior of that new enemy.

So, why write a scripting engine for XNA? Well after reading the article ‘Embracing Dynamism’  by Niklas Frykholm on #AltDevBlogADay I got interested again in scripting engines. Shortly after that I heard that someone wrote a full JavaScript interpreter for C# called JINT  , well 1 + 1 = 2 so I started working on integrating JINT into XNA and see if I could set up an external IDE in WPF that, while the game is running, could load, modify and execute script code. After a few tries I finally succeeded and I’m pretty proud of the result.

All the wrapping and magic happens in the JintXNA project. The code, as it is now, works fine on Windows but Windows Phone and Xbox 360 support isn’t there yet out of the box since JINT is targeted at the full .NET 4.0 framework. However there is a port of JINT which targets the .NET Compact Framework  which should run on WP7 and the 360, I haven’t tried this yet though.

You can download the full source code of JintXNA here this package includes the JintXNA project, the IDE and a sample project and script as seen in the video.

05
Jun 2012
COMMENTS 1 Comment