From f8840a70a68618a490af240f0989335cec1b41fd Mon Sep 17 00:00:00 2001 From: Matej Jan Date: Thu, 23 Sep 2010 14:51:10 +0000 Subject: [PATCH] Completed basic vector, matrix and quaternion operations. git-svn-id: http://xni.googlecode.com/svn/XNI@25 ac433895-eea3-a490-d80a-17149a75e588 --- .../Xni/Framework/Graphics/Vector4.h | 4 - .../Xni/Framework/Graphics/Vector4.m | 137 ++++++++++++ Classes/Retronator/Xni/Framework/Matrix.h | 39 +++- Classes/Retronator/Xni/Framework/Matrix.m | 132 +++++++++--- .../Retronator/Xni/Framework/MatrixStruct.h | 132 +++++++++++- Classes/Retronator/Xni/Framework/Quaternion.h | 10 +- Classes/Retronator/Xni/Framework/Quaternion.m | 202 ++++++++++++++++++ Classes/Retronator/Xni/Framework/Vector2.m | 144 +++++++++++++ .../Retronator/Xni/Framework/Vector2Struct.h | 2 +- .../Retronator/Xni/Framework/Vector4Struct.h | 2 +- 10 files changed, 757 insertions(+), 47 deletions(-) diff --git a/Classes/Retronator/Xni/Framework/Graphics/Vector4.h b/Classes/Retronator/Xni/Framework/Graphics/Vector4.h index 7295bcb..f15ba5f 100644 --- a/Classes/Retronator/Xni/Framework/Graphics/Vector4.h +++ b/Classes/Retronator/Xni/Framework/Graphics/Vector4.h @@ -26,21 +26,17 @@ @property (nonatomic) float y; @property (nonatomic) float z; @property (nonatomic) float w; - @property (nonatomic, readonly) Vector4Struct *data; + (Vector4*) normalize:(Vector4*)value; + (Vector4*) negate:(Vector4*)value; - + (Vector4*) add:(Vector4*)value1 to:(Vector4*)value2; + (Vector4*) subtract:(Vector4*)value1 by:(Vector4*)value2; + (Vector4*) multiply:(Vector4*)value by:(float)scalar; - + (Vector4*) transform:(Vector4*)value with:(Matrix*)matrix; - (float) length; - (float) lengthSquared; - - (Vector4*) normalize; - (Vector4*) negate; - (Vector4*) add:(Vector4*)value; diff --git a/Classes/Retronator/Xni/Framework/Graphics/Vector4.m b/Classes/Retronator/Xni/Framework/Graphics/Vector4.m index 1bba1bf..f782eaa 100644 --- a/Classes/Retronator/Xni/Framework/Graphics/Vector4.m +++ b/Classes/Retronator/Xni/Framework/Graphics/Vector4.m @@ -8,7 +8,144 @@ #import "Vector4.h" +#import "Retronator.Xni.Framework.h" @implementation Vector4 +// CONSTRUCTORS + +- (id) initWithX:(float)x y:(float)y z:(float)z w:(float)w { + if (self = [super init]) { + data = Vector4Make(x, y, z, w); + } + return self; +} + +- (id) initWithStruct: (Vector4Struct*)vectorData { + if (self = [super init]) { + data = *vectorData; + } + return self; +} + +- (id) initWithVector: (Vector4*)vector { + return [self initWithStruct:vector.data]; +} + ++ (Vector4*) vectorWithX:(float)x y:(float)y z:(float)z w:(float)w { + return [[[Vector4 alloc] initWithX:x y:y z:z w:w] autorelease]; +} + ++ (Vector4*) vectorWithStruct: (Vector4Struct*)vectorData { + return [[[Vector4 alloc] initWithStruct:vectorData] autorelease]; +} + ++ (Vector4*) vectorWithVector: (Vector4*)vector { + return [[[Vector4 alloc] initWithVector:vector] autorelease]; +} + +// PROPERTIES + +- (float) x {return data.x;} +- (void) setX:(float)value {data.x = value;} + +- (float) y {return data.y;} +- (void) setY:(float)value {data.y = value;} + +- (float) z {return data.z;} +- (void) setZ:(float)value {data.z = value;} + +- (float) w {return data.w;} +- (void) setW:(float)value {data.w = value;} + +- (Vector4Struct*) data {return &data;} + +// METHODS + ++ (Vector4*) normalize:(Vector4*)value { + Vector4Struct resultData = *value.data; + Vector4Normalize(&resultData); + return [Vector4 vectorWithStruct:&resultData]; +} + ++ (Vector4*) negate:(Vector4*)value { + Vector4Struct resultData = *value.data; + Vector4Negate(&resultData); + return [Vector4 vectorWithStruct:&resultData]; +} + ++ (Vector4*) add:(Vector4*)value1 to:(Vector4*)value2 { + Vector4Struct resultData; + Vector4Add(value1.data, value2.data, &resultData); + return [Vector4 vectorWithStruct:&resultData]; +} + ++ (Vector4*) subtract:(Vector4*)value1 by:(Vector4*)value2 { + Vector4Struct resultData; + Vector4Subtract(value1.data, value2.data, &resultData); + return [Vector4 vectorWithStruct:&resultData]; +} + ++ (Vector4*) multiply:(Vector4*)value by:(float)scalar { + Vector4Struct resultData; + Vector4Multiply(value.data, scalar, &resultData); + return [Vector4 vectorWithStruct:&resultData]; +} + ++ (Vector4*) transform:(Vector4*)value with:(Matrix*)matrix { + Vector4Struct resultData; + Vector4Transform(value.data, matrix.data, &resultData); + return [Vector4 vectorWithStruct:&resultData]; +} + +- (float) length { + return Vector4Length(self.data); +} + +- (float) lengthSquared { + return Vector4LengthSquared(self.data); +} + +- (Vector4*) normalize { + Vector4Normalize(&data); + return self; +} +- (Vector4*) negate { + Vector4Negate(&data); + return self; +} + +- (Vector4*) add:(Vector4*)value { + Vector4Add(self.data, value.data, self.data); + return self; +} + +- (Vector4*) subtract:(Vector4*)value { + Vector4Subtract(self.data, value.data, self.data); + return self; +} + +- (Vector4*) multiplyBy:(float)scalar { + Vector4Multiply(self.data, scalar, self.data); + return self; +} + +- (Vector4*) transformWith:(Matrix*)matrix { + Vector4Transform(self.data, matrix.data, self.data); + return self; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"Vector(%f, %f, %f, %f)", data.x, data.y, data.z, data.w]; +} + +// Constants + ++ (Vector4*) zero {return [Vector4 vectorWithX:0 y:0 z:0 w:0];} ++ (Vector4*) one {return [Vector4 vectorWithX:1 y:1 z:1 w:1];} ++ (Vector4*) unitX {return [Vector4 vectorWithX:1 y:0 z:0 w:0];} ++ (Vector4*) unitY {return [Vector4 vectorWithX:0 y:1 z:0 w:0];} ++ (Vector4*) unitZ {return [Vector4 vectorWithX:0 y:0 z:1 w:0];} ++ (Vector4*) unitW {return [Vector4 vectorWithX:0 y:0 z:0 w:1];} + @end diff --git a/Classes/Retronator/Xni/Framework/Matrix.h b/Classes/Retronator/Xni/Framework/Matrix.h index bed8a1b..34c8d91 100644 --- a/Classes/Retronator/Xni/Framework/Matrix.h +++ b/Classes/Retronator/Xni/Framework/Matrix.h @@ -20,14 +20,15 @@ + (Matrix*) matrixWithStruct: (MatrixStruct*)matrixData; + (Matrix*) matrixWithMatrix: (Matrix*)matrix; -+ (Matrix*) translation:(Vector3*)position; -+ (Matrix*) scale:(Vector3*)scale; -+ (Matrix*) rotationAround:(Vector3*)axis for:(float)angle; -+ (Matrix*) rotationWithQuaternion:(Quaternion*)quaternion; -+ (Matrix*) lookAt:(Vector3*)target from:(Vector3*)position up:(Vector3*)up; -+ (Matrix*) perspectiveWithWidth:(float)width height:(float)height nearPlane:(float)nearPlane farPlane:(float)farPlane; -+ (Matrix*) perspectiveWithFieldOfView:(float)fieldOfView aspectRatio:(float)aspectRatio nearPlane:(float)nearPlane farPlane:(float)farPlane; -+ (Matrix*) worldAt:(Vector3*)position forward:(Vector3*)forward up:(Vector3*)up; ++ (Matrix*) createTranslation:(Vector3*)position; ++ (Matrix*) createScaleUniform:(float)scale; ++ (Matrix*) createScale:(Vector3*)scales; ++ (Matrix*) createFromAxis:(Vector3*)axis angle:(float)angle; ++ (Matrix*) createFromQuaternion:(Quaternion*)quaternion; ++ (Matrix*) createLookAtFrom:(Vector3*)position to:(Vector3*)target up:(Vector3*)up; ++ (Matrix*) createPerspectiveWithWidth:(float)width height:(float)height nearPlane:(float)nearPlane farPlane:(float)farPlane; ++ (Matrix*) createPerspectiveFieldOfView:(float)fieldOfView aspectRatio:(float)aspectRatio nearPlane:(float)nearPlane farPlane:(float)farPlane; ++ (Matrix*) createWorldAtPosition:(Vector3*)position forward:(Vector3*)forward up:(Vector3*)up; @property (nonatomic, readonly) MatrixStruct *data; @property (nonatomic, assign) Vector3 *left; @@ -38,9 +39,25 @@ @property (nonatomic, assign) Vector3 *backward; @property (nonatomic, assign) Vector3 *translation; -- (Matrix*) transpose; -- (Matrix*) inverse; -- (Matrix*) multiplyWith:(Matrix*)value; ++ (Matrix*) negate:(Matrix*)value; ++ (Matrix*) transpose:(Matrix*)value; ++ (Matrix*) invert:(Matrix*)value; + ++ (Matrix*) add:(Matrix*)value1 to:(Matrix*)value2; ++ (Matrix*) subtract:(Matrix*)value1 by:(Matrix*)value2; ++ (Matrix*) multiply:(Matrix*)value1 byScalar:(float)scaleFactor; ++ (Matrix*) multiply:(Matrix*)value1 by:(Matrix*)value2; ++ (Matrix*) divide:(Matrix*)value1 byScalar:(float)divider; ++ (Matrix*) divide:(Matrix*)value1 by:(Matrix*)value2; + +- (float) determinant; +- (Matrix*) negate; +- (Matrix*) add:(Matrix*)value; +- (Matrix*) subtract:(Matrix*)value; +- (Matrix*) multiplyByScalar:(float)scaleFactor; +- (Matrix*) multiplyBy:(Matrix*)value; +- (Matrix*) divideByScalar:(float)divider; +- (Matrix*) divideBy:(Matrix*)value; // Constants + (id) zero; diff --git a/Classes/Retronator/Xni/Framework/Matrix.m b/Classes/Retronator/Xni/Framework/Matrix.m index b508c1b..61305ba 100644 --- a/Classes/Retronator/Xni/Framework/Matrix.m +++ b/Classes/Retronator/Xni/Framework/Matrix.m @@ -31,21 +31,29 @@ return [[[Matrix alloc] initWithMatrix:matrix] autorelease]; } -+ (Matrix*) translation:(Vector3*)position { ++ (Matrix*) createTranslation:(Vector3*)position { Matrix *matrix = [Matrix identity]; matrix.translation = position; return matrix; } -+ (Matrix*) scale:(Vector3 *)scale { ++ (Matrix*) createScaleUniform:(float)scale { Matrix *matrix = [Matrix identity]; - matrix.data->m11= scale.x; - matrix.data->m22= scale.y; - matrix.data->m33= scale.z; + matrix.data->m11 = scale; + matrix.data->m22 = scale; + matrix.data->m33 = scale; return matrix; } -+ (Matrix*) rotationAround:(Vector3 *)axis for:(float)angle { ++ (Matrix*) createScale:(Vector3 *)scales { + Matrix *matrix = [Matrix identity]; + matrix.data->m11 = scales.x; + matrix.data->m22 = scales.y; + matrix.data->m33 = scales.z; + return matrix; +} + ++ (Matrix*) createFromAxis:(Vector3 *)axis angle:(float)angle { Vector3 *normalizedAxis = [[Vector3 vectorWithVector:axis] normalize]; float c = cosf(angle); @@ -68,7 +76,7 @@ return matrix; } -+ (Matrix*) rotationWithQuaternion:(Quaternion *)quaternion { ++ (Matrix*) createFromQuaternion:(Quaternion *)quaternion { Quaternion *normalizedQuaternion = [[Quaternion quaternionWithQuaternion:quaternion] normalize]; float x = normalizedQuaternion.x; @@ -90,7 +98,7 @@ return matrix; } -+ (Matrix*) lookAt:(Vector3*)target from:(Vector3*)position up:(Vector3*)up { ++ (Matrix*) createLookAtFrom:(Vector3*)position to:(Vector3*)target 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]; @@ -115,7 +123,7 @@ return matrix; } -+ (Matrix*) perspectiveWithWidth:(float)width height:(float)height nearPlane:(float)nearPlane farPlane:(float)farPlane { ++ (Matrix*) createPerspectiveWithWidth:(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; @@ -125,13 +133,13 @@ return matrix; } -+ (Matrix*) perspectiveWithFieldOfView:(float)fieldOfView aspectRatio:(float)aspectRatio nearPlane:(float)nearPlane farPlane:(float)farPlane{ ++ (Matrix*) createPerspectiveFieldOfView:(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]; + return [Matrix createPerspectiveWithWidth:width height:height nearPlane:nearPlane farPlane:farPlane]; } -+ (Matrix*) worldAt:(Vector3 *)position forward:(Vector3 *)forward up:(Vector3 *)up { ++ (Matrix*) createWorldAtPosition:(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]; @@ -174,32 +182,108 @@ // METHODS -- (Matrix*) transpose { - MatrixTranspose(self.data); ++ (Matrix*) negate:(Matrix*)value { + Matrix *result = [Matrix matrixWithMatrix:value]; + [result negate]; + return result; +} + ++ (Matrix*) transpose:(Matrix*)value { + MatrixStruct resultData = *value.data; + MatrixTranspose(&resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) invert:(Matrix*)value { + MatrixStruct resultData = *value.data; + MatrixInvert(&resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) add:(Matrix*)value1 to:(Matrix*)value2 { + MatrixStruct resultData; + MatrixAdd(value1.data, value2.data, &resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) subtract:(Matrix*)value1 by:(Matrix*)value2{ + MatrixStruct resultData; + MatrixSubtract(value1.data, value2.data, &resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) multiply:(Matrix*)value1 byScalar:(float)scaleFactor{ + MatrixStruct resultData; + MatrixMultiplyScalar(value1.data, scaleFactor, &resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) multiply:(Matrix*)value1 by:(Matrix*)value2{ + MatrixStruct resultData; + MatrixMultiply(value1.data, value2.data, &resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) divide:(Matrix*)value1 byScalar:(float)divider{ + MatrixStruct resultData; + MatrixDivideScalar(value1.data, divider, &resultData); + return [Matrix matrixWithStruct:&resultData]; +} + ++ (Matrix*) divide:(Matrix*)value1 by:(Matrix*)value2{ + MatrixStruct resultData; + MatrixDivide(value1.data, value2.data, &resultData); + return [Matrix matrixWithStruct:&resultData]; +} + +- (float) determinant { + return MatrixDeterminant(self.data); +} + +- (Matrix*) negate { + MatrixNegate(self.data); return self; } -- (Matrix*) inverse { - MatrixInverse(self.data); +- (Matrix*) add:(Matrix*)value { + MatrixAdd(self.data, value.data, self.data); return self; } -- (Matrix*) multiplyWith:(Matrix*)value { - MatrixStruct result; - MatrixMultiply(self.data, value.data, &result); - data = result; +- (Matrix*) subtract:(Matrix*)value { + MatrixSubtract(self.data, value.data, self.data); + return self; +} + +- (Matrix*) multiplyByScalar:(float)scaleFactor { + MatrixMultiplyScalar(self.data, scaleFactor, self.data); + return self; +} + +- (Matrix*) multiplyBy:(Matrix*)value { + MatrixMultiply(self.data, value.data, self.data); + return self; +} + +- (Matrix*) divideByScalar:(float)divider { + MatrixDivideScalar(self.data, divider, self.data); + return self; +} + +- (Matrix*) divideBy:(Matrix*)value { + MatrixDivide(self.data, value.data, self.data); 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]; + 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]; + MatrixStruct MatrixStruct = MatrixMake(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + return [Matrix matrixWithStruct:&MatrixStruct]; } @end diff --git a/Classes/Retronator/Xni/Framework/MatrixStruct.h b/Classes/Retronator/Xni/Framework/MatrixStruct.h index f4a2797..c23b304 100644 --- a/Classes/Retronator/Xni/Framework/MatrixStruct.h +++ b/Classes/Retronator/Xni/Framework/MatrixStruct.h @@ -39,6 +39,41 @@ static inline MatrixStruct MatrixMake(float m11, float m12, float m13, float m14 return matrix; } +static inline float MatrixDeterminant(MatrixStruct *value) { + float det1 = value->m11 * value->m22 - value->m12 * value->m21; + float det2 = value->m11 * value->m23 - value->m13 * value->m21; + float det3 = value->m11 * value->m24 - value->m14 * value->m21; + float det4 = value->m12 * value->m23 - value->m13 * value->m22; + float det5 = value->m12 * value->m24 - value->m14 * value->m22; + float det6 = value->m13 * value->m24 - value->m14 * value->m23; + float det7 = value->m31 * value->m42 - value->m32 * value->m41; + float det8 = value->m31 * value->m43 - value->m33 * value->m41; + float det9 = value->m31 * value->m44 - value->m34 * value->m41; + float det10 = value->m32 * value->m43 - value->m33 * value->m42; + float det11 = value->m32 * value->m44 - value->m34 * value->m42; + float det12 = value->m33 * value->m44 - value->m34 * value->m43; + return det1*det12 - det2*det11 + det3*det10 + det4*det9 - det5*det8 + det6*det7; +} + +static inline void MatrixNegate(MatrixStruct *value) { + value->m11 = -value->m11; + value->m12 = -value->m12; + value->m13 = -value->m13; + value->m14 = -value->m14; + value->m21 = -value->m21; + value->m22 = -value->m22; + value->m23 = -value->m23; + value->m24 = -value->m24; + value->m31 = -value->m31; + value->m32 = -value->m32; + value->m33 = -value->m33; + value->m34 = -value->m34; + value->m41 = -value->m41; + value->m42 = -value->m42; + value->m43 = -value->m43; + value->m44 = -value->m44; +} + static inline void MatrixTranspose(MatrixStruct *value) { MatrixStruct matrix = *value; value->m11 = matrix.m11; @@ -59,7 +94,7 @@ static inline void MatrixTranspose(MatrixStruct *value) { value->m44 = matrix.m44; } -static inline void MatrixInverse(MatrixStruct *value) { +static inline void MatrixInvert(MatrixStruct *value) { MatrixStruct matrix = *value; float det1 = matrix.m11 * matrix.m22 - matrix.m12 * matrix.m21; float det2 = matrix.m11 * matrix.m23 - matrix.m13 * matrix.m21; @@ -95,6 +130,63 @@ static inline void MatrixInverse(MatrixStruct *value) { value->m44 = (matrix.m31*det4 - matrix.m32*det2 + matrix.m33*det1) * invDetMatrix; } +static inline void MatrixAdd(MatrixStruct *value1, MatrixStruct *value2, MatrixStruct *result) { + result->m11 = value1->m11 + value2->m11; + result->m12 = value1->m12 + value2->m12; + result->m13 = value1->m13 + value2->m13; + result->m14 = value1->m14 + value2->m14; + result->m21 = value1->m21 + value2->m21; + result->m22 = value1->m22 + value2->m22; + result->m23 = value1->m23 + value2->m23; + result->m24 = value1->m24 + value2->m24; + result->m31 = value1->m31 + value2->m31; + result->m32 = value1->m32 + value2->m32; + result->m33 = value1->m33 + value2->m33; + result->m34 = value1->m34 + value2->m34; + result->m41 = value1->m41 + value2->m41; + result->m42 = value1->m42 + value2->m42; + result->m43 = value1->m43 + value2->m43; + result->m44 = value1->m44 + value2->m44; +} + +static inline void MatrixSubtract(MatrixStruct *value1, MatrixStruct *value2, MatrixStruct *result) { + result->m11 = value1->m11 - value2->m11; + result->m12 = value1->m12 - value2->m12; + result->m13 = value1->m13 - value2->m13; + result->m14 = value1->m14 - value2->m14; + result->m21 = value1->m21 - value2->m21; + result->m22 = value1->m22 - value2->m22; + result->m23 = value1->m23 - value2->m23; + result->m24 = value1->m24 - value2->m24; + result->m31 = value1->m31 - value2->m31; + result->m32 = value1->m32 - value2->m32; + result->m33 = value1->m33 - value2->m33; + result->m34 = value1->m34 - value2->m34; + result->m41 = value1->m41 - value2->m41; + result->m42 = value1->m42 - value2->m42; + result->m43 = value1->m43 - value2->m43; + result->m44 = value1->m44 - value2->m44; +} + +static inline void MatrixMultiplyScalar(MatrixStruct *value1, float scaleFactor, MatrixStruct *result) { + result->m11 = value1->m11 * scaleFactor; + result->m12 = value1->m12 * scaleFactor; + result->m13 = value1->m13 * scaleFactor; + result->m14 = value1->m14 * scaleFactor; + result->m21 = value1->m21 * scaleFactor; + result->m22 = value1->m22 * scaleFactor; + result->m23 = value1->m23 * scaleFactor; + result->m24 = value1->m24 * scaleFactor; + result->m31 = value1->m31 * scaleFactor; + result->m32 = value1->m32 * scaleFactor; + result->m33 = value1->m33 * scaleFactor; + result->m34 = value1->m34 * scaleFactor; + result->m41 = value1->m41 * scaleFactor; + result->m42 = value1->m42 * scaleFactor; + result->m43 = value1->m43 * scaleFactor; + result->m44 = value1->m44 * scaleFactor; +} + static inline void MatrixMultiply(MatrixStruct *value1, MatrixStruct *value2, MatrixStruct *result) { float m11 = value1->m11 * value2->m11 + value1->m12 * value2->m21 + value1->m13 * value2->m31 + value1->m14 * value2->m41; float m12 = value1->m11 * value2->m12 + value1->m12 * value2->m22 + value1->m13 * value2->m32 + value1->m14 * value2->m42; @@ -128,4 +220,42 @@ static inline void MatrixMultiply(MatrixStruct *value1, MatrixStruct *value2, Ma result->m42 = m42; result->m43 = m43; result->m44 = m44; +} + +static inline void MatrixDivideScalar(MatrixStruct *value1, float divider, MatrixStruct *result) { + result->m11 = value1->m11 / divider; + result->m12 = value1->m12 / divider; + result->m13 = value1->m13 / divider; + result->m14 = value1->m14 / divider; + result->m21 = value1->m21 / divider; + result->m22 = value1->m22 / divider; + result->m23 = value1->m23 / divider; + result->m24 = value1->m24 / divider; + result->m31 = value1->m31 / divider; + result->m32 = value1->m32 / divider; + result->m33 = value1->m33 / divider; + result->m34 = value1->m34 / divider; + result->m41 = value1->m41 / divider; + result->m42 = value1->m42 / divider; + result->m43 = value1->m43 / divider; + result->m44 = value1->m44 / divider; +} + +static inline void MatrixDivide(MatrixStruct *value1, MatrixStruct *value2, MatrixStruct *result) { + result->m11 = value1->m11 / value2->m11; + result->m12 = value1->m12 / value2->m12; + result->m13 = value1->m13 / value2->m13; + result->m14 = value1->m14 / value2->m14; + result->m21 = value1->m21 / value2->m21; + result->m22 = value1->m22 / value2->m22; + result->m23 = value1->m23 / value2->m23; + result->m24 = value1->m24 / value2->m24; + result->m31 = value1->m31 / value2->m31; + result->m32 = value1->m32 / value2->m32; + result->m33 = value1->m33 / value2->m33; + result->m34 = value1->m34 / value2->m34; + result->m41 = value1->m41 / value2->m41; + result->m42 = value1->m42 / value2->m42; + result->m43 = value1->m43 / value2->m43; + result->m44 = value1->m44 / value2->m44; } \ No newline at end of file diff --git a/Classes/Retronator/Xni/Framework/Quaternion.h b/Classes/Retronator/Xni/Framework/Quaternion.h index 0f767ff..2b2b3cb 100644 --- a/Classes/Retronator/Xni/Framework/Quaternion.h +++ b/Classes/Retronator/Xni/Framework/Quaternion.h @@ -19,7 +19,7 @@ - (id) initWithStruct: (Vector4Struct*)quaternionData; - (id) initWithQuaternion: (Quaternion*)quaternion; -+ (Quaternion*) quaternionWithX:(float)x Y:(float)y Z:(float)z W:(float)w; ++ (Quaternion*) quaternionWithX:(float)x y:(float)y z:(float)z w:(float)w; + (Quaternion*) quaternionWithVectorPart:(Vector3*)vector scalarPart:(float)scalar; + (Quaternion*) quaternionWithStruct: (Vector4Struct*)quaternionData; + (Quaternion*) quaternionWithQuaternion: (Quaternion*)quaternion; @@ -39,8 +39,8 @@ + (Quaternion*) inverse:(Quaternion*)value; + (Quaternion*) add:(Quaternion*)value1 to:(Quaternion*)value2; + (Quaternion*) subtract:(Quaternion*)value1 by:(Quaternion*)value2; -+ (Quaternion*) multiply:(Quaternion*)value by:(float)scalar; -+ (Quaternion*) multiply:(Quaternion*)value1 with:(Quaternion*)value2; ++ (Quaternion*) multiply:(Quaternion*)value1 byScalar:(float)scaleFactor; ++ (Quaternion*) multiply:(Quaternion*)value1 by:(Quaternion*)value2; - (float) length; - (float) lengthSquared; @@ -50,8 +50,8 @@ - (Quaternion*) inverse; - (Quaternion*) add:(Quaternion*)value; - (Quaternion*) subtract:(Quaternion*)value; -- (Quaternion*) scaleBy:(float)scalar; -- (Quaternion*) multiplyWith:(Quaternion*)value; +- (Quaternion*) multiplyByScalar:(float)scaleFactor; +- (Quaternion*) multiplyBy:(Quaternion*)value; // Constants + (Quaternion*) identity; diff --git a/Classes/Retronator/Xni/Framework/Quaternion.m b/Classes/Retronator/Xni/Framework/Quaternion.m index 4039eb7..33fb1e9 100644 --- a/Classes/Retronator/Xni/Framework/Quaternion.m +++ b/Classes/Retronator/Xni/Framework/Quaternion.m @@ -8,7 +8,209 @@ #import "Quaternion.h" +#import "Retronator.Xni.Framework.h" @implementation Quaternion +- (id) initWithX:(float)x y:(float)y z:(float)z w:(float)w { + if (self = [super init]) { + data = Vector4Make(x, y, z, w); + } + return self; +} + +- (id) initWithVectorPart:(Vector3 *)vector scalarPart:(float)scalar { + if (self = [super init]) { + data = Vector4Make(vector.x, vector.y, vector.z, scalar); + } + return self; +} + +- (id) initWithStruct: (Vector4Struct*)quaternionData { + if (self = [super init]) { + data = *quaternionData; + } + return self; +} + +- (id) initWithQuaternion: (Quaternion*)quaternion { + return [self initWithStruct:quaternion.data]; +} + ++ (Quaternion*) quaternionWithX:(float)x y:(float)y z:(float)z w:(float)w { + return [[[Quaternion alloc] initWithX:x y:y z:z w:w] autorelease]; +} + ++ (Quaternion*) quaternionWithVectorPart:(Vector3 *)vector scalarPart:(float)scalar { + return [[[Quaternion alloc] initWithVectorPart:vector scalarPart:scalar] autorelease]; +} + ++ (Quaternion*) quaternionWithStruct: (Vector4Struct*)quaternionData { + return [[[Quaternion alloc] initWithData:(id)quaternionData] autorelease]; +} + ++ (Quaternion*) quaternionWithQuaternion: (Quaternion*)quaternion { + return [[[Quaternion alloc] initWithQuaternion:quaternion] autorelease]; +} + ++ (Quaternion*) axis:(Vector3 *)axis angle:(float)angle { + float s = sinf(angle / 2.0f); + float c = cosf(angle / 2.0f); + return [Quaternion quaternionWithVectorPart:[Vector3 multiply:axis by:s] scalarPart:c]; +} + ++ (Quaternion *) rotationMatrix:(Matrix *)matrix { + Quaternion *result = [[Quaternion alloc] init]; + + if ((matrix.data->m11 + matrix.data->m22 + matrix.data->m33) > 0.0F) { + float M1 = sqrtf(matrix.data->m11 + matrix.data->m22 + matrix.data->m33 + 1); + result.w = M1 * 0.5F; + M1 = 0.5F / M1; + result.x = (matrix.data->m23 - matrix.data->m32) * M1; + result.y = (matrix.data->m31 - matrix.data->m13) * M1; + result.z = (matrix.data->m12 - matrix.data->m21) * M1; + return result; + } + + if ((matrix.data->m11 >= matrix.data->m22) && (matrix.data->m11 >= matrix.data->m33)) { + float M2 = sqrtf(1 + matrix.data->m11 - matrix.data->m22 - matrix.data->m33); + float M3 = 0.5F / M2; + result.x = 0.5F * M2; + result.y = (matrix.data->m12 + matrix.data->m21) * M3; + result.z = (matrix.data->m13 + matrix.data->m31) * M3; + result.w = (matrix.data->m23 - matrix.data->m32) * M3; + return result; + } + + if (matrix.data->m22 > matrix.data->m33) { + float M4 = sqrtf(1 + matrix.data->m22 - matrix.data->m11 - matrix.data->m33); + float M5 = 0.5F / M4; + result.x = (matrix.data->m21 + matrix.data->m12) * M5; + result.y = 0.5F * M4; + result.z = (matrix.data->m32 + matrix.data->m23) * M5; + result.w = (matrix.data->m31 - matrix.data->m13) * M5; + return result; + } + + float M6 = sqrtf(1 + matrix.data->m33 - matrix.data->m11 - matrix.data->m22); + float M7 = 0.5F / M6; + result.x = (matrix.data->m31 + matrix.data->m13) * M7; + result.y = (matrix.data->m32 + matrix.data->m23) * M7; + result.z = 0.5F * M6; + result.w = (matrix.data->m12 - matrix.data->m21) * M7; + return result; +} + +// PROPERTIES + +- (float) x {return data.x;} +- (void) setX:(float)value {data.x = value;} + +- (float) y {return data.y;} +- (void) setY:(float)value {data.y = value;} + +- (float) z {return data.z;} +- (void) setZ:(float)value {data.z = value;} + +- (float) w {return data.w;} +- (void) setW:(float)value {data.w = value;} + +- (Vector4Struct*) data {return &data;} + +// METHODS + ++ (Quaternion*) normalize:(Quaternion*)value { + Vector4Struct resultData = *value.data; + Vector4Normalize(&resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + ++ (Quaternion*) negate:(Quaternion*)value { + Vector4Struct resultData = *value.data; + Vector4Negate(&resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + ++ (Quaternion*) inverse:(Quaternion*)value { + Vector4Struct resultData = *value.data; + QuaternionInverse(&resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + ++ (Quaternion *) add:(Quaternion *)value1 to:(Quaternion *)value2 { + Vector4Struct resultData; + Vector4Add(value1.data, value2.data, &resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + ++ (Quaternion *) subtract:(Quaternion *)value1 by:(Quaternion *)value2 { + Vector4Struct resultData; + Vector4Subtract(value1.data, value2.data, &resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + ++ (Quaternion *) multiply:(Quaternion *)value byScalar:(float)scaleFactor { + Vector4Struct resultData; + Vector4Multiply(value.data, scaleFactor, &resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + ++ (Quaternion *) multiply:(Quaternion *)value1 by:(Quaternion *)value2 { + Vector4Struct resultData; + QuaternionMultiply(value1.data, value2.data, &resultData); + return [Quaternion quaternionWithStruct:&resultData]; +} + +- (float) length { + return Vector4Length(self.data); +} + +- (float) lengthSquared { + return Vector4LengthSquared(self.data); +} + +- (Quaternion*) normalize { + Vector4Normalize(&data); + return self; +} + +- (Quaternion*) negate { + Vector4Negate(&data); + return self; +} + +- (Quaternion*) inverse { + QuaternionInverse(&data); + return self; +} + +- (Quaternion *) add:(Quaternion *)value { + Vector4Add(self.data, value.data, self.data); + return self; +} + +- (Quaternion *) subtract:(Quaternion *)value { + Vector4Subtract(self.data, value.data, self.data); + return self; +} + +- (Quaternion *) multiplyByScalar:(float)scaleFactor { + Vector4Multiply(self.data, scaleFactor, self.data); + return self; +} + +- (Quaternion *) multiplyBy:(Quaternion *)value { + QuaternionMultiply(self.data, value.data, self.data); + return self; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"Quaternion(%f, %f, %f, %f)", data.x, data.y, data.z, data.w]; +} + ++ (Quaternion *) identity { + Vector4Struct data = Vector4Make(0, 0, 0, 1); + return [Quaternion quaternionWithStruct:&data]; +} + @end diff --git a/Classes/Retronator/Xni/Framework/Vector2.m b/Classes/Retronator/Xni/Framework/Vector2.m index 63a0797..e828701 100644 --- a/Classes/Retronator/Xni/Framework/Vector2.m +++ b/Classes/Retronator/Xni/Framework/Vector2.m @@ -8,7 +8,151 @@ #import "Vector2.h" +#import "Retronator.Xni.Framework.h" @implementation Vector2 +// CONSTRUCTORS + +- (id) initWithX:(float)x y:(float)y { + if (self = [super init]) { + data = Vector2Make(x, y); + } + return self; +} + +- (id) initWithStruct: (Vector2Struct*)vectorData { + if (self = [super init]) { + data = *vectorData; + } + return self; +} + +- (id) initWithVector: (Vector2*)vector { + return [self initWithStruct:vector.data]; +} + ++ (Vector2*) vectorWithX:(float)x y:(float)y{ + return [[[Vector2 alloc] initWithX:x y:y] autorelease]; +} + ++ (Vector2*) vectorWithStruct: (Vector2Struct*)vectorData { + return [[[Vector2 alloc] initWithStruct:vectorData] autorelease]; +} + ++ (Vector2*) vectorWithVector: (Vector2*)vector { + return [[[Vector2 alloc] initWithVector:vector] autorelease]; +} + +// PROPERTIES + +- (float) x {return data.x;} +- (void) setX:(float)value {data.x = value;} + +- (float) y {return data.y;} +- (void) setY:(float)value {data.y = value;} + +- (Vector2Struct*) data {return &data;} + +// METHODS + ++ (Vector2*) normalize:(Vector2*)value { + Vector2Struct resultData = *value.data; + Vector2Normalize(&resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + ++ (Vector2*) negate:(Vector2*)value { + Vector2Struct resultData = *value.data; + Vector2Negate(&resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + ++ (Vector2*) add:(Vector2*)value1 to:(Vector2*)value2 { + Vector2Struct resultData; + Vector2Add(value1.data, value2.data, &resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + ++ (Vector2*) subtract:(Vector2*)value1 by:(Vector2*)value2 { + Vector2Struct resultData; + Vector2Subtract(value1.data, value2.data, &resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + ++ (Vector2*) multiply:(Vector2*)value by:(float)scalar { + Vector2Struct resultData; + Vector2Multiply(value.data, scalar, &resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + ++ (float) dotProductOf:(Vector2*)value1 with:(Vector2*)value2 { + return Vector2DotProduct(value1.data, value2.data); +} + ++ (Vector2*) transform:(Vector2*)value with:(Matrix*)matrix { + Vector2Struct resultData; + Vector2Transform(value.data, matrix.data, &resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + ++ (Vector2*) transformNormal:(Vector2*)value with:(Matrix*)matrix { + Vector2Struct resultData; + Vector2TransformNormal(value.data, matrix.data, &resultData); + return [Vector2 vectorWithStruct:&resultData]; +} + +- (float) length { + return Vector2Length(self.data); +} + +- (float) lengthSquared { + return Vector2LengthSquared(self.data); +} + +- (Vector2*) normalize { + Vector2Normalize(&data); + return self; +} +- (Vector2*) negate { + Vector2Negate(&data); + return self; +} + +- (Vector2*) add:(Vector2*)value { + Vector2Add(self.data, value.data, self.data); + return self; +} + +- (Vector2*) subtract:(Vector2*)value { + Vector2Subtract(self.data, value.data, self.data); + return self; +} + +- (Vector2*) multiplyBy:(float)scalar { + Vector2Multiply(self.data, scalar, self.data); + return self; +} + +- (Vector2*) transformWith:(Matrix*)matrix { + Vector2Transform(self.data, matrix.data, self.data); + return self; +} + +- (Vector2*) transformNormalWith:(Matrix*)matrix { + Vector2TransformNormal(self.data, matrix.data, self.data); + return self; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"Vector(%f, %f)", data.x, data.y]; +} + +// Constants + ++ (Vector2*) zero {return [Vector2 vectorWithX:0 y:0];} ++ (Vector2*) one {return [Vector2 vectorWithX:1 y:1];} ++ (Vector2*) unitX {return [Vector2 vectorWithX:1 y:0];} ++ (Vector2*) unitY {return [Vector2 vectorWithX:0 y:1];} + @end diff --git a/Classes/Retronator/Xni/Framework/Vector2Struct.h b/Classes/Retronator/Xni/Framework/Vector2Struct.h index 9a74bf7..3af7c11 100644 --- a/Classes/Retronator/Xni/Framework/Vector2Struct.h +++ b/Classes/Retronator/Xni/Framework/Vector2Struct.h @@ -42,7 +42,7 @@ static inline void Vector2Add(Vector2Struct *value1, Vector2Struct *value2, Vect Vector2Set(result, value1->x + value2->x, value1->y + value2->y); } -static inline void Vector2Substract(Vector2Struct *value1, Vector2Struct *value2, Vector2Struct *result) { +static inline void Vector2Subtract(Vector2Struct *value1, Vector2Struct *value2, Vector2Struct *result) { Vector2Set(result, value1->x - value2->x, value1->y - value2->y); } diff --git a/Classes/Retronator/Xni/Framework/Vector4Struct.h b/Classes/Retronator/Xni/Framework/Vector4Struct.h index 01c5f9e..5c02351 100644 --- a/Classes/Retronator/Xni/Framework/Vector4Struct.h +++ b/Classes/Retronator/Xni/Framework/Vector4Struct.h @@ -68,7 +68,7 @@ static inline void Vector4Multiply(Vector4Struct *value1, float scaleFactor, Vec Vector4Set(result, value1->x * scaleFactor, value1->y * scaleFactor, value1->z * scaleFactor, value1->w * scaleFactor); } -static inline void QuaternionProduct(Vector4Struct *value1, Vector4Struct *value2, Vector4Struct *result) { +static inline void QuaternionMultiply(Vector4Struct *value1, Vector4Struct *value2, Vector4Struct *result) { float f12 = (value1->y * value2->z) - (value1->z * value2->y); float f11 = (value1->z * value2->x) - (value1->x * value2->z); float f10 = (value1->x * value2->y) - (value1->y * value2->x);