/* =========================================================================== ARX FATALIS GPL Source Code Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company. This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code'). Arx Fatalis Source Code 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. Arx Fatalis Source Code 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 Arx Fatalis Source Code. If not, see . In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ ////////////////////////////////////////////////////////////////////////////////////// // @@ @@@ @@@ @@ @@@@@ // // @@@ @@@@@@ @@@ @@ @@@@ @@@ @@@ // // @@@ @@@@@@@ @@@ @@@@ @@@@ @@ @@@@ // // @@@ @@ @@@@ @@@ @@@@@ @@@@@@ @@@ @@@ // // @@@@@ @@ @@@@ @@@ @@@@@ @@@@@@@ @@@ @ @@@ // // @@@@@ @@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@ @@@@@@@ // // @@ @@@ @@ @@@@ @@@@@@@ @@@ @@@ @@@@@@ @@ @@@@ // // @@@ @@@ @@@ @@@@ @@@@@ @@@@@@@@@ @@@@@@@ @@@ @@@@ // // @@@ @@@@ @@@@@@@ @@@@@@ @@@ @@@@ @@@ @@@ @@@ @@@@ // // @@@@@@@@ @@@@@ @@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@@@ // // @@@ @@@@ @@@@ @@@ @@@@@@@ @@@ @@@ @@@@ @@@ @@@@ @@@@@ // //@@@ @@@@ @@@@@ @@@ @@@@@@ @@ @@@ @@@@ @@@@@@@ @@@@@ @@@@@ // //@@@ @@@@@ @@@@@ @@@@ @@@ @@ @@ @@@@ @@@@@@@ @@@@@@@@@ // //@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ // //@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@ // //@@@ @@@ @@@ @@@@@ @@ @@@ // // @@@ @@@ @@ @@ STUDIOS // ////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // EERIEMath /////////////////////////////////////////////////////////////////////////////// // // Description: // // Updates: (date) (person) (update) // // Code: Cyril Meynier // // Copyright (c) 1999 ARKANE Studios SA. All rights reserved /////////////////////////////////////////////////////////////////////////////// #ifndef EERIEMATH_H #define EERIEMATH_H #define D3D_OVERLOADS #include #include #include "EERIETypes.h" #include "EeriePoly.h" //----------------------------------------------------------------------------- // RANDOM Sequences Funcs/Defs //----------------------------------------------------------------------------- #define ornd() (((FLOAT)rand() ) / RAND_MAX) #define rnd() (((FLOAT)rand() ) * 0.00003051850947599f) //Approximative Methods #define EEsqrt(val) (float)ffsqrt(val) #define EEcos(val) (float)cos((float)val) #define EEsin(val) (float)sin((float)val) #define EEfabs(val) (float)fabs(val) #define EEatan(val) (float)atan(val) //True Methods #define TRUEsqrt(val) (float)sqrt(val) #define TRUEcos(val) (float)cos(val) #define TRUEsin(val) (float)sin(val) #define TRUEfabs(val) (float)fabs(val) #define TRUEatan(val) (float)atan(val) //----------------------------------------------------------------------------- // Math constants //----------------------------------------------------------------------------- #define EEdef_PI 3.14159265358979323846f // Pi #define EEdef_2_PI 6.28318530717958623200f // 2 * Pi #define EEdef_PI_DIV_2 1.57079632679489655800f // Pi / 2 #define EEdef_PI_DIV_4 0.78539816339744827900f // Pi / 4 #define EEdef_PI_0_75 4.7123889803846896397f //EEdef_2_PI-EEdef_PI_DIV_2 #define EEdef_DEGTORAD 0.01745329251994329547f // Degrees to Radians #define EEdef_RADTODEG 57.29577951308232286465f // Radians to Degrees #define EEdef_HUGE 1.0e+38f // Huge number for FLOAT #define EEdef_EPSILON 1.0e-5f // Tolerance for FLOATs #define EEdef_MAXfloat 1.0e+38f #define EEdef_MINfloat -1.0e+38f #define RAD2DEG(x) ((x)*(float)EEdef_RADTODEG) #define DEG2RAD(x) ((x)*(float)EEdef_DEGTORAD) //----------------------------------------------------------------------------- // DIVISIONS Optimization List (Mul) //----------------------------------------------------------------------------- #define DEUXTIERS 0.6666666666666666666667f #define DIV2 0.5f #define DIV3 0.3333333333333333333333f #define DIV4 0.25f #define DIV5 0.2f #define DIV6 0.1666666666666666666666f #define DIV7 0.1428571428571428571428f #define DIV8 0.125f #define DIV9 0.1111111111111111111111f #define DIV10 0.1f #define DIV11 0.0909090909090909090909f #define DIV12 0.0833333333333333333333f #define DIV13 0.0769230769230769230769f #define DIV14 0.0714285714285714285714f #define DIV15 0.0666666666666666666667f #define DIV16 0.0625f #define DIV17 0.0588235294117647058823f #define DIV18 0.0555555555555555555555f #define DIV19 0.0526315789473684210526f #define DIV20 0.05f #define DIV21 0.0476190476190476190476f #define DIV22 0.0454545454545454545454f #define DIV23 0.0434782608695652173913f #define DIV24 0.0416666666666666666667f #define DIV25 0.04f #define DIV26 0.0384615384615384615384f #define DIV27 0.0370370370370370370370f #define DIV28 0.0357142857142857142857f #define DIV29 0.0344827586206896551724f #define DIV30 0.0333333333333333333333f #define DIV32 0.03125f #define DIV40 0.025f #define DIV50 0.02f #define DIV60 0.0166666666666666666666f #define DIV64 0.015625f #define DIV70 0.0142857142857142857142f #define DIV80 0.0125f #define DIV90 0.0111111111111111111111f #define DIV100 0.01f #define DIV110 0.0090909090909090909090f #define DIV120 0.0083333333333333333333f #define DIV130 0.0076923076923076923076f #define DIV128 0.0078125f #define DIV140 0.0071428571428571428571f #define DIV150 0.0066666666666666666666f #define DIV160 0.00625f #define DIV170 0.0058823529411764705882f #define DIV180 0.0055555555555555555555f #define DIV190 0.0052631578947368421052f #define DIV200 0.005f #define DIV255 0.00392156862745098f #define DIV256 0.00390625f #define DIV300 0.0033333333333333333333f #define DIV384 0.0026041666666666666666f #define DIV400 0.0025f #define DIV480 0.0020833333333333333333f #define DIV500 0.002f #define DIV512 0.001953125f #define DIV600 0.0016666666666666666666f #define DIV640 0.0015625f #define DIV700 0.0014285714285714285714f #define DIV800 0.00125f #define DIV900 0.0011111111111111111111f #define DIV1000 0.001f #define DIV1024 0.0009765625f #define DIV2000 0.0005f #define DIV2048 0.00048828125f #define DIV3000 0.00033333333f #define DIV4000 0.00025f #define DIV4096 0.000244140625f #define DIV5000 0.0002f #define DIV10000 0.0001f #define DIV12000 0.0000833333333333333333f #define DIV13000 0.0000769230769230769231f #define DIV15000 0.0000666666666666666666f #define DIV16000 0.0000625f #define DIV18000 0.0000555555555555555555f #define DIV20000 0.00005f #define DIV32768 0.000030517578125f #define DIV100000 0.00001f #define DIVPI 0.318309886183790671537767526745029f #define ARXROTCONVERT 0.087890625f //----------------------------------------------------------------------------- __inline bool In3DBBoxTolerance(const EERIE_3D * pos, const EERIE_3D_BBOX * bbox, const float tolerance) { return ((pos->x >= bbox->min.x - tolerance) && (pos->x <= bbox->max.x + tolerance) && (pos->y >= bbox->min.y - tolerance) && (pos->y <= bbox->max.y + tolerance) && (pos->z >= bbox->min.z - tolerance) && (pos->z <= bbox->max.z + tolerance)); } extern EERIE_QUAT LocalUseQuat; extern float Eatan[]; extern float Esin[]; //----------------------------------------------------------------------------- __inline unsigned __int8 clipByte(int value) { value = (0 & (-(int)(value < 0))) | (value & (-(int)!(value < 0))); value = (255 & (-(int)(value > 255))) | (value & (-(int)!(value > 255))); return ARX_CLEAN_WARN_CAST_UCHAR(value); } __inline unsigned __int8 clipByte255(int value) { value = (255 & (-(int)(value > 255))) | (value & (-(int)!(value > 255))); return ARX_CLEAN_WARN_CAST_UCHAR(value); } long F2L_RoundUp(float val); void EERIEMathPrecalc(); void PrecalcATAN(); void PrecalcSIN(); BOOL PointInCylinder(const EERIE_CYLINDER * cyl, const EERIE_3D * pt); BOOL CylinderInCylinder(const EERIE_CYLINDER * cyl1, const EERIE_CYLINDER * cyl2); BOOL SphereInCylinder(const EERIE_CYLINDER * cyl1, const EERIE_SPHERE * s); // Optimized Float 2 Long Conversion __forceinline void F2L(const float f, long * l) { _asm { _asm fld f _asm mov eax, DWORD PTR [l] _asm fistp DWORD PTR [eax] } } __forceinline D3DCOLOR EERIERGB(float r, float g, float b) { long t[3]; F2L(r * 255.f, &t[0]); F2L(g * 255.f, &t[1]); F2L(b * 255.f, &t[2]); return (0xff000000L | (t[0] << 16) | (t[1] << 8) | t[2]); } __forceinline D3DCOLOR _EERIERGB(float v) { long t; F2L(v * 255.f, &t); return (0xff000000L | (t << 16) | (t << 8) | t); } __forceinline D3DCOLOR _EERIERGBA(float v) { long t; F2L(v * 255.f, &t); return (0x00000000L | (t << 24) | (t << 16) | (t << 8) | t); } #define EERIELRGB255(r,g,b) (0xff000000L | ( r << 16) | ( g << 8) | b); #ifdef ASSEMBLER_OPTIMS ////////////////////// extern float __mov; //__mov=x; #define FLOAT2LONG( x, l) __asm \ { \ __asm fld x \ __asm fistp l \ } #else ////////////////////// #define FLOAT2LONG(floatx,longx) \ longx = (long)floatx #endif float SSQRT(long a); float InterpolateAngle(float a1, float a2, float pour); //************************************************************************************* // Simple 2D Functions //************************************************************************************* float FORCEANGLE(float a); __inline float ffsqrt(float f) { unsigned int y = ((((unsigned int &)f) - 0x3f800000) >> 1) + 0x3f800000; // can repeat the following line 3 times for improved precision... return (float &)y; } #define FORCERANGE(a,b,c) if (ac) a=c; //************************************************************************************* // Rotations //************************************************************************************* __inline void _ZRotatePoint(EERIE_3D * in, EERIE_3D * out, float c, float s) { out->x = (in->x * c) + (in->y * s); out->y = (in->y * c) - (in->x * s); out->z = in->z; } __inline void _YRotatePoint(EERIE_3D * in, EERIE_3D * out, float c, float s) { out->x = (in->x * c) + (in->z * s); out->y = in->y; out->z = (in->z * c) - (in->x * s); } __inline void _XRotatePoint(EERIE_3D * in, EERIE_3D * out, float c, float s) { out->x = in->x; out->y = (in->y * c) - (in->z * s); out->z = (in->y * s) + (in->z * c); } //************************************************************************************* // Fuzzy compares (within tolerance) //************************************************************************************* #define EPSILON 0.000001f //************************************************************************************* // Init a vector if v1, v2 & v3 aren't given, init vector with 0s //************************************************************************************* inline void Vector_Init(EERIE_3D * dest, const float x, const float y, const float z) { dest->x = x; dest->y = y; dest->z = z; } //************************************************************************************* // Computes Length of a vector // WARNING: EEsqrt may use a approximative way of computing sqrt //************************************************************************************* inline float TRUEVector_Magnitude(const EERIE_3D * v) { return (float)TRUEsqrt(v->x * v->x + v->y * v->y + v->z * v->z); } inline float Vector_Magnitude(const EERIE_3D * v) { return (float)EEsqrt(v->x * v->x + v->y * v->y + v->z * v->z); } //************************************************************************************* // Normalizes a Vector. Returns its length before normalization //************************************************************************************* inline float Vector_Normalize(EERIE_3D * v) { register float len = Vector_Magnitude(v); register float l2 = 1.f / len; v->x *= l2; v->y *= l2; v->z *= l2; return len; } inline float TRUEVector_Normalize(EERIE_3D * v) { register float len = TRUEVector_Magnitude(v); register float l2 = 1.f / len; v->x *= l2; v->y *= l2; v->z *= l2; return len; } //******************************************************************************* // Matrix functions //******************************************************************************* void MatrixSetByVectors(EERIEMATRIX * m, const EERIE_3D * d, const EERIE_3D * u); void MatrixReset(EERIEMATRIX * mat); VOID MatrixMultiply(EERIEMATRIX * q, const EERIEMATRIX * a, const EERIEMATRIX * b); void VectorMatrixMultiply(EERIE_3D * vDest, const EERIE_3D * vSrc, const EERIEMATRIX * mat); #define VertexMatrixMultiply(a,b,c) VectorMatrixMultiply(a,b,c) void GenerateMatrixUsingVector(EERIEMATRIX * matrix, const EERIE_3D * vect, const float rollDegrees); float ffsqrt(float value); long isqrt(long value); //******************************************************************************* // Rotation Functions //******************************************************************************* __inline void _YXZRotatePoint(EERIE_3D * in, EERIE_3D * out, EERIE_CAMERA * cam) { register float tempy; out->z = (in->z * cam->Ycos) - (in->x * cam->Ysin); out->y = (in->x * cam->Ycos) + (in->z * cam->Ysin); tempy = (in->y * cam->Xcos) - (out->z * cam->Xsin); out->x = (out->y * cam->Zcos) + (tempy * cam->Zsin); out->y = (tempy * cam->Zcos) - (out->y * cam->Zsin); out->z = (in->y * cam->Xsin) + (out->z * cam->Xcos); } //************************************************************************************* // Fast normal rotation :p //************************************************************************************* __forceinline void _YXZRotateNorm(EERIE_3D * in, EERIE_3D * out, EERIE_CAMERA * cam) { out->z = (in->y * cam->Xsin) + (((in->z * cam->Ycos) - (in->x * cam->Ysin)) * cam->Xcos); } // QUATERNION Funcs/Defs //************************************************************************************* // Copy a quaternion into another //************************************************************************************* inline void Quat_Copy(EERIE_QUAT * dest, const EERIE_QUAT * src) { dest->x = src->x; dest->y = src->y; dest->z = src->z; dest->w = src->w; } //************************************************************************************* // Quaternion Initialization // quat -> quaternion to init //************************************************************************************* inline void Quat_Init(EERIE_QUAT * quat, const float x, const float y, const float z, const float w) { quat->x = x; quat->y = y; quat->z = z; quat->w = w; } // Transforms a Vertex by a matrix __inline void TransformVertexMatrix(EERIEMATRIX * mat, EERIE_3D * vertexin, EERIE_3D * vertexout) { vertexout->x = vertexin->x * mat->_11 + vertexin->y * mat->_21 + vertexin->z * mat->_31; vertexout->y = vertexin->x * mat->_12 + vertexin->y * mat->_22 + vertexin->z * mat->_32; vertexout->z = vertexin->x * mat->_13 + vertexin->y * mat->_23 + vertexin->z * mat->_33; } // Transforms a Vertex by a quaternion __inline void TransformVertexQuat(EERIE_QUAT * quat, EERIE_3D * vertexin, EERIE_3D * vertexout) { register float rx = vertexin->x * quat->w - vertexin->y * quat->z + vertexin->z * quat->y; register float ry = vertexin->y * quat->w - vertexin->z * quat->x + vertexin->x * quat->z; register float rz = vertexin->z * quat->w - vertexin->x * quat->y + vertexin->y * quat->x; register float rw = vertexin->x * quat->x + vertexin->y * quat->y + vertexin->z * quat->z; vertexout->x = quat->w * rx + quat->x * rw + quat->y * rz - quat->z * ry; vertexout->y = quat->w * ry + quat->y * rw + quat->z * rx - quat->x * rz; vertexout->z = quat->w * rz + quat->z * rw + quat->x * ry - quat->y * rx; } void TransformVertexQuat(const EERIE_QUAT * quat, const EERIE_3D * vertexin, EERIE_3D * vertexout); void TransformInverseVertexQuat(const EERIE_QUAT * quat, const EERIE_3D * vertexin, EERIE_3D * vertexout); void RotationFromQuat(EERIE_3D * v, FLOAT fTheta, const EERIE_QUAT * q); void QuatFromRotation(EERIE_QUAT * q, const EERIE_3D * v, const FLOAT fTheta); void Quat_Init(EERIE_QUAT * quat, const float x = 0, const float y = 0, const float z = 0, const float w = 1); void Quat_Divide(EERIE_QUAT * dest, const EERIE_QUAT * q1, const EERIE_QUAT * q2); void Quat_Multiply(EERIE_QUAT * dest , const EERIE_QUAT * q1, const EERIE_QUAT * q2); float Quat_Magnitude(EERIE_QUAT * q); void Quat_AxisRotate(EERIE_QUAT * quat, EERIE_3D * v, float ang); void Quat_Rotate(EERIE_QUAT * quat, EERIE_3D * angle); void Quat_Copy(EERIE_QUAT * q1, const EERIE_QUAT * q2); void Quat_Slerp(EERIE_QUAT * result, const EERIE_QUAT * from, EERIE_QUAT * to, float t); void Quat_Reverse(EERIE_QUAT * quat); void Quat_GetShortestArc(EERIE_QUAT * q1 , EERIE_QUAT * q2); //******************************************************************************* // VECTORS Functions //******************************************************************************* void Vector_Copy(EERIE_3D * dest, const EERIE_3D * src); void Vector_Init(EERIE_3D * dest, float v1 = 0.f, float v2 = 0.f, float v3 = 0.f); void Vector_Sub(EERIE_3D * dest, const EERIE_3D * v1, const EERIE_3D * v2); void Vector_Add(EERIE_3D * dest, const EERIE_3D * v1, const EERIE_3D * v2); void Vector_ScaleTo(EERIE_3D * dest, EERIE_3D * v, float scale); bool Vector_Compare(const EERIE_3D * v1, const EERIE_3D * v2); float Vector_Magnitude(const EERIE_3D * v); float Vector_Normalize(EERIE_3D * v); float TRUEVector_Magnitude(const EERIE_3D * v); float TRUEVector_Normalize(EERIE_3D * v); void Vector_CrossProduct(EERIE_3D * dest, const EERIE_3D * v1, const EERIE_3D * v2); float Vector_DotProduct(const EERIE_3D * v1, const EERIE_3D * v2); void Vector_RotateY(EERIE_3D * dest, const EERIE_3D * src, const float angle); void Vector_RotateZ(EERIE_3D * dest, const EERIE_3D * src, const float angle); void VRotateX(EERIE_3D * v1, const float angle); void VRotateY(EERIE_3D * v1, const float angle); void VRotateZ(EERIE_3D * v1, const float angle); void QuatFromMatrix(EERIE_QUAT & quat, EERIEMATRIX & mat); #define Vinit Vector_Init #define VrotY Vector_RotateY #define Vsub Vector_Sub #define Vadd Vector_Add #define Vcmp Vector_Compare #define Vcopy Vector_Copy #define Vinv Vector_Invert #define Vscale Vector_Scale #define Vscaleto Vector_ScaleTo #define Vcross Vector_CrossProduct #define Vdot Vector_DotProduct #define Vmag Vector_Magnitude #define Vnorm Vector_Normalize #define CROSS(dest,v1,v2) \ dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; #define DOTPRODUCT(v1,v2) (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z) #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define SUB(dest,v1,v2) \ dest[0]=v1[0]-v2[0]; \ dest[1]=v1[1]-v2[1]; \ dest[2]=v1[2]-v2[2]; inline float ScalarProduct(EERIE_3D * v0, EERIE_3D * v1) { return ((v0->x * v1->x) + (v0->y * v1->y) + (v0->z * v1->z)); } /* sort so that a<=b */ #define SORT(a,b) \ if(a>b) \ { \ float c; \ c=a; \ a=b; \ b=c; \ } #define ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1) \ isect0=VV0+(VV1-VV0)*D0/(D0-D1); \ isect1=VV0+(VV2-VV0)*D0/(D0-D2); void CalcFaceNormal(EERIEPOLY * ep, const D3DTLVERTEX * v); void CalcObjFaceNormal(const EERIE_3D * v0, const EERIE_3D * v1, const EERIE_3D * v2, EERIE_FACE * ef); void Triangle_ComputeBoundingBox(EERIE_3D_BBOX * bb, EERIE_3D * v0, EERIE_3D * v1, EERIE_3D * v2); BOOL Triangles_Intersect(const EERIE_TRI * v, const EERIE_TRI * u); void MatrixFromQuat(EERIEMATRIX * mat, const EERIE_QUAT * q); //******************************************************************************* // DISTANCES Functions //******************************************************************************* #define SquaredDistance2D(x0,y0,x1,y1) (float)( ((x1-x0)*(x1-x0)) +((y1-y0)*(y1-y0)) ) #define SquaredDistance3D(x0,y0,z0,x1,y1,z1) (float)( ((x1-x0)*(x1-x0)) +((y1-y0)*(y1-y0)) +((z1-z0)*(z1-z0)) ) __inline float EESquaredDistance3D(const EERIE_3D * from, const EERIE_3D * to) { return (float)(((to->x - from->x) * (to->x - from->x)) + ((to->y - from->y) * (to->y - from->y)) + ((to->z - from->z) * (to->z - from->z))); } #define Distance2D(x0,y0,x1,y1) (float)EEsqrt( ((x1-x0)*(x1-x0)) +((y1-y0)*(y1-y0)) ) #define Distance3D(x0,y0,z0,x1,y1,z1) (float)EEsqrt( ((x1-x0)*(x1-x0)) +((y1-y0)*(y1-y0)) +((z1-z0)*(z1-z0)) ) #define TRUEDistance2D(x0,y0,x1,y1) (float)TRUEsqrt( ((x1-x0)*(x1-x0)) +((y1-y0)*(y1-y0)) ) #define TRUEDistance3D(x0,y0,z0,x1,y1,z1) (float)TRUEsqrt( ((x1-x0)*(x1-x0)) +((y1-y0)*(y1-y0)) +((z1-z0)*(z1-z0)) ) __inline float TRUEEEDistance3D(const EERIE_3D * from, const EERIE_3D * to) { return (float)TRUEsqrt(((to->x - from->x) * (to->x - from->x)) + ((to->y - from->y) * (to->y - from->y)) + ((to->z - from->z) * (to->z - from->z))); } //************************************************************************************* // Compute Distance between two 3D points // WARNING: EEsqrt may use an approximative way of computing sqrt ! //************************************************************************************* __inline float EEDistance3D(const EERIE_3D * from, const EERIE_3D * to) { return (float)EEsqrt(((to->x - from->x) * (to->x - from->x)) + ((to->y - from->y) * (to->y - from->y)) + ((to->z - from->z) * (to->z - from->z))); } __inline BOOL PointInCylinder(const EERIE_CYLINDER * cyl, const EERIE_3D * pt) { register float pos1 = cyl->origin.y + cyl->height; if (pt->y < __min(cyl->origin.y, pos1)) return FALSE; if (pt->y > __max(cyl->origin.y, pos1)) return FALSE; if (Distance2D(cyl->origin.x, cyl->origin.z, pt->x, pt->z) <= cyl->radius) return TRUE; return FALSE; } __inline long PointInUnderCylinder(const EERIE_CYLINDER * cyl, const EERIE_3D * pt) { register float pos1 = cyl->origin.y + cyl->height; long ret = 2; if (pt->y < __min(cyl->origin.y, pos1)) return 0; if (pt->y > __max(cyl->origin.y, pos1)) ret = 1; if (Distance2D(cyl->origin.x, cyl->origin.z, pt->x, pt->z) <= cyl->radius) { return ret; } return 0; } //******************************************************************************* // ANGLES Functions //******************************************************************************* float GetAngle(const float x0, const float y0, const float x1, const float y1); float AngleDifference(float d, float e); __inline float MAKEANGLE(float a) { if (a >= 0) return a - 360 * (int)(a * 0.0027777777f); else return a + 360 * (1 + (int)(-a * 0.0027777777f)); } float GetNearestSnappedAngle(float angle); void QuatFromAngles(EERIE_QUAT * q, const EERIE_3D * angle); extern D3DMATRIX ProjectionMatrix; __forceinline void specialEE_RT(D3DTLVERTEX * in, EERIE_3D * out) { register EERIE_TRANSFORM * et = (EERIE_TRANSFORM *)&ACTIVECAM->transform; out->x = in->sx - et->posx; out->y = in->sy - et->posy; out->z = in->sz - et->posz; register float temp = (out->z * et->ycos) - (out->x * et->ysin); out->x = (out->z * et->ysin) + (out->x * et->ycos); out->z = (out->y * et->xsin) + (temp * et->xcos); out->y = (out->y * et->xcos) - (temp * et->xsin); } __forceinline void specialEE_P(EERIE_3D * in, D3DTLVERTEX * out) { register EERIE_TRANSFORM * et = (EERIE_TRANSFORM *)&ACTIVECAM->transform; float fZTemp = 1.f / in->z; out->sz = fZTemp * ProjectionMatrix._33 + ProjectionMatrix._43; out->sx = in->x * ProjectionMatrix._11 * fZTemp + et->xmod; out->sy = in->y * ProjectionMatrix._22 * fZTemp + et->ymod; out->rhw = fZTemp; } #endif