[Gcblue-commits] gcb_wx/src/sim Game.cpp,1.141,1.142 tcAirObject.cpp,1.28,1.29 tcCommandQueue.cpp,1.
Status: Alpha
Brought to you by:
ddcforge
Update of /cvsroot/gcblue/gcb_wx/src/sim In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6732/src/sim Modified Files: Game.cpp tcAirObject.cpp tcCommandQueue.cpp tcGameObject.cpp tcLauncher.cpp tcPlatformObject.cpp tcRadar.cpp tcSimState.cpp Log Message: - Added waypoint drag edit feature to gui. User can adjust waypoints on map screen by clicking and dragging - Fixed sound disable to include music. Previously sound failure would disable sound effects, but then play music leading to a crash. - Added random feature targeting to missiles. Missiles should now lock on to a random feature of the target instead of always hitting the center. Index: tcLauncher.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcLauncher.cpp,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** tcLauncher.cpp 14 Sep 2005 01:33:24 -0000 1.30 --- tcLauncher.cpp 27 Nov 2005 22:21:29 -0000 1.31 *************** *** 560,564 **** else // sonobuoy { ! meLaunchMode = DATUM_ONLY; } } --- 560,564 ---- else // sonobuoy { ! meLaunchMode = AUTO; } } *************** *** 703,707 **** bool hasDatum = (msDatum.mfLat_rad != 0) || (msDatum.mfLon_rad != 0); ! if ((meLaunchMode == AUTO) && (hasDatum)) { status = LAUNCHER_READY; --- 703,707 ---- bool hasDatum = (msDatum.mfLat_rad != 0) || (msDatum.mfLon_rad != 0); ! if (meLaunchMode == AUTO) { status = LAUNCHER_READY; Index: tcPlatformObject.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcPlatformObject.cpp,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** tcPlatformObject.cpp 19 Nov 2005 19:27:47 -0000 1.55 --- tcPlatformObject.cpp 27 Nov 2005 22:21:29 -0000 1.56 *************** *** 205,208 **** --- 205,210 ---- if (mcKin.mfHeading_rad >= C_TWOPI) {mcKin.mfHeading_rad -= C_TWOPI;} if (mcKin.mfHeading_rad < 0) {mcKin.mfHeading_rad += C_TWOPI;} + + mcKin.mfYaw_rad = mcKin.mfHeading_rad; } *************** *** 439,444 **** } } - - model->AddExplosion(osg::Vec3(0, 0, 0)); } --- 441,444 ---- Index: tcGameObject.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcGameObject.cpp,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** tcGameObject.cpp 28 Jun 2005 02:51:35 -0000 1.39 --- tcGameObject.cpp 27 Nov 2005 22:21:29 -0000 1.40 *************** *** 34,37 **** --- 34,39 ---- #include "common/tcStream.h" #include "common/tcObjStream.h" + #include <osg/LineSegment> + #include <osgUtil/IntersectVisitor> #ifdef _DEBUG *************** *** 168,171 **** --- 170,272 ---- } + + /** + * Gets relative position and velocity of obj relative to this GameObject + * dx east, dy north, dz up + * + * Results are in the local world frame of reference + */ + void tcGameObject::GetRelativeStateWorld(tcGameObject *obj, osg::Vec3& position, osg::Vec3& velocity) + { + // local world coordinates, x--east, y--north, z--up + + // store relative position in local world frame + position._v[2] = obj->mcKin.mfAlt_m - mcKin.mfAlt_m; + + double delta_lat = obj->mcKin.mfLat_rad - mcKin.mfLat_rad; + double delta_lon = obj->mcKin.mfLon_rad - mcKin.mfLon_rad; + delta_lon = delta_lon*cosf((float)mcKin.mfLat_rad); // correct for latitude + position._v[1] = (float)(delta_lat*C_RADTOM); + position._v[0] = (float)(delta_lon*C_RADTOM); + + + osg::Vec3 v1 = GetWorldVelocity(); + osg::Vec3 v2 = obj->GetWorldVelocity(); + + velocity = v2 - v1; // relative velocity in local world frame + } + + + /** + * Gets relative position and velocity of obj relative to this GameObject + * dx right, dy forward, dz up + * + * Results are in the frame of reference of this object + */ + void tcGameObject::GetRelativeStateLocal(tcGameObject *obj, osg::Vec3& position, osg::Vec3& velocity) + { + // local world coordinates, x--east, y--north, z--up + GetRelativeStateWorld(obj, position, velocity); + + /* obj to world transform: + osg::Matrix m = + osg::Matrix::rotate(osg::inRadians(roll),0.0f,1.0f,0.0f)* + osg::Matrix::rotate(osg::inRadians(pitch),1.0f,0.0f,0.0f)* + osg::Matrix::rotate(-osg::inRadians(yaw),0.0f,0.0f,1.0f)*osg::Matrix::translate(x,y,z) + ; + */ + osg::Matrix world_to_obj = + osg::Matrix::rotate(osg::inRadians(mcKin.mfYaw_rad),0.0f,0.0f,1.0f)* + osg::Matrix::rotate(-osg::inRadians(mcKin.mfPitch_rad),1.0f,0.0f,0.0f)* + osg::Matrix::rotate(-osg::inRadians(mcKin.mfRoll_rad),0.0f,1.0f,0.0f); + + position = world_to_obj.preMult(position); + velocity = world_to_obj.preMult(velocity); + } + + /** + * Convert coordinates in model frame of reference to local world frame. + * Would be faster to use saved transform matrix from ObjectUpdater + * instead of recalculating it here. + * + * @return x--east, y--north, z--up + */ + osg::Vec3 tcGameObject::ConvertModelCoordinatesToWorld(const osg::Vec3& x) const + { + osg::Matrix obj_to_world = + osg::Matrix::rotate(osg::inRadians(mcKin.mfRoll_rad),0.0f,1.0f,0.0f)* + osg::Matrix::rotate(osg::inRadians(mcKin.mfPitch_rad),1.0f,0.0f,0.0f)* + osg::Matrix::rotate(-osg::inRadians(mcKin.mfYaw_rad),0.0f,0.0f,1.0f); + + return obj_to_world.preMult(x); + } + + + + /** + * @return velocity in local world coords in m/s + * x--east, y--north, z--up + */ + osg::Vec3 tcGameObject::GetWorldVelocity() const + { + float hdg = mcKin.mfHeading_rad; + float climb = mcKin.mfClimbAngle_rad; + + float speed_mps = C_KTSTOMPS * mcKin.mfSpeed_kts; + float cos_hdg = cosf(hdg); + float sin_hdg = sinf(hdg); + float cos_climb = cosf(climb); + float sin_climb = sinf(climb); + + float vxy = cos_climb * speed_mps; + + float vz = sin_climb * speed_mps; + float vy = cos_hdg * vxy; + float vx = sin_hdg * vxy; + + return osg::Vec3(vx, vy, vz); + } + + /** * @returns sonar source level of object or, if object has active sonar on, maximum of source level of *************** *** 246,249 **** --- 347,399 ---- /** + * Calculates collision point or closest point of approach in model coordinates + * @return true if collision occurs, false otherwise + */ + bool tcGameObject::CalculateCollisionPoint(tcGameObject* collider, osg::Vec3& pos, float& dt) + { + osg::Vec3 x_collider; // position of collider in model frame + osg::Vec3 v_collider; // velocity of collider in model frame + + GetRelativeStateLocal(collider, x_collider, v_collider); + + const float t12 = 0.05f; // time interval to check for collision + osg::Vec3 x2_collider = x_collider + v_collider * t12; + + + osg::LineSegment* colliderPath = new osg::LineSegment(); + colliderPath->set(x_collider, x2_collider); + + + osgUtil::IntersectVisitor collisionVisitor; + collisionVisitor.addLineSegment(colliderPath); + + + osg::Node* modelNode = model->GetModelNode(); + modelNode->accept(collisionVisitor); + + osgUtil::IntersectVisitor::HitList hitList = + collisionVisitor.getHitList(colliderPath); + + if (!hitList.empty()) + { + float speed_collider = v_collider.length(); + float inv_speed_collider = 1.0f / speed_collider; + + osgUtil::Hit firstHit = hitList.front(); + pos = firstHit.getWorldIntersectPoint(); + + osg::Vec3 hitOffset = pos - x_collider; + + dt = hitOffset.length() * inv_speed_collider; + return true; + } + else + { + return false; + } + + } + + /** * */ Index: tcSimState.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcSimState.cpp,v retrieving revision 1.89 retrieving revision 1.90 diff -C2 -d -r1.89 -r1.90 *** tcSimState.cpp 10 Sep 2005 21:47:38 -0000 1.89 --- tcSimState.cpp 27 Nov 2005 22:21:29 -0000 1.90 *************** *** 405,420 **** void tcSimState::EvaluateGuidedMissileHit(tcMissileObject* missile, tcGameObject* target) { ! float range_m = 1000.0f*missile->mcKin.RangeToKmAlt(target->mcKin); ! float fFactor = 0.01f*(missile->mcKin.mfSpeed_kts + target->mcKin.mfSpeed_kts + 2000.0f); ! if (range_m >= fFactor) return; // too far away, no damage ! float dx, dy, dz, tclosest; ! tclosest = target->mcKin.CalculateCollisionPoint(missile->mcKin, dx, dy, dz); ! if (tclosest > 0.05f) return; // defer until future time step ! float trueRange2 = dx*dx + dy*dy + dz*dz; ! if (trueRange2 < 144.0f) // 12.0 m range { bool alreadyDestroyed = target->mfDamageLevel >= 1.0f; --- 405,434 ---- void tcSimState::EvaluateGuidedMissileHit(tcMissileObject* missile, tcGameObject* target) { ! //float range_m = 1000.0f*missile->mcKin.RangeToKmAlt(target->mcKin); ! //float fFactor = 0.01f*(missile->mcKin.mfSpeed_kts + target->mcKin.mfSpeed_kts + 2000.0f); ! //if (range_m >= fFactor) return; // too far away, no damage ! float dx, dy, dz, dt; ! osg::Vec3 collisionPoint; ! float trueRange2; ! // first check for impact ! if (target->CalculateCollisionPoint(missile, collisionPoint, dt)) ! { ! collisionPoint = target->ConvertModelCoordinatesToWorld(collisionPoint); ! dx = collisionPoint.x(); ! dy = collisionPoint.y(); ! dz = collisionPoint.z(); ! trueRange2 = 0; ! } ! else // if no impact, check for sufficient proximity to target ! { ! dt = target->mcKin.CalculateCollisionPoint(missile->mcKin, dx, dy, dz); ! if (dt > 0.1) return; // defer until future time step ! trueRange2 = dx*dx + dy*dy + 0.5*dz*dz; ! } ! if (trueRange2 < 0.00001440f) // 12.0 m range { bool alreadyDestroyed = target->mfDamageLevel >= 1.0f; *************** *** 441,444 **** --- 455,460 ---- } PlayEntitySoundEffect(missile, "Explosion2"); + + target->model->AddExplosion(osg::Vec3(dx, dy, dz)); } *************** *** 449,453 **** std::cout << s.c_str(); fprintf(stdout," collision relative time: %f, dx:%f dy:%f dz:%f\n", ! tclosest, dx, dy, dz); #endif } --- 465,469 ---- std::cout << s.c_str(); fprintf(stdout," collision relative time: %f, dx:%f dy:%f dz:%f\n", ! dt, dx, dy, dz); #endif } *************** *** 465,477 **** float range_m = 1000.0f * torp->mcKin.RangeToKmAlt(target->mcKin); ! if (range_m >= 200) return; // too far away, no damage - float dx, dy, dz, tclosest; - tclosest = target->mcKin.CalculateCollisionPoint(torp->mcKin, dx, dy, dz); ! if (tclosest > 0.3) return; // defer until future time step ! float trueRange2 = dx*dx + dy*dy + 0.5*dz*dz; ! if (trueRange2 < 144.0f) // 12.0 m range, dz not counted as heavily { bool alreadyDestroyed = target->mfDamageLevel >= 1.0f; --- 481,512 ---- float range_m = 1000.0f * torp->mcKin.RangeToKmAlt(target->mcKin); ! if ((range_m > 200.0) || (range_m >= 0.6*target->GetSpan())) ! { ! return; // too far away, no damage ! } ! float dx, dy, dz, dt; ! osg::Vec3 collisionPoint; ! float trueRange2; ! // first check for impact ! if (target->CalculateCollisionPoint(torp, collisionPoint, dt)) ! { ! collisionPoint = target->ConvertModelCoordinatesToWorld(collisionPoint); ! dx = collisionPoint.x(); ! dy = collisionPoint.y(); ! dz = collisionPoint.z(); ! trueRange2 = 0; ! } ! else // if no impact, check for sufficient proximity to target ! { ! dt = target->mcKin.CalculateCollisionPoint(torp->mcKin, dx, dy, dz); ! if (dt > 0.1) return; // defer until future time step ! trueRange2 = dx*dx + dy*dy + 0.5*dz*dz; ! } ! ! ! if (trueRange2 < 144.0f) // 12.0 m "range", dz not counted as heavily { bool alreadyDestroyed = target->mfDamageLevel >= 1.0f; *************** *** 499,502 **** --- 534,539 ---- } + target->model->AddExplosion(osg::Vec3(dx, dy, dz)); + #ifdef _DEBUG wxString s = wxString::Format("torpedo %d hit target %d, range^2: %3.1f m, dmg: %3.1f %%, time %.1f s", *************** *** 505,509 **** std::cout << s.c_str(); fprintf(stdout," collision relative time: %f, dx:%f dy:%f dz:%f\n", ! tclosest, dx, dy, dz); #endif } --- 542,546 ---- std::cout << s.c_str(); fprintf(stdout," collision relative time: %f, dx:%f dy:%f dz:%f\n", ! dt, dx, dy, dz); #endif } *************** *** 596,599 **** --- 633,642 ---- } PlayEntitySoundEffect(weapon, "Explosion2"); + + // use a random explosion point for display purposes only + float dx = randfc(20.0f); + float dy = randfc(20.0f); + float dz = randf(10.0f); + target->model->AddExplosion(osg::Vec3(dx, dy, dz)); } else *************** *** 663,666 **** --- 706,711 ---- PlayEntitySoundEffect(weapon, "Explosion2"); } + + target->model->AddExplosion(osg::Vec3(dx, dy, dz)); } Index: tcAirObject.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcAirObject.cpp,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** tcAirObject.cpp 10 Sep 2005 21:47:38 -0000 1.28 --- tcAirObject.cpp 27 Nov 2005 22:21:29 -0000 1.29 *************** *** 422,425 **** --- 422,426 ---- mcKin.mfRoll_rad = dh_rps*rps_to_roll; + mcKin.mfYaw_rad = mcKin.mfHeading_rad; } Index: Game.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/Game.cpp,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -d -r1.141 -r1.142 *** Game.cpp 14 Sep 2005 01:33:24 -0000 1.141 --- Game.cpp 27 Nov 2005 22:21:29 -0000 1.142 *************** *** 494,497 **** --- 494,498 ---- "Error", wxICON_ERROR); tcOptions::Get()->disableSound = true; // disable sound + tcOptions::Get()->mbPlayMusic = false; // disable music tcOptions::Get()->Synchronize(); } *************** *** 693,697 **** void tcGame::InitializeSound() { ! if (tcOptions::Get()->disableSound) return; if (tcSound::Get()->Init()) --- 694,703 ---- void tcGame::InitializeSound() { ! if (tcOptions::Get()->disableSound) ! { ! tcOptions::Get()->mbPlayMusic = false; ! tcOptions::Get()->Synchronize(); ! return; ! } if (tcSound::Get()->Init()) *************** *** 2408,2459 **** tsCommandInfo cmd_info; if (commandQueue->GetCommand(cmd_info)) { ! if (cmd_info.mbUsePython) { ! if (cmd_info.mbCallback) { ! ProcessCallback(cmd_info.mzString, cmd_info.mzUserInput, ! cmd_info.platformID, cmd_info.mnData); } ! else if (cmd_info.mbGetUserInput) { ! if (cmd_info.platformID.size() == 0) cmd_info.platformID = tacticalMap->GetHookedGroup(); ! GetUserInput(cmd_info.mzString, cmd_info.mzUserInput, ! cmd_info.platformID, cmd_info.mnData); } else { ! std::string s = cmd_info.mzString; ! int param = cmd_info.mnData; ! pythonInterface->ProcessCommand(s, cmd_info.platformID, ! param, cmd_info.textParam); } ! } ! else if (cmd_info.meCmd == GC_TEXTCOMMAND) ! { ! ProcessTextCommand(cmd_info); ! } ! else if (cmd_info.meCmd == GC_DISPLAYMESSAGE) ! { ! infoConsole->Print(cmd_info.mzString); ! } ! else if (cmd_info.meCmd == GC_QUIT) ! { ! mbQuit = true; ! } ! else if (cmd_info.meCmd == GC_SHOWBRIEFING) ! { ! meScreenMode = SIMPLEBRIEF; ! } ! else if (cmd_info.meCmd == GC_SHOWMISSIONSTATUS) ! { ! meScreenMode = MESSAGES; ! messageCenter->ActivateChannel("Mission"); ! } ! else ! { ! fprintf(stderr, "Unrecognized command (%d)\n", cmd_info.meCmd); ! } } } --- 2414,2477 ---- tsCommandInfo cmd_info; + if (commandQueue->GetCommand(cmd_info)) { ! switch (cmd_info.commandType) { ! case PYTHON_CALLBACK: ! ProcessCallback(cmd_info.mzString, cmd_info.mzUserInput, ! cmd_info.platformID, cmd_info.mnData); ! break; ! case PYTHON_USERINPUT: ! if (cmd_info.platformID.size() == 0) cmd_info.platformID = tacticalMap->GetHookedGroup(); ! GetUserInput(cmd_info.mzString, cmd_info.mzUserInput, ! cmd_info.platformID, cmd_info.mnData); ! break; ! case PYTHON_COMMAND_TEXT: { ! std::string s = cmd_info.mzString; ! int param = cmd_info.mnData; ! pythonInterface->ProcessCommand(s, cmd_info.platformID, ! param, cmd_info.textParam); } ! break; ! case PYTHON_COMMAND_GENERAL: { ! std::string s = cmd_info.mzString; ! pythonInterface->ProcessCommandWithArguments(s, cmd_info.platformID, cmd_info.textParam); ! } ! break; ! case GAME_COMMAND: ! if (cmd_info.meCmd == GC_TEXTCOMMAND) ! { ! ProcessTextCommand(cmd_info); ! } ! else if (cmd_info.meCmd == GC_DISPLAYMESSAGE) ! { ! infoConsole->Print(cmd_info.mzString); ! } ! else if (cmd_info.meCmd == GC_QUIT) ! { ! mbQuit = true; ! } ! else if (cmd_info.meCmd == GC_SHOWBRIEFING) ! { ! meScreenMode = SIMPLEBRIEF; ! } ! else if (cmd_info.meCmd == GC_SHOWMISSIONSTATUS) ! { ! meScreenMode = MESSAGES; ! messageCenter->ActivateChannel("Mission"); } else { ! fprintf(stderr, "Unrecognized game command (%d)\n", cmd_info.meCmd); } ! ! break; ! default: ! fprintf(stderr, "Unrecognized command type (%d)\n", cmd_info.commandType); ! break; ! } // switch } } Index: tcCommandQueue.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcCommandQueue.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tcCommandQueue.cpp 10 Jan 2005 00:30:55 -0000 1.2 --- tcCommandQueue.cpp 27 Nov 2005 22:21:29 -0000 1.3 *************** *** 57,72 **** /** ! * */ void tcCommandQueue::AddCommand(teGameCommand aeCmd, float afData, long anData, int anData2) { tsCommandInfo newcmd; newcmd.meCmd = aeCmd; newcmd.mfData = afData; newcmd.mnData = anData; newcmd.mnData2 = anData2; - newcmd.mbUsePython = false; - newcmd.mbCallback = false; - newcmd.mbGetUserInput = false; newcmd.platformID.clear(); if (mnCount < MAX_QUEUED_COMMANDS) --- 57,71 ---- /** ! * Adds game command (old style command from enumerated list) */ void tcCommandQueue::AddCommand(teGameCommand aeCmd, float afData, long anData, int anData2) { tsCommandInfo newcmd; + + newcmd.commandType = GAME_COMMAND; newcmd.meCmd = aeCmd; newcmd.mfData = afData; newcmd.mnData = anData; newcmd.mnData2 = anData2; newcmd.platformID.clear(); if (mnCount < MAX_QUEUED_COMMANDS) *************** *** 77,89 **** /** ! * For string commands */ void tcCommandQueue::AddCommand(const char *azCommand, int param) { tsCommandInfo newcmd; newcmd.meCmd = GC_TEXTCOMMAND; - newcmd.mbUsePython = false; - newcmd.mbCallback = false; - newcmd.mbGetUserInput = false; newcmd.mnData = param; strcpy(newcmd.mzString , azCommand); --- 76,87 ---- /** ! * For old style string commands */ void tcCommandQueue::AddCommand(const char *azCommand, int param) { tsCommandInfo newcmd; + + newcmd.commandType = GAME_COMMAND; newcmd.meCmd = GC_TEXTCOMMAND; newcmd.mnData = param; strcpy(newcmd.mzString , azCommand); *************** *** 96,108 **** } /** ! * version without user input and callback */ void tcCommandQueue::AddPythonCommand(const char *azCommand, int param) { tsCommandInfo newcmd; newcmd.meCmd = (teGameCommand)0; - newcmd.mbUsePython = true; - newcmd.mbCallback = false; - newcmd.mbGetUserInput = false; newcmd.mnData = param; // int param newcmd.textParam = ""; // text param --- 94,105 ---- } /** ! * Version without user input and callback */ void tcCommandQueue::AddPythonCommand(const char *azCommand, int param) { tsCommandInfo newcmd; + + newcmd.commandType = PYTHON_COMMAND_TEXT; newcmd.meCmd = (teGameCommand)0; newcmd.mnData = param; // int param newcmd.textParam = ""; // text param *************** *** 117,129 **** /** ! * version without user input and callback */ ! void tcCommandQueue::AddPythonCommand(const char *azCommand, std::string textParam) { tsCommandInfo newcmd; newcmd.meCmd = (teGameCommand)0; - newcmd.mbUsePython = true; - newcmd.mbCallback = false; - newcmd.mbGetUserInput = false; newcmd.mnData = -1; // int param newcmd.textParam = textParam; --- 114,125 ---- /** ! * Version without user input and callback */ ! void tcCommandQueue::AddPythonCommand(const char *azCommand, const std::string& textParam) { tsCommandInfo newcmd; + + newcmd.commandType = PYTHON_COMMAND_TEXT; newcmd.meCmd = (teGameCommand)0; newcmd.mnData = -1; // int param newcmd.textParam = textParam; *************** *** 137,153 **** } ! /* GetUserInput is called to add a command to get user input data. ! ** Once the user input is complete, the callback function is called though ! ** AddPythonCallback. Data that describes the user input is passed to the ! ** callback function along with an optional parameter. */ void tcCommandQueue::GetUserInput(const char *azCallback, const char *azUserInput, int param) { tsCommandInfo newcmd; newcmd.meCmd = (teGameCommand)0; - newcmd.mbUsePython = true; - newcmd.mbCallback = false; - newcmd.mbGetUserInput = true; newcmd.mnData = param; newcmd.textParam = ""; --- 133,168 ---- } + void tcCommandQueue::AddPythonCommandGeneral(const std::string& command, const std::string& args, + const std::vector<long>& platformID) + { + tsCommandInfo newcmd; ! newcmd.commandType = PYTHON_COMMAND_GENERAL; ! newcmd.meCmd = (teGameCommand)0; ! newcmd.mnData = -1; // int param ! ! strcpy(newcmd.mzString , command.c_str()); ! newcmd.textParam = args; ! strcpy(newcmd.mzUserInput, ""); ! newcmd.platformID = platformID; ! if (mnCount < MAX_QUEUED_COMMANDS) ! { ! maCommand[mnCount++] = newcmd; ! } ! } ! ! ! /** ! * GetUserInput is called to add a command to get user input data. ! * Once the user input is complete, the callback function is called though ! * AddPythonCallback. Data that describes the user input is passed to the ! * callback function along with an optional parameter. */ void tcCommandQueue::GetUserInput(const char *azCallback, const char *azUserInput, int param) { tsCommandInfo newcmd; + + newcmd.commandType = PYTHON_USERINPUT; newcmd.meCmd = (teGameCommand)0; newcmd.mnData = param; newcmd.textParam = ""; *************** *** 173,180 **** { tsCommandInfo newcmd; newcmd.meCmd = (teGameCommand)0; - newcmd.mbUsePython = true; - newcmd.mbCallback = false; - newcmd.mbGetUserInput = true; newcmd.mnData = param; newcmd.textParam = ""; --- 188,194 ---- { tsCommandInfo newcmd; + + newcmd.commandType = PYTHON_USERINPUT; newcmd.meCmd = (teGameCommand)0; newcmd.mnData = param; newcmd.textParam = ""; *************** *** 197,204 **** { tsCommandInfo newcmd; newcmd.meCmd = (teGameCommand)0; - newcmd.mbUsePython = true; - newcmd.mbCallback = true; - newcmd.mbGetUserInput = false; newcmd.mnData = param; newcmd.textParam = ""; --- 211,217 ---- { tsCommandInfo newcmd; + + newcmd.commandType = PYTHON_CALLBACK; newcmd.meCmd = (teGameCommand)0; newcmd.mnData = param; newcmd.textParam = ""; *************** *** 219,226 **** { tsCommandInfo newcmd; newcmd.meCmd = (teGameCommand)0; - newcmd.mbUsePython = true; - newcmd.mbCallback = true; - newcmd.mbGetUserInput = false; newcmd.mnData = param; newcmd.textParam = ""; --- 232,238 ---- { tsCommandInfo newcmd; + + newcmd.commandType = PYTHON_CALLBACK; newcmd.meCmd = (teGameCommand)0; newcmd.mnData = param; newcmd.textParam = ""; *************** *** 236,246 **** /** ! * for sending messages */ void tcCommandQueue::DisplayInfoMessage(const char *azString) { tsCommandInfo newcmd; newcmd.meCmd = GC_DISPLAYMESSAGE; - newcmd.mbUsePython = false; strcpy(newcmd.mzString, azString); newcmd.platformID.clear(); --- 248,259 ---- /** ! * For sending messages to info console */ void tcCommandQueue::DisplayInfoMessage(const char *azString) { tsCommandInfo newcmd; + + newcmd.commandType = GAME_COMMAND; newcmd.meCmd = GC_DISPLAYMESSAGE; strcpy(newcmd.mzString, azString); newcmd.platformID.clear(); Index: tcRadar.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcRadar.cpp,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** tcRadar.cpp 10 Sep 2005 21:47:38 -0000 1.33 --- tcRadar.cpp 27 Nov 2005 22:21:29 -0000 1.34 *************** *** 179,182 **** --- 179,184 ---- tgt_kin->mfLat_rad,tgt_kin->mfLon_rad); range_km = fTargetRange_km; + last_range_km = range_km; + if (fTargetRange_km > fRadarHorizon) { *************** *** 561,566 **** --- 563,602 ---- #endif } + + AdjustTrackForFineTargeting(target); } + /** + * If sufficiently close to target, adjust track to lock on to random feature + * of target. Intended to add more realism so that weapons do not always strike + * origin of target model. + */ + void tcRadar::AdjustTrackForFineTargeting(const tcGameObject* target) + { + if (last_range_km > 1.0f) return; + + /* if target offset has not been selected yet, randomly select + ** based on box around target model. This assumes that only one + ** target will be engaged throughout life of seeker */ + if ((target_x_offset_m == 0) && (target_y_offset_m == 0)) + { + /* since we don't have a getBoundingBox method, just use the + ** span (diameter of bounding sphere) and assume width is narrow + ** compared to length */ + float span_m = target->GetSpan(); + target_y_offset_m = randfc(0.9*span_m); + target_x_offset_m = 0*randfc(0.01f * span_m); + } + osg::Vec3 worldOffset = + target->ConvertModelCoordinatesToWorld(osg::Vec3(target_x_offset_m, target_y_offset_m, 0)); + + float lon_corr = C_MTORAD / cosf(mcTrack.mfLat_rad); + mcTrack.mfAlt_m += worldOffset.z(); + if (mcTrack.mfAlt_m < 1) mcTrack.mfAlt_m = 1; + mcTrack.mfLat_rad += C_MTORAD * worldOffset.y(); + mcTrack.mfLon_rad += lon_corr * worldOffset.x(); + } + + void tcRadar::Update(double t) { *************** *** 599,603 **** fireControlTrackCount(0), isSemiactive(mpDBObj->isSemiactive), ! isCommandReceiver(mpDBObj->isCommandReceiver) { wxASSERT(dbObj); --- 635,642 ---- fireControlTrackCount(0), isSemiactive(mpDBObj->isSemiactive), ! isCommandReceiver(mpDBObj->isCommandReceiver), ! last_range_km(0), ! target_x_offset_m(0), ! target_y_offset_m(0) { wxASSERT(dbObj); |