diff options
Diffstat (limited to 'src/math')
-rw-r--r-- | src/math/func.h | 38 | ||||
-rw-r--r-- | src/math/geometry.h | 141 | ||||
-rw-r--r-- | src/math/intsize.h | 61 | ||||
-rw-r--r-- | src/math/matrix.h | 20 | ||||
-rw-r--r-- | src/math/point.h | 22 | ||||
-rw-r--r-- | src/math/size.h | 66 | ||||
-rw-r--r-- | src/math/vector.h | 35 |
7 files changed, 290 insertions, 93 deletions
diff --git a/src/math/func.h b/src/math/func.h index 8f0e4ab..2127d1a 100644 --- a/src/math/func.h +++ b/src/math/func.h @@ -34,15 +34,15 @@ namespace Math /* @{ */ // start of group //! Compares \a a and \a b within \a tolerance -inline bool IsEqual(float a, float b, float tolerance = TOLERANCE) +inline bool IsEqual(float a, float b, float tolerance = Math::TOLERANCE) { return fabs(a - b) < tolerance; } //! Compares \a a to zero within \a tolerance -inline bool IsZero(float a, float tolerance = TOLERANCE) +inline bool IsZero(float a, float tolerance = Math::TOLERANCE) { - return IsEqual(a, 0.0f, tolerance); + return Math::IsEqual(a, 0.0f, tolerance); } //! Minimum @@ -59,12 +59,12 @@ inline float Min(float a, float b, float c) inline float Min(float a, float b, float c, float d) { - return Min( Min(a, b), Min(c, d) ); + return Math::Min( Math::Min(a, b), Math::Min(c, d) ); } inline float Min(float a, float b, float c, float d, float e) { - return Min( Min(a, b), Min(c, d), e ); + return Math::Min( Math::Min(a, b), Math::Min(c, d), e ); } //! Maximum @@ -76,17 +76,17 @@ inline float Max(float a, float b) inline float Max(float a, float b, float c) { - return Max( Max(a, b), c ); + return Math::Max( Math::Max(a, b), c ); } inline float Max(float a, float b, float c, float d) { - return Max( Max(a, b), Max(c, d) ); + return Math::Max( Math::Max(a, b), Math::Max(c, d) ); } inline float Max(float a, float b, float c, float d, float e) { - return Max( Max(a, b), Max(c, d), e ); + return Math::Max( Math::Max(a, b), Math::Max(c, d), e ); } //! Returns the normalized value (0 .. 1) @@ -118,19 +118,19 @@ inline void Swap(float &a, float &b) Mod(n, 1) = fractional part of n */ inline float Mod(float a, float m) { - return a - ((int)(a/m))*m; + return a - ( static_cast<int>(a / m) ) * m; } //! Returns a random value between 0 and 1. inline float Rand() { - return (float)rand()/RAND_MAX; + return static_cast<float>(rand()) / static_cast<float>(RAND_MAX); } //! Returns a normalized angle, that is in other words between 0 and 2 * PI inline float NormAngle(float angle) { - angle = Mod(angle, PI*2.0f); + angle = Math::Mod(angle, PI*2.0f); if ( angle < 0.0f ) return PI*2.0f + angle; @@ -140,9 +140,9 @@ inline float NormAngle(float angle) //! Test if a angle is between two terminals inline bool TestAngle(float angle, float min, float max) { - angle = NormAngle(angle); - min = NormAngle(min); - max = NormAngle(max); + angle = Math::NormAngle(angle); + min = Math::NormAngle(min); + max = Math::NormAngle(max); if ( min > max ) return ( angle <= max || angle >= min ); @@ -153,18 +153,18 @@ inline bool TestAngle(float angle, float min, float max) //! Calculates a value (radians) proportional between a and b (degrees) inline float PropAngle(int a, int b, float p) { - float aa = (float)a * DEG_TO_RAD; - float bb = (float)b * DEG_TO_RAD; + float aa = static_cast<float>(a) * DEG_TO_RAD; + float bb = static_cast<float>(b) * DEG_TO_RAD; - return aa+p*(bb-aa); + return aa + p * (bb - aa); } //! Calculates the angle to rotate the angle \a a to the angle \a g /** A positive angle is counterclockwise (CCW). */ inline float Direction(float a, float g) { - a = NormAngle(a); - g = NormAngle(g); + a = Math::NormAngle(a); + g = Math::NormAngle(g); if ( a < g ) { diff --git a/src/math/geometry.h b/src/math/geometry.h index 2f937e5..61d1868 100644 --- a/src/math/geometry.h +++ b/src/math/geometry.h @@ -40,7 +40,7 @@ namespace Math //! Returns py up on the line \a a - \a b -inline float MidPoint(const Point &a, const Point &b, float px) +inline float MidPoint(const Math::Point &a, const Math::Point &b, float px) { if (IsEqual(a.x, b.x)) { @@ -53,7 +53,7 @@ inline float MidPoint(const Point &a, const Point &b, float px) } //! Tests whether the point \a p is inside the triangle (\a a,\a b,\a c) -inline bool IsInsideTriangle(Point a, Point b, Point c, Point p) +inline bool IsInsideTriangle(Math::Point a, Math::Point b, Math::Point c, Math::Point p) { float n, m; @@ -82,13 +82,13 @@ inline bool IsInsideTriangle(Point a, Point b, Point c, Point p) /** \a center center of rotation \a angle angle is in radians (positive is counterclockwise (CCW) ) \a p the point */ -inline Point RotatePoint(const Point ¢er, float angle, const Point &p) +inline Math::Point RotatePoint(const Math::Point ¢er, float angle, const Math::Point &p) { - Point a; + Math::Point a; a.x = p.x-center.x; a.y = p.y-center.y; - Point b; + Math::Point b; b.x = a.x*cosf(angle) - a.y*sinf(angle); b.y = a.x*sinf(angle) + a.y*cosf(angle); @@ -101,23 +101,23 @@ inline Point RotatePoint(const Point ¢er, float angle, const Point &p) //! Rotates a point around the origin (0,0) /** \a angle angle in radians (positive is counterclockwise (CCW) ) \a p the point */ -inline Point RotatePoint(float angle, const Point &p) +inline Math::Point RotatePoint(float angle, const Math::Point &p) { float x = p.x*cosf(angle) - p.y*sinf(angle); float y = p.x*sinf(angle) + p.y*cosf(angle); - return Point(x, y); + return Math::Point(x, y); } //! Rotates a vector (dist, 0). /** \a angle angle is in radians (positive is counterclockwise (CCW) ) \a dist distance to origin */ -inline Point RotatePoint(float angle, float dist) +inline Math::Point RotatePoint(float angle, float dist) { float x = dist*cosf(angle); float y = dist*sinf(angle); - return Point(x, y); + return Math::Point(x, y); } //! TODO documentation @@ -140,13 +140,13 @@ inline void RotatePoint(float cx, float cy, float angle, float &px, float &py) \a angleH,angleV rotation angles in radians (positive is counterclockwise (CCW) ) ) \a p the point \returns the rotated point */ -inline void RotatePoint(const Vector ¢er, float angleH, float angleV, Vector &p) +inline void RotatePoint(const Math::Vector ¢er, float angleH, float angleV, Math::Vector &p) { p.x -= center.x; p.y -= center.y; p.z -= center.z; - Vector b; + Math::Vector b; b.x = p.x*cosf(angleH) - p.z*sinf(angleH); b.y = p.z*sinf(angleV) + p.y*cosf(angleV); b.z = p.x*sinf(angleH) + p.z*cosf(angleH); @@ -159,18 +159,18 @@ inline void RotatePoint(const Vector ¢er, float angleH, float angleV, Vector \a angleH,angleV rotation angles in radians (positive is counterclockwise (CCW) ) ) \a p the point \returns the rotated point */ -inline void RotatePoint2(const Vector center, float angleH, float angleV, Vector &p) +inline void RotatePoint2(const Math::Vector center, float angleH, float angleV, Math::Vector &p) { p.x -= center.x; p.y -= center.y; p.z -= center.z; - Vector a; + Math::Vector a; a.x = p.x*cosf(angleH) - p.z*sinf(angleH); a.y = p.y; a.z = p.x*sinf(angleH) + p.z*cosf(angleH); - Vector b; + Math::Vector b; b.x = a.x; b.y = a.z*sinf(angleV) + a.y*cosf(angleV); b.z = a.z*cosf(angleV) - a.y*sinf(angleV); @@ -196,7 +196,7 @@ inline float RotateAngle(float x, float y) /** \a center the center point \a p1,p2 the two points \returns The angle in radians (positive is counterclockwise (CCW) ) */ -inline float RotateAngle(const Point ¢er, const Point &p1, const Point &p2) +inline float RotateAngle(const Math::Point ¢er, const Math::Point &p1, const Math::Point &p2) { if (PointsEqual(p1, center)) return 0; @@ -221,11 +221,12 @@ inline float RotateAngle(const Point ¢er, const Point &p1, const Point &p2) /** \a from origin \a at view direction \a worldUp up vector */ -inline void LoadViewMatrix(Matrix &mat, const Vector &from, const Vector &at, const Vector &worldUp) +inline void LoadViewMatrix(Math::Matrix &mat, const Math::Vector &from, + const Math::Vector &at, const Math::Vector &worldUp) { // Get the z basis vector, which points straight ahead. This is the // difference from the eyepoint to the lookat point. - Vector view = at - from; + Math::Vector view = at - from; float length = view.Length(); assert(! IsZero(length) ); @@ -237,18 +238,18 @@ inline void LoadViewMatrix(Matrix &mat, const Vector &from, const Vector &at, co // vector onto the up vector. The projection is the y basis vector. float dotProduct = DotProduct(worldUp, view); - Vector up = worldUp - dotProduct * view; + Math::Vector up = worldUp - dotProduct * view; // If this vector has near-zero length because the input specified a // bogus up vector, let's try a default up vector if ( IsZero(length = up.Length()) ) { - up = Vector(0.0f, 1.0f, 0.0f) - view.y * view; + up = Math::Vector(0.0f, 1.0f, 0.0f) - view.y * view; // If we still have near-zero length, resort to a different axis. if ( IsZero(length = up.Length()) ) { - up = Vector(0.0f, 0.0f, 1.0f) - view.z * view; + up = Math::Vector(0.0f, 0.0f, 1.0f) - view.z * view; assert(! IsZero(up.Length()) ); } @@ -259,7 +260,7 @@ inline void LoadViewMatrix(Matrix &mat, const Vector &from, const Vector &at, co // The x basis vector is found simply with the cross product of the y // and z basis vectors - Vector right = CrossProduct(up, view); + Math::Vector right = CrossProduct(up, view); // Start building the matrix. The first three rows contains the basis // vectors used to rotate the view to point at the lookat point @@ -286,28 +287,44 @@ inline void LoadViewMatrix(Matrix &mat, const Vector &from, const Vector &at, co \a aspect aspect ratio (width / height) \a nearPlane distance to near cut plane \a farPlane distance to far cut plane */ -inline void LoadProjectionMatrix(Matrix &mat, float fov = 1.570795f, float aspect = 1.0f, +inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = Math::PI / 2.0f, float aspect = 1.0f, float nearPlane = 1.0f, float farPlane = 1000.0f) { assert(fabs(farPlane - nearPlane) >= 0.01f); assert(fabs(sin(fov / 2)) >= 0.01f); - float w = aspect * (cosf(fov / 2) / sinf(fov / 2)); - float h = 1.0f * (cosf(fov / 2) / sinf(fov / 2)); - float q = farPlane / (farPlane - nearPlane); + float f = cosf(fov / 2.0f) / sinf(fov / 2.0f); mat.LoadZero(); - /* (1,1) */ mat.m[0 ] = w; - /* (2,2) */ mat.m[5 ] = h; - /* (3,3) */ mat.m[10] = q; - /* (4,3) */ mat.m[11] = 1.0f; - /* (3,4) */ mat.m[14] = -q * nearPlane; + /* (1,1) */ mat.m[0 ] = f / aspect; + /* (2,2) */ mat.m[5 ] = f; + /* (3,3) */ mat.m[10] = (nearPlane + farPlane) / (nearPlane - farPlane); + /* (4,3) */ mat.m[11] = -1.0f; + /* (3,4) */ mat.m[14] = (2.0f * farPlane * nearPlane) / (nearPlane - farPlane); +} + +//! Loads an othogonal projection matrix +/** \a left,right coordinates for left and right vertical clipping planes + \a bottom,top coordinates for bottom and top horizontal clipping planes + \a zNear,zFar distance to nearer and farther depth clipping planes */ +inline void LoadOrthoProjectionMatrix(Math::Matrix &mat, float left, float right, float bottom, float top, + float zNear = -1.0f, float zFar = 1.0f) +{ + mat.LoadIdentity(); + + /* (1,1) */ mat.m[0 ] = 2.0f / (right - left); + /* (2,2) */ mat.m[5 ] = 2.0f / (top - bottom); + /* (3,3) */ mat.m[10] = -2.0f / (zFar - zNear); + + /* (1,4) */ mat.m[12] = - (right + left) / (right - left); + /* (2,4) */ mat.m[13] = - (top + bottom) / (top - bottom); + /* (3,4) */ mat.m[14] = - (zFar + zNear) / (zFar - zNear); } //! Loads a translation matrix from given vector /** \a trans vector of translation*/ -inline void LoadTranslationMatrix(Matrix &mat, const Vector &trans) +inline void LoadTranslationMatrix(Math::Matrix &mat, const Math::Vector &trans) { mat.LoadIdentity(); /* (1,4) */ mat.m[12] = trans.x; @@ -317,7 +334,7 @@ inline void LoadTranslationMatrix(Matrix &mat, const Vector &trans) //! Loads a scaling matrix fom given vector /** \a scale vector with scaling factors for X, Y, Z */ -inline void LoadScaleMatrix(Matrix &mat, const Vector &scale) +inline void LoadScaleMatrix(Math::Matrix &mat, const Math::Vector &scale) { mat.LoadIdentity(); /* (1,1) */ mat.m[0 ] = scale.x; @@ -327,7 +344,7 @@ inline void LoadScaleMatrix(Matrix &mat, const Vector &scale) //! Loads a rotation matrix along the X axis /** \a angle angle in radians */ -inline void LoadRotationXMatrix(Matrix &mat, float angle) +inline void LoadRotationXMatrix(Math::Matrix &mat, float angle) { mat.LoadIdentity(); /* (2,2) */ mat.m[5 ] = cosf(angle); @@ -338,7 +355,7 @@ inline void LoadRotationXMatrix(Matrix &mat, float angle) //! Loads a rotation matrix along the Y axis /** \a angle angle in radians */ -inline void LoadRotationYMatrix(Matrix &mat, float angle) +inline void LoadRotationYMatrix(Math::Matrix &mat, float angle) { mat.LoadIdentity(); /* (1,1) */ mat.m[0 ] = cosf(angle); @@ -349,7 +366,7 @@ inline void LoadRotationYMatrix(Matrix &mat, float angle) //! Loads a rotation matrix along the Z axis /** \a angle angle in radians */ -inline void LoadRotationZMatrix(Matrix &mat, float angle) +inline void LoadRotationZMatrix(Math::Matrix &mat, float angle) { mat.LoadIdentity(); /* (1,1) */ mat.m[0 ] = cosf(angle); @@ -361,11 +378,11 @@ inline void LoadRotationZMatrix(Matrix &mat, float angle) //! Loads a rotation matrix along the given axis /** \a dir axis of rotation \a angle angle in radians */ -inline void LoadRotationMatrix(Matrix &mat, const Vector &dir, float angle) +inline void LoadRotationMatrix(Math::Matrix &mat, const Math::Vector &dir, float angle) { float cos = cosf(angle); float sin = sinf(angle); - Vector v = Normalize(dir); + Math::Vector v = Normalize(dir); mat.LoadIdentity(); @@ -383,9 +400,9 @@ inline void LoadRotationMatrix(Matrix &mat, const Vector &dir, float angle) } //! Calculates the matrix to make three rotations in the order X, Z and Y -inline void LoadRotationXZYMatrix(Matrix &mat, const Vector &angle) +inline void LoadRotationXZYMatrix(Math::Matrix &mat, const Math::Vector &angle) { - Matrix temp; + Math::Matrix temp; LoadRotationXMatrix(temp, angle.x); LoadRotationZMatrix(mat, angle.z); @@ -396,9 +413,9 @@ inline void LoadRotationXZYMatrix(Matrix &mat, const Vector &angle) } //! Calculates the matrix to make three rotations in the order Z, X and Y -inline void LoadRotationZXYMatrix(Matrix &mat, const Vector &angle) +inline void LoadRotationZXYMatrix(Math::Matrix &mat, const Math::Vector &angle) { - Matrix temp; + Math::Matrix temp; LoadRotationZMatrix(temp, angle.z); LoadRotationXMatrix(mat, angle.x); @@ -409,7 +426,7 @@ inline void LoadRotationZXYMatrix(Matrix &mat, const Vector &angle) } //! Returns the distance between projections on XZ plane of two vectors -inline float DistanceProjected(const Vector &a, const Vector &b) +inline float DistanceProjected(const Math::Vector &a, const Math::Vector &b) { return sqrtf( (a.x-b.x)*(a.x-b.x) + (a.z-b.z)*(a.z-b.z) ); @@ -417,10 +434,10 @@ inline float DistanceProjected(const Vector &a, const Vector &b) //! Returns the normal vector to a plane /** \param p1,p2,p3 points defining the plane */ -inline Vector NormalToPlane(const Vector &p1, const Vector &p2, const Vector &p3) +inline Math::Vector NormalToPlane(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3) { - Vector u = p3 - p1; - Vector v = p2 - p1; + Math::Vector u = p3 - p1; + Math::Vector v = p2 - p1; return Normalize(CrossProduct(u, v)); } @@ -428,7 +445,7 @@ inline Vector NormalToPlane(const Vector &p1, const Vector &p2, const Vector &p3 //! Returns a point on the line \a p1 - \a p2, in \a dist distance from \a p1 /** \a p1,p2 line start and end \a dist scaling factor from \a p1, relative to distance between \a p1 and \a p2 */ -inline Vector SegmentPoint(const Vector &p1, const Vector &p2, float dist) +inline Math::Vector SegmentPoint(const Math::Vector &p1, const Math::Vector &p2, float dist) { return p1 + (p2 - p1) * dist; } @@ -436,9 +453,10 @@ inline Vector SegmentPoint(const Vector &p1, const Vector &p2, float dist) //! Returns the distance between given point and a plane /** \param p the point \param a,b,c points defining the plane */ -inline float DistanceToPlane(const Vector &a, const Vector &b, const Vector &c, const Vector &p) +inline float DistanceToPlane(const Math::Vector &a, const Math::Vector &b, + const Math::Vector &c, const Math::Vector &p) { - Vector n = NormalToPlane(a, b, c); + Math::Vector n = NormalToPlane(a, b, c); float d = -(n.x*a.x + n.y*a.y + n.z*a.z); return fabs(n.x*p.x + n.y*p.y + n.z*p.z + d); @@ -447,10 +465,10 @@ inline float DistanceToPlane(const Vector &a, const Vector &b, const Vector &c, //! Checks if two planes defined by three points are the same /** \a plane1 array of three vectors defining the first plane \a plane2 array of three vectors defining the second plane */ -inline bool IsSamePlane(const Vector (&plane1)[3], const Vector (&plane2)[3]) +inline bool IsSamePlane(const Math::Vector (&plane1)[3], const Math::Vector (&plane2)[3]) { - Vector n1 = NormalToPlane(plane1[0], plane1[1], plane1[2]); - Vector n2 = NormalToPlane(plane2[0], plane2[1], plane2[2]); + Math::Vector n1 = NormalToPlane(plane1[0], plane1[1], plane1[2]); + Math::Vector n2 = NormalToPlane(plane2[0], plane2[1], plane2[2]); if ( fabs(n1.x-n2.x) > 0.1f || fabs(n1.y-n2.y) > 0.1f || @@ -465,7 +483,8 @@ inline bool IsSamePlane(const Vector (&plane1)[3], const Vector (&plane2)[3]) } //! Calculates the intersection "i" right "of" the plane "abc". -inline bool Intersect(const Vector &a, const Vector &b, const Vector &c, const Vector &d, const Vector &e, Vector &i) +inline bool Intersect(const Math::Vector &a, const Math::Vector &b, const Math::Vector &c, + const Math::Vector &d, const Math::Vector &e, Math::Vector &i) { float d1 = (d.x-a.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) - (d.y-a.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) + @@ -487,7 +506,7 @@ inline bool Intersect(const Vector &a, const Vector &b, const Vector &c, const V //! Calculates the intersection of the straight line passing through p (x, z) /** Line is parallel to the y axis, with the plane abc. Returns p.y. */ -inline bool IntersectY(const Vector &a, const Vector &b, const Vector &c, Vector &p) +inline bool IntersectY(const Math::Vector &a, const Math::Vector &b, const Math::Vector &c, Math::Vector &p) { float d = (b.x-a.x)*(c.z-a.z) - (c.x-a.x)*(b.z-a.z); float d1 = (p.x-a.x)*(c.z-a.z) - (c.x-a.x)*(p.z-a.z); @@ -502,9 +521,9 @@ inline bool IntersectY(const Vector &a, const Vector &b, const Vector &c, Vector } //! Calculates the end point -inline Vector LookatPoint(const Vector &eye, float angleH, float angleV, float length) +inline Math::Vector LookatPoint(const Math::Vector &eye, float angleH, float angleV, float length) { - Vector lookat = eye; + Math::Vector lookat = eye; lookat.z += length; RotatePoint(eye, angleH, angleV, lookat); @@ -513,7 +532,7 @@ inline Vector LookatPoint(const Vector &eye, float angleH, float angleV, float l } //! TODO documentation -inline Vector Transform(const Matrix &m, const Vector &p) +inline Math::Vector Transform(const Math::Matrix &m, const Math::Vector &p) { return MatrixVectorMultiply(m, p); } @@ -521,7 +540,7 @@ inline Vector Transform(const Matrix &m, const Vector &p) //! Calculates the projection of the point \a p on a straight line \a a to \a b. /** \a p point to project \a a,b two ends of the line */ -inline Vector Projection(const Vector &a, const Vector &b, const Vector &p) +inline Math::Vector Projection(const Math::Vector &a, const Math::Vector &b, const Math::Vector &p) { float k = DotProduct(b - a, p - a); k /= DotProduct(b - a, b - a); @@ -530,15 +549,15 @@ inline Vector Projection(const Vector &a, const Vector &b, const Vector &p) } //! Calculates point of view to look at a center two angles and a distance -inline Vector RotateView(Vector center, float angleH, float angleV, float dist) +inline Math::Vector RotateView(Math::Vector center, float angleH, float angleV, float dist) { - Matrix mat1, mat2; + Math::Matrix mat1, mat2; LoadRotationZMatrix(mat1, -angleV); LoadRotationYMatrix(mat2, -angleH); - Matrix mat = MultiplyMatrices(mat2, mat1); + Math::Matrix mat = MultiplyMatrices(mat2, mat1); - Vector eye; + Math::Vector eye; eye.x = 0.0f+dist; eye.y = 0.0f; eye.z = 0.0f; diff --git a/src/math/intsize.h b/src/math/intsize.h new file mode 100644 index 0000000..f4b2431 --- /dev/null +++ b/src/math/intsize.h @@ -0,0 +1,61 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program 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 +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +/** @defgroup MathIntSizeModule math/intsize.h + Contains the IntSize struct. + */ + +#pragma once + +// Math module namespace +namespace Math +{ + +/* @{ */ // start of group + +/** \struct IntSize math/size.h + \brief 2D size with integer dimensions */ +struct IntSize +{ + //! Width + int w; + //! Height + int h; + + //! Constructs a zero size: (0,0) + inline IntSize() + { + LoadZero(); + } + + //! Constructs a size from given dimensions: (w,h) + inline explicit IntSize(int w, int h) + { + this->w = w; + this->h = h; + } + + //! Sets the zero size: (0,0) + inline void LoadZero() + { + w = h = 0; + } +}; // struct Size + + +/* @} */ // end of group + +}; // namespace Math diff --git a/src/math/matrix.h b/src/math/matrix.h index 9b29f46..45a7d75 100644 --- a/src/math/matrix.h +++ b/src/math/matrix.h @@ -118,6 +118,12 @@ struct Matrix /* (4,4) */ m[15] = 1.0f; } + //! Returns the struct cast to \c float* array; use with care! + inline float* Array() + { + return reinterpret_cast<float*>(this); + } + //! Transposes the matrix inline void Transpose() { @@ -382,9 +388,9 @@ inline bool MatricesEqual(const Matrix &m1, const Matrix &m2, } //! Convenience function for getting transposed matrix -inline Matrix Transpose(const Matrix &m) +inline Math::Matrix Transpose(const Math::Matrix &m) { - Matrix result = m; + Math::Matrix result = m; result.Transpose(); return result; } @@ -393,7 +399,7 @@ inline Matrix Transpose(const Matrix &m) /** \a left left-hand matrix \a right right-hand matrix \returns multiplied matrices */ -inline Matrix MultiplyMatrices(const Matrix &left, const Matrix &right) +inline Math::Matrix MultiplyMatrices(const Math::Matrix &left, const Math::Matrix &right) { return left.Multiply(right); } @@ -407,25 +413,25 @@ inline Matrix MultiplyMatrices(const Matrix &left, const Matrix &right) The result, a 4x1 vector is then converted to 3x1 by dividing x,y,z coords by the fourth coord (w). */ -inline Vector MatrixVectorMultiply(const Matrix &m, const Vector &v, bool wDivide = false) +inline Math::Vector MatrixVectorMultiply(const Math::Matrix &m, const Math::Vector &v, bool wDivide = false) { float x = v.x * m.m[0 ] + v.y * m.m[4 ] + v.z * m.m[8 ] + m.m[12]; float y = v.x * m.m[1 ] + v.y * m.m[5 ] + v.z * m.m[9 ] + m.m[13]; float z = v.x * m.m[2 ] + v.y * m.m[6 ] + v.z * m.m[10] + m.m[14]; if (!wDivide) - return Vector(x, y, z); + return Math::Vector(x, y, z); float w = v.x * m.m[3 ] + v.y * m.m[7 ] + v.z * m.m[11] + m.m[15]; if (IsZero(w)) - return Vector(x, y, z); + return Math::Vector(x, y, z); x /= w; y /= w; z /= w; - return Vector(x, y, z); + return Math::Vector(x, y, z); } /* @} */ // end of group diff --git a/src/math/point.h b/src/math/point.h index 84be190..ea20db9 100644 --- a/src/math/point.h +++ b/src/math/point.h @@ -24,6 +24,7 @@ #include "func.h" #include <cmath> +#include <sstream> // Math module namespace @@ -67,6 +68,18 @@ struct Point x = y = 0.0f; } + //! Returns the struct cast to \c float* array; use with care! + inline float* Array() + { + return reinterpret_cast<float*>(this); + } + + //! Returns the struct cast to <tt>const float*</tt> array; use with care! + inline const float* Array() const + { + return reinterpret_cast<const float*>(this); + } + //! Returns the distance from (0,0) to the point (x,y) inline float Length() { @@ -141,6 +154,15 @@ struct Point return Point(left.x / right, left.y / right); } + + //! Returns a string "[x, y]" + inline std::string ToString() const + { + std::stringstream s; + s.precision(3); + s << "[" << x << ", " << y << "]"; + return s.str(); + } }; // struct Point diff --git a/src/math/size.h b/src/math/size.h new file mode 100644 index 0000000..781b9a4 --- /dev/null +++ b/src/math/size.h @@ -0,0 +1,66 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program 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 +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +/** @defgroup MathSizeModule math/size.h + Contains the Size struct. + */ + +#pragma once + +// Math module namespace +namespace Math +{ + +/* @{ */ // start of group + +/** \struct Size math/size.h + \brief 2D size + + Represents a 2D size (w, h). + Is separate from Math::Point to avoid confusion. + + */ +struct Size +{ + //! Width + float w; + //! Height + float h; + + //! Constructs a zero size: (0,0) + inline Size() + { + LoadZero(); + } + + //! Constructs a size from given dimensions: (w,h) + inline explicit Size(float w, float h) + { + this->w = w; + this->h = h; + } + + //! Sets the zero size: (0,0) + inline void LoadZero() + { + w = h = 0.0f; + } +}; // struct Size + + +/* @} */ // end of group + +}; // namespace Math diff --git a/src/math/vector.h b/src/math/vector.h index 3c756f2..147869f 100644 --- a/src/math/vector.h +++ b/src/math/vector.h @@ -24,6 +24,7 @@ #include "func.h" #include <cmath> +#include <sstream> // Math module namespace @@ -72,6 +73,18 @@ struct Vector x = y = z = 0.0f; } + //! Returns the struct cast to \c float* array; use with care! + inline float* Array() + { + return reinterpret_cast<float*>(this); + } + + //! Returns the struct cast to <tt>const float*</tt> array; use with care! + inline const float* Array() const + { + return reinterpret_cast<const float*>(this); + } + //! Returns the vector length inline float Length() const { @@ -196,10 +209,20 @@ struct Vector return Vector(left.x / right, left.y / right, left.z / right); } + + //! Returns a string "[x, y, z]" + inline std::string ToString() const + { + std::stringstream s; + s.precision(3); + s << "[" << x << ", " << y << ", " << z << "]"; + return s.str(); + } + }; // struct Point //! Checks if two vectors are equal within given \a tolerance -inline bool VectorsEqual(const Vector &a, const Vector &b, float tolerance = TOLERANCE) +inline bool VectorsEqual(const Math::Vector &a, const Math::Vector &b, float tolerance = TOLERANCE) { return IsEqual(a.x, b.x, tolerance) && IsEqual(a.y, b.y, tolerance) @@ -207,7 +230,7 @@ inline bool VectorsEqual(const Vector &a, const Vector &b, float tolerance = TOL } //! Convenience function for getting normalized vector -inline Vector Normalize(const Vector &v) +inline Vector Normalize(const Math::Vector &v) { Vector result = v; result.Normalize(); @@ -215,25 +238,25 @@ inline Vector Normalize(const Vector &v) } //! Convenience function for calculating dot product -inline float DotProduct(const Vector &left, const Vector &right) +inline float DotProduct(const Math::Vector &left, const Math::Vector &right) { return left.DotMultiply(right); } //! Convenience function for calculating cross product -inline Vector CrossProduct(const Vector &left, const Vector &right) +inline Vector CrossProduct(const Math::Vector &left, const Math::Vector &right) { return left.CrossMultiply(right); } //! Convenience function for calculating angle (in radians) between two vectors -inline float Angle(const Vector &a, const Vector &b) +inline float Angle(const Math::Vector &a, const Math::Vector &b) { return a.Angle(b); } //! Returns the distance between the ends of two vectors -inline float Distance(const Vector &a, const Vector &b) +inline float Distance(const Math::Vector &a, const Math::Vector &b) { return sqrtf( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + |