//---------------------------------------------------------------------------- // // ROUTINE: CHoverMovementModifier::Update() // // PURPOSE: Try to smooth the path within limits so that we don't snap on // stairs. Otherwise just // //---------------------------------------------------------------------------- LTVector CHoverMovementModifier::Update( HOBJECT hObject, const LTVector& vDims, const LTVector& vOldPos, const LTVector& vNewPos, AIVolume* pLastVolume ) { // Get the position the AI is really at -- that is, the new X and Z, with // the OLD positions Y const LTVector vTruePos = LTVector( vNewPos.x, vOldPos.y, vNewPos.z); LTVector vFinalPosition = vTruePos; // Find the distance down to the new position the AI would be popped to. float flLowerBound = GetLowerBound( hObject, m_cCheckDist, vDims, vTruePos ); // Find the DIFFERENCE between the heights. If it is less than +-X, then // drift in that direction. If it is greater, then snap to the max // distance away that is allowed float flDifference = (float)fabs( flLowerBound - vOldPos.y ); if ( flDifference != 0.0f ) { if ( flDifference <= m_cMaxVerticalDifference ) { // Attempt to make the path a little bit smoother by adjusting // the position a bit more slowly LTVector vHorizontalMovement = vNewPos - vOldPos; vHorizontalMovement.y = 0; vFinalPosition.y = Interpolate( vOldPos.y, flLowerBound, vHorizontalMovement.Mag() ); } else { vFinalPosition.y = Snap( vOldPos.y, flLowerBound, flDifference ); } } return vFinalPosition; }
__forceinline __checkReturn bool GetLowerBound(__in_opt const TYPE* root, __inout const TYPE** node) { const TYPE* _node = GetLowerBound(root); if (_node) { *node = _node; return true; } return false; }
/** * バウンダリをマトリクスをかけて再計算 * @param matrix [IN] マトリクス */ void nxBoundary::MulMatrix4(nxMatrix4 &matrix) { nxVector4 point[8]; float p[3]; float s[3]; GetLowerBound(p[0], p[1], p[2]); GetDimension(s[0], s[1], s[2]); /* バウンダリの端点 */ point[0].Set(p[0] , p[1] , p[2] , 1.0f); point[1].Set(p[0] + s[0], p[1] , p[2] , 1.0f); point[2].Set(p[0] + s[0], p[1] + s[1], p[2] , 1.0f); point[3].Set(p[0] , p[1] + s[1], p[2] , 1.0f); point[4].Set(p[0] , p[1] , p[2] + s[2], 1.0f); point[5].Set(p[0] + s[0], p[1] , p[2] + s[2], 1.0f); point[6].Set(p[0] + s[0], p[1] + s[1], p[2] + s[2], 1.0f); point[7].Set(p[0] , p[1] + s[1], p[2] + s[2], 1.0f); /* マトリクスをかけてバウンダリ計算 */ nxVector4 r; float minVal[3]; float maxVal[3]; /* 点0で初期化 */ matrix.MulVector4(r, point[0]); minVal[0] = maxVal[0] = r.v[0]; minVal[1] = maxVal[1] = r.v[1]; minVal[2] = maxVal[2] = r.v[2]; /* LowerBound, HigherBound計算 */ for (int i = 1; i < 8; i++) { matrix.MulVector4(r, point[i]); for (int i = 0; i < 3; i++) { minVal[i] = r.v[i] < minVal[i] ? r.v[i] : minVal[i]; maxVal[i] = r.v[i] > maxVal[i] ? r.v[i] : maxVal[i]; } } /* バウンダリ値保存 */ for (int i = 0; i < 3; i++) { lowerBound.v[i] = minVal[i]; dimension.v[i] = maxVal[i] - minVal[i]; } }
__forceinline __checkReturn bool GetFirst( __out TYPE** val ) { TYPE* _val = GetLowerBound(); if (_val) { RTL_BALANCED_LINKS* node_or_parent = NULL; (void)Find(_val, val, &node_or_parent); m_iterator = node_or_parent; return true; } return false; }
/** * @brief マトリクスをかけて、和の領域を求める * @param rhs [IN] 和をもとめる対象のバウンダリん * @param matrix [IN] */ void nxBoundary::Or(nxBoundary &rhs, nxMatrix4 &matrix) { nxVector4 rhsPoint[8]; float p[3]; float s[3]; rhs.GetLowerBound(p[0], p[1], p[2]); rhs.GetDimension(s[0], s[1], s[2]); /* バウンダリの端点 */ rhsPoint[0].Set(p[0] , p[1] , p[2] , 1.0f); rhsPoint[1].Set(p[0] + s[0], p[1] , p[2] , 1.0f); rhsPoint[2].Set(p[0] + s[0], p[1] + s[1], p[2] , 1.0f); rhsPoint[3].Set(p[0] , p[1] + s[1], p[2] , 1.0f); rhsPoint[4].Set(p[0] , p[1] , p[2] + s[2], 1.0f); rhsPoint[5].Set(p[0] + s[0], p[1] , p[2] + s[2], 1.0f); rhsPoint[6].Set(p[0] + s[0], p[1] + s[1], p[2] + s[2], 1.0f); rhsPoint[7].Set(p[0] , p[1] + s[1], p[2] + s[2], 1.0f); /* マトリクスをかけてバウンダリ計算 */ nxVector4 r; float minVal[3]; float maxVal[3]; GetLowerBound(minVal[0], minVal[1], minVal[2]); GetHigherBound(maxVal[0], maxVal[1], maxVal[2]); for (int i = 0; i < 8; i++) { matrix.MulVector4(r, rhsPoint[i]); for (int i = 0; i < 3; i++) { minVal[i] = r.v[i] < minVal[i] ? r.v[i] : minVal[i]; maxVal[i] = r.v[i] > maxVal[i] ? r.v[i] : maxVal[i]; } } for (int i = 0; i < 3; i++) { lowerBound.v[i] = minVal[i]; dimension.v[i] = maxVal[i] - minVal[i]; } }
//m$ implementation ==> MiGetNextNode __checkReturn bool GetNext( __inout const TYPE** node ) { if (node && *node) { const TYPE* next; if (next = RightChild(*node)) return GetLowerBound(next, node); next = Parent(*node); for (const void* child = *node; next && next != child; next = Parent(child)) { if (RightChild(next) != child) { *node = next; return true; } child = next; } } return false; }
~CAVL() { const AVL_NODE<TYPE>* element; while (GetLowerBound(GetRoot(), &element)) Remove(&element->Value); }