virtual bool ExternalCondition(const BevNodeInputParam& input) const { const BevInputData& inputData = input.GetRealDataType<BevInputData>(); f32 timeStep = inputData.m_TimeStep; Vec2 targetPoint2D = inputData.m_TargetPosition2D; Vec3 curPosition3D = inputData.m_Owner->GetPosition(); Vec2 curPosition2D(curPosition3D.x, curPosition3D.y); Vec2 dir = targetPoint2D - curPosition2D; if(Math::IsZero(dir.LengthSq())) { return true; } else { Vec2 curFacing = inputData.m_CurrentFacing; dir.Nomalize(); f32 dotValue = dir.DotProduct(curFacing); f32 angle = Math::ACos(Math::Clamp<f32>(dotValue, -1.f, 1.f)); if(angle < 0.1f) { return true; } else { return false; } } return false; }
virtual BevRunningStatus _DoExecute(const BevNodeInputParam& input, BevNodeOutputParam& output) { const BevInputData& inputData = input.GetRealDataType<BevInputData>(); BevOutputData& outputData = output.GetRealDataType<BevOutputData>(); f32 timeStep = inputData.m_TimeStep; Vec2 targetPoint2D = inputData.m_TargetPosition2D; Vec3 curPosition3D = inputData.m_Owner->GetPosition(); Vec2 curPosition2D(curPosition3D.x, curPosition3D.y); Vec2 dir = targetPoint2D - curPosition2D; if(Math::IsZero(dir.LengthSq())) { return k_BRS_Finish; } else { Vec2 curFacing = inputData.m_CurrentFacing; dir.Nomalize(); f32 dotValue = dir.DotProduct(curFacing); f32 angle = Math::ACos(Math::Clamp<f32>(dotValue, -1.f, 1.f)); if(angle < 0.1f) { outputData.m_NextFacing = dir; return k_BRS_Finish; } Vec3 vA(curFacing.x, curFacing.y, 0); Vec3 vB(dir.x, dir.y, 0); Vec3 vC = vA.CrossProduct(vB); f32 angleToTurn = Math::Min(timeStep * 3.f, angle); if(vC.z < 0) angleToTurn = -angleToTurn; Quat rotAxis( angleToTurn, Vec3::ZUNIT ); Vec3 ret = vA * rotAxis; outputData.m_NextFacing = Vec2(ret.x, ret.y); } return k_BRS_Executing; }