BASIC
xMath API
XCAngle

XCVector
XCMatrix

Collision
XCPlane


- BASIC -

구좌표계(spherical coordinate)


- xMath API -

#define X_FCOS(X) fcos4096[X&(4095)]
#define X_FSIN(X) fsin4096[X&(4095)] 

inline floatxMath_COS(int iANG) {   return fcos4096[iANG&(4095)];   }
inline floatxMath_SIN(int iANG) {   return fsin4096[iANG&(4095)];   }

360도가 4096으로 단계가 변화되어 있다. 라운딩 처리가 define되어있으므로 따로 라운딩 처리할필요는 없다.

ex) cos(230)  ==> X_FCOS(230/360*4096)

 

inline int  xMath_ABS(int x){   int iRET; (x<0) ? iRET = -x : iRET = x; return iRET;}
inline floatxMath_FABS(float f) {   int iRetValue = *((int*)&f);iRetValue &= 0x7fffffff;return *((float*)&iRetValue);   }

float   xMath_SQRT(float fVAL);
 

xMath_MatrixMul(MF,M1,M2)
행렬M1 * 행렬M2 = 행렬 MF
xMath_VectorMultiflyWithMatrix(VOUT,M,VIN)
행렬 M * 벡터 VIN = 벡터 VOUT
xMath_VectorMultiflyWithMatrix_Array(aVOUT,M,aVIN,nVER)
행렬 M * 벡터들 aVIN ( nVER 벡터 갯수 ) = 벡터들 aVOUT
xMath_VectorMultiflyWithMatrixOnlyRotate(VOUT,M,VIN)
행렬 M * 벡터 VIN = 벡터 VOUT
xMath_VectorMultiflyWithMatrixOnlyRotate_Array(aVOUT,M,aVIN,nVER)
행렬 M( 회전성분만 ) * 벡터들 aVIN ( nVER 벡터 갯수 ) = 벡터들 aVOUT

bool    xMath_GetEdgeVSSphereCollisionInfo(const XCPoint& PS,const XCPoint& PCSphere,const XCVector& VRAY,float fRayLength,float fRadius,XCPoint* pPHit,XCPoint* pPEnd,float* pfSeparation,bool bCalcHitPoint);
레이와 구 충돌 처리를 판단합니다.
Ray 시작점,Ray 끝점,Ray 방향 벡터,Ray의 길이,구의 반지름,되돌려지는 충돌지점,끝점,충돌점을 지나친 거리,충돌지점을 계산할것인가?
 

int     xMath_RandomExc(int x);
x값 미만의 렌덤값들을 구합니다.
float   xMath_RandomFloat(float fVAL);
fVAL 이하의 렌덤값들을 소수점 첫째짜리 까지의 정밀도로
구합니다.
int     xMath_RandomABS(int iVAL);
-iVAL -  +iVAL 까지의 렌덤값들을
구합니다.
int     xMath_RandomMINMAX(int iMIN,int iMAX);
iMIN - iMAX 까지의 렌덤값들을
구합니다.
int     xMath_Random();
렌던값을 구합니다.

bool    xMath_MoveLimitWithDiv(float& fVAR,float fLimit,float fDIV);
bool    xMath_MoveLimitWithAdd(float& fVAR,float fLimit,float fADD);
bool    xMath_InnerPoint(const
XCPoint& P,XCEdge** apEdge,const XCVector& VN,const XCVector& V1,const XCVector& V2,const XCVector& V3);

float   xMath_ProcessCollision(XCCollisionData& COLDATA,XCEdge** apEdge,bool bTwoFace,XCPlane& PLN,const XCVector& V1,const XCVector& V2,const XCVector& V3);

float   xMath_GetAngXZ(float fX,float fZ);
float   xMath_GetAngYZ(float fY,float fZ);
float   xMath_GetAngXZFixedLen(float fX,float fZ,float fRow);
void    xMath_GetAngXYZ(float fX,float fY,float fZ,int* piTheta,int* piPhi);
void    xMath_GetAngXYZFixedLen(float fX,float fY,float fZ,int* iTheta,int* piPhi,float fLEN);

bool    xMath_ShortestDistanceTwo3DLine(const XCPoint& P1,const XCPoint& P2,const XCPoint& P3,const XCPoint& P4,XCPoint* pPRet1,XCPoint* pPRet2,float* pf1,float* pf2);
bool    xMath_IsCloseTwo3DLine(const
XCPoint& P1,const XCPoint& P2,const XCPoint& P3,const XCPoint& P4,float fNEARLEN);

void    xMath_GetAxisRotatedVector(const XCVector& VS,const XCVector& VAxis,XCVector* pDV,int iANG);
   VS 벡터를 VAxis 축으로 iANG 만큼 회전시킨 벡터를 pDV로 구해줍니다.

float   xMath_GetLength(const
XCVector& VS,const XCVector& VE);
   두벡터 사이의 거리를 얻는다.

float   xMath_GetDoubleLength(const
XCVector& VS,const XCVector& VE);
   두벡터 사이의 거리의 제곱을 얻는다.

 


- XCAngle -

class XCAngle
{
public:
union{
struct{ int
iTHETA,iPHI,iBR;   };
struct{ int m_iYaw,m_iPitch,m_iRoll;    };
};
.....
};

각도는 0-4096도로 해상도를 올려서 쓴다. 1024가 90도.


- XCVector -

XCVector(float fX, float fY, float fZ) { x = fX; y = fY; z = fZ; }
XCVector(float fVAL) { x = fVAL; y = fVAL; z = fVAL; }

void Set(float fX,float fY,float fZ) { x = fX; y = fY; z = fZ; }
void Set(float fVAL) { x = fVAL; y = fVAL; z = fVAL; }

float Normalize();
단위 벡터를 만들고 그 길이를 되돌려줍니다.
float Normalize(float fLEN); 주어진 인자만큼의 길이를 가진 벡터를 만들어줍니다.
float NormalizeDouble(float fLEN); 루트를 취하지 않은 더블 길이의 노말 벡터를 만들어줍니다.

void RotateX(int
iPHI); X축으로 회전
void RotateY(int iTHETA); Y축 회전
void RotateZ(int iBR); Z축 회전

void RotateXY(int
iPHI,int iTHETA); X,Y축 순으로 회전.
void RotateZXY(int iBR,int iPHI,int iTHETA); Z,X,Y 축으로 회전.
void RotateZXY(XCAngle& ANG); 구좌표계 값을 가지고 회전

void RotateZXYDest(int
iBR,int iPHI,int iTHETA,XCVector& VD) const;Z->X->Y 회전한뒤 VD 에 값을 넣어 줍니다
void RotateZX(int iBR,int iPHI); Z,X 순으로 회전.
void RotateZXDest(int iBR,int iPHI,XCVector& VD) const;Z,X 순으로 회전 시킨 다음 VD에 넣어줍니다.
void RotateXZ(int iPHI,int iBR); X,Z 순으로 회전
void RotateXZ(int iPHI,int iBR,XCVector& VD ) const;X,Z 순으로 회전 시킨 다음 VD에 넣어줍니다.
void RotateYXZ(int iTHETA,int iPHI,int iBR); Y,X,Z 순으로 회전
void RotateYXZDest(int iTHETA,int iPHI,int iBR,XCVector& VD) const;Y,X,Z 순으로 회전 시킨다음에 VD에 넣어줍니다.

void GetMIN(XCPoint& PMIN) const;
PMIN보다 적으면 PMIN으로 값을 되돌립니다.
void GetMAX(XCPoint& PMAX) const; PMAX보다 크면 PMAX로 값을 되돌립니다.
void GetMINMAX(XCPoint& PMIN, XCPoint& PMAX) const;PMIN보다 작거나 PMAX보다 크면 값을 되돌립니다.

float GetDoubleLength() const;
루트를 취하지 않은 길이를 구합니다.
float GetLength() const; 길이를 구합니다.
float GetAverage() const; 평균치를 구합니다.
void SetMaximize(); 3변수중에 가장 큰수를 구하고 그 수를 3변수로 취합니다.

float MakeNormalVector(const XCVector& V1,const XCVector& V2,const XCVector& V3);
세점으로 이루어진 평면의 노말 벡터를 구합니다. D 값 리턴!
float MakeUnitNormalVector(const XCVector& V1,const XCVector& V2,const XCVector& V3);
세점으로 이루어진 평면의 Unit 노말 벡터를 구합니다. D 값 리턴!


XCVector operator%(const XCVector& V) const;
외적
float operator^(const XCVector& V) const;
내적

void MakeVectorWithSphereCoordinate(int iPHI,int
iTHETA,float fRho); 구좌표 회전각을 가지고 벡터를 구축합니다.
void MakeVectorWithSphereCoordinate(int iTHETA,int fRho);

void TransposeYZ();
y와 z를 교환 합니다.
void TransposeXY();x와 y를 교환 합니다.
void Inverse() { x = 1/x; y = 1/y; z = 1/z; }역수 취함
float GetAmount() const { return (x + y + z); }총합을 구합니다.


- XCMatrix -

void SetPosition(const XCPoint& P);

float&        operator()(int iRow, int iColumn) { return mm[iRow][iColumn]; }    
해당 위치의 값을 돌려 줍니다.
const float&  operator()(int iRow, int iColumn) const { return mm[iRow][iColumn]; }  
해당 위치의 값을 돌려 줍니다.
XCMatrix&     operator=(const XCMatrix& M); 
XCMatrix&     operator=(const XCMatrix4X3& M);  

bool operator!=(const
XCMatrix& M) const ;  
bool operator==(const
XCMatrix
& M) const;   

XCVector operator*(const XCVector& V) const;
XCMatrix operator*(const XCMatrix &M) const;

void    Identity(); 
void    Clear();
void    ClearExtra(){   _14 = 0; _24 = 0; _34 = 0;  _44 = 1;}
void    IdentityOnlyRotateAxis(){   _11 = 1; _12 = 0; _13 = 0; _14 = 0; _21 = 0; _22 = 1; _23 = 0; _24 = 0; _31 = 0; _32 = 0; _33 = 1; _34 = 0; }

XCPoint*    GetPtrPosition(){   return &m_VT;   }
const
XCPoint
* GetPtrPosition() const   {   return &m_VT;   }

void    RotateZ(int iTHETA);    월드 Z축 회전
void    RotateX(int
iPHI);      월드 X축 회전
void    RotateY(int
iBR);       월드 Z축 회전

void    RotateZNoTranslate(int iBR);
void    RotateXNoTranslate(int
iPHI);   
void    RotateYNoTranslate(int
iTHETA);

void    RotateZLocalNoTranslateUnit(int iBR);       로칼 Z축 회전
void    RotateXLocalNoTranslateUnit(int
iPHI);      로칼 X축 회전
void    RotateYLocalNoTranslateUnit(int
iTHETA);    로칼 Y축 회전

void    RotateYaw(int iTHETA) { RotateY(iTHETA); }    월드의 원점을 중심으로 Y축으로 회전합니다.
void    RotateRoll(int
iBR) { RotateZ(iBR); }         월드의 원점을 중심으로 Z축으로 회전합니다.
void    RotatePitch(int iPHI) { RotateX(iPHI); }      월드의 원점을 중심으로 X축으로 회전합니다.

void    RotateYawNoTranslate(int
iTHETA) { RotateYNoTranslate(iTHETA); }
m_VT를 중심으로 월드의Y축으로 회전합니다. NoTranslate는 위치변화가 없다는 말.
void    RotateRollNoTranslate(int
iBR) { RotateZNoTranslate(iBR); }
m_VT를 중심으로 월드의Z축으로 회전합니다. NoTranslate는 위치변화가 없다는 말.
void    RotatePitchNoTranslate(int iPHI) { RotateXNoTranslate(iPHI); }
m_VT를 중심으로 월드의X축으로 회전합니다. NoTranslate는 위치변화가 없다는 말.

void    RotateYawLocalNoTranslateUnit(int
iTHETA) { RotateYLocalNoTranslateUnit(iTHETA);}
m_VT를 중심으로 m_VY축으로 회전합니다. NoTranslate는 위치변화가 없다는 말.
void    RotateRollLocalNoTranslateUnit(int
iBR) { RotateZLocalNoTranslateUnit(iBR); }
m_VT를 중심으로 m_VZ축으로 회전합니다. NoTranslate는 위치변화가 없다는 말.
void    RotatePitchLocalNoTranslateUnit(int iPHI) { RotateXLocalNoTranslateUnit(iPHI); }
m_VT를 중심으로 m_VX축으로 회전합니다. NoTranslate는 위치변화가 없다는 말.

void    MakeRotateXNoTranslate(int
iPHI);
void    MakeRotateYNoTranslate(int
iTHETA);
void    MakeRotateZNoTranslate(int
iBR);

