Index: src/OFMatrix4x4.h ================================================================== --- src/OFMatrix4x4.h +++ src/OFMatrix4x4.h @@ -69,15 +69,29 @@ * * @param matrix The matrix to multiply the receiver with */ - (void)multiplyWithMatrix: (OFMatrix4x4 *)matrix; +/** + * @brief Translates the matrix with the specified 3D vector. + * + * @param vector The vector to translate the matrix with + */ +- (void)translateWithVector3D: (OFVector3D)vector; + +/** + * @brief Scales the matrix with the specified 3D vector. + * + * @param vector The vector to scale the matrix with + */ +- (void)scaleWithVector3D: (OFVector3D)vector; + /** * @brief Transforms the specified point in 3D space according to the matrix. * * @param point The point to transform * @return The transformed point */ -- (OFPoint3D)transformedPoint3D: (OFPoint3D)point; +- (OFVector3D)transformedPoint3D: (OFVector3D)point; @end OF_ASSUME_NONNULL_END Index: src/OFMatrix4x4.m ================================================================== --- src/OFMatrix4x4.m +++ src/OFMatrix4x4.m @@ -182,13 +182,39 @@ matrix->_values[7] * copy[13] + matrix->_values[11] * copy[14] + matrix->_values[15] * copy[15]; } -- (OFPoint3D)transformedPoint3D: (OFPoint3D)point +- (void)translateWithVector3D: (OFVector3D)vector +{ + OFMatrix4x4 *translation = [[OFMatrix4x4 alloc] initWithValues: + (float [16]){ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + vector.x, vector.y, vector.z, 1 + }]; + [self multiplyWithMatrix: translation]; + [translation release]; +} + +- (void)scaleWithVector3D: (OFVector3D)vector +{ + OFMatrix4x4 *scale = [[OFMatrix4x4 alloc] initWithValues: + (float [16]){ + vector.x, 0, 0, 0, + 0, vector.y, 0, 0, + 0, 0, vector.z, 0, + 0, 0, 0, 1 + }]; + [self multiplyWithMatrix: scale]; + [scale release]; +} + +- (OFVector3D)transformedPoint3D: (OFVector3D)point { - return OFMakePoint3D( + return OFMakeVector3D( _values[0] * point.x + _values[4] * point.y + _values[8] * point.z + _values[12], _values[1] * point.x + _values[5] * point.y + _values[9] * point.z + _values[13], _values[2] * point.x + _values[6] * point.y + Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -294,56 +294,56 @@ return true; } /** - * @struct OFPoint3D OFObject.h ObjFW/OFObject.h + * @struct OFVector3D OFObject.h ObjFW/OFObject.h * - * @brief A point in 3D space. + * @brief A vector in 3D space. */ typedef struct OF_BOXABLE { - /** The x coordinate of the point */ - float x; - /** The y coordinate of the point */ - float y; - /** The z coordinate of the point */ - float z; -} OFPoint3D; - -/** - * @brief Creates a new OFPoint3D. - * - * @param x The x coordinate of the point - * @param y The x coordinate of the point - * @param z The z coordinate of the point - * @return An OFPoint3D with the specified coordinates - */ -static OF_INLINE OFPoint3D OF_CONST_FUNC -OFMakePoint3D(float x, float y, float z) -{ - OFPoint3D point = { x, y, z }; - - return point; -} - -/** - * @brief Returns whether the two points are equal. - * - * @param point1 The first point for the comparison - * @param point2 The second point for the comparison - * @return Whether the two points are equal + /** The x coordinate of the vector */ + float x; + /** The y coordinate of the vector */ + float y; + /** The z coordinate of the vector */ + float z; +} OFVector3D; + +/** + * @brief Creates a new OFVector3D. + * + * @param x The x coordinate of the vector + * @param y The x coordinate of the vector + * @param z The z coordinate of the vector + * @return An OFVector3D with the specified coordinates + */ +static OF_INLINE OFVector3D OF_CONST_FUNC +OFMakeVector3D(float x, float y, float z) +{ + OFVector3D vector = { x, y, z }; + + return vector; +} + +/** + * @brief Returns whether the two vectors are equal. + * + * @param vector1 The first vector for the comparison + * @param vector2 The second vectors for the comparison + * @return Whether the two vectors are equal */ static OF_INLINE bool -OFEqualPoints3D(OFPoint3D point1, OFPoint3D point2) +OFEqualVectors3D(OFVector3D vector1, OFVector3D vector2) { - if (point1.x != point2.x) + if (vector1.x != vector2.x) + return false; + + if (vector1.y != vector2.y) return false; - if (point1.y != point2.y) - return false; - - if (point1.z != point2.z) + if (vector1.z != vector2.z) return false; return true; } Index: tests/OFMatrix4x4Tests.m ================================================================== --- tests/OFMatrix4x4Tests.m +++ tests/OFMatrix4x4Tests.m @@ -22,11 +22,11 @@ @implementation TestsAppDelegate (OFMatrix4x4Tests) - (void)matrix4x4Tests { void *pool = objc_autoreleasePoolPush(); OFMatrix4x4 *matrix, *matrix2; - OFPoint3D point; + OFVector3D point; TEST(@"+[identityMatrix]", memcmp([[OFMatrix4x4 identityMatrix] values], (float [16]){ 1, 0, 0, 0, 0, 1, 0, 0, @@ -85,12 +85,23 @@ 10000, 22800, 35600, 48400, 11000, 25400, 39800, 54200, 12000, 28000, 44000, 60000 }]]) + TEST(@"[-translateWithVector3D:]", + R(matrix2 = [OFMatrix4x4 identityMatrix]) && + R([matrix2 translateWithVector3D: OFMakeVector3D(1, 2, 3)]) && + R(point = [matrix2 transformedPoint3D: OFMakeVector3D(2, 3, 4)]) && + point.x == 3 && point.y == 5 && point.z == 7) + + TEST(@"-[scaleWithVector3D:]", + R([matrix2 scaleWithVector3D: OFMakeVector3D(-1, 0.5, 2)]) && + R(point = [matrix2 transformedPoint3D: OFMakeVector3D(2, 3, 4)]) && + point.x == -3 && point.y == 2.5 && point.z == 14) + TEST(@"-[transformedPoint3D:]", - R((point = [matrix transformedPoint3D: OFMakePoint3D(1, 2, 3)])) && + R((point = [matrix transformedPoint3D: OFMakeVector3D(1, 2, 3)])) && point.x == 18 && point.y == 46 && point.z == 74) objc_autoreleasePoolPop(pool); } @end