Exemple #1
0
void ClientSetup::SanityCheck()
{
	if (myPlayerName.empty()) myPlayerName = UnnamedPlayerName;
	StringReplaceInPlace(myPlayerName, ' ', '_');

	if (hostIP == "none") {
		hostIP = "";
	}
}
Exemple #2
0
bool COBJParser::ParseModelData(S3DModel* model, const std::string& modelData, const LuaTable& metaData)
{
	static const boost::regex commentPattern("^[ ]*(#|//).*");
	static const boost::regex objectPattern("^[ ]*o [ ]*[a-zA-Z0-9_]+[ ]*");
	static const boost::regex vertexPattern(
		"^[ ]*v "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)? "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)? "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)?"
		"[ ]*"
	);
	static const boost::regex normalPattern(
		"^[ ]*vn "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)? "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)? "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)?"
		"[ ]*"
	);
	static const boost::regex txcoorPattern(
		"^[ ]*vt "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)? "
		"[ ]*-?[0-9]*\\.?[0-9]*(e-?[0-9]*)?"
		"[ ]*"
	);
	static const boost::regex polygonPattern(
		"^[ ]*f "
		"[ ]*-?[0-9]+/-?[0-9]+/-?[0-9]+"
		"[ ]*-?[0-9]+/-?[0-9]+/-?[0-9]+"
		"[ ]*-?[0-9]+/-?[0-9]+/-?[0-9]+"
		"[ ]*"
		// do not allow spaces around the '/' separators or the
		// stringstream >> operator will tokenize the wrong way
		// (according to the OBJ spec they are illegal anyway:
		// "there is no space between numbers and the slashes")
		// "[ ]*-?[0-9]+[ ]*/[ ]*-?[0-9]+[ ]*/[ ]*-?[0-9]+"      // 1st vertex/texcoor/normal idx
		// "[ ]*-?[0-9]+[ ]*/[ ]*-?[0-9]+[ ]*/[ ]*-?[0-9]+"      // 2nd vertex/texcoor/normal idx
		// "[ ]*-?[0-9]+[ ]*/[ ]*-?[0-9]+[ ]*/[ ]*-?[0-9]+"      // 3rd vertex/texcoor/normal idx
	);


	PieceMap pieceMap;
	SOBJPiece* piece = NULL;

	std::vector<float3> vertices; vertices.reserve(2048);
	std::vector<float2> texcoors; texcoors.reserve(2048);
	std::vector<float3> vnormals; vnormals.reserve(2048);

	std::string line, lineHeader;
	std::stringstream lineStream;

	size_t prevReadIdx = 0;
	size_t currReadIdx = 0;

	bool regexMatch = false;

	while ((currReadIdx = modelData.find_first_of('\n', prevReadIdx)) != std::string::npos) {
		line = modelData.substr(prevReadIdx, (currReadIdx - prevReadIdx));
		line = StringReplaceInPlace(line, '\r', ' ');

		if (!line.empty()) {
			                   regexMatch = (boost::regex_match(line, commentPattern));
			if (!regexMatch) { regexMatch = (boost::regex_match(line, objectPattern )); }
			if (!regexMatch) { regexMatch = (boost::regex_match(line, vertexPattern )); }
			if (!regexMatch) { regexMatch = (boost::regex_match(line, normalPattern )); }
			if (!regexMatch) { regexMatch = (boost::regex_match(line, txcoorPattern )); }
			if (!regexMatch) { regexMatch = (boost::regex_match(line, polygonPattern)); }

			if (!regexMatch) {
				// ignore groups ('g'), smoothing groups ('s'),
				// and materials ("mtllib", "usemtl") for now
				// (s-groups are obsolete with vertex normals)
				logOutput.Print("[OBJParser] failed to parse line \"%s\" for model \"%s\"", line.c_str(), model->name.c_str());

				prevReadIdx = currReadIdx + 1;
				continue;
			}

			lineStream.str(line);
			lineStream >> lineHeader;

			switch (lineHeader[0]) {
				case '#': {
					// comment, no-op
				} break;

				case 'o': {
					// named object (piece)
					std::string pieceName;
					lineStream >> pieceName;

					assert(pieceMap.find(pieceName) == pieceMap.end());

					piece = new SOBJPiece();
					piece->name = pieceName;
					pieceMap[pieceName] = piece;

					model->numPieces += 1;
				} break;

				case 'v': {
					// position, normal, or texture-coordinates
					assert(piece != NULL);

					float3 f3;
						lineStream >> f3.x;
						lineStream >> f3.y;
						lineStream >> f3.z;
					float2 f2(f3.x, f3.y);

					     if (lineHeader == "v" ) { vertices.push_back(f3);   }
					else if (lineHeader == "vt") { texcoors.push_back(f2);   }
					else if (lineHeader == "vn") { vnormals.push_back(f3);   }
				} break;

				case 'f': {
					// face definition
					assert(piece != NULL);

					int
						vIdx = 0,
						tIdx = 0,
						nIdx = 0;
					size_t
						i = 0,
						j = 0,
						n = 0;

					SOBJTriangle triangle = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};

					while (lineStream.good() && n < 3) {
						std::string vtnIndices; lineStream >> vtnIndices;

						// vIdx/tcIdx/nIdx triplet of indices into the global lists
						i = vtnIndices.find('/',     0); assert(i != std::string::npos);
						j = vtnIndices.find('/', i + 1); assert(j != std::string::npos);

						vIdx = std::atoi(vtnIndices.substr(    0,     i).c_str());
						tIdx = std::atoi(vtnIndices.substr(i + 1, j - i).c_str());
						nIdx = std::atoi(vtnIndices.substr(j + 1       ).c_str());

						if (vIdx < 0) {
							triangle.vIndices[n] = vertices.size() + vIdx;
						} else {
							triangle.vIndices[n] = vIdx - 1;
						}

						if (tIdx < 0) {
							triangle.tIndices[n] = texcoors.size() + tIdx;
						} else {
							triangle.tIndices[n] = tIdx - 1;
						}

						if (nIdx < 0) {
							triangle.nIndices[n] = vnormals.size() + nIdx;
						} else {
							triangle.nIndices[n] = nIdx - 1;
						}

						n += 1;
					}

					const bool b0 =
						(triangle.vIndices[0] >= 0 && triangle.vIndices[1] >= 0 && triangle.vIndices[2] >= 0) &&
						(triangle.tIndices[0] >= 0 && triangle.tIndices[1] >= 0 && triangle.tIndices[2] >= 0) &&
						(triangle.nIndices[0] >= 0 && triangle.nIndices[1] >= 0 && triangle.nIndices[2] >= 0);
					const bool b1 =
						(triangle.vIndices[0] < vertices.size() && triangle.vIndices[1] < vertices.size() && triangle.vIndices[2] < vertices.size()) &&
						(triangle.tIndices[0] < texcoors.size() && triangle.tIndices[1] < texcoors.size() && triangle.tIndices[2] < texcoors.size()) &&
						(triangle.nIndices[0] < vnormals.size() && triangle.nIndices[1] < vnormals.size() && triangle.nIndices[2] < vnormals.size());

					assert(n == 3);
					assert(b0 && b1);

					if (b0 && b1) {
						// note: this assumes face elements may not reference indices
						// ahead of the current {vertices, texcoors, vnormals}.size()
						// if this *is* allowed, the entire file must be parsed first
						float3 &v0 = vertices[triangle.vIndices[0]], &v1 = vertices[triangle.vIndices[1]], &v2 = vertices[triangle.vIndices[2]];
						float2 &t0 = texcoors[triangle.tIndices[0]], &t1 = texcoors[triangle.tIndices[1]], &t2 = texcoors[triangle.tIndices[2]];
						float3 &n0 = vnormals[triangle.nIndices[0]], &n1 = vnormals[triangle.nIndices[1]], &n2 = vnormals[triangle.nIndices[2]];

						const int
							idx0 = (piece->GetTriangleCount() * 3) + 0,
							idx1 = (piece->GetTriangleCount() * 3) + 1,
							idx2 = (piece->GetTriangleCount() * 3) + 2;

						// convert to piece-local vtn indices
						triangle.vIndices[0] = idx0; piece->AddVertex(v0             );
						triangle.nIndices[0] = idx0; piece->AddNormal(n0.ANormalize());
						triangle.tIndices[0] = idx0; piece->AddTxCoor(t0             );

						triangle.vIndices[1] = idx1; piece->AddVertex(v1             );
						triangle.nIndices[1] = idx1; piece->AddNormal(n1.ANormalize());
						triangle.tIndices[1] = idx1; piece->AddTxCoor(t1             );

						triangle.vIndices[2] = idx2; piece->AddVertex(v2             );
						triangle.nIndices[2] = idx2; piece->AddNormal(n2.ANormalize());
						triangle.tIndices[2] = idx2; piece->AddTxCoor(t2             );

						piece->AddTriangle(triangle);
					} else {
						logOutput.Print("[OBJParser] illegal face-element indices on line \"%s\" for model \"%s\"", line.c_str(), model->name.c_str());
					}
				} break;

				default: {
				} break;
			}

			lineStream.clear();
			lineStream.str("");
		}

		prevReadIdx = currReadIdx + 1;
	}
