size_t MapWriter::writeFace(Model::Face& face, const size_t lineNumber, FILE* stream) { const String textureName = Utility::isBlank(face.textureName()) ? Model::Texture::Empty : face.textureName(); std::fprintf(stream, FaceFormat.c_str(), face.point(0).x(), face.point(0).y(), face.point(0).z(), face.point(1).x(), face.point(1).y(), face.point(1).z(), face.point(2).x(), face.point(2).y(), face.point(2).z(), textureName.c_str(), face.xOffset(), face.yOffset(), face.rotation(), face.xScale(), face.yScale()); face.setFilePosition(lineNumber); return 1; }
Model::Face* MapParser::parseFace(const BBox& worldBounds) { Vec3f p1, p2, p3; float xOffset, yOffset, rotation, xScale, yScale; Token token = m_tokenizer.nextToken(); if (token.type() == TokenType::Eof) return NULL; expect(TokenType::OParenthesis, token); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p1.x = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p1.y = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p1.z = token.toFloat(); expect(TokenType::CParenthesis, token = m_tokenizer.nextToken()); expect(TokenType::OParenthesis, token = m_tokenizer.nextToken()); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p2.x = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p2.y = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p2.z = token.toFloat(); expect(TokenType::CParenthesis, token = m_tokenizer.nextToken()); expect(TokenType::OParenthesis, token = m_tokenizer.nextToken()); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p3.x = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p3.y = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); p3.z = token.toFloat(); expect(TokenType::CParenthesis, token = m_tokenizer.nextToken()); expect(TokenType::String, token = m_tokenizer.nextToken()); String textureName = token.data(); token = m_tokenizer.nextToken(); if (m_format == Undefined) { expect(TokenType::Integer | TokenType::Decimal | TokenType::OBracket, token); m_format = token.type() == TokenType::OBracket ? Valve : Standard; if (m_format == Valve) m_console.warn("Loading unsupported map Valve 220 map format"); } if (m_format == Standard) { expect(TokenType::Integer | TokenType::Decimal, token); xOffset = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); yOffset = token.toFloat(); } else { // Valve 220 format expect(TokenType::OBracket, token); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // X texture axis x expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // X texture axis y expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // X texture axis z expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // X texture axis offset xOffset = token.toFloat(); expect(TokenType::CBracket, token = m_tokenizer.nextToken()); expect(TokenType::OBracket, token = m_tokenizer.nextToken()); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // Y texture axis x expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // Y texture axis y expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // Y texture axis z expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); // Y texture axis offset yOffset = token.toFloat(); expect(TokenType::CBracket, token = m_tokenizer.nextToken()); } expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); rotation = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); xScale = token.toFloat(); expect(TokenType::Integer | TokenType::Decimal, token = m_tokenizer.nextToken()); yScale = token.toFloat(); if (((p3 - p1).crossed(p2 - p1)).null()) { m_console.warn("Skipping face with colinear points in line %i", token.line()); return NULL; } if (textureName == Model::Texture::Empty) textureName = ""; Model::Face* face = new Model::Face(worldBounds, p1, p2, p3, textureName); face->setXOffset(xOffset); face->setYOffset(yOffset); face->setRotation(rotation); face->setXScale(xScale); face->setYScale(yScale); face->setFilePosition(token.line()); return face; }