From 4531ac88d3c022866d564be40c20593de4c70bfc Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 22 Jun 2012 15:54:16 +0200 Subject: Moved old implementations to src/old --- src/old/math3d.cpp | 1197 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1197 insertions(+) create mode 100644 src/old/math3d.cpp (limited to 'src/old/math3d.cpp') diff --git a/src/old/math3d.cpp b/src/old/math3d.cpp new file mode 100644 index 0000000..a9d67f2 --- /dev/null +++ b/src/old/math3d.cpp @@ -0,0 +1,1197 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * 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/. + +// math3d.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "graphics/d3d/d3dengine.h" +#include "math/old/d3dmath.h" +#include "graphics/d3d/d3dutil.h" +#include "math/old/math3d.h" + + +// Old defines +#define MATH3D_PI 3.14159265358979323846f +#define MATH3D_CHOUIA 1e-6f +#define MATH3D_BEAUCOUP 1e6f + + +// Old FPOINT struct +struct FPOINT +{ + float x; + float y; + + FPOINT() { } + FPOINT(float _x, float _y) + { + x = _x; + y = _y; + } +}; + + +// === Functions already replaced by new implementation === + +//>>> func.h IsEqual() +bool IsEqual(float a, float b); + +//>>> func.h Min() +float Min(float a, float b); +float Min(float a, float b, float c); +float Min(float a, float b, float c, float d); +float Min(float a, float b, float c, float d, float e); + +//>>> func.h Max() +float Max(float a, float b); +float Max(float a, float b, float c); +float Max(float a, float b, float c, float d); +float Max(float a, float b, float c, float d, float e); + +//>>> func.h Norm() +float Norm(float a); +//>>> fabs() +float Abs(float a); + +//>>> func.h Swap() +void Swap(int &a, int &b); +//>>> func.h Swap() +void Swap(float &a, float &b); +//>>> point.h Swap() +void Swap(FPOINT &a, FPOINT &b); + +//>>> func.h Mod() +float Mod(float a, float m); +//>>> func.h NormAngle() +float NormAngle(float angle); +//>>> func.h TestAngle() +bool TestAngle(float angle, float min, float max); + +//>>> geometry.h RotateAngle() +float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2); + +//>>> func.h Direction() +float Direction(float a, float g); + +//>>> geometry.h RotatePoint() +FPOINT RotatePoint(FPOINT center, float angle, FPOINT p); +//>>> geometry.h RotatePoint() +FPOINT RotatePoint(float angle, FPOINT p); +//>>> geometry.h RotatePoint() +FPOINT RotatePoint(float angle, float dist); +//>>> geometry.h RotateAngle() +float RotateAngle(float x, float y); +//>>> geometry.h RotatePoint() +void RotatePoint(float cx, float cy, float angle, float &px, float &py); + +//>>> geometry.h IsInsideTriangle() +bool IsInsideTriangle(FPOINT a, FPOINT b, FPOINT c, FPOINT p); + +//>>> point.h Distance() +float Length(FPOINT a, FPOINT b); + +//>>> point.h Point::Length() +float Length(float x, float y); + +//>>> func.h Rand() +float Rand(); +//>>> func.h Neutral() +float Neutral(float value, float dead); + +//>>> func.h PropAngle() +float Prop(int a, int b, float p); +//>>> func.h Smooth() +float Smooth(float actual, float hope, float time); +//>>> func.h Bounce() +float Bounce(float progress, float middle=0.3f, float bounce=0.4f); + + +//>>> geometry.h SegmentPoint() +D3DVECTOR SegmentDist(const D3DVECTOR &p1, const D3DVECTOR &p2, float dist); + +//>>> geometry.h Intersect() +bool Intersect(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR d, D3DVECTOR e, D3DVECTOR &i); + +//>>> geometry.h IntersectY() +bool IntersectY(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR &p); + +//>>> geometry.h RotatePoint() +void RotatePoint(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p); + +//>>> geometry.h RotatePoint2() +void RotatePoint2(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p); + +//>>> geometry.h RotateView() +D3DVECTOR RotateView(D3DVECTOR center, float angleH, float angleV, float dist); + +//>>> geometry.h LookatPoint() +D3DVECTOR LookatPoint( D3DVECTOR eye, float angleH, float angleV, float length ); + +//>>> vector.h Vector::Length() +float Length(const D3DVECTOR &u); + +//>>> vector.h Distance() +float Length(const D3DVECTOR &a, const D3DVECTOR &b); + +//>>> geometry.h DistanceProjected() +float Length2d(const D3DVECTOR &a, const D3DVECTOR &b); + +//>>> vector.h Angle() +float Angle( D3DVECTOR u, D3DVECTOR v ); + +//>>> vector.h CrossProduct() +D3DVECTOR Cross( D3DVECTOR u, D3DVECTOR v ); + +//>>> geometry.h NormalToPlane() +D3DVECTOR ComputeNormal( D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3 ); + +//>>> geometry.h Transform() +D3DVECTOR Transform(const D3DMATRIX &m, D3DVECTOR p); + +//>>> geometry.h Projection() +D3DVECTOR Projection(const D3DVECTOR &a, const D3DVECTOR &b, const D3DVECTOR &p); + +//>>> geometry.h DistanceToPlane() +float DistancePlanPoint(const D3DVECTOR &a, const D3DVECTOR &b, const D3DVECTOR &c, const D3DVECTOR &p); + +//>>> geometry.h IsSamePlane() +bool IsSamePlane(D3DVECTOR *plan1, D3DVECTOR *plan2); + +//>>> geometry.h LoadRotationXZYMatrix() +void MatRotateXZY(D3DMATRIX &mat, D3DVECTOR angle); + +//>>> geometry.h LoadRotationZXYMatrix() +void MatRotateZXY(D3DMATRIX &mat, D3DVECTOR angle); + + + +// UNUSED +float MidPoint(FPOINT a, FPOINT b, float px); + +// UNUSED +bool LineFunction(FPOINT p1, FPOINT p2, float &a, float &b); + + + + +// Returns true if two numbers are nearly equal. + +bool IsEqual(float a, float b) +{ + return Abs(a-b) < MATH3D_CHOUIA; +} + + +// Returns the minimum value. + +float Min(float a, float b) +{ + if ( a <= b ) return a; + else return b; +} + +float Min(float a, float b, float c) +{ + return Min( Min(a,b), c ); +} + +float Min(float a, float b, float c, float d) +{ + return Min( Min(a,b), Min(c,d) ); +} + +float Min(float a, float b, float c, float d, float e) +{ + return Min( Min(a,b), Min(c,d), e ); +} + + +// Returns the maximum value. + +float Max(float a, float b) +{ + if ( a >= b ) return a; + else return b; +} + +float Max(float a, float b, float c) +{ + return Max( Max(a,b), c ); +} + +float Max(float a, float b, float c, float d) +{ + return Max( Max(a,b), Max(c,d) ); +} + +float Max(float a, float b, float c, float d, float e) +{ + return Max( Max(a,b), Max(c,d), e ); +} + + +// Returns the normalized value (0 .. 1). + +float Norm(float a) +{ + if ( a < 0.0f ) return 0.0f; + if ( a > 1.0f ) return 1.0f; + return a; +} + + +// Returns the absolute value of a number. + +float Abs(float a) +{ + return (float)fabs(a); +} + + +// Swaps two integers. + +void Swap(int &a, int &b) +{ + int c; + + c = a; + a = b; + b = c; +} + +// Swaps two real numbers. + +void Swap(float &a, float &b) +{ + float c; + + c = a; + a = b; + b = c; +} + +// Permutes two points. + +void Swap(FPOINT &a, FPOINT &b) +{ + FPOINT c; + + c = a; + a = b; + b = c; +} + +// Returns the modulo of a floating point number. +// Mod(8.1, 4) = 0.1 +// Mod(n, 1) = fractional part of n + +float Mod(float a, float m) +{ + return a - ((int)(a/m))*m; +} + +// Returns a normalized angle, that is in other words between 0 and 2 * MATH3D_PI. + +float NormAngle(float angle) +{ + angle = Mod(angle, MATH3D_PI*2.0f); + if ( angle < 0.0f ) + { + return MATH3D_PI*2.0f + angle; + } + else + { + return angle; + } +} + +// Test if a angle is between two terminals. + +bool TestAngle(float angle, float min, float max) +{ + angle = NormAngle(angle); + min = NormAngle(min); + max = NormAngle(max); + + if ( min > max ) + { + return ( angle <= max || angle >= min ); + } + else + { + return ( angle >= min && angle <= max ); + } +} + + +// Calculates the angle to rotate the angle a to the angle g. +// A positive angle is counterclockwise (CCW). + +float Direction(float a, float g) +{ + a = NormAngle(a); + g = NormAngle(g); + + if ( a < g ) + { + if ( a+MATH3D_PI*2.0f-g < g-a ) a += MATH3D_PI*2.0f; + } + else + { + if ( g+MATH3D_PI*2.0f-a < a-g ) g += MATH3D_PI*2.0f; + } + return (g-a); +} + + +// Rotates a point around a center. +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +FPOINT RotatePoint(FPOINT center, float angle, FPOINT p) +{ + FPOINT a, b; + + a.x = p.x-center.x; + a.y = p.y-center.y; + + b.x = a.x*cosf(angle) - a.y*sinf(angle); + b.y = a.x*sinf(angle) + a.y*cosf(angle); + + b.x += center.x; + b.y += center.y; + return b; +} + +// Rotates a point around the origin. +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +FPOINT RotatePoint(float angle, FPOINT p) +{ + FPOINT a; + + a.x = p.x*cosf(angle) - p.y*sinf(angle); + a.y = p.x*sinf(angle) + p.y*cosf(angle); + + return a; +} + +// Rotates a vector (dist, 0). +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +FPOINT RotatePoint(float angle, float dist) +{ + FPOINT a; + + a.x = dist*cosf(angle); + a.y = dist*sinf(angle); + + return a; +} + +// Calculates the angle of a right triangle. +// The angle is counterclockwise (CCW), between 0 and 2 * MATH3D_PI. +// For an angle clockwise (CW), just go ahead. +// +// ^ +// | +// y o----o +// | / | +// |/)a | +// ----o----o--> +// | x +// | + +float RotateAngle(float x, float y) +{ +#if 1 + if ( x == 0.0f && y == 0.0f ) return 0.0f; + + if ( x >= 0.0f ) + { + if ( y >= 0.0f ) + { + if ( x > y ) return atanf(y/x); + else return MATH3D_PI*0.5f - atanf(x/y); + } + else + { + if ( x > -y ) return MATH3D_PI*2.0f + atanf(y/x); + else return MATH3D_PI*1.5f - atanf(x/y); + } + } + else + { + if ( y >= 0.0f ) + { + if ( -x > y ) return MATH3D_PI*1.0f + atanf(y/x); + else return MATH3D_PI*0.5f - atanf(x/y); + } + else + { + if ( -x > -y ) return MATH3D_PI*1.0f + atanf(y/x); + else return MATH3D_PI*1.5f - atanf(x/y); + } + } +#else + float angle; + + if ( x == 0.0f ) + { + if ( y > 0.0f ) + { + return 90.0f*MATH3D_PI/180.0f; + } + else + { + return 270.0f*MATH3D_PI/180.0f; + } + } + else + { + angle = atanf(y/x); + if ( x < 0.0f ) + { + angle += MATH3D_PI; + } + return angle; + } +#endif +} + +// Calculates the angle between two points and one center. +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2) +{ + float a1, a2, a; + + if ( p1.x == center.x && + p1.y == center.y ) return 0; + + if ( p2.x == center.x && + p2.y == center.y ) return 0; + + a1 = asinf((p1.y-center.y)/Length(p1,center)); + a2 = asinf((p2.y-center.y)/Length(p2,center)); + + if ( p1.x < center.x ) a1 = MATH3D_PI-a1; + if ( p2.x < center.x ) a2 = MATH3D_PI-a2; + + a = a2-a1; + if ( a < 0 ) a += MATH3D_PI*2; + return a; +} + +// Returns py up on the line ab. + +float MidPoint(FPOINT a, FPOINT b, float px) +{ + if ( Abs(a.x-b.x) < MATH3D_CHOUIA ) + { + if ( a.y < b.y ) return MATH3D_BEAUCOUP; + else return -MATH3D_BEAUCOUP; + } + return (b.y-a.y)*(px-a.x)/(b.x-a.x)+a.y; +} + +// Advance "dist" along the segment p1-p2. + +D3DVECTOR SegmentDist(const D3DVECTOR &p1, const D3DVECTOR &p2, float dist) +{ + return p1+Normalize(p2-p1)*dist; +} + +// Check if a point is inside a triangle. + +bool IsInsideTriangle(FPOINT a, FPOINT b, FPOINT c, FPOINT p) +{ + float n, m; + + if ( p.x < a.x && p.x < b.x && p.x < c.x ) return false; + if ( p.x > a.x && p.x > b.x && p.x > c.x ) return false; + if ( p.y < a.y && p.y < b.y && p.y < c.y ) return false; + if ( p.y > a.y && p.y > b.y && p.y > c.y ) return false; + + if ( a.x > b.x ) Swap(a,b); + if ( a.x > c.x ) Swap(a,c); + if ( c.x < a.x ) Swap(c,a); + if ( c.x < b.x ) Swap(c,b); + + n = MidPoint(a, b, p.x); + m = MidPoint(a, c, p.x); + if ( (n>p.y||p.y>m) && (np.y||p.y>m) && (n= 100 ) break; + } + } + + sum.x = 0; + sum.y = 0; + sum.z = 0; + for ( j=0 ; j 0.1f || + Abs(n1.y-n2.y) > 0.1f || + Abs(n1.z-n2.z) > 0.1f ) return false; + + dist = DistancePlanPoint(plan1[0], plan1[1], plan1[2], plan2[0]); + if ( dist > 0.1f ) return false; + + return true; +} + + +// Calculates the matrix to make three rotations in the X, Y and Z +// >>>>>> OPTIMIZING!!! + +void MatRotateXZY(D3DMATRIX &mat, D3DVECTOR angle) +{ + D3DMATRIX temp; + + D3DUtil_SetRotateXMatrix(temp, angle.x); + D3DUtil_SetRotateZMatrix(mat, angle.z); + D3DMath_MatrixMultiply(mat, mat, temp); + D3DUtil_SetRotateYMatrix(temp, angle.y); + D3DMath_MatrixMultiply(mat, mat, temp); // X-Z-Y +} + +// Calculates the matrix to make three rotations in the order Z, X and Y. +// >>>>>> OPTIMIZING!!! + +void MatRotateZXY(D3DMATRIX &mat, D3DVECTOR angle) +{ + D3DMATRIX temp; + + D3DUtil_SetRotateZMatrix(temp, angle.z); + D3DUtil_SetRotateXMatrix(mat, angle.x); + D3DMath_MatrixMultiply(mat, mat, temp); + D3DUtil_SetRotateYMatrix(temp, angle.y); + D3DMath_MatrixMultiply(mat, mat, temp); // Z-X-Y +} + + +// Returns a random value between 0 and 1. + +float Rand() +{ + return (float)rand()/RAND_MAX; +} + + +// Managing the dead zone of a joystick. + +// in: -1 0 1 +// --|-------|----o----|-------|--> +// <----> +// dead +// out: -1 0 0 1 + +float Neutral(float value, float dead) +{ + if ( Abs(value) <= dead ) + { + return 0.0f; + } + else + { + if ( value > 0.0f ) return (value-dead)/(1.0f-dead); + else return (value+dead)/(1.0f-dead); + } +} + + +// Calculates a value (radians) proportional between a and b (degrees). + +float Prop(int a, int b, float p) +{ + float aa, bb; + + aa = (float)a*MATH3D_PI/180.0f; + bb = (float)b*MATH3D_PI/180.0f; + + return aa+p*(bb-aa); +} + +// Gently advanced a desired value from its current value. +// Over time, the greater the progression is rapid. + +float Smooth(float actual, float hope, float time) +{ + float futur; + + futur = actual + (hope-actual)*time; + + if ( hope > actual ) + { + if ( futur > hope ) futur = hope; + } + if ( hope < actual ) + { + if ( futur < hope ) futur = hope; + } + + return futur; +} + + +// Bounces any movement. + +// out +// | +// 1+------o-------o--- +// | o | o o | | bounce +// | o | o---|--- +// | o | | +// | o | | +// -o------|-------+----> progress +// 0| | 1 +// |<---->|middle + +float Bounce(float progress, float middle, float bounce) +{ + if ( progress < middle ) + { + progress = progress/middle; // 0..1 + return 0.5f+sinf(progress*MATH3D_PI-MATH3D_PI/2.0f)/2.0f; + } + else + { + progress = (progress-middle)/(1.0f-middle); // 0..1 + return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*MATH3D_PI)*(bounce/2.0f); + } +} + + +// Returns the color corresponding D3DCOLOR. + +D3DCOLOR RetColor(float intensity) +{ + D3DCOLOR color; + + if ( intensity <= 0.0f ) return 0x00000000; + if ( intensity >= 1.0f ) return 0xffffffff; + + color = (int)(intensity*255.0f)<<24; + color |= (int)(intensity*255.0f)<<16; + color |= (int)(intensity*255.0f)<<8; + color |= (int)(intensity*255.0f); + + return color; +} + +// Returns the color corresponding D3DCOLOR. + +D3DCOLOR RetColor(D3DCOLORVALUE intensity) +{ + D3DCOLOR color; + + color = (int)(intensity.a*255.0f)<<24; + color |= (int)(intensity.r*255.0f)<<16; + color |= (int)(intensity.g*255.0f)<<8; + color |= (int)(intensity.b*255.0f); + + return color; +} + +// Returns the color corresponding D3DCOLORVALUE. + +D3DCOLORVALUE RetColor(D3DCOLOR intensity) +{ + D3DCOLORVALUE color; + + color.r = (float)((intensity>>16)&0xff)/256.0f; + color.g = (float)((intensity>>8 )&0xff)/256.0f; + color.b = (float)((intensity>>0 )&0xff)/256.0f; + color.a = (float)((intensity>>24)&0xff)/256.0f; + + return color; +} + + +// RGB to HSV conversion. + +void RGB2HSV(D3DCOLORVALUE src, ColorHSV &dest) +{ + float min, max, delta; + + min = Min(src.r, src.g, src.b); + max = Max(src.r, src.g, src.b); + + dest.v = max; // intensity + + if ( max == 0.0f ) + { + dest.s = 0.0f; // saturation + dest.h = 0.0f; // undefined color! + } + else + { + delta = max-min; + dest.s = delta/max; // saturation + + if ( src.r == max ) // between yellow & magenta + { + dest.h = (src.g-src.b)/delta; + } + else if ( src.g == max ) // between cyan & yellow + { + dest.h = 2.0f+(src.b-src.r)/delta; + } + else // between magenta & cyan + { + dest.h = 4.0f+(src.r-src.g)/delta; + } + + dest.h *= 60.0f; // in degrees + if ( dest.h < 0.0f ) dest.h += 360.0f; + dest.h /= 360.0f; // 0..1 + } +} + +// HSV to RGB conversion. + +void HSV2RGB(ColorHSV src, D3DCOLORVALUE &dest) +{ + int i; + float f,v,p,q,t; + + src.h = Norm(src.h)*360.0f; + src.s = Norm(src.s); + src.v = Norm(src.v); + + if ( src.s == 0.0f ) // zero saturation? + { + dest.r = src.v; + dest.g = src.v; + dest.b = src.v; // gray + } + else + { + if ( src.h == 360.0f ) src.h = 0.0f; + src.h /= 60.0f; + i = (int)src.h; // integer part (0 .. 5) + f = src.h-i; // fractional part + + v = src.v; + p = src.v*(1.0f-src.s); + q = src.v*(1.0f-(src.s*f)); + t = src.v*(1.0f-(src.s*(1.0f-f))); + + switch (i) + { + case 0: dest.r=v; dest.g=t; dest.b=p; break; + case 1: dest.r=q; dest.g=v; dest.b=p; break; + case 2: dest.r=p; dest.g=v; dest.b=t; break; + case 3: dest.r=p; dest.g=q; dest.b=v; break; + case 4: dest.r=t; dest.g=p; dest.b=v; break; + case 5: dest.r=v; dest.g=p; dest.b=q; break; + } + } +} + -- cgit v1.2.3-1-g7c22