Exemple #3
0
/**
 * Initializes instance of GameSetup
 */
void SpringApp::Startup()
{
	std::string inputFile = cmdline->GetInputFile();
	if (inputFile.empty())
	{
#ifdef HEADLESS
		LOG_L(L_FATAL,
				"The headless version of the engine can not be run in interactive mode.\n"
				"Please supply a start-script, save- or demo-file.");
		exit(1);
#endif
		bool server = !cmdline->IsSet("client") || cmdline->IsSet("server");
#ifdef SYNCDEBUG
		CSyncDebugger::GetInstance()->Initialize(server, 64);
#endif
		activeController = new SelectMenu(server);
	}
	else if (inputFile.rfind("sdf") == inputFile.size() - 3)
	{
		std::string demoFileName = inputFile;
		std::string demoPlayerName = configHandler->GetString("name");

		if (demoPlayerName.empty()) {
			demoPlayerName = "UnnamedPlayer";
		} else {
			demoPlayerName = StringReplaceInPlace(demoPlayerName, ' ', '_');
		}

		demoPlayerName += " (spec)";

		startsetup = new ClientSetup();
			startsetup->isHost       = true; // local demo play
			startsetup->myPlayerName = demoPlayerName;

#ifdef SYNCDEBUG
		CSyncDebugger::GetInstance()->Initialize(true, 64); //FIXME: add actual number of player
#endif

		pregame = new CPreGame(startsetup);
		pregame->LoadDemo(demoFileName);
	}
	else if (inputFile.rfind("ssf") == inputFile.size() - 3)
	{
		std::string savefile = inputFile;
		startsetup = new ClientSetup();
		startsetup->isHost = true;
		startsetup->myPlayerName = configHandler->GetString("name");
#ifdef SYNCDEBUG
		CSyncDebugger::GetInstance()->Initialize(true, 64); //FIXME: add actual number of player
#endif
		pregame = new CPreGame(startsetup);
		pregame->LoadSavefile(savefile);
	}
	else
	{
		LOG("Loading startscript from: %s", inputFile.c_str());
		std::string startscript = inputFile;
		CFileHandler fh(startscript);
		if (!fh.FileExists())
			throw content_error("Setup-script does not exist in given location: "+startscript);

		std::string buf;
		if (!fh.LoadStringData(buf))
			throw content_error("Setup-script cannot be read: " + startscript);
		startsetup = new ClientSetup();
		startsetup->Init(buf);

		// commandline parameters overwrite setup
		if (cmdline->IsSet("client"))
			startsetup->isHost = false;
		else if (cmdline->IsSet("server"))
			startsetup->isHost = true;

#ifdef SYNCDEBUG
		CSyncDebugger::GetInstance()->Initialize(startsetup->isHost, 64); //FIXME: add actual number of player
#endif
		pregame = new CPreGame(startsetup);
		if (startsetup->isHost)
			pregame->LoadSetupscript(buf);
	}
}