void    MakeRotateZ(int iBR);                                 Z축으로 회전하는 행렬을 구성합니다.
void    MakeRotateX(int
iPHI);                                X축으로 회전하는 행렬을 구성합니다.
void    MakeRotateY(int
iTHETA);                              Y축으로 회전하는 행렬을 구성합니다.
void    MakeRotateZX(int
iBR,int iPHI);                       Z축,X축 으로 회전하는 행렬을 구성합니다. (순서대로 적용)
void    MakeRotateZXY(int
iBR,int iPHI,int iTHETA);           Z축,X축,Y축 으로 회전하는 행렬을 구성합니다. (순서대로 적용)    
void    MakeRotateZXYNoTranslate(int
iBR,int iPHI,int iTHETA);위의 함수와 다르게 이동 성분부분은 건드리지 않습니다.
void    MakeRotateZXY(const
XCAngle& ANG);                    인자로 구좌표계 형식을 받는다.(실지로 좌표게 변환을 적용하는게 아니라 단지 인자로만 사용합니다.)
void    MakeRotateZXYNoTranslate(const
XCAngle& ANG);         
위의 함수와 다르게 이동 성분부분은 건드리지 않습니다.

void    MakeRotateZXYTranslate(int iTHETA,int iPHI,int iBR,const XCVector& InV);
void    MakeRotateYXZTranslate(int
iBR,int iPHI,int iTHETA,const XCVector& InV);
void    MakeRotateXZTranslate(int
iPHI,int iTHETA,const XCVector& InV);
void    MakeRotateZTranslate(int
iTHETA,const XCVector& InV);

void    MakeRotateYX(int iTHETA,int iPHI);
void    MakeRotateXZ(int
iPHI,int iBR);
void    MakeRotateYXZ(int
iTHETA,int iPHI,int iBR);
void    MakeRotateXY(int
iPHI,int iTHETA);

void    Translate(const XCPoint& P);
void    Translate(float fX,float fY,float fZ);

bool    IsScaleFactor() const                   행렬에 스케일 성분이 있는가.
void    RemoveScalePreMultiplied();             행렬의 스케일 성분을 제거해줍니다.
void    RemoveScalePreMultiplied(
XCVector& V);  행렬의 스케일 성분을 제거하고 스케일 값을 인자로 구해낸다.
void    PreMultScale(const
XCVector &V);        행렬에 스케일 성분을 곱해줍니다.

void    MakeWorldMatrix(const XCPoint& PS,const XCPoint& PE);
void    MakeEasyInverseMatrix(const
XCMatrix& M);   
   
각축 성분에 스케일 성분이 없다고 가정할때 역행렬을 고속으로 구할수 있다.

void    MakeEasyInverseMatrix(const
XCVector& VX,const XCVector& VY,const XCVector& VZ,const XCVector& VT);

void    MakeTransposeDest(XCMatrix& MT) const;
XCMatrix    GetTranspose() const;
XCMatrix
   GetInversMatrix() const ;

void    MulOnlyRotate(const XCVector& VS,XCVector& VD); VS에 *this 행렬의 회전성분만 곱해서 VD로 출력합니다

void    UpdateVectorXY();
void    UpdateVectorXYZ();
void    UpdateZVectorWithPosition(const
XCPoint& P);
void    UpdateZVector(const
XCVector& V);
void    MakeLookAtLH(const
XCVector& VEYE,const XCVector& VAT,const XCVector& VUP);

void    MakeTranslate(float fX,float fY,float fZ);       주어진 공간좌표로 이동 행렬을 구성합니다.
void    MakeTranslate(const
XCVector& V);                주어진 벡터로 이동 행렬을 구성합니다.
void    ReplaceTranslate(const  
XCPoint& P);            
 행렬의 이동 부분을 대체합니다.

void    MakeTransform(float fX,float ifY,float ifZ,int iTHETA,int iPHI,int iBR);

void    LoadTXT(X_FILE hFILE);
void    LoadBINSimple(X_FILE hFILE);

void    MakeLinearInterpolated(const XCMatrix& MA,const XCMatrix& MB,float fAlpha);
void    MakeLinearInterpolated(const XCMatrix4X3& MA,const XCMatrix4X3& MB,float fAlpha);

void    MakeScale(float fVAL);
void    MakeScaleNoTranslate(float fVAL);
void    MakeScale(float fX,float fY,float fZ);
void    MakeScale(const
XCVector& VT);

void    MatMultPerfect(const XCMatrix &M);
void    MatMultM1xM2(const
XCMatrix& M1,const XCMatrix& M2);
void    MatMult4x3(const XCMatrix4X3& M1,const
XCMatrix& M2);
void    MatMult4x3(const XCMatrix4X3& M1,const XCMatrix4X3& M2);
void    MatMultDest(const
XCMatrix& M1,XCMatrix& M2) const;
void    MatMultOnlyRotate(const
XCMatrix& M1,const XCMatrix* M);
void    MatMult4x3(const
XCMatrix& M2);
void    MatMultOnlyRotate(const
XCMatrix
& M);

