| 2057 | } |
| 2058 | |
| 2059 | MatrixF River::getNodeTransform( U32 idx ) const |
| 2060 | { |
| 2061 | MatrixF mat(true); |
| 2062 | |
| 2063 | if ( mNodes.size() - 1 < idx ) |
| 2064 | return mat; |
| 2065 | |
| 2066 | bool hasNext = idx + 1 < mNodes.size(); |
| 2067 | bool hasPrev = (S32)idx - 1 >= 0; |
| 2068 | |
| 2069 | const RiverNode &node = mNodes[idx]; |
| 2070 | |
| 2071 | VectorF fvec( 0, 1, 0 ); |
| 2072 | |
| 2073 | if ( hasNext ) |
| 2074 | { |
| 2075 | fvec = mNodes[idx+1].point - node.point; |
| 2076 | fvec.normalizeSafe(); |
| 2077 | } |
| 2078 | else if ( hasPrev ) |
| 2079 | { |
| 2080 | fvec = node.point - mNodes[idx-1].point; |
| 2081 | fvec.normalizeSafe(); |
| 2082 | } |
| 2083 | else |
| 2084 | fvec = mPerp( node.normal ); |
| 2085 | |
| 2086 | if ( fvec.isZero() ) |
| 2087 | fvec = mPerp( node.normal ); |
| 2088 | |
| 2089 | F32 dot = mDot( fvec, node.normal ); |
| 2090 | if ( dot < -0.9f || dot > 0.9f ) |
| 2091 | fvec = mPerp( node.normal ); |
| 2092 | |
| 2093 | VectorF rvec = mCross( fvec, node.normal ); |
| 2094 | if ( rvec.isZero() ) |
| 2095 | rvec = mPerp( fvec ); |
| 2096 | rvec.normalize(); |
| 2097 | |
| 2098 | fvec = mCross( node.normal, rvec ); |
| 2099 | fvec.normalize(); |
| 2100 | |
| 2101 | mat.setColumn( 0, rvec ); |
| 2102 | mat.setColumn( 1, fvec ); |
| 2103 | mat.setColumn( 2, node.normal ); |
| 2104 | mat.setColumn( 3, node.point ); |
| 2105 | |
| 2106 | AssertFatal( m_matF_determinant( mat ) != 0.0f, "no inverse!"); |
| 2107 | |
| 2108 | return mat; |
| 2109 | } |
| 2110 | |
| 2111 | void River::deleteNode( U32 idx ) |
| 2112 | { |
no test coverage detected