## Monday, January 16, 2012

### Units of measure to the rescue!

Physics can really improve immersion in a game, regardless of how faithful they are to reality. That's why I always enjoyed writing simple physics engine. Even though I have stuck to really simple physics engine, I always end up mixing accelerations and forces. That usually doesn't lead to much trouble in the final result, as masses tend to be constant, and physical properties of game objects are typically chosen after experimentation to maximize fun.

The feeling that there is something wrong with the math in my code is always annoying, though. It turns out F# has a solution for that, called units of measure.

A unit of measure is a type annotation that helps programmers write correct formulas. It's obviously useful for formulas in simulations, whether one is dealing with physics, finances or any other domain where models play an important role.

The code below shows how to declare a unit measure.
```/// Position, meters
[<Measure>] type m

/// Time, seconds
[<Measure>] type s

/// Mass, kilograms
[<Measure>] type kg
```
Units in physics have a certain level of redundancy, one might say. For instance, forces can be expressed in Newtons or in kilograms time meters per squared seconds. Newtons are obviously more convenient to use, but you want that masses multiplied by accelerations be recognized as forces. This is how you capture Newton's law:
```/// Force, Newtons
[<Measure>] type N = kg m/s^2
```
Units of measure can be used with primitive numeric types such as int, float and float32.
```let integrateShips (dt : float32<s>) (ships : Ships) ...
```
dt above denotes a time duration in seconds represented using a 32-bit floating point value. Units of measure can also be applied to complex types. The code below shows the code for a wrapper around Xna's Vector3.
```/// A three-dimensional vector with a unit of measure. Built on top of Xna's Vector3.
type TypedVector3<[<Measure>] 'M> =
struct
val v : Vector3
new(x : float32<'M>, y : float32<'M>, z : float32<'M>) =
{ v = Vector3(float32 x, float32 y, float32 z) }
new(V) = { v = V }

member this.X : float32<'M> = LanguagePrimitives.Float32WithMeasure this.v.X
member this.Y : float32<'M> = LanguagePrimitives.Float32WithMeasure this.v.Y
member this.Z : float32<'M> = LanguagePrimitives.Float32WithMeasure this.v.Z
end

[<RequireQualifiedAccessAttribute>]
module TypedVector =
let add3 (U : TypedVector3<'M>, V : TypedVector3<'M>) =
new TypedVector3<'M>(U.v + V.v)

let sub3 (U : TypedVector3<'M>, V : TypedVector3<'M>) =
new TypedVector3<'M>(U.v - V.v)

type TypedVector3<[<Measure>] 'M>
with
static member public (+) (U, V) = TypedVector.add3 (U, V)
static member public (-) (U, V) = TypedVector.sub3 (U, V)
```
This allows to add and subtract vectors with compatible units of measure. It took me some effort to figure out how to handle multiplication by a scalar. First, in module TypedVector:
```let scale3 (k : float32<'K>, U : TypedVector3<'M>) : TypedVector3<'K 'M> =
let conv = LanguagePrimitives.Float32WithMeasure<'K 'M>
let v = Vector3.Multiply(U.v, float32 k)
new TypedVector3<_>(conv v.X, conv v.Y, conv v.Z)
```
Then the type extension:
```type TypedVector3<[<Measure>] 'M>
with
static member public (*) (k, U) = TypedVector.scale3 (k, U)
```
Note the use of LanguagePrimitives.Float32WithMeasure<'K 'M> to produce a number with a specific unit of measure in a generic fashion.

I have designed the class to reuse Xna's implementation although it wouldn't have been hard to write my own from scratch. The key benefit, on Windows Phone 7, is to take advantage of some fast vector math that's only accessible through Xna's types. The PC and Xbox platforms don't support fast vector math, but who knows, it may come.

Finally, here comes an example of how to use all this:
```    let speeds2 =
Array.map2
(fun speed (accel : TypedVector3<m/s^2>) ->
let speed : TypedVector3<m/s> = speed + dt * accel
speed)
ships.speeds.Content accels.Content

let posClient =
ArrayInlined.map3
(fun pos speed speed2-> pos + 0.5f * dt * (speed + speed2))
ships.posClient.Content
ships.speeds.Content
speeds2
```
There is more to be said and written about units of measures, a future post will show how they can be used for safe access of array contents.