void    CopyOnlyRotate(const XCMatrix& M);

bool    IsOrthogonalYAxis();

void    LoadTXT(FILE* pFILE);
void    SaveTXT(FILE* pFILE) const;
void    SaveTXTInteger(FILE* pFILE) const;
void    SaveBINSimple(FILE* pFILE) const;

void    SetElement( int Row, int Column, float Value ); 
void    AfterVectorMul(const
XCPoint &P,XCPoint_4 &P4) const ;
void    AfterVectorMul(const
XCVector &V,XCVector& VD) const;
void    PreVectorMul(const
XCVector &V,XCVector& VD) const ;

void    GetAng(XCAngle* pANG) const;
void    DisplayAxis(float fLEN,const XCRGBA& RGBA);
void    MakeRotateMatrixWithPosition(const
XCPoint& P,const XCMatrix& MT);  

   P 포지션과 MT의 회전 성분만을 가지고 행렬을 만듭니다.

bool    IsZERO();
void    MakeBlockTCCoord(int iINDEX,int iTilingMul);
void    MakePerspectiveLH(float fFOVRadian,float fVHRatio,float fNear,float fFar);

void    MakeMirrorMatrix(const XCPoint& P1,const XCPoint& P2,const XCPoint& P3);
   
세 지점으로 이루어진 평면의 반사 행렬을 만듭니다.
void    MakeMirrorMatrix(const
XCVector& VN,float fD ); 
   
평면의 노말과 원점과의 거리로 반사 행렬을 만듭니다.


- Collision -

XCWorldInfo
   엔진에서 쓰이는 모델 데이터형들의 집합. 주로 데이터 역추적에 이용된다.
X_WORLD      m_hBlockModels;
X_MODEL      m_hModel;
X_SUBMODEL   m_hSubModel;
X_FACE       m_hFace;

XCCollisionDataInfo
   충돌 지점 하나에 대한 정보를 보유하고 있다.

   m_XCWorldInfo    m_WRLINFO 충돌 된 면의 정보. 역으로 추적하면 소유자 모델로 갈수 있다.

   XCPoint          m_PHitPoint;  충돌 지점

   XCVector         m_VN;     충돌된 면의 수직벡터
   
XCVector         m_VNX;    충돌된 면의 엣지벡터 ( 모서리 벡터 )


XCCollisionData
   직선과 면의 충돌에서 많은 면들과 교차된 충돌지점들을 보유하고 있다.

XCCollisionDataLink
   많은 구로 이루어진 충돌 링크 구조체.


- XCPlane -

XCPlaneSimple(const XCVector& VN,float fD)
VN 노말 벡터와 월드 중심 원점과의 최단거리 -fD로 평면 생성 합니다.
ex) 수면높이 100 짜리 물의 평면 방정식 ( Normal( 0,1,0) , -fD 최단거리 ( -100) = XCPlane(XCVector(0,1,0),-100) )

void SetNormalVector(const
XCVector& VN);    노말 벡터를 지정
void SetD(float fD); 원점과의 -(마이너스) 최단거리 지정
void Set(const XCVector& VN,float fD);VN 노말 벡터와 월드 중심 원점과의 최단거리 -fD로 평면 생성 합니다.

bool GetIntersectionPoint(
XCPoint* pRET,const XCPoint& SP,const XCPoint& EP);
SP(시점),EP(종점) 으로 이루어진 직선과 평면의 통과 지점을 pRET로 되돌립니다.

bool ProcessCollision(XCCollisionData* pCOLDATA);
충돌 처리
void CalculatePlaneEquation(const XCPoint& P1,const XCPoint& P2,const XCPoint& P3); 시계 방향의 세점을 가지고 평면 방정식 생성

XCVector* GetNormalVector() const; 노말 벡터를 구합니다.

float GetPlaneDistance(const
XCPoint& P) const;
점 P와 평면 방정식과의 거리를 구합니다. + - 로 평면의 앞뒤 판단을 할수 있습니다.

float GetYWithXZ(float fX,float fZ) const; 
X,Z 좌표로 Y좌표를 구해냅니다.
void GetShortestVector(const XCPoint& PT,XCVector* pV); PT에서 면으로의 최단거리의 벡터를 pV로 구해냅니다.(fD 길이를 반영한 벡터)