#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2009 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using Microsoft.Xna.Framework;
namespace Nuclex.Geometry {
/// Provides helper methods for working with matrices
internal static class MatrixHelper {
/// Creates a new matrix from the given directional vectors
/// Vector that's pointing to the right in the matrix
/// Vector that's pointing upwards in the matrix
/// Vector that's pointing backwards in the matrix
/// The new matrix
public static Matrix Create(Vector3 right, Vector3 up, Vector3 backward) {
return new Matrix(
right.X, right.Y, right.Z, 0.0f,
up.X, up.Y, up.Z, 0.0f,
backward.X, backward.Y, backward.Z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);
}
///
/// Creates a new matrix from the given directional vectors and a translational
///
/// Positional translation done by the matrix
/// Vector that's pointing to the right in the matrix
/// Vector that's pointing upwards in the matrix
/// Vector that's pointing backwards in the matrix
/// The new matrix
public static Matrix Create(
Vector3 translation, Vector3 right, Vector3 up, Vector3 backward
) {
return new Matrix(
right.X, right.Y, right.Z, 0.0f,
up.X, up.Y, up.Z, 0.0f,
backward.X, backward.Y, backward.Z, 0.0f,
translation.X, translation.Y, translation.Z, 1.0f
);
}
/// Retrieves a row of the matrix as a vector
/// Matrix of which to retrieve a row
/// Index of the row that will be retrieved
/// The vector built from the requested matrix row
public static Vector3 Get(ref Matrix matrix, int row) {
switch(row) {
case 0: { return new Vector3(matrix.M11, matrix.M12, matrix.M13); }
case 1: { return new Vector3(matrix.M21, matrix.M22, matrix.M23); }
case 2: { return new Vector3(matrix.M31, matrix.M32, matrix.M33); }
case 3: { return new Vector3(matrix.M41, matrix.M42, matrix.M43); }
default: {
throw new ArgumentOutOfRangeException("Matrix row index out of range");
}
}
}
/// Retrieves an element of the matrix by its column and row index
/// Matrix of which to retrieve an element
/// Index of the row from which to retrieve the element
/// Index of the column to retrieve
/// The element at the given row and column
public static float Get(ref Matrix matrix, int row, int col) {
if((col < 0) || (col > 3)) {
throw new ArgumentOutOfRangeException("col", "Matrix column index out of range");
}
switch(row << 2 | col) {
case 0: { return matrix.M11; }
case 1: { return matrix.M12; }
case 2: { return matrix.M13; }
case 3: { return matrix.M14; }
case 4: { return matrix.M21; }
case 5: { return matrix.M22; }
case 6: { return matrix.M23; }
case 7: { return matrix.M24; }
case 8: { return matrix.M31; }
case 9: { return matrix.M32; }
case 10: { return matrix.M33; }
case 11: { return matrix.M34; }
case 12: { return matrix.M41; }
case 13: { return matrix.M42; }
case 14: { return matrix.M43; }
case 15: { return matrix.M44; }
default: {
throw new ArgumentOutOfRangeException("row", "Matrix row index out of range");
}
}
}
/// Sets a row of the matrix from a vector
/// Matrix in which to set a row
/// Index of the row that will be set
/// Vector containing the values to assign to the row
public static void Set(ref Matrix matrix, int row, Vector3 values) {
switch(row) {
case 0: {
matrix.M11 = values.X;
matrix.M12 = values.Y;
matrix.M13 = values.Z;
break;
}
case 1: {
matrix.M21 = values.X;
matrix.M22 = values.Y;
matrix.M23 = values.Z;
break;
}
case 2: {
matrix.M31 = values.X;
matrix.M32 = values.Y;
matrix.M33 = values.Z;
break;
}
case 3: {
matrix.M41 = values.X;
matrix.M42 = values.Y;
matrix.M43 = values.Z;
break;
}
default: {
throw new ArgumentOutOfRangeException("Matrix row index out of range");
}
}
}
/// Set an element of the matrix by its column and row index
/// Matrix in which to set an element
/// Index of the row in which to set an element
/// Index of the column to set
///
/// Value to set to the matrix element at the specified row and column
///
public static void Set(ref Matrix matrix, int row, int col, float value) {
if((col < 0) || (col > 3)) {
throw new ArgumentOutOfRangeException("col", "Matrix column index out of range");
}
switch(row << 2 | col) {
case 0: { matrix.M11 = value; break; }
case 1: { matrix.M12 = value; break; }
case 2: { matrix.M13 = value; break; }
case 3: { matrix.M14 = value; break; }
case 4: { matrix.M21 = value; break; }
case 5: { matrix.M22 = value; break; }
case 6: { matrix.M23 = value; break; }
case 7: { matrix.M24 = value; break; }
case 8: { matrix.M31 = value; break; }
case 9: { matrix.M32 = value; break; }
case 10: { matrix.M33 = value; break; }
case 11: { matrix.M34 = value; break; }
case 12: { matrix.M41 = value; break; }
case 13: { matrix.M42 = value; break; }
case 14: { matrix.M43 = value; break; }
case 15: { matrix.M44 = value; break; }
default: {
throw new ArgumentOutOfRangeException("row", "Matrix row index out of range");
}
}
}
}
} // namespace Nuclex.Geometry