diff --git a/code/nel/tools/3d/textures_tool/main.cpp b/code/nel/tools/3d/textures_tool/main.cpp index 997557ffc..592df935f 100644 --- a/code/nel/tools/3d/textures_tool/main.cpp +++ b/code/nel/tools/3d/textures_tool/main.cpp @@ -44,7 +44,7 @@ const CPoint Down(0, 1); const CPoint Left(-1, 0); const CPoint Right(1, 0); -const uint TextureSize = 4096; +uint TextureSize = 4096; const NLMISC::CRGBA DiscardColor = NLMISC::CRGBA::Red; const NLMISC::CRGBA KeepColor = NLMISC::CRGBA::Blue; @@ -53,8 +53,19 @@ typedef std::vector CPoints; struct CFace { - static const uint INDICES_COUNT = 3; - uint indices[INDICES_COUNT]; + std::vector indices; +}; + +struct CObject +{ + std::string name; + std::vector textureCoords; + std::vector faces; + + void display() + { + nlinfo("Object %s processed with %u vertices and %u faces", name.c_str(), (uint)textureCoords.size(), (uint)faces.size()); + } }; bool fillPoint(NLMISC::CBitmap &bitmap, sint width, CPoints &points) @@ -100,6 +111,23 @@ bool fillPoint(NLMISC::CBitmap &bitmap, sint width, CPoints &points) return true; } +void drawEdge(NLMISC::CBitmap &bitmap, const CObject &object, const CFace &face, uint index0, uint index1) +{ + NLMISC::CUV uv0 = object.textureCoords[face.indices[index0]]; + NLMISC::CUV uv1 = object.textureCoords[face.indices[index1]]; + + std::vector > pixels; + + // draw the triangle with vertices UV coordinates + NLMISC::drawFullLine(uv0.U, uv0.V, uv1.U, uv1.V, pixels); + + // for each pixels, set them to black + for (uint j = 0, jlen = pixels.size(); j < jlen; ++j) + { + bitmap.setPixelColor(pixels[j].first, pixels[j].second, NLMISC::CRGBA::Black); + } +} + int main(int argc, char **argv) { NLMISC::CApplicationContext applicationContext; @@ -113,6 +141,7 @@ int main(int argc, char **argv) args.addArg("f", "fill", "color or image", "Fill background part with color or image"); args.addArg("u", "uvmap", "", "Generate a UV Map texture from OBJ file"); args.addArg("w", "width", "width of border", "Width of the border to fill (default 0)"); + args.addArg("s", "size", "size of output bitmap", "Width and height of generated bitmap (default 4096)"); args.addArg("b", "background", "background color", "Color to use to fill background"); args.addArg("o", "output", "filename", "Output filename"); args.addAdditionalArg("filename", "File to process", true, true); @@ -123,6 +152,12 @@ int main(int argc, char **argv) std::string output = args.haveArg("o") ? args.getArg("o").front() : ""; + if (args.haveArg("s")) + { + // size of generated bitmap + NLMISC::fromString(args.getArg("s").front(), TextureSize); + } + if (args.haveArg("c")) { // colorize @@ -278,9 +313,6 @@ int main(int argc, char **argv) if (args.haveArg("u")) { - std::vector verticeTextureCoords; - std::vector faces; - NLMISC::CIFile objFile; if (!objFile.open(filename)) @@ -289,6 +321,8 @@ int main(int argc, char **argv) return 1; } + CObject object; + char buffer[1024]; while (!objFile.eof()) @@ -298,11 +332,18 @@ int main(int argc, char **argv) std::string line(buffer); + if (line.size() > 1022) + { + nlwarning("More than 1022 bytes on a line!"); + return 1; + } + if (line.size() < 3) continue; // texture coordinate if (line.substr(0, 3) == "vt ") { + // vertex texture std::vector tokens; NLMISC::explode(line, std::string(" "), tokens); @@ -313,7 +354,7 @@ int main(int argc, char **argv) NLMISC::fromString(tokens[2], v); // V coordinates are inverted - verticeTextureCoords.push_back(NLMISC::CUV(u * (float)TextureSize, (1.f - v) * (float)TextureSize)); + object.textureCoords.push_back(NLMISC::CUV(u * (float)TextureSize, (1.f - v) * (float)TextureSize)); } else { @@ -322,41 +363,49 @@ int main(int argc, char **argv) } else if (line.substr(0, 2) == "f ") { + // face std::vector tokens; NLMISC::explode(line, std::string(" "), tokens); - if (tokens.size() == 4) + CFace face; + face.indices.resize(tokens.size()-1); + + bool faceValid = true; + + for (uint i = 1, ilen = tokens.size(); i < ilen; ++i) { - CFace face; + std::vector tokens2; + NLMISC::explode(tokens[i], std::string("/"), tokens2); - for (uint i = 1; i < 4; ++i) + if (tokens2.size() == 3) { - std::vector tokens2; - NLMISC::explode(tokens[i], std::string("/"), tokens2); - - if (tokens2.size() == 3) + if (NLMISC::fromString(tokens2[1], face.indices[i - 1])) { - NLMISC::fromString(tokens2[1], face.indices[i - 1]); - // we want indices start from 0 instead of 1 --face.indices[i - 1]; } else { - nlwarning("Not 3 arguments for indices"); + faceValid = false; } } + else + { + nlwarning("Not 3 arguments for indices"); + } + } - faces.push_back(face); - } - else - { - nlwarning("Not 4 arguments for F"); - } + if (faceValid) object.faces.push_back(face); + } + else if (line.substr(0, 2) == "o ") + { + // object + object.name = line.substr(2); + object.display(); } } - nlinfo("OBJ file processed with %u vertices and %u faces", (uint)verticeTextureCoords.size(), (uint)faces.size()); + object.display(); objFile.close(); @@ -369,35 +418,18 @@ int main(int argc, char **argv) memset(&outBitmap.getPixels()[0], 255, TextureSize * TextureSize * 4); // process all faces - for (uint i = 0, len = faces.size(); i < len; ++i) + for (uint i = 0, ilen = object.faces.size(); i < ilen; ++i) { - const CFace &face = faces[i]; + const CFace &face = object.faces[i]; - // the 3 pixels of a vertice - NLMISC::CUV uv0 = verticeTextureCoords[face.indices[0]]; - NLMISC::CUV uv1 = verticeTextureCoords[face.indices[1]]; - NLMISC::CUV uv2 = verticeTextureCoords[face.indices[2]]; - - std::vector > pixels, temp; - - // draw the triangle with vertices UV coordinates - NLMISC::drawFullLine(uv0.U, uv0.V, uv1.U, uv1.V, pixels); - - // append pixels - NLMISC::drawFullLine(uv1.U, uv1.V, uv2.U, uv2.V, temp); - pixels.reserve(pixels.size() + temp.size()); - pixels.insert(pixels.end(), temp.begin(), temp.end()); - - // append pixels - NLMISC::drawFullLine(uv2.U, uv2.V, uv0.U, uv0.V, temp); - pixels.reserve(pixels.size() + temp.size()); - pixels.insert(pixels.end(), temp.begin(), temp.end()); - - // for each pixels, set them to black - for (uint j = 0, jlen = pixels.size(); j < jlen; ++j) + // pixels of a face + for (uint k = 1, klen = face.indices.size(); k < klen; ++k) { - outBitmap.setPixelColor(pixels[j].first, pixels[j].second, NLMISC::CRGBA::Black); + drawEdge(outBitmap, object, face, k - 1, k); } + + // link last and fist pixels + drawEdge(outBitmap, object, face, face.indices.size()-1, 0); } // save output bitmap