| 3305 | } |
| 3306 | |
| 3307 | MatrixF MeshRoad::getNodeTransform( U32 idx ) |
| 3308 | { |
| 3309 | MatrixF mat(true); |
| 3310 | |
| 3311 | if ( mNodes.size() - 1 < idx ) |
| 3312 | return mat; |
| 3313 | |
| 3314 | bool hasNext = idx + 1 < mNodes.size(); |
| 3315 | bool hasPrev = (S32)idx - 1 > 0; |
| 3316 | |
| 3317 | const MeshRoadNode &node = mNodes[idx]; |
| 3318 | |
| 3319 | VectorF fvec( 0, 1, 0 ); |
| 3320 | |
| 3321 | if ( hasNext ) |
| 3322 | { |
| 3323 | fvec = mNodes[idx+1].point - node.point; |
| 3324 | fvec.normalizeSafe(); |
| 3325 | } |
| 3326 | else if ( hasPrev ) |
| 3327 | { |
| 3328 | fvec = node.point - mNodes[idx-1].point; |
| 3329 | fvec.normalizeSafe(); |
| 3330 | } |
| 3331 | else |
| 3332 | fvec = mPerp( node.normal ); |
| 3333 | |
| 3334 | if ( fvec.isZero() ) |
| 3335 | fvec = mPerp( node.normal ); |
| 3336 | |
| 3337 | F32 dot = mDot( fvec, node.normal ); |
| 3338 | if ( dot < -0.9f || dot > 0.9f ) |
| 3339 | fvec = mPerp( node.normal ); |
| 3340 | |
| 3341 | VectorF rvec = mCross( fvec, node.normal ); |
| 3342 | if ( rvec.isZero() ) |
| 3343 | rvec = mPerp( fvec ); |
| 3344 | rvec.normalize(); |
| 3345 | |
| 3346 | fvec = mCross( node.normal, rvec ); |
| 3347 | fvec.normalize(); |
| 3348 | |
| 3349 | mat.setColumn( 0, rvec ); |
| 3350 | mat.setColumn( 1, fvec ); |
| 3351 | mat.setColumn( 2, node.normal ); |
| 3352 | mat.setColumn( 3, node.point ); |
| 3353 | |
| 3354 | AssertFatal( m_matF_determinant( mat ) != 0.0f, "no inverse!"); |
| 3355 | |
| 3356 | return mat; |
| 3357 | } |
| 3358 | |
| 3359 | void MeshRoad::calcSliceTransform( U32 idx, MatrixF &mat ) |
| 3360 | { |