diff --git a/code/nel/tools/3d/build_interface/main.cpp b/code/nel/tools/3d/build_interface/main.cpp index 266cd410b..2a5cef8f5 100644 --- a/code/nel/tools/3d/build_interface/main.cpp +++ b/code/nel/tools/3d/build_interface/main.cpp @@ -210,6 +210,7 @@ int main(int argc, char **argv) args.setDescription("Build a huge interface texture from several small elements to optimize video memory usage."); args.addArg("s", "subset", "existing_uv_txt_name", "Build a subset of an existing interface definition while preserving the existing texture ids, to support freeing up VRAM by switching to the subset without rebuilding the entire interface."); + args.addArg("x", "extract", "", "Extract all interface elements from to ."); args.addAdditionalArg("output_filename", "PNG or TGA file to generate", true); args.addAdditionalArg("input_path", "Path that containts interfaces elements", false); @@ -225,6 +226,9 @@ int main(int argc, char **argv) existingUVfilename = args.getArg("s").front(); } + // extract all interface elements + bool extractElements = args.haveArg("x"); + std::vector inputDirs = args.getAdditionalArg("input_path"); string fmtName = args.getAdditionalArg("output_filename").front(); @@ -232,6 +236,111 @@ int main(int argc, char **argv) // append PNG extension if no one provided if (fmtName.rfind('.') == string::npos) fmtName += ".png"; + if (extractElements) + { + if (inputDirs.empty()) + { + outString(toString("ERROR: No input directories specified")); + return -1; + } + + // name of UV file + existingUVfilename = fmtName.substr(0, fmtName.rfind('.')); + existingUVfilename += ".txt"; + + // Load existing UV file + CIFile iFile; + string filename = CPath::lookup(existingUVfilename, false); + + if (filename.empty() || !iFile.open(filename)) + { + outString(toString("ERROR: Unable to open %s", existingUVfilename.c_str())); + return -1; + } + + // Load existing bitmap file + CIFile bitmapFile; + + if (!bitmapFile.open(fmtName)) + { + outString(toString("ERROR: Unable to open %s", fmtName.c_str())); + return -1; + } + + // load bitmap + CBitmap textureBitmap; + uint8 colors = textureBitmap.load(bitmapFile); + + // file already loaded in memory, close it + bitmapFile.close(); + + if (colors != 32) + { + outString(toString("ERROR: %s is not a RGBA bitmap", existingUVfilename.c_str())); + return -1; + } + + // make sure transparent pixels are black + textureBitmap.makeTransparentPixelsBlack(); + + float textureWidth = (float)textureBitmap.getWidth(); + float textureHeight = (float)textureBitmap.getHeight(); + + char bufTmp[256], tgaName[256]; + string sTGAname; + float uvMinU, uvMinV, uvMaxU, uvMaxV; + while (!iFile.eof()) + { + iFile.getline(bufTmp, 256); + + if (sscanf(bufTmp, "%s %f %f %f %f", tgaName, &uvMinU, &uvMinV, &uvMaxU, &uvMaxV) != 5) + { + nlwarning("Can't parse %s", bufTmp); + continue; + } + + float xf = uvMinU * textureWidth; + float yf = uvMinV * textureHeight; + float widthf = (uvMaxU - uvMinU) * textureWidth; + float heightf = (uvMaxV - uvMinV) * textureHeight; + + uint x = (uint)xf; + uint y = (uint)yf; + uint width = (uint)widthf; + uint height = (uint)heightf; + + if ((float)x != xf || (float)y != yf || (float)width != widthf || (float)height != heightf) + { + nlwarning("Wrong round"); + } + + if (width && height) + { + // create bitmap + CBitmap bitmap; + bitmap.resize(width, height); + bitmap.blit(textureBitmap, x, y, width, height, 0, 0); + + sTGAname = inputDirs.front() + "/" + tgaName; + + if (writeFileDependingOnFilename(sTGAname, bitmap)) + { + outString(toString("Writing file %s", sTGAname.c_str())); + } + else + { + outString(toString("Unable to writing file %s", sTGAname.c_str())); + } + } + else + { + outString(toString("Bitmap with wrong size")); + } + } + + return 0; + } + vector AllMapNames; vector::iterator it = inputDirs.begin(), itEnd = inputDirs.end();