mirror of
https://github.com/thes3m/XNI
synced 2024-12-26 13:26:06 +01:00
206 lines
6.7 KiB
Objective-C
206 lines
6.7 KiB
Objective-C
//
|
|
// Matrix.m
|
|
// XNI
|
|
//
|
|
// Created by Matej Jan on 9.9.10.
|
|
// Copyright 2010 Retronator. All rights reserved.
|
|
//
|
|
|
|
#import "Matrix.h"
|
|
|
|
#import "Retronator.Xni.Framework.h"
|
|
|
|
@implementation Matrix
|
|
|
|
- (id) initWithStruct: (MatrixStruct*)matrixStruct {
|
|
if (self = [super init]) {
|
|
data = *matrixStruct;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id) initWithMatrix: (Matrix*)matrix {
|
|
return [self initWithStruct:matrix.data];
|
|
}
|
|
|
|
+ (Matrix*) matrixWithStruct: (MatrixStruct*)matrixStruct {
|
|
return [[[Matrix alloc] initWithStruct:matrixStruct] autorelease];
|
|
}
|
|
|
|
+ (Matrix*) matrixWithMatrix: (Matrix*)matrix {
|
|
return [[[Matrix alloc] initWithMatrix:matrix] autorelease];
|
|
}
|
|
|
|
+ (Matrix*) translation:(Vector3*)position {
|
|
Matrix *matrix = [Matrix identity];
|
|
matrix.translation = position;
|
|
return matrix;
|
|
}
|
|
|
|
+ (Matrix*) scale:(Vector3 *)scale {
|
|
Matrix *matrix = [Matrix identity];
|
|
matrix.data->m11= scale.x;
|
|
matrix.data->m22= scale.y;
|
|
matrix.data->m33= scale.z;
|
|
return matrix;
|
|
}
|
|
|
|
+ (Matrix*) rotationAround:(Vector3 *)axis for:(float)angle {
|
|
Vector3 *normalizedAxis = [[Vector3 vectorWithVector:axis] normalize];
|
|
|
|
float c = cosf(angle);
|
|
float s = sinf(angle);
|
|
float x = normalizedAxis.x;
|
|
float y = normalizedAxis.y;
|
|
float z = normalizedAxis.z;
|
|
|
|
Matrix *matrix = [Matrix zero];
|
|
matrix.data->m11 = (x * x) * (1 - c) + c;
|
|
matrix.data->m12 = (y * x) * (1 - c) + (z * s);
|
|
matrix.data->m13 = (x * z) * (1 - c) - (y * s);
|
|
matrix.data->m21 = (x * y) * (1 - c) - (z * s);
|
|
matrix.data->m22 = (y * y) * (1 - c) + c;
|
|
matrix.data->m23 = (y * z) * (1 - c) + (x * s);
|
|
matrix.data->m31 = (x * z) * (1 - c) + (y * s);
|
|
matrix.data->m32 = (y * z) * (1 - c) - (x * s);
|
|
matrix.data->m33 = (z * z) * (1 - c) + c;
|
|
matrix.data->m44 = 1;
|
|
return matrix;
|
|
}
|
|
|
|
+ (Matrix*) rotationWithQuaternion:(Quaternion *)quaternion {
|
|
Quaternion *normalizedQuaternion = [[Quaternion quaternionWithQuaternion:quaternion] normalize];
|
|
|
|
float x = normalizedQuaternion.x;
|
|
float y = normalizedQuaternion.y;
|
|
float z = normalizedQuaternion.z;
|
|
float w = normalizedQuaternion.w;
|
|
|
|
Matrix *matrix = [Matrix zero];
|
|
matrix.data->m11 = 1 - 2 * ( y * y + z * z );
|
|
matrix.data->m12 = 2 * ( x * y - z * w );
|
|
matrix.data->m13 = 2 * ( x * z + y * w );
|
|
matrix.data->m21 = 2 * ( x * y + z * w );
|
|
matrix.data->m22 = 1 - 2 * ( x * x + z * z );
|
|
matrix.data->m23 = 2 * ( y * z - x * w );
|
|
matrix.data->m31 = 2 * ( x * z - y * w );
|
|
matrix.data->m32 = 2 * ( y * z + x * w );
|
|
matrix.data->m33 = 1 - 2 * ( x * x + y * y );
|
|
matrix.data->m44 = 1;
|
|
return matrix;
|
|
}
|
|
|
|
+ (Matrix*) lookAt:(Vector3*)target from:(Vector3*)position up:(Vector3*)up {
|
|
Vector3 *z = [[Vector3 subtract:position by:target] normalize];
|
|
Vector3 *x = [[Vector3 crossProductOf:up with:z] normalize];
|
|
Vector3 *y = [Vector3 crossProductOf:z with:x];
|
|
Matrix *matrix = [Matrix zero];
|
|
// First column
|
|
matrix.data->m11 = x.x;
|
|
matrix.data->m21 = x.y;
|
|
matrix.data->m31 = x.z;
|
|
// Second column
|
|
matrix.data->m12 = y.x;
|
|
matrix.data->m22 = y.y;
|
|
matrix.data->m32 = y.z;
|
|
// Third column
|
|
matrix.data->m13 = z.x;
|
|
matrix.data->m23 = z.y;
|
|
matrix.data->m33 = z.z;
|
|
// Translation
|
|
matrix.data->m41 = -[Vector3 dotProductOf:x with:position];
|
|
matrix.data->m42 = -[Vector3 dotProductOf:y with:position];
|
|
matrix.data->m43 = -[Vector3 dotProductOf:z with:position];
|
|
matrix.data->m44 = 1;
|
|
return matrix;
|
|
}
|
|
|
|
+ (Matrix*) perspectiveWithWidth:(float)width height:(float)height nearPlane:(float)nearPlane farPlane:(float)farPlane {
|
|
Matrix *matrix = [Matrix zero];
|
|
matrix.data->m11 = (2 * nearPlane) / width;
|
|
matrix.data->m22 = (2 * nearPlane) / height;
|
|
matrix.data->m33 = farPlane / (nearPlane - farPlane);
|
|
matrix.data->m34 = -1;
|
|
matrix.data->m43 = nearPlane * farPlane / (nearPlane - farPlane);
|
|
return matrix;
|
|
}
|
|
|
|
+ (Matrix*) perspectiveWithFieldOfView:(float)fieldOfView aspectRatio:(float)aspectRatio nearPlane:(float)nearPlane farPlane:(float)farPlane{
|
|
float width = 2 * nearPlane * tanf(fieldOfView * 0.5f);
|
|
float height = width / aspectRatio;
|
|
return [Matrix perspectiveWithWidth:width height:height nearPlane:nearPlane farPlane:farPlane];
|
|
}
|
|
|
|
+ (Matrix*) worldAt:(Vector3 *)position forward:(Vector3 *)forward up:(Vector3 *)up {
|
|
Vector3 *z = [[Vector3 negate:forward] normalize];
|
|
Vector3 *x = [[Vector3 crossProductOf:up with:z] normalize];
|
|
Vector3 *y = [Vector3 crossProductOf:z with:x];
|
|
Matrix *matrix = [Matrix identity];
|
|
matrix.right = x;
|
|
matrix.up = y;
|
|
matrix.backward = z;
|
|
matrix.translation = position;
|
|
return matrix;
|
|
}
|
|
|
|
// PROPERTIES
|
|
|
|
- (MatrixStruct*) data {return &data;}
|
|
|
|
// Main rows
|
|
|
|
- (Vector3 *) right {return [Vector3 vectorWithX:data.m11 y:data.m12 z:data.m13];}
|
|
- (void) setRight:(Vector3 *)value {data.m11 = value.x; data.m12 = value.y; data.m13 = value.z;}
|
|
|
|
- (Vector3 *) up {return [Vector3 vectorWithX:data.m21 y:data.m22 z:data.m23];}
|
|
- (void) setUp:(Vector3 *)value {data.m21 = value.x; data.m22 = value.y; data.m23 = value.z;}
|
|
|
|
- (Vector3 *) backward {return [Vector3 vectorWithX:data.m31 y:data.m32 z:data.m33];}
|
|
- (void) setBackward:(Vector3 *)value {data.m31 = value.x; data.m32 = value.y; data.m33 = value.z;}
|
|
|
|
- (Vector3 *) translation {return [Vector3 vectorWithX:data.m41 y:data.m42 z:data.m43];}
|
|
- (void) setTranslation:(Vector3 *)value {data.m41 = value.x; data.m42 = value.y; data.m43 = value.z;}
|
|
|
|
// Negative rows
|
|
|
|
- (Vector3 *) left {return [Vector3 vectorWithX:-data.m11 y:-data.m12 z:-data.m13];}
|
|
- (void) setLeft:(Vector3 *)value {data.m11 = -value.x; data.m12 = -value.y; data.m13 = -value.z;}
|
|
|
|
- (Vector3 *) down {return [Vector3 vectorWithX:-data.m21 y:-data.m22 z:-data.m23];}
|
|
- (void) setDown:(Vector3 *)value {data.m21 = -value.x; data.m22 = -value.y; data.m23 = -value.z;}
|
|
|
|
- (Vector3 *) forward {return [Vector3 vectorWithX:-data.m31 y:-data.m32 z:-data.m33];}
|
|
- (void) setForward:(Vector3 *)value {data.m31 = -value.x; data.m32 = -value.y; data.m33 = -value.z;}
|
|
|
|
// METHODS
|
|
|
|
- (Matrix*) transpose {
|
|
MatrixTranspose(self.data);
|
|
return self;
|
|
}
|
|
|
|
- (Matrix*) inverse {
|
|
MatrixInverse(self.data);
|
|
return self;
|
|
}
|
|
|
|
- (Matrix*) multiplyWith:(Matrix*)value {
|
|
MatrixStruct result;
|
|
MatrixMultiply(self.data, value.data, &result);
|
|
data = result;
|
|
return self;
|
|
}
|
|
|
|
// CONSTANTS
|
|
|
|
+ (id) zero {
|
|
MatrixStruct MatrixStruct = MatrixMake(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
return [Matrix matrixWithStruct:&MatrixStruct];
|
|
}
|
|
+ (id) identity {
|
|
MatrixStruct MatrixStruct = MatrixMake(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
|
return [Matrix matrixWithStruct:&MatrixStruct];
|
|
}
|
|
|
|
@end
|