38 laCollisionDomain::laCollisionDomain(
void)
48 laPoint3 laCollisionDomain::normal(laPoint3 a, laPoint3 b, laPoint3 c)
54 normal[0] = v1.y()*v2.z() - v1.z()*v2.y();
55 normal[1] = v1.z()*v2.x() - v1.x()*v2.z();
56 normal[2] = v1.x()*v2.y() - v1.y()*v2.x();
58 double len = normal.lenght()*3.0;
59 normal = laPoint3(normal/len)*
M_UNIT;
66 void laCollisionDomain::optimize()
70 while( pNext && (pNext->countLines() == 0) )
71 pNext = pNext->nextDomain();
74 if(pNext) _pNextDomain->optimize();
77 void laCollisionDomain::addLine(laPoint3 a, laPoint3 b, laPoint3 normal,
rpgTrap* pTrap)
79 ASSERT( (_nLineCnt+1) < M_MAX_COLLISION_DOMAIN_SZ,
"Collision domain exceeds maximal size" );
83 _arLines[_nLineCnt] = ln;
84 _arNormals[_nLineCnt] = normal;
85 _arTrap[_nLineCnt] = pTrap;
90 void laCollisionDomain::addTriangle(
const laPoint3 &a,
const laPoint3 &b,
const laPoint3 &c,
rpgTrap* pTrap)
92 const double CollisionPathZ =
M_UNIT/2.0;
93 const double SmallDistance =
M_UNIT/20.0;
95 laPoint3 arTrianglePoints[3];
98 unsigned arLinePointIndexs[3];
99 unsigned nLinePoints=0;
102 arTrianglePoints[0] = _offset + a;
103 arTrianglePoints[1] = _offset + b;
104 arTrianglePoints[2] = _offset + c;
114 if(
M_ABS(arTrianglePoints[i].z()-CollisionPathZ) <= SmallDistance )
117 arLinePointIndexs[nLinePoints++] = i;
119 else if(arTrianglePoints[i].z() < CollisionPathZ) arSide[i] = -1;
124 if(
M_ABS(arSide[0]+arSide[1]+arSide[2])==3 )
return;
127 if( nLinePoints == 3 )
return;
130 if(nLinePoints == 2){
131 addLine(arTrianglePoints[arLinePointIndexs[0]],
132 arTrianglePoints[arLinePointIndexs[1]],
133 normal(a,b,c), pTrap);
141 if( (arSide[0]+arSide[1]+arSide[2]) !=0 )
return;
144 if(arLinePointIndexs[0]==0)
146 arLinePointIndexs[1] = 1;
147 arLinePointIndexs[2] = 2;
149 else if(arLinePointIndexs[0]==1)
151 arLinePointIndexs[1] = 0;
152 arLinePointIndexs[2] = 2;
154 else if(arLinePointIndexs[0]==2)
156 arLinePointIndexs[1] = 0;
157 arLinePointIndexs[2] = 1;
161 laPoint3 track_pt = arTrianglePoints[arLinePointIndexs[0]];
162 laPoint3 pt1 = arTrianglePoints[arLinePointIndexs[1]];
163 laPoint3 pt2 = arTrianglePoints[arLinePointIndexs[2]];
169 laLine2 edge_xz(laPoint3(pt1.x(), pt1.z()), laPoint3(pt2.x(), pt2.z()));
171 double k = edge_xz.getK_atY(CollisionPathZ);
172 double x = edge_xz.getX(k);
175 laLine2 edge_yz(laPoint3(pt1.y(), pt1.z()), laPoint3(pt2.y(), pt2.z()));
176 k = edge_yz.getK_atY(CollisionPathZ);
177 double y = edge_yz.getX(k);
180 addLine(track_pt, laPoint3(x, y), normal(a,b,c), pTrap);
191 if( arSide[0]+arSide[1] != 0)
193 arLinePointIndexs[0] = 2;
194 arLinePointIndexs[1] = 0;
195 arLinePointIndexs[2] = 1;
198 else if( arSide[0]+arSide[2] != 0)
200 arLinePointIndexs[0] = 1;
201 arLinePointIndexs[1] = 0;
202 arLinePointIndexs[2] = 2;
205 else if( arSide[1]+arSide[2] != 0)
207 arLinePointIndexs[0] = 0;
208 arLinePointIndexs[1] = 1;
209 arLinePointIndexs[2] = 2;
216 laPoint3 lone = arTrianglePoints[arLinePointIndexs[0]];
217 laPoint3 pt1 = arTrianglePoints[arLinePointIndexs[1]];
218 laPoint3 pt2 = arTrianglePoints[arLinePointIndexs[2]];
224 laLine2 edge1_xz(laPoint3(lone.x(), lone.z()), laPoint3(pt1.x(), pt1.z()));
225 laLine2 edge2_xz(laPoint3(lone.x(), lone.z()), laPoint3(pt2.x(), pt2.z()));
227 double k1 = edge1_xz.getK_atY(CollisionPathZ);
228 double k2 = edge2_xz.getK_atY(CollisionPathZ);
230 double x1 = edge1_xz.getX(k1);
231 double x2 = edge2_xz.getX(k2);
234 laLine2 edge1_yz(laPoint3(lone.y(), lone.z()), laPoint3(pt1.y(), pt1.z()));
235 laLine2 edge2_yz(laPoint3(lone.y(), lone.z()), laPoint3(pt2.y(), pt2.z()));
237 k1 = edge1_yz.getK_atY(CollisionPathZ);
238 k2 = edge2_yz.getK_atY(CollisionPathZ);
240 double y1 = edge1_yz.getX(k1);
241 double y2 = edge2_yz.getX(k2);
244 addLine(laPoint3(x1, y1), laPoint3(x2, y2), normal(a,b,c), pTrap);
248 void laCollisionDomain::updateBounds()
251 for(
unsigned i=0; i<_nLineCnt; i++) _rectBounds.
add( _arLines[i] );
256 void laCollisionDomain::draw(
laRenderer* r, laPoint3 ptBasePos)
265 for(
unsigned i=0; i<_nLineCnt; i++)
267 laLine2 ln(_arLines[i].origin - (
laPoint2)_offset, _arLines[i].origin - (
laPoint2)_offset + _arLines[i].vector);
268 laLine2 ln_normal(ln.origin + ln.vector*0.5, ln.origin + ln.vector*0.5 + _arNormals[i]*0.5);
271 r->styleSet(laColor(255,0,0));
275 r->styleSet(laColor(255,0,0));
276 ln_normal.draw(r, (
laPoint2)ptBasePos);
#define M_UNIT
Unit of 1 meter.
void add(const laPoint2 &p)
Revert to "uninitialized" state.
#define M_ABS(a)
Return abs(a)
Virtual interface for the Engine graphics renderer.