[Gcblue-commits] gcb_wx/src/sim tcSensorMapTrack.cpp,NONE,1.1 tcSensorMap.cpp,1.20,1.21 tcSensorTrac
Status: Alpha
Brought to you by:
ddcforge
|
From: Dewitt C. <ddc...@us...> - 2005-05-17 00:22:00
|
Update of /cvsroot/gcblue/gcb_wx/src/sim In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32418/src/sim Modified Files: tcSensorMap.cpp tcSensorTrackIterator.cpp Added Files: tcSensorMapTrack.cpp Log Message: New feature to display 3D models for sensor tracks based on track position (only generic models for now) Index: tcSensorTrackIterator.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcSensorTrackIterator.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tcSensorTrackIterator.cpp 11 Dec 2004 01:09:08 -0000 1.1 --- tcSensorTrackIterator.cpp 17 May 2005 00:20:41 -0000 1.2 *************** *** 159,162 **** --- 159,181 ---- } + /** + * Version that doesn't require region argument + */ + tcSensorTrackIterator::tcSensorTrackIterator(unsigned int alliance_, unsigned int classificationMask) + : + useRegion(false), + alliance(alliance_), + classMask(classificationMask) + { + if (!simState) + { + simState = tcSimState::Get(); + } + + map = simState->mcSensorMap.GetMap(alliance); + + First(); + } + tcSensorTrackIterator::tcSensorTrackIterator() : useRegion(false), Index: tcSensorMap.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcSensorMap.cpp,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** tcSensorMap.cpp 6 May 2005 23:57:52 -0000 1.20 --- tcSensorMap.cpp 17 May 2005 00:20:40 -0000 1.21 *************** *** 36,619 **** - /******************************* tcSensorMapTrack ****************************/ - tcDatabase* tcSensorMapTrack::database = NULL; - tcSimState* tcSensorMapTrack::simState = NULL; - unsigned int tcSensorMapTrack::ambiguityListUpdates = 0; - bool tcSensorMapTrack::autoKillAssess = false; - - - /** - * Set to true to automatically check and mark stale tracks that - * are destroyed. - */ - void tcSensorMapTrack::SetAutoKillAssess(bool state) - { - autoKillAssess = state; - } - - - - - /** - * Loads state from update stream - */ - tcUpdateStream& tcSensorMapTrack::operator<<(tcUpdateStream& stream) - { - tcTrack::operator<<(stream); - - stream >> mnContributors; - for (int n = 0; n < mnContributors; n++) - { - stream >> maSensorReport[n].mfTimestamp; - } - - stream >> sensorFlags; - - return stream; - } - - /** - * Saves state to update stream - */ - tcUpdateStream& tcSensorMapTrack::operator>>(tcUpdateStream& stream) - { - tcTrack::operator>>(stream); - - stream << mnContributors; - for (int n = 0; n < mnContributors; n++) - { - stream << maSensorReport[n].mfTimestamp; - } - - stream << sensorFlags; - - return stream; - } - - /** - * @return false if id already in engaged vector - */ - bool tcSensorMapTrack::AddEngagement(long id) - { - if (id == -1) return false; - - unsigned nEngaged = engaged.size(); - for(unsigned n=0;n<nEngaged;n++) - { - if (engaged[n] == id) return false; - } - engaged.push_back(id); - return true; - } - - /** - * @return false if id already in intercepts vector - */ - bool tcSensorMapTrack::AddIntercept(long id) - { - if (id == -1) return false; - - unsigned nIntercepts = intercepts.size(); - for(unsigned n=0;n<nIntercepts;n++) - { - if (intercepts[n] == id) return false; - } - intercepts.push_back(id); - return true; - } - - - void tcSensorMapTrack::Clear() - { - for (int k=0; k<mnContributors; k++) - { - tcSensorReport* sensorReport = &maSensorReport[k]; - sensorReport->Clear(); - } - - mnContributors = 0; - mnEmitters = 0; - mnDatabaseID = -1; - assessedDamage = 0; - intercepts.clear(); - engaged.clear(); - - tcTrack::Clear(); - } - - /** - * @return number of contributors to this track - */ - unsigned tcSensorMapTrack::GetContributorCount() const - { - return (unsigned)mnContributors; - } - - /** - * @return name of contributing platform <idx> or pointer to "" if bad idx - */ - const char* tcSensorMapTrack::GetContributorName(unsigned idx) const - { - static const std::string emptyString(""); - - if (idx >= (unsigned)mnContributors) return emptyString.c_str(); - - long contributorId = maSensorReport[idx].mnSensorPlatformID; - if (tcGameObject* obj = simState->GetObject(contributorId)) - { - return obj->mzUnit.mz; - } - else - { - return emptyString.c_str(); - } - } - - - unsigned tcSensorMapTrack::GetEngagedCount() const - { - return engaged.size(); - } - - - unsigned tcSensorMapTrack::GetInterceptCount() const - { - return intercepts.size(); - } - /** - * This method is called periodically to cleanup the engaged vector. - * There will be some lag between the state of this vector and true - * state in the sim. - */ - void tcSensorMapTrack::UpdateEngagements() - { - wxASSERT(simState); - int nEngaged = (int)engaged.size(); - for (int n=nEngaged-1;n>=0;n--) - { - long id = engaged[n]; - tcWeaponObject *weapon = dynamic_cast<tcWeaponObject*>(simState->GetObject(id)); - if (weapon) - { - if (!weapon->IsIntendedTarget(tcTrack::mnID)) - { - engaged.erase(engaged.begin() + n); // weapon isn't targeting track - } - } - else // weapon doesn't exist anymore, erase engaged id - { - engaged.erase(engaged.begin() + n); - } - - } - } - - /** - * This method is called periodically to cleanup the intercepts vector. - * There will be some lag between the state of this vector and true - * state in the sim. - */ - void tcSensorMapTrack::UpdateIntercepts() - { - wxASSERT(simState); - - int nIntercepts = (int)intercepts.size(); - for (int n=nIntercepts-1;n>=0;n--) - { - long id = intercepts[n]; - tcPlatformObject *platform = dynamic_cast<tcPlatformObject*>(simState->GetObject(id)); - if (platform) - { - if (!platform->IsInterceptingTrack(tcTrack::mnID)) - { - intercepts.erase(intercepts.begin() + n); // platform isn't intercepting track - } - } - else // platform doesn't exist anymore, erase intercepts id - { - intercepts.erase(intercepts.begin() + n); - } - - } - } - - - bool tcSensorMapTrack::UpdateEmitter(tsEmitterInfo*& rpEmitterInfo, tnPoolIndex anEmitterID) { - // search for existing match - for(int n=0;n<mnEmitters;n++) { - tsEmitterInfo *pEmitterInfo = &maEmitterInfo[n]; - if (pEmitterInfo->mnEmitterID == anEmitterID) { - rpEmitterInfo = pEmitterInfo; - return true; - } - } - // add new emitter if there is room - if (mnEmitters < MAX_EMITTERS) { - rpEmitterInfo = &maEmitterInfo[mnEmitters++]; - rpEmitterInfo->mnEmitterID = anEmitterID; - rpEmitterInfo->mfTimestamp = 0; - rpEmitterInfo->mnMode = 0; - - UpdateAmbiguityList(); - return true; - } - return false; - } - - - bool tcSensorMapTrack::UpdateActiveReport(Sensor::tcSensorReport*& rpReport, tnPoolIndex anSensorID) - { - int nPassiveIdx = -1; - - // search for existing match - for(int n=0; n<mnContributors; n++) - { - tcSensorReport *pSensorReport = &maSensorReport[n]; - if (pSensorReport->mnFlags & (TRACK_BEARING_ONLY|TRACK_TRIANGULATED)) - { - nPassiveIdx = n; // used to have "int nPassiveIdx = n;" here !? - } - else if (pSensorReport->mnSensorPlatformID == anSensorID) - { - rpReport = pSensorReport; - return true; - } - } - - // add new report if there is room - if (mnContributors < MAX_SENSOR_REPORTS) - { - tcSensorReport *pSensorReport = &maSensorReport[mnContributors++]; - pSensorReport->Clear(); - pSensorReport->mnSensorPlatformID = anSensorID; - rpReport = pSensorReport; - return true; - } - - // overwrite passive with active if one exists - if (nPassiveIdx >= 0) - { - tcSensorReport *pSensorReport = &maSensorReport[nPassiveIdx]; - pSensorReport->Clear(); - pSensorReport->mnSensorPlatformID = anSensorID; - rpReport = pSensorReport; - return true; - } - - rpReport = NULL; - return false; - } - - /** - * Using database, updates ambiguity list of platforms - * consistent with detected emitters - */ - void tcSensorMapTrack::UpdateAmbiguityList() - { - ambiguityList.clear(); - - // return if coarse classification is not available - if (mnClassification == PTYPE_UNKNOWN) return; - if (mnEmitters < 1) return; - - std::vector<long> emitterList; - for (int n=0; n<mnEmitters; n++) - { - emitterList.push_back(maEmitterInfo[n].mnEmitterID); - } - - tcDatabaseIterator iter(mnClassification); - for (iter.First(); !iter.IsDone(); iter.Next()) - { - bool platformMatches = false; - tcDatabaseObject* obj = iter.Get(); - wxASSERT(obj); - if (tcGenericDBObject* generic = dynamic_cast<tcGenericDBObject*>(obj)) - { - if (generic->HasAllEmitters(emitterList)) platformMatches = true; - } - else if (tcMissileDBObject* missile = dynamic_cast<tcMissileDBObject*>(obj)) - { - if (missile->HasAllEmitters(emitterList)) platformMatches = true; - } - - if (platformMatches) - { - ambiguityList.push_back(obj->mnKey); - } - - } - - /* use esm ambiguity list for identification if platform not - ** identified, and there is exactly one entry in ambiguity list */ - if ((ambiguityList.size() == 1) && (mnDatabaseID == -1)) - { - mnDatabaseID = ambiguityList[0]; - } - - ambiguityListUpdates++; - } - - bool tcSensorMapTrack::UpdatePassiveReport(Sensor::tcSensorReport*& rpReport, tnPoolIndex anSensorID) { - //int nPassiveIdx = -1; - - // if track already has active data then do not update with passive data - if (tcTrack::mnFlags & TRACK_ACTIVE) {return false;} - - // search for existing match - for(int n=0;n<mnContributors;n++) - { - tcSensorReport *pSensorReport = &maSensorReport[n]; - if ((pSensorReport->mnFlags & (TRACK_BEARING_ONLY|TRACK_TRIANGULATED))&& - (pSensorReport->mnSensorPlatformID == anSensorID)) - { - rpReport = pSensorReport; - return true; - } - } - - // add new report if there is room - if (mnContributors < MAX_SENSOR_REPORTS) - { - tcSensorReport *pSensorReport = &maSensorReport[mnContributors++]; - pSensorReport->Clear(); - pSensorReport->mnSensorPlatformID = anSensorID; - rpReport = pSensorReport; - return true; - } - - rpReport = NULL; - return false; - } - - - void tcSensorMapTrack::UpdateClassification(UINT16 mnClassification, teAffiliation meAffiliation, - tnPoolIndex databaseID) - { - if (mnClassification != 0) - { - tcTrack::mnClassification |= mnClassification; - } - if (meAffiliation != UNKNOWN) - { - tcTrack::mnAffiliation = meAffiliation; - } - if (databaseID != -1) - { - mnDatabaseID = databaseID; - } - - UpdateAmbiguityList(); - - } - - - /** - * check if reporting sensor has reported, if so update report - * if not add new report if slots are free - */ - bool tcSensorMapTrack::AddReport(const Sensor::tcSensorReport& report) - { - // search for existing match - for(int n=0;n<mnContributors;n++) - { - tcSensorReport *pSensorReport = &maSensorReport[n]; - //bool bActivePassiveMatch = (pSensorReport->mnFlags & report.mnFlags & TRACK_BEARING_ONLY); - if ((pSensorReport->mnSensorPlatformID == report.mnSensorPlatformID)) - { - *pSensorReport = report; - return true; - } - } - // add new report if there is room - if (mnContributors < MAX_SENSOR_REPORTS) - { - maSensorReport[mnContributors] = report; - mnContributors++; - return true; - } - return false; - } - - /** - * Queries simState to check if track object exists. If - * not the track is marked as destroyed. - * This assumes that the track id matches the simState object - * id. This assumption will be invalid someday once the two - * sets of ids are decoupled. - * TODO repair for this - */ - void tcSensorMapTrack::KillAssess() - { - if (simState->GetObject(mnID) == 0) - { - MarkDestroyed(); - #ifdef _DEBUG - fprintf(stdout, "Track %d marked destroyed\n", mnID); - #endif - } - } - - /** - * check for update reports and update track - */ - void tcSensorMapTrack::UpdateTrack() - { - - if (autoKillAssess) - { - if (IsStale() && !IsDestroyed()) - { - KillAssess(); - } - } - - // find first new active report since last update and update track - for(int n=0;n<mnContributors;n++) - { - tcSensorReport *pSensorReport = &maSensorReport[n]; - if ((!(pSensorReport->mnFlags & (TRACK_BEARING_ONLY|TRACK_TRIANGULATED))) - &&(pSensorReport->mfTimestamp > tcTrack::mfTimestamp)) - { - int bSpeedValid = (pSensorReport->mnFlags & TRACK_SPEED_VALID) ; - int bHeadingValid = (pSensorReport->mnFlags & TRACK_HEADING_VALID); - int bAltValid = (pSensorReport->mnFlags & TRACK_ALT_VALID); - - tcTrack::mnID = pSensorReport->mnTrackID; - tcTrack::mfLat_rad = pSensorReport->mfLat_rad; - tcTrack::mfLon_rad = pSensorReport->mfLon_rad; - tcTrack::mfTimestamp = pSensorReport->mfTimestamp; - - tcTrack::mnFlags = TRACK_ACTIVE; - if (bHeadingValid) - { - tcTrack::mfHeading_rad = pSensorReport->mfHeading_rad; - tcTrack::mnFlags |= TRACK_HEADING_VALID; - } - if (bSpeedValid) - { - tcTrack::mfSpeed_kts = pSensorReport->mfSpeed_kts; - tcTrack::mnFlags |= TRACK_SPEED_VALID; - } - if (bAltValid) - { - tcTrack::mfAlt_m = pSensorReport->mfAlt_m; - tcTrack::mnFlags |= TRACK_ALT_VALID; - } - return; - } - } - - // if the track is passive update with first new passive - if (tcTrack::mnFlags & TRACK_ACTIVE) {return;} - - for(int n=0;n<mnContributors;n++) - { - tcSensorReport *pSensorReport = &maSensorReport[n]; - if ((pSensorReport->mnFlags & (TRACK_BEARING_ONLY | TRACK_TRIANGULATED)) - &&(pSensorReport->mfTimestamp > tcTrack::mfTimestamp)) - { - tcTrack::mnID = pSensorReport->mnTrackID; - tcTrack::mfLat_rad = pSensorReport->mfLat_rad; - tcTrack::mfLon_rad = pSensorReport->mfLon_rad; - tcTrack::mfHeading_rad = pSensorReport->mfHeading_rad; - tcTrack::mfSpeed_kts = pSensorReport->mfSpeed_kts; - tcTrack::mfTimestamp = pSensorReport->mfTimestamp; - tcTrack::mnFlags = pSensorReport->mnFlags; - - tcTrack::mnPassivePlatformID = pSensorReport->mnSensorPlatformID; - return; - } - } - - - } - - /** - * remove report n and shift other reports to fill array from beginning - */ - void tcSensorMapTrack::RemoveReport(int n) - { - if ((n<0)||(n>=mnContributors)) {return;} - for(int k=n+1;k<mnContributors;k++) - { - maSensorReport[k-1] = maSensorReport[k]; - } - mnContributors--; - } - - bool tcSensorMapTrack::IsDestroyed() const - { - return (sensorFlags & TRACK_DESTROYED) != 0; - } - - bool tcSensorMapTrack::IsStale() const - { - return (sensorFlags & TRACK_STALE) != 0; - } - - void tcSensorMapTrack::MarkDestroyed() - { - sensorFlags |= TRACK_DESTROYED; - } - - void tcSensorMapTrack::MarkStale() - { - sensorFlags |= TRACK_STALE; - } - - void tcSensorMapTrack::ClearStale() - { - sensorFlags &= (~TRACK_STALE); - } - - - - - tcSensorMapTrack& tcSensorMapTrack::operator= (const tcSensorMapTrack& t) - { - *(tcTrack*)this = t ; - - for(int i=0;i<MAX_SENSOR_REPORTS;i++) - { - maSensorReport[i] = t.maSensorReport[i]; - } - mnContributors = t.mnContributors; - - for(int j=0;j<MAX_EMITTERS;j++) - { - maEmitterInfo[j] = t.maEmitterInfo[j]; - } - - mnEmitters = t.mnEmitters; - mnDatabaseID = t.mnDatabaseID; - sensorFlags = t.sensorFlags; - intercepts = t.intercepts; - engaged = t.engaged; - assessedDamage = t.assessedDamage; - - return(*this); - } - - tcSensorMapTrack::tcSensorMapTrack() - : sensorFlags(0), - mnEmitters(0), - mnContributors(0), - mnDatabaseID(-1), - assessedDamage(0) - { - tcTrack::mnID = NULL_INDEX; - tcTrack::mnAffiliation = 0; - tcTrack::mnAlliance = 0; - tcTrack::mnClassification = 0; - tcTrack::mfTimestamp = 0; - tcTrack::mnFlags = 0; - - } - - tcSensorMapTrack::~tcSensorMapTrack() - { - } /******************************* tcAllianceSensorMap ****************************/ --- 36,40 ---- --- NEW FILE: tcSensorMapTrack.cpp --- /** ** @file tcSensorMapTrack.cpp */ /* Copyright (C) 2003-2005 Dewitt Colclough (de...@tw...) ** All rights reserved. ** This file is part of the Global Conflict Blue (GCB) program. ** GCB is free software; you can redistribute it and/or modify ** it under the terms of version 2 of the GNU General Public License as ** published by the Free Software Foundation. ** GCB is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** You should have received a copy of the GNU General Public License ** along with GCB; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "stdwx.h" #include "tcSensorMapTrack.h" #include "aerror.h" #include "simmath.h" #include "tcSimState.h" #include "tcWeaponObject.h" #include "tcGenericDBObject.h" #include "common/tcObjStream.h" #include "tcDatabaseIterator.h" #include "tc3DModel.h" #ifdef _DEBUG #define new DEBUG_NEW #endif using namespace Sensor; /******************************* tcSensorMapTrack ****************************/ tcDatabase* tcSensorMapTrack::database = NULL; tcSimState* tcSensorMapTrack::simState = NULL; unsigned int tcSensorMapTrack::ambiguityListUpdates = 0; bool tcSensorMapTrack::autoKillAssess = false; /** * Set to true to automatically check and mark stale tracks that * are destroyed. */ void tcSensorMapTrack::SetAutoKillAssess(bool state) { autoKillAssess = state; } /** * Loads state from update stream */ tcUpdateStream& tcSensorMapTrack::operator<<(tcUpdateStream& stream) { tcTrack::operator<<(stream); stream >> mnContributors; for (int n = 0; n < mnContributors; n++) { stream >> maSensorReport[n].mfTimestamp; } stream >> sensorFlags; return stream; } /** * Saves state to update stream */ tcUpdateStream& tcSensorMapTrack::operator>>(tcUpdateStream& stream) { tcTrack::operator>>(stream); stream << mnContributors; for (int n = 0; n < mnContributors; n++) { stream << maSensorReport[n].mfTimestamp; } stream << sensorFlags; return stream; } /** * @return false if id already in engaged vector */ bool tcSensorMapTrack::AddEngagement(long id) { if (id == -1) return false; unsigned nEngaged = engaged.size(); for(unsigned n=0;n<nEngaged;n++) { if (engaged[n] == id) return false; } engaged.push_back(id); return true; } /** * @return false if id already in intercepts vector */ bool tcSensorMapTrack::AddIntercept(long id) { if (id == -1) return false; unsigned nIntercepts = intercepts.size(); for(unsigned n=0;n<nIntercepts;n++) { if (intercepts[n] == id) return false; } intercepts.push_back(id); return true; } void tcSensorMapTrack::Clear() { for (int k=0; k<mnContributors; k++) { tcSensorReport* sensorReport = &maSensorReport[k]; sensorReport->Clear(); } mnContributors = 0; mnEmitters = 0; mnDatabaseID = -1; assessedDamage = 0; intercepts.clear(); engaged.clear(); tcTrack::Clear(); } /** * @return number of contributors to this track */ unsigned tcSensorMapTrack::GetContributorCount() const { return (unsigned)mnContributors; } /** * @return name of contributing platform <idx> or pointer to "" if bad idx */ const char* tcSensorMapTrack::GetContributorName(unsigned idx) const { static const std::string emptyString(""); if (idx >= (unsigned)mnContributors) return emptyString.c_str(); long contributorId = maSensorReport[idx].mnSensorPlatformID; if (tcGameObject* obj = simState->GetObject(contributorId)) { return obj->mzUnit.mz; } else { return emptyString.c_str(); } } unsigned tcSensorMapTrack::GetEngagedCount() const { return engaged.size(); } unsigned tcSensorMapTrack::GetInterceptCount() const { return intercepts.size(); } tc3DModel* tcSensorMapTrack::GetModel() const { return model; } void tcSensorMapTrack::SetModel(tc3DModel* model_) { if (model) delete model; model = model_; } /** * This method is called periodically to cleanup the engaged vector. * There will be some lag between the state of this vector and true * state in the sim. */ void tcSensorMapTrack::UpdateEngagements() { wxASSERT(simState); int nEngaged = (int)engaged.size(); for (int n=nEngaged-1;n>=0;n--) { long id = engaged[n]; tcWeaponObject *weapon = dynamic_cast<tcWeaponObject*>(simState->GetObject(id)); if (weapon) { if (!weapon->IsIntendedTarget(tcTrack::mnID)) { engaged.erase(engaged.begin() + n); // weapon isn't targeting track } } else // weapon doesn't exist anymore, erase engaged id { engaged.erase(engaged.begin() + n); } } } /** * This method is called periodically to cleanup the intercepts vector. * There will be some lag between the state of this vector and true * state in the sim. */ void tcSensorMapTrack::UpdateIntercepts() { wxASSERT(simState); int nIntercepts = (int)intercepts.size(); for (int n=nIntercepts-1;n>=0;n--) { long id = intercepts[n]; tcPlatformObject *platform = dynamic_cast<tcPlatformObject*>(simState->GetObject(id)); if (platform) { if (!platform->IsInterceptingTrack(tcTrack::mnID)) { intercepts.erase(intercepts.begin() + n); // platform isn't intercepting track } } else // platform doesn't exist anymore, erase intercepts id { intercepts.erase(intercepts.begin() + n); } } } bool tcSensorMapTrack::UpdateEmitter(tsEmitterInfo*& rpEmitterInfo, tnPoolIndex anEmitterID) { // search for existing match for(int n=0;n<mnEmitters;n++) { tsEmitterInfo *pEmitterInfo = &maEmitterInfo[n]; if (pEmitterInfo->mnEmitterID == anEmitterID) { rpEmitterInfo = pEmitterInfo; return true; } } // add new emitter if there is room if (mnEmitters < MAX_EMITTERS) { rpEmitterInfo = &maEmitterInfo[mnEmitters++]; rpEmitterInfo->mnEmitterID = anEmitterID; rpEmitterInfo->mfTimestamp = 0; rpEmitterInfo->mnMode = 0; UpdateAmbiguityList(); return true; } return false; } bool tcSensorMapTrack::UpdateActiveReport(Sensor::tcSensorReport*& rpReport, tnPoolIndex anSensorID) { int nPassiveIdx = -1; // search for existing match for(int n=0; n<mnContributors; n++) { tcSensorReport *pSensorReport = &maSensorReport[n]; if (pSensorReport->mnFlags & (TRACK_BEARING_ONLY|TRACK_TRIANGULATED)) { nPassiveIdx = n; // used to have "int nPassiveIdx = n;" here !? } else if (pSensorReport->mnSensorPlatformID == anSensorID) { rpReport = pSensorReport; return true; } } // add new report if there is room if (mnContributors < MAX_SENSOR_REPORTS) { tcSensorReport *pSensorReport = &maSensorReport[mnContributors++]; pSensorReport->Clear(); pSensorReport->mnSensorPlatformID = anSensorID; rpReport = pSensorReport; return true; } // overwrite passive with active if one exists if (nPassiveIdx >= 0) { tcSensorReport *pSensorReport = &maSensorReport[nPassiveIdx]; pSensorReport->Clear(); pSensorReport->mnSensorPlatformID = anSensorID; rpReport = pSensorReport; return true; } rpReport = NULL; return false; } /** * Using database, updates ambiguity list of platforms * consistent with detected emitters */ void tcSensorMapTrack::UpdateAmbiguityList() { ambiguityList.clear(); // return if coarse classification is not available if (mnClassification == PTYPE_UNKNOWN) return; if (mnEmitters < 1) return; std::vector<long> emitterList; for (int n=0; n<mnEmitters; n++) { emitterList.push_back(maEmitterInfo[n].mnEmitterID); } tcDatabaseIterator iter(mnClassification); for (iter.First(); !iter.IsDone(); iter.Next()) { bool platformMatches = false; tcDatabaseObject* obj = iter.Get(); wxASSERT(obj); if (tcGenericDBObject* generic = dynamic_cast<tcGenericDBObject*>(obj)) { if (generic->HasAllEmitters(emitterList)) platformMatches = true; } else if (tcMissileDBObject* missile = dynamic_cast<tcMissileDBObject*>(obj)) { if (missile->HasAllEmitters(emitterList)) platformMatches = true; } if (platformMatches) { ambiguityList.push_back(obj->mnKey); } } /* use esm ambiguity list for identification if platform not ** identified, and there is exactly one entry in ambiguity list */ if ((ambiguityList.size() == 1) && (mnDatabaseID == -1)) { mnDatabaseID = ambiguityList[0]; } ambiguityListUpdates++; } bool tcSensorMapTrack::UpdatePassiveReport(Sensor::tcSensorReport*& rpReport, tnPoolIndex anSensorID) { //int nPassiveIdx = -1; // if track already has active data then do not update with passive data if (tcTrack::mnFlags & TRACK_ACTIVE) {return false;} // search for existing match for(int n=0;n<mnContributors;n++) { tcSensorReport *pSensorReport = &maSensorReport[n]; if ((pSensorReport->mnFlags & (TRACK_BEARING_ONLY|TRACK_TRIANGULATED))&& (pSensorReport->mnSensorPlatformID == anSensorID)) { rpReport = pSensorReport; return true; } } // add new report if there is room if (mnContributors < MAX_SENSOR_REPORTS) { tcSensorReport *pSensorReport = &maSensorReport[mnContributors++]; pSensorReport->Clear(); pSensorReport->mnSensorPlatformID = anSensorID; rpReport = pSensorReport; return true; } rpReport = NULL; return false; } void tcSensorMapTrack::UpdateClassification(UINT16 mnClassification, teAffiliation meAffiliation, tnPoolIndex databaseID) { if (mnClassification != 0) { tcTrack::mnClassification |= mnClassification; } if (meAffiliation != UNKNOWN) { tcTrack::mnAffiliation = meAffiliation; } if (databaseID != -1) { mnDatabaseID = databaseID; } UpdateAmbiguityList(); } /** * check if reporting sensor has reported, if so update report * if not add new report if slots are free */ bool tcSensorMapTrack::AddReport(const Sensor::tcSensorReport& report) { // search for existing match for(int n=0;n<mnContributors;n++) { tcSensorReport *pSensorReport = &maSensorReport[n]; //bool bActivePassiveMatch = (pSensorReport->mnFlags & report.mnFlags & TRACK_BEARING_ONLY); if ((pSensorReport->mnSensorPlatformID == report.mnSensorPlatformID)) { *pSensorReport = report; return true; } } // add new report if there is room if (mnContributors < MAX_SENSOR_REPORTS) { maSensorReport[mnContributors] = report; mnContributors++; return true; } return false; } /** * Queries simState to check if track object exists. If * not the track is marked as destroyed. * This assumes that the track id matches the simState object * id. This assumption will be invalid someday once the two * sets of ids are decoupled. * TODO repair for this */ void tcSensorMapTrack::KillAssess() { if (simState->GetObject(mnID) == 0) { MarkDestroyed(); #ifdef _DEBUG fprintf(stdout, "Track %d marked destroyed\n", mnID); #endif } } /** * check for update reports and update track */ void tcSensorMapTrack::UpdateTrack() { if (autoKillAssess) { if (IsStale() && !IsDestroyed()) { KillAssess(); } } // find first new active report since last update and update track for(int n=0;n<mnContributors;n++) { tcSensorReport *pSensorReport = &maSensorReport[n]; if ((!(pSensorReport->mnFlags & (TRACK_BEARING_ONLY|TRACK_TRIANGULATED))) &&(pSensorReport->mfTimestamp > tcTrack::mfTimestamp)) { int bSpeedValid = (pSensorReport->mnFlags & TRACK_SPEED_VALID) ; int bHeadingValid = (pSensorReport->mnFlags & TRACK_HEADING_VALID); int bAltValid = (pSensorReport->mnFlags & TRACK_ALT_VALID); tcTrack::mnID = pSensorReport->mnTrackID; tcTrack::mfLat_rad = pSensorReport->mfLat_rad; tcTrack::mfLon_rad = pSensorReport->mfLon_rad; tcTrack::mfTimestamp = pSensorReport->mfTimestamp; tcTrack::mnFlags = TRACK_ACTIVE; if (bHeadingValid) { tcTrack::mfHeading_rad = pSensorReport->mfHeading_rad; tcTrack::mnFlags |= TRACK_HEADING_VALID; } if (bSpeedValid) { tcTrack::mfSpeed_kts = pSensorReport->mfSpeed_kts; tcTrack::mnFlags |= TRACK_SPEED_VALID; } if (bAltValid) { tcTrack::mfAlt_m = pSensorReport->mfAlt_m; tcTrack::mnFlags |= TRACK_ALT_VALID; } return; } } // if the track is passive update with first new passive if (tcTrack::mnFlags & TRACK_ACTIVE) {return;} for(int n=0;n<mnContributors;n++) { tcSensorReport *pSensorReport = &maSensorReport[n]; if ((pSensorReport->mnFlags & (TRACK_BEARING_ONLY | TRACK_TRIANGULATED)) &&(pSensorReport->mfTimestamp > tcTrack::mfTimestamp)) { tcTrack::mnID = pSensorReport->mnTrackID; tcTrack::mfLat_rad = pSensorReport->mfLat_rad; tcTrack::mfLon_rad = pSensorReport->mfLon_rad; tcTrack::mfHeading_rad = pSensorReport->mfHeading_rad; tcTrack::mfSpeed_kts = pSensorReport->mfSpeed_kts; tcTrack::mfTimestamp = pSensorReport->mfTimestamp; tcTrack::mnFlags = pSensorReport->mnFlags; tcTrack::mnPassivePlatformID = pSensorReport->mnSensorPlatformID; return; } } } /** * remove report n and shift other reports to fill array from beginning */ void tcSensorMapTrack::RemoveReport(int n) { if ((n<0)||(n>=mnContributors)) {return;} for(int k=n+1;k<mnContributors;k++) { maSensorReport[k-1] = maSensorReport[k]; } mnContributors--; } bool tcSensorMapTrack::IsDestroyed() const { return (sensorFlags & TRACK_DESTROYED) != 0; } bool tcSensorMapTrack::IsStale() const { return (sensorFlags & TRACK_STALE) != 0; } void tcSensorMapTrack::MarkDestroyed() { sensorFlags |= TRACK_DESTROYED; } void tcSensorMapTrack::MarkStale() { sensorFlags |= TRACK_STALE; } void tcSensorMapTrack::ClearStale() { sensorFlags &= (~TRACK_STALE); } tcSensorMapTrack& tcSensorMapTrack::operator= (const tcSensorMapTrack& t) { *(tcTrack*)this = t ; for(int i=0;i<MAX_SENSOR_REPORTS;i++) { maSensorReport[i] = t.maSensorReport[i]; } mnContributors = t.mnContributors; for(int j=0;j<MAX_EMITTERS;j++) { maEmitterInfo[j] = t.maEmitterInfo[j]; } mnEmitters = t.mnEmitters; mnDatabaseID = t.mnDatabaseID; sensorFlags = t.sensorFlags; intercepts = t.intercepts; engaged = t.engaged; assessedDamage = t.assessedDamage; /* model is deliberately not copied to avoid overhead. This is ** a side effect of mixing graphics and data within tcSensorMapTrack */ model = 0; return(*this); } tcSensorMapTrack::tcSensorMapTrack(const tcSensorMapTrack& src) : tcTrack(src), sensorFlags(src.sensorFlags), mnEmitters(src.mnEmitters), mnContributors(src.mnContributors), mnDatabaseID(src.mnDatabaseID), assessedDamage(src.assessedDamage), model(0) { } tcSensorMapTrack::tcSensorMapTrack() : sensorFlags(0), mnEmitters(0), mnContributors(0), mnDatabaseID(-1), assessedDamage(0), model(0) { tcTrack::mnID = NULL_INDEX; tcTrack::mnAffiliation = 0; tcTrack::mnAlliance = 0; tcTrack::mnClassification = 0; tcTrack::mfTimestamp = 0; tcTrack::mnFlags = 0; } tcSensorMapTrack::~tcSensorMapTrack() { /* model is used for multiplayer client and for enemy alliances in single-play, ** otherwise it will remain 0 */ if (model) { model->SetSmokeMode(0); model->UpdateEffects(); // clear smoke particle generator model->DetachFromParent(); delete model; } } |