00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_EDGE_COLLIDE_H
00027 #define NL_EDGE_COLLIDE_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/vector_2f.h"
00031
00032
00033 namespace NLPACS
00034 {
00035
00036
00037 using NLMISC::CVector2f;
00038
00039
00040
00041
00048 class CInt128
00049 {
00050 public:
00051 sint64 High;
00052 sint64 Low;
00053
00054 public:
00055
00057 void setMul(sint64 a, sint64 b)
00058 {
00059
00060 sint sgn=0;
00061 if(a<0)
00062 sgn++, a=-a;
00063 if(b<0)
00064 sgn--, b=-b;
00065
00066
00067
00068 uint64 high, low, hl1, hl2, oldLow;
00069 uint32 mask32= 0xFFFFFFFF;
00070 high= (a>>32) * (b>>32);
00071 low= (a&mask32) * (b&mask32);
00072 hl1= (a&mask32) * (b>>32);
00073 hl2= (a>>32) * (b&mask32);
00074
00075 oldLow= low;
00076 low+= (hl1&mask32) << 32;
00077 if(low<oldLow)
00078 high++;
00079 high+= (hl1>>32);
00080
00081 oldLow= low;
00082 low+= (hl2&mask32) << 32;
00083 if(low<oldLow)
00084 high++;
00085 high+= (hl2>>32);
00086
00087
00088
00089 High= high;
00090 Low= low;
00091 if(sgn!=0)
00092 {
00093 High= -High;
00094 Low= -Low;
00095 }
00096 }
00097
00099 bool operator<(const CInt128 &o) const
00100 {
00101 if(High!=o.High)
00102 return High<o.High;
00103 else
00104 return Low<o.Low;
00105 }
00106
00108 bool operator==(const CInt128 &o) const
00109 {
00110 return High==o.High && Low==o.Low;
00111 }
00112
00113 };
00114
00115
00116
00123 class CRational64
00124 {
00125 public:
00127 sint64 Numerator;
00129 sint64 Denominator;
00130
00131
00132 public:
00133
00134 CRational64() {}
00135 CRational64(sint64 a) : Numerator(a), Denominator(1) {}
00136 CRational64(sint64 num, sint64 den)
00137 {
00138 if(den>0)
00139 {
00140 Numerator= num;
00141 Denominator= den;
00142 }
00143 else
00144 {
00145 Numerator= -num;
00146 Denominator= -den;
00147 }
00148 }
00149
00151 bool operator<(const CRational64 &o) const
00152 {
00153 CInt128 n0, n1;
00154
00155 n0.setMul(Numerator, o.Denominator);
00156 n1.setMul(o.Numerator, Denominator);
00157 return n0<n1;
00158 }
00159
00161 bool operator==(const CRational64 &o) const
00162 {
00163 CInt128 n0, n1;
00164
00165 n0.setMul(Numerator, o.Denominator);
00166 n1.setMul(o.Numerator, Denominator);
00167 return n0==n1;
00168 }
00169
00170 };
00171
00172
00173
00180 class CEdgeCollide
00181 {
00182 public:
00183 enum TPointMoveProblem {ParallelEdges=0, StartOnEdge, StopOnEdge, TraverseEndPoint, EdgeNull, PointMoveProblemCount};
00184
00185
00186 public:
00187 CVector2f P0;
00188 CVector2f P1;
00189 CVector2f Dir, Norm;
00190 float A0, A1;
00191 float C;
00192
00193 public:
00194
00195 void make(const CVector2f &p0, const CVector2f &p1);
00196
00204 CRational64 testPointMove(const CVector2f &start, const CVector2f &end, TPointMoveProblem &moveBug);
00209 float testCircleMove(const CVector2f &start, const CVector2f &delta, float radius, CVector2f &normal);
00215 float testBBoxMove(const CVector2f &start, const CVector2f &delta, const CVector2f bbox[4], CVector2f &normal);
00220 bool testBBoxCollide(const CVector2f bbox[4]);
00221
00222
00223
00224 private:
00225
00229 bool testEdgeMove(const CVector2f &q0, const CVector2f &q1, const CVector2f &delta, float &tMin, float &tMax, bool &normalOnBox);
00230
00231 };
00232
00233
00234
00235 }
00236
00237
00238 #endif // NL_EDGE_COLLIDE_H
00239
00240