corrected angle conversion for different coordinate system
This commit is contained in:
parent
9ce83797ec
commit
10b4074e8a
@ -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;
|
||||||
@ -727,14 +727,29 @@ EntityConverter::extractFromEntity(const std::string &line, std::istream &is)
|
|||||||
std::string
|
std::string
|
||||||
EntityConverter::offset(const std::string &value, const float amount) const
|
EntityConverter::offset(const std::string &value, const float amount) const
|
||||||
{
|
{
|
||||||
std::istringstream iss(value);
|
std::istringstream iss(value);
|
||||||
float c;
|
float c;
|
||||||
iss >> c;
|
iss >> c;
|
||||||
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();
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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]);
|
||||||
|
Loading…
Reference in New Issue
Block a user