## Thursday, January 12, 2012

### Parallel draw-update XNA game component

Video games are often demanding when it comes to computation power, especially simulations and 3d games. The Xbox 360 has 3 cores with two hardware threads each. Of these 2 are reserved for the system, leaving 4 available to the programmer.
This article describes an easy to use custom XNA game component that allows to run computations in parallel with rendering.

The typical game loop is often divided in two steps, update and draw. I suggest a slightly different workflow divided in three steps, two of which run in parallel: update, compute and draw. The traditional update stage is divided in two new steps, update and compute.

In this new setting, update is used for receiving inputs from the player and the network, in the case of an online multiplayer game. Compute is potentially cpu-hungry operation implemented in a purely functional way. Rendering plays the same role as usual.

The code for the entire component fits in little over 100 lines, see below.
```namespace CleverRake.XnaUtils

open Microsoft.Xna.Framework

type IFramePerSecondCounter =
abstract FramesPerSecond : float

/// An update-able and drawable game component which performs light updates on the main
/// initialize_fun is called when assets are loaded.
/// dispose is called when the component is disposed, and should be used to unload assets.
/// update_fun takes a GameTime and a state, and should produce draw data and computation
/// data.
/// draw_fun takes a game time and draw data and should return nothing.
/// compute_fun takes a game time and computation data and should return a new state.
type ParallelUpdateDrawGameComponent<'State, 'DrawData, 'ComputationData>
(game,
initial_state : 'State,
initialize_fun : unit -> unit,
update_fun : GameTime -> 'State -> 'DrawData * 'ComputationData,
compute_fun : GameTime -> 'ComputationData -> 'State,
draw_fun : GameTime -> 'DrawData -> unit,
dispose : unit -> unit) =

inherit DrawableGameComponent(game)

let mutable state = initial_state
let mutable draw_data = Unchecked.defaultof<'DrawData>
let mutable compute_data = Unchecked.defaultof<'ComputationData>
let mutable gt_shared = GameTime()

let mutable enabled = true
let mutable update_order = 0

let signal_start = new AutoResetEvent(false)
let mutable kill_requested = false
let signal_done = new AutoResetEvent(false)

let do_compute() =
#if XBOX360
// Set affinity
// 0 and 2 are reserved, I assume the "main" thread is 1.
#endif
while not kill_requested do
signal_start.WaitOne() |> ignore
state <- compute_fun gt_shared compute_data
signal_done.Set() |> ignore

// Must be called from the main thread.
let post_compute_then_draw gt =
if not kill_requested then
let state = state
gt_shared <- gt
signal_start.Set() |> ignore
draw_fun gt draw_data
signal_done.WaitOne() |> ignore

let mutable frameCounter = 0
let mutable timeCounter = 0.0
let mutable fps = 0.0
let fpsUpdatePeriod = 0.3

do

override this.Initialize() =
base.Initialize()
initialize_fun()

override this.Update(gt) =
if base.Enabled then
base.Update(gt)
let draw, compute = update_fun gt state
draw_data <- draw
compute_data <- compute

override this.Draw(gt) =
if base.Visible then
base.Draw(gt)
post_compute_then_draw gt
else
state <- compute_fun gt compute_data
timeCounter <- timeCounter + gt.ElapsedGameTime.TotalSeconds
frameCounter <- frameCounter + 1
if timeCounter > fpsUpdatePeriod then
fps <- float frameCounter / timeCounter
timeCounter <- timeCounter - fpsUpdatePeriod
frameCounter <- 0

interface System.IDisposable with
member this.Dispose() =
base.Dispose()
dispose()
signal_start.Dispose()
signal_done.Dispose()

interface IFramePerSecondCounter with
member this.FramesPerSecond = fps

member this.FramesPerSecond = fps

member this.RequestKill() =
kill_requested <- false
signal_start.Set() |> ignore