00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- 00002 00003 this file is part of rcssserver3D 00004 Fri May 9 2003 00005 Copyright (C) 2002,2003 Koblenz University 00006 Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group 00007 $Id: ballstateaspect.cpp,v 1.5 2004/03/23 10:40:52 rollmark Exp $ 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; version 2 of the License. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 #include "ballstateaspect.h" 00023 #include <zeitgeist/logserver/logserver.h> 00024 #include <oxygen/sceneserver/sceneserver.h> 00025 #include <oxygen/sceneserver/scene.h> 00026 #include <oxygen/agentaspect/agentaspect.h> 00027 #include <oxygen/physicsserver/recorderhandler.h> 00028 #include <soccer/gamestateaspect/gamestateaspect.h> 00029 #include <soccer/soccerbase/soccerbase.h> 00030 #include <soccer/ball/ball.h> 00031 00032 using namespace oxygen; 00033 using namespace boost; 00034 using namespace std; 00035 using namespace salt; 00036 00037 BallStateAspect::BallStateAspect() : SoccerControlAspect() 00038 { 00039 mBallOnField = false; 00040 mLastValidBallPos = Vector3f(0,0,0); 00041 mGoalState = TI_NONE; 00042 mLastAgentCollisionTime = 0; 00043 } 00044 00045 BallStateAspect::~BallStateAspect() 00046 { 00047 } 00048 00049 bool BallStateAspect::GetLastCollidingAgent(shared_ptr<AgentAspect>& agent, 00050 TTime& time) 00051 { 00052 agent = mLastCollidingAgent; 00053 time = mLastAgentCollisionTime; 00054 00055 return (agent.get() != 0); 00056 } 00057 00058 void BallStateAspect::UpdateLastCollidingAgent() 00059 { 00060 // get a list of agents that collided with the ball since the last 00061 // update of the recorder and remember the first returned node as 00062 // the last agent that collided with the ball. 00063 RecorderHandler::TParentList agents; 00064 mBallRecorder->GetParentsSupportingClass("AgentAspect",agents); 00065 00066 if (agents.size() > 0) 00067 { 00068 mLastCollidingAgent = shared_static_cast<AgentAspect> 00069 (make_shared(agents.front())); 00070 mLastAgentCollisionTime = mGameState->GetTime(); 00071 } 00072 00073 // empty the recorder buffer 00074 mBallRecorder->Clear(); 00075 } 00076 00077 void 00078 BallStateAspect::UpdateLastCollidingAgent(boost::shared_ptr<AgentAspect> agent) 00079 { 00080 mLastCollidingAgent = agent; 00081 mLastAgentCollisionTime = mGameState->GetTime(); 00082 } 00083 00084 void BallStateAspect::UpdateBallOnField() 00085 { 00086 // get a list of Ball nodes that collided with the field 00087 RecorderHandler::TParentList ball; 00088 mFieldRecorder->GetParentsSupportingClass("Ball",ball); 00089 00090 // the ball is on or above the playing field iff it collided with 00091 // the box collider around the playing field 00092 mBallOnField = (ball.size() > 0); 00093 00094 // empty the recorder buffer 00095 mFieldRecorder->Clear(); 00096 } 00097 00098 void BallStateAspect::UpdateLastValidBallPos() 00099 { 00100 if (! mBallOnField) 00101 { 00102 return; 00103 } 00104 00105 mLastValidBallPos = mBall->GetWorldTransform().Pos(); 00106 } 00107 00108 void BallStateAspect::UpdateGoalState() 00109 { 00110 // check both goal box collider 00111 RecorderHandler::TParentList ball; 00112 mLeftGoalRecorder->GetParentsSupportingClass("Ball",ball); 00113 00114 if (! ball.empty()) 00115 { 00116 mGoalState = TI_LEFT; 00117 } else 00118 { 00119 mRightGoalRecorder->GetParentsSupportingClass("Ball",ball); 00120 00121 if (! ball.empty()) 00122 { 00123 mGoalState = TI_RIGHT; 00124 } else 00125 { 00126 mGoalState = TI_NONE; 00127 } 00128 } 00129 00130 mLeftGoalRecorder->Clear(); 00131 mRightGoalRecorder->Clear(); 00132 } 00133 00134 TTeamIndex BallStateAspect::GetGoalState() 00135 { 00136 return mGoalState; 00137 } 00138 00139 void BallStateAspect::Update(float deltaTime) 00140 { 00141 if ( 00142 (mFieldRecorder.get() == 0) || 00143 (mBall.get() == 0) || 00144 (mBallRecorder.get() == 0) || 00145 (mLeftGoalRecorder.get() == 0) || 00146 (mRightGoalRecorder.get() == 0) 00147 ) 00148 { 00149 return; 00150 } 00151 00152 UpdateLastCollidingAgent(); 00153 UpdateBallOnField(); 00154 UpdateLastValidBallPos(); 00155 UpdateGoalState(); 00156 } 00157 00158 void BallStateAspect::OnLink() 00159 { 00160 SoccerControlAspect::OnLink(); 00161 00162 mFieldRecorder = GetFieldRecorder(); 00163 SoccerBase::GetBall(*this,mBall); 00164 mBallRecorder = GetBallRecorder(); 00165 mLeftGoalRecorder = GetLeftGoalRecorder(); 00166 mRightGoalRecorder = GetRightGoalRecorder(); 00167 00168 mGameState = shared_dynamic_cast<GameStateAspect> 00169 (GetControlAspect("GameStateAspect")); 00170 } 00171 00172 void BallStateAspect::OnUnlink() 00173 { 00174 SoccerControlAspect::OnUnlink(); 00175 00176 mBallRecorder.reset(); 00177 mFieldRecorder.reset(); 00178 mLastCollidingAgent.reset(); 00179 mLeftGoalRecorder.reset(); 00180 mRightGoalRecorder.reset(); 00181 mGameState.reset(); 00182 } 00183 00184 bool BallStateAspect::GetBallOnField() 00185 { 00186 return mBallOnField; 00187 } 00188 00189 salt::Vector3f BallStateAspect::GetLastValidBallPosition() 00190 { 00191 return mLastValidBallPos; 00192 } 00193