///////////////////////////////////////////////////////////////////// // Created by Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// /* // TODO Painting hitPoints = 0 armour = 0 centerOfMass = 0 0 0 mass = 0 ../entities/models/painting_0.obj A painting of a brunette.@@She has brown eyes... */ #include "InstanceBlueprint.h" #include "Utilities.h" #include #include using namespace ::GameLogic; using namespace ::Oyster::Math; using ::std::string; using ::std::vector; using ::std::ifstream; using ::std::stringstream; namespace PrivateStatic { bool seekNextObject( string &idNameOutput, ::std::istream &source ) { string str; vector splitString; while( !source.eof() ) { source >> str; if( str.size() == 0 ) continue; if( str[0] == '#' ) { // rest of line is all commentary ::std::getline( source, str ); continue; } if( str[0] != '<' ) continue; if( str.size() == 1 ) { if( !source.eof() ) source >> str; } else str = str.substr( 1 ); ::Utility::String::toLowerCase( str ); if( str != "object" ) continue; if( source.eof() ) return false; source >> str; ::Utility::String::split( splitString, str, '\"' ); // since str have no prefix whitespaces, we can safely assume // splitString[0] is the string we want. the rest is garbage. idNameOutput = ::Utility::String::trim( splitString[0] ); return true; } return false; } void fillInstanceBlueprint( InstanceBlueprint &targetMem, ::std::istream &source, const Float4x4 &transform ) { string line; vector splitString; vector tagDelims(2); tagDelims[0] = "<"; tagDelims[1] = ">"; Float4 minPoint = Float4( Float3(::std::numeric_limits::max()), 1.0f ), maxPoint = Float4( Float3(-::std::numeric_limits::max()), 1.0f ), centerOfMass = Float4( Float3::null, 1.0f ); while( !source.eof() ) { ::std::getline( source, line ); line = ::Utility::String::trim( line ); if( line.length() == 0 ) continue; if( line[0] == '#' ) continue; splitString = vector(); ::Utility::String::split( splitString, line, '#' ); line = ::Utility::String::trim( splitString[0] ); if( line.length() == 0 ) continue; // just to be sure if( line[0] == '<' ) { // it's possibly , , , or splitString = vector(); ::Utility::String::split( splitString, line, tagDelims ); line = ::Utility::String::toLowerCase( ::Utility::String::trim(splitString[0]) ); if( line == "displayname" ) { // Painting targetMem.name = ::Utility::String::trim(splitString[1]); } else if( line == "model" ) { // ../entities/models/painting_0.obj targetMem.objFileName = ::Utility::String::replaceCharacters( ::Utility::String::trim(splitString[1]), '/', '\\' ); } else if( line == "description" ) { /* A painting of a brunette.@@She has brown eyes... */ if( splitString.size() > 1 ) line = ::Utility::String::trim( splitString[1] ); else { if( source.eof() ) return; ::std::getline( source, line ); } splitString = vector(); ::Utility::String::split( splitString, line, "@@" ); stringstream strBuilder( splitString[0] ); vector::size_type numSplits = splitString.size(); for( vector::size_type i = 1; i < numSplits; ++i ) { if( i > 1 ) strBuilder << '\n'; strBuilder << splitString[i]; } targetMem.description = strBuilder.str(); } else if( line.find_first_of("box") == 0 ) { /* */ stringstream stream( line ); stream >> line; if( line != "box" ) continue; Float3 point; ::Utility::Stream::readFloats( point.element, stream, 3 ); minPoint.xyz = ::Utility::Value::min( minPoint.xyz, point ); maxPoint.xyz = ::Utility::Value::max( maxPoint.xyz, point ); ::Utility::Stream::readFloats( point.element, stream, 3 ); minPoint.xyz = ::Utility::Value::min( minPoint.xyz, point ); maxPoint.xyz = ::Utility::Value::max( maxPoint.xyz, point ); } else if( line == "/object" ) break; continue; // no point to continue further down } // end of "if( line[0] == '<' )" splitString = vector(); ::Utility::String::split( splitString, line, '=' ); if( splitString.size() > 1 ) { splitString[0] = ::Utility::String::toLowerCase( ::Utility::String::trim(splitString[0]) ); if( splitString[0] == "hitpoints" ) { // hitPoints = 0 splitString[1] = ::Utility::String::trim(splitString[1]); targetMem.hullPoints = ::std::atoi( splitString[1].c_str() ); } else if( splitString[0] == "armour" ) // ?? { // armour = 0 splitString[1] = ::Utility::String::trim(splitString[1]); targetMem.shieldPoints = ::std::atoi( splitString[1].c_str() ); } else if( splitString[0] == "mass" ) { // mass = 0 splitString[1] = ::Utility::String::trim(splitString[1]); targetMem.mass = (float)::std::atof( splitString[1].c_str() ); if( targetMem.mass == 0.0f ) targetMem.mass = ::std::numeric_limits::max(); } else if( splitString[0] == "centerofmass" ) { // centerOfMass = 0 0 0 stringstream stream( splitString[1] ); ::Utility::Stream::readFloats( centerOfMass.element, stream, 3 ); } else if( splitString[0] == "maxspeed" ) { // maxspeed = [ float of top speed: default 400.0 ] stringstream stream( splitString[1] ); string value; stream >> value; targetMem.movementProperty.maxSpeed = (float)::std::atof( value.c_str() ); } else if( splitString[0] == "deacceleration" ) { // deacceleration = [ float of acceleration : default 50.0 ] stringstream stream( splitString[1] ); string value; stream >> value; targetMem.movementProperty.deAcceleration = (float)::std::atof( value.c_str() ); } else if( splitString[0] == "forward" ) { // forward = [ float of acceleration : default 50.0 ] stringstream stream( splitString[1] ); string value; stream >> value; targetMem.movementProperty.acceleration.forward = (float)::std::atof( value.c_str() ); } else if( splitString[0] == "backward" ) { // backward = [ float of acceleration : default 25.0 ] stringstream stream( splitString[1] ); string value; stream >> value; targetMem.movementProperty.acceleration.backward = (float)::std::atof( value.c_str() ); } else if( splitString[0] == "strafe" ) { // strafe = [ float of acceleration : default 25.0 ] stringstream stream( splitString[1] ); string sValue; stream >> sValue; float fValue = (float)::std::atof( sValue.c_str() ); targetMem.movementProperty.acceleration.horizontal = fValue; targetMem.movementProperty.acceleration.vertical = fValue; } else if( splitString[0] == "turnspeed" ) { // turnspeed = [ float in degrees : default 90.0 ] stringstream stream( splitString[1] ); string sValue; stream >> sValue; float fValue = ::Utility::Value::radian( (float)::std::atof(sValue.c_str()) ); targetMem.rotationProperty.maxSpeed = fValue; targetMem.rotationProperty.deAcceleration = 2.0f * fValue; targetMem.rotationProperty.acceleration.pitch = fValue; targetMem.rotationProperty.acceleration.yaw = fValue; targetMem.rotationProperty.acceleration.roll = fValue; } } } targetMem.centerOfMass = transformVector( centerOfMass, centerOfMass, transform ).xyz; if( minPoint != Float4( Float3(::std::numeric_limits::max()), 1.0f ) ) if( maxPoint != Float4( Float3(-::std::numeric_limits::max()), 1.0f ) ) { transformVector( minPoint, minPoint, transform ); transformVector( maxPoint, maxPoint, transform ); targetMem.hitBox.position = (maxPoint.xyz - minPoint.xyz) * 0.5f; targetMem.hitBox.halfSize = ::Utility::Value::abs( targetMem.hitBox.position ); targetMem.hitBox.position += minPoint.xyz; } } } InstanceBlueprint::Result InstanceBlueprint::loadFromFile( vector &output, vector &idOutput, const string &entityFile, const Float4x4 &transform ) { ifstream file( entityFile ); if( file.is_open() ) { string idName, workingDir; ::Utility::String::extractDirPath( workingDir, entityFile, '\\' ); while( PrivateStatic::seekNextObject(idName, file) ) { InstanceBlueprint* blueprint = new InstanceBlueprint(); PrivateStatic::fillInstanceBlueprint( *blueprint, file, transform ); if( blueprint->objFileName.length() > 0 ) blueprint->objFileName = workingDir + blueprint->objFileName; output.push_back( blueprint ); idOutput.push_back( idName ); } file.close( ); return Success; } else return Failure; } InstanceBlueprint::InstanceBlueprint( ) : name(), objFileName(), description(), mass(::std::numeric_limits::max()), centerOfMass(Float3::null), hullPoints(255), shieldPoints(255) { this->hitBox.halfSize = Float3::null; this->hitBox.position = Float3::null; this->movementProperty.maxSpeed = 400.0f; this->movementProperty.deAcceleration = 50.0f; this->movementProperty.acceleration.forward = 50.0f; this->movementProperty.acceleration.backward = 25.0f; this->movementProperty.acceleration.horizontal = 25.0f; this->movementProperty.acceleration.vertical = 25.0f; this->rotationProperty.maxSpeed = ::Utility::Value::radian( 90.0f ); this->rotationProperty.deAcceleration = ::Utility::Value::radian( 180.0f ); this->rotationProperty.acceleration.pitch = ::Utility::Value::radian( 90.0f ); this->rotationProperty.acceleration.yaw = ::Utility::Value::radian( 90.0f ); this->rotationProperty.acceleration.roll = ::Utility::Value::radian( 90.0f ); }