corrected angle conversion for different coordinate system

This commit is contained in:
suhrke 2017-07-08 02:50:37 -07:00
parent 9ce83797ec
commit 10b4074e8a
3 changed files with 76 additions and 38 deletions

View File

@ -5,7 +5,7 @@
* *
* Description: Convert Reflex entities into Xonotic entities * Description: Convert Reflex entities into Xonotic entities
* *
* Version: 0.1 * Version: 1.0
* Created: 06/05/2017 07:15:25 PM * Created: 06/05/2017 07:15:25 PM
* Revision: none * Revision: none
* Compiler: gcc * Compiler: gcc
@ -30,7 +30,8 @@
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
EntityConverter::EntityConverter(const std::string &entityMapFile) : EntityConverter::EntityConverter(const std::string &entityMapFile) :
OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0), BRIGHTNESS_ADJUST(50.0) OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0), BRIGHTNESS_ADJUST(50.0),
OUTPUT_PRECISION(10)
{ {
//MUST RUN extractMapInfo method after this constructor //MUST RUN extractMapInfo method after this constructor
haveMapInfo_ = false; haveMapInfo_ = false;
@ -48,7 +49,7 @@ EntityConverter::EntityConverter(const std::string &entityMapFile) :
EntityConverter::EntityConverter(const std::string &entityMapFile, EntityConverter::EntityConverter(const std::string &entityMapFile,
const std::string &reflexMapFile) : OFFSET_PLAYER(32.0), const std::string &reflexMapFile) : OFFSET_PLAYER(32.0),
OFFSET_PICKUP(2.0), BRIGHTNESS_ADJUST(50.0) OFFSET_PICKUP(2.0), BRIGHTNESS_ADJUST(50.0), OUTPUT_PRECISION(10)
{ {
haveMapInfo_ = false; haveMapInfo_ = false;
// game modes default to enabled // game modes default to enabled
@ -299,8 +300,8 @@ EntityConverter::convertPlayerSpawn(const std::vector<std::string> &lines) const
std::vector<std::string> convertedLines; std::vector<std::string> convertedLines;
// Requires position coordinate // Requires position coordinate
std::string coords[3]; std::string coords[3];
// Requires an angle so if no reflex one is given, use 0 // Requires an angle, default to 0 degrees (floating point)
std::string angle("0"); std::string angle("0.0");
// 1-2 for corresponding team, 0 for deathmatch spawn // 1-2 for corresponding team, 0 for deathmatch spawn
int team = 0; int team = 0;
std::string trash; std::string trash;
@ -359,7 +360,6 @@ EntityConverter::convertPlayerSpawn(const std::vector<std::string> &lines) const
} }
if ( havePosition ) { if ( havePosition ) {
// Will convert all race points to dm/team spawns on maps that support race AND others
if ( isModeCtf || isModeTdm || isModeFfa || isModeDuel ) { if ( isModeCtf || isModeTdm || isModeFfa || isModeDuel ) {
switch (team) { switch (team) {
case 0: case 0:
@ -387,7 +387,7 @@ EntityConverter::convertPlayerSpawn(const std::vector<std::string> &lines) const
offset(coords[1], OFFSET_PLAYER) << "\"" << std::endl; offset(coords[1], OFFSET_PLAYER) << "\"" << std::endl;
convertedLines.push_back ( positionStream.str() ); convertedLines.push_back ( positionStream.str() );
std::stringstream angleStream; std::stringstream angleStream;
angleStream << "\"angle\" \"" << angle << "\"" << std::endl; angleStream << "\"angle\" \"" << adjustAngleForHandedness(angle) << "\"" << std::endl;
convertedLines.push_back (angleStream.str() ); convertedLines.push_back (angleStream.str() );
return convertedLines; return convertedLines;
} }
@ -534,7 +534,7 @@ EntityConverter::convertTarget(const std::vector<std::string> &lines) const
// Write angle only if position and name exist // Write angle only if position and name exist
if ( haveAngle ) { if ( haveAngle ) {
std::stringstream angleStream; std::stringstream angleStream;
angleStream << "\"angle\" \"" << angle << "\"" << std::endl; angleStream << "\"angle\" \"" << adjustAngleForHandedness(angle) << "\"" << std::endl;
convertedLines.push_back( angleStream.str() ); convertedLines.push_back( angleStream.str() );
} }
return convertedLines; return convertedLines;
@ -733,7 +733,22 @@ EntityConverter::offset(const std::string &value, const float amount) const
c += amount; c += amount;
std::stringstream ss; std::stringstream ss;
ss << std::fixed << std::setprecision(5) << c; ss << std::fixed << std::setprecision(OUTPUT_PRECISION) << c;
return ss.str();
}
std::string
EntityConverter::adjustAngleForHandedness(const std::string &angle) const
{
std::istringstream iss(angle);
float a;
iss >> a;
a = -a + 90.0;
std::stringstream ss;
ss << std::fixed << std::setprecision(OUTPUT_PRECISION) << a;
return ss.str(); return ss.str();
} }

View File

@ -133,25 +133,6 @@ class EntityConverter
std::vector<std::string> convertRaceFinish(const std::vector<std::string> &lines) const; std::vector<std::string> convertRaceFinish(const std::vector<std::string> &lines) const;
std::vector<std::string> convertPointLight(const std::vector<std::string> &lines) const; std::vector<std::string> convertPointLight(const std::vector<std::string> &lines) const;
// Map Reflex pickup IDs to Xonotic pickup identifiers
std::map<int, std::string> pickupMap_;
// Map targets (by name) to their source type
std::map<std::string, std::string> targetMap_;
// Related entities must be matched prior to entity conversion
bool haveMapInfo_;
WorldSpawn ws_;
// Offsets for item/spawn height
const float OFFSET_PLAYER;
const float OFFSET_PICKUP;
// Brightness adjustment factor
const float BRIGHTNESS_ADJUST;
private:
/* /*
*-------------------------------------------------------------------------------------- *--------------------------------------------------------------------------------------
* Class: EntityConverter * Class: EntityConverter
@ -194,6 +175,16 @@ class EntityConverter
*-------------------------------------------------------------------------------------- *--------------------------------------------------------------------------------------
*/ */
std::string offset(const std::string &value, const float offset) const; std::string offset(const std::string &value, const float offset) const;
/*
*--------------------------------------------------------------------------------------
* Class: EntityConverter
* Method: EntityConverter :: adjustAngleForHandedness
* Description: Axis swaps require angles to take this into account
* Parameter: string angle, an angle in degrees
* Return: string, the adjusted angle in degrees
*--------------------------------------------------------------------------------------
*/
std::string adjustAngleForHandedness(const std::string &angle) const;
/* /*
*-------------------------------------------------------------------------------------- *--------------------------------------------------------------------------------------
* Class: EntityConverter * Class: EntityConverter
@ -218,6 +209,25 @@ class EntityConverter
// Map Reflex pickup IDs to Xonotic pickup identifiers
std::map<int, std::string> pickupMap_;
// Map targets (by name) to their source type
std::map<std::string, std::string> targetMap_;
// Related entities must be matched prior to entity conversion
bool haveMapInfo_;
WorldSpawn ws_;
// Offsets for item/spawn height
const float OFFSET_PLAYER;
const float OFFSET_PICKUP;
// Brightness adjustment factor
const float BRIGHTNESS_ADJUST;
// Floating point precision for output
const int OUTPUT_PRECISION;
private:
void printMapping() const; //DEBUG void printMapping() const; //DEBUG
void printTargetSources() const; //DEBUG void printTargetSources() const; //DEBUG

View File

@ -5,7 +5,7 @@
* *
* Description: Unit Tests for EntityConverter * Description: Unit Tests for EntityConverter
* *
* Version: 0.1 * Version: 1.0
* Created: 07/03/2017 08:25:04 PM * Created: 07/03/2017 08:25:04 PM
* Revision: none * Revision: none
* Compiler: gcc * Compiler: gcc
@ -136,7 +136,6 @@ TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityC
REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" ); REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" );
REQUIRE( converted[1] == "\"target\" \"cp1\"\n" ); REQUIRE( converted[1] == "\"target\" \"cp1\"\n" );
REQUIRE( converted[2] == "\"race_place\" \"-1\"\n" ); REQUIRE( converted[2] == "\"race_place\" \"-1\"\n" );
REQUIRE( converted[4] == "\"angle\" \"180.00000\"\n" );
// The z (vertical) is offset by +32 // The z (vertical) is offset by +32
std::istringstream iss(converted[3]); std::istringstream iss(converted[3]);
@ -150,6 +149,22 @@ TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityC
REQUIRE( coords[1] == "-1488.000488" ); REQUIRE( coords[1] == "-1488.000488" );
REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA );
SECTION( "Converted angles are valid (Different coordinate system handedness)" ) {
std::istringstream angleLineStream(converted[4]);
std::string angleAttribute;
std::string a;
float angle;
angleLineStream >> attribute >> a;
a.erase(a.begin()); //removing preceding quote is necessary
std::stringstream angleStream(a);
angleStream >> angle;
REQUIRE( attribute == "\"angle\"" );
REQUIRE( fabs( -90.0 - angle) <= DELTA );
}
SECTION( "Encountering a new worldspawn reenables all modes" ) { SECTION( "Encountering a new worldspawn reenables all modes" ) {
std::vector<std::string> basicWorldspawn; std::vector<std::string> basicWorldspawn;
basicWorldspawn.push_back(" type WorldSpawn"); basicWorldspawn.push_back(" type WorldSpawn");
@ -192,7 +207,6 @@ TEST_CASE( "r2x: a single PlayerSpawn (teamA) entity can be converted", "[Entity
std::vector<std::string> converted = ec.convert(entity); std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"info_player_team1\"\n" ); REQUIRE( converted[0] == "\"classname\" \"info_player_team1\"\n" );
REQUIRE( converted[2] == "\"angle\" \"180.00000\"\n" );
// The z (vertical) is offset by +32 // The z (vertical) is offset by +32
std::istringstream iss(converted[1]); std::istringstream iss(converted[1]);
@ -231,7 +245,6 @@ TEST_CASE( "r2x: a single PlayerSpawn (non-team) entity can be converted", "[Ent
std::vector<std::string> converted = ec.convert(entity); std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"info_player_deathmatch\"\n" ); REQUIRE( converted[0] == "\"classname\" \"info_player_deathmatch\"\n" );
REQUIRE( converted[2] == "\"angle\" \"180.00000\"\n" );
// The z (vertical) is offset by +32 // The z (vertical) is offset by +32
std::istringstream iss(converted[1]); std::istringstream iss(converted[1]);