| 3357 | } |
| 3358 | |
| 3359 | void MeshRoad::calcSliceTransform( U32 idx, MatrixF &mat ) |
| 3360 | { |
| 3361 | if ( mSlices.size() - 1 < idx ) |
| 3362 | return; |
| 3363 | |
| 3364 | bool hasNext = idx + 1 < mSlices.size(); |
| 3365 | bool hasPrev = (S32)idx - 1 >= 0; |
| 3366 | |
| 3367 | const MeshRoadSlice &slice = mSlices[idx]; |
| 3368 | |
| 3369 | VectorF fvec( 0, 1, 0 ); |
| 3370 | |
| 3371 | if ( hasNext ) |
| 3372 | { |
| 3373 | fvec = mSlices[idx+1].p1 - slice.p1; |
| 3374 | fvec.normalizeSafe(); |
| 3375 | } |
| 3376 | else if ( hasPrev ) |
| 3377 | { |
| 3378 | fvec = slice.p1 - mSlices[idx-1].p1; |
| 3379 | fvec.normalizeSafe(); |
| 3380 | } |
| 3381 | else |
| 3382 | fvec = mPerp( slice.normal ); |
| 3383 | |
| 3384 | if ( fvec.isZero() ) |
| 3385 | fvec = mPerp( slice.normal ); |
| 3386 | |
| 3387 | F32 dot = mDot( fvec, slice.normal ); |
| 3388 | if ( dot < -0.9f || dot > 0.9f ) |
| 3389 | fvec = mPerp( slice.normal ); |
| 3390 | |
| 3391 | VectorF rvec = mCross( fvec, slice.normal ); |
| 3392 | if ( rvec.isZero() ) |
| 3393 | rvec = mPerp( fvec ); |
| 3394 | rvec.normalize(); |
| 3395 | |
| 3396 | fvec = mCross( slice.normal, rvec ); |
| 3397 | fvec.normalize(); |
| 3398 | |
| 3399 | mat.setColumn( 0, rvec ); |
| 3400 | mat.setColumn( 1, fvec ); |
| 3401 | mat.setColumn( 2, slice.normal ); |
| 3402 | mat.setColumn( 3, slice.p1 ); |
| 3403 | |
| 3404 | AssertFatal( m_matF_determinant( mat ) != 0.0f, "no inverse!"); |
| 3405 | } |
| 3406 | |
| 3407 | F32 MeshRoad::getRoadLength() const |
| 3408 | { |