I have updated my camera class once again to do quite a bit more its starting to grow a bit bigger now.
Previously the mouse look didn’t work properly as it was reversed, as well it had no smoothing that’s been added.
The camera only had 1 space sim like behavior i added a basic y Up behavior as well as a horizon behavior. Neither work as well as id like, ill probably revisit that at a later time.
There was no Scaling on objects thru the WorldSpaceObjects so i added 4 scale functions two of them implicitly negate the z axis. Used by the ViewSpaceCameraTransformer when building a final matrix.
public class WorldSpaceObject
{
/// <summary>
/// this is the primary pre- scaled and transformed world orientations
/// </summary>
public Matrix world = Matrix.Identity;
/// <summary>
/// This returns the orientation matrix without the translations.
/// I.E this is the local rotations.
/// Typically ignored, it is here for convenience for shaders.
/// </summary>
public Matrix LocalOrientationMatrix
{
get
{
Matrix m = Matrix.Identity;
m.Forward = world.Forward;
m.Right = world.Right;
m.Up = world.Up;
return m;
}
}
/// <summary>
/// gets just the scaling matrix for the world
/// </summary>
public Matrix ScaleMatrix
{
get;
private set;
}
/// <summary>
/// returns a scaled world matrix
/// </summary>
public Matrix ScaledWorldMatrix
{
get
{
var temp = world.Translation;
var m = world * ScaleMatrix;
m.Translation = temp;
return m;
}
}
/// <summary>
/// Free type Behavior setting like a space sim.
/// </summary>
public const int UP_FREE_Y = 0;
/// <summary>
/// A basic fixed camera pointing straight up will spin you.
/// Though no gimble lock will occur ill probably improve this later on
/// </summary>
public const int UP_FIXED_Y = 1;
/// <summary>
/// Free behavior for the most part but there is a gravitation to the horizon on the z axis.
/// This is basically a planned forerunner to a automated panoramic waypoint steped scene camera.
/// Calling rotate continually even with a vector3.Zero will auto rotate the camera to a horrizontal position.
/// </summary>
public const int UP_FREE_HORIZONTAL_Y = 2;
private int upBehavior = 1;
/// <summary>
/// This changes the behavior to how a world object moves.
/// These are primarily used by world objects that act as cameras.
/// </summary>
public int SetTheUpBehavior
{
set
{
upBehavior = value;
if (value < 0 || value > 2) upBehavior = 0;
}
}
/// <summary>
/// While the rotations are in fact axis angle rotations.
/// About the current objects orientation, we still have a multiplication order.
/// </summary>
public bool UseYawPitchRollToRotate
{
get;
set;
}
/// <summary>
/// gets or sets the position in the world
/// </summary>
public Vector3 Position
{
get { return world.Translation; }
set { world.Translation = value; }
}
/// <summary>
/// gets or sets the forward directional orientation
/// </summary>
public Vector3 Forward
{
get { return world.Forward; }
set { world = Matrix.CreateWorld(world.Translation, value, world.Up); }
}
/// <summary>
/// Move on a dimensional vector axis of the object itself. Note, we dont use the system vectors for this.
/// This is typically used by the uiCameraInput class or such as for an ai's movements.
/// </summary>
public void Move(Vector3 moveSpeedInEachAxis)
{
var motion =
moveSpeedInEachAxis.X * world.Right +
moveSpeedInEachAxis.Y * world.Up +
moveSpeedInEachAxis.Z * world.Forward
;
Position += motion;
}
// for reference
//var crossFL = Vector3.Cross(F, L); // = up
//var crossFU = Vector3.Cross(F, U); // = right
//var crossUR = Vector3.Cross(U, R); // = forward
/// <summary>
/// We designate the dimensional speed of rotation in dimension x y or z upon a perpendicular axis.
/// We may change the cw or ccw of rotation by using the reverse or negated axis vector or any component thereof.
/// </summary>
public void Rotate(Vector3 turnSpeedInDimension)
{
Vector3 up = world.Up;
Vector3 temp = world.Translation;
switch (upBehavior)
{
// free floating look the camera.
case UP_FREE_Y:
if (UseYawPitchRollToRotate)
{
world *=
Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y) *
Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z)
;
Forward = world.Forward;
}
else
{
world *=
Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z) *
Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
;
Forward = world.Forward;
}
world.Translation = temp;
break;
// this is basically a fixed camera we dissallow z rotations
case UP_FIXED_Y:
if (UseYawPitchRollToRotate)
{
world = world
* Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
* Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X)
;
}
else
{
world = world
* Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X)
* Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
;
}
// partially lerped
up = ((new Vector3(0f, .99f, 0f) - world.Up) * .03f) + world.Up;
world = Matrix.CreateWorld(world.Translation, world.Forward, up);
world.Translation = temp;
break;
// similar to a free camera
case UP_FREE_HORIZONTAL_Y:
if (UseYawPitchRollToRotate)
{
world *=
Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y) *
Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z)
;
}
else
{
world *=
Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z) *
Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
;
}
// set weights,
// these form a ratio to each other and effect blending formulas.
float weightup = 20f;
float weightmid = 50f;
// ranged virtual average, basically a double weighted binomiminal.
var dotFu = Vector3.Dot(world.Forward, Vector3.Up);
// the Acos and Absolute.
// the meaning here of this value is it increases to 1 from 0 when we are look straight up or down.
// we are using these directions specifically due to how createworld(...) and createlookat(...) function.
dotFu *= dotFu;
// in this case well ensure that the inverse of 0 becomes 1.
var invFu = 1.001f / (dotFu + .001f);
// this value allows the weighted middle to act as a floating scalar against the upweight
// and a counterbalance to the midweight
float invwgtmid = 1f / weightmid;
var up1 = (world.Up * (dotFu * weightup));
var up2 = (invFu * invwgtmid * Vector3.Up) + (invFu * weightmid * world.Up);
up = up1 + up2;
up.Normalize();
world = Matrix.CreateWorld(world.Translation, world.Forward, up);
world.Translation = temp;
break;
}
}
/// <summary>
/// This creates a world scale matrix with a corrected z
/// </summary>
public void Scale(float scale)
{
ScaleMatrix = Matrix.CreateScale(scale, scale, -scale);
}
/// <summary>
/// This creates a world scale matrix with a corrected z
/// </summary>
public void Scale(Vector3 scale)
{
ScaleMatrix = Matrix.CreateScale(scale.X, scale.Y, -scale.Z);
}
/// <summary>
/// This creates a world scale matrix no z adjustment is made
/// </summary>
public void CreateScale(Vector3 scale)
{
ScaleMatrix = Matrix.CreateScale(scale.X, scale.Y, scale.Z);
}
/// <summary>
/// This creates a world scale matrix no z adjustment is made
/// </summary>
public void CreateScale(float x, float y, float z)
{
ScaleMatrix = Matrix.CreateScale(x, y, z);
}
}
The other 2 classes follow well 3 including the timer class.