mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Dump heightmaps to 16-bit pngs.
This commit is contained in:
parent
f9c4071b3f
commit
712fa30090
7 changed files with 102 additions and 40 deletions
|
|
@ -114,40 +114,10 @@ public:
|
|||
return m;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCV_IMGCODECS
|
||||
operator cv::Mat() const
|
||||
{
|
||||
return flip().toCvMat();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::vector<T> data;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
#ifdef HAVE_OPENCV_IMGCODECS
|
||||
cv::Mat toCvMat() const
|
||||
{
|
||||
if constexpr (std::is_same_v<T, uint32_t>)
|
||||
{
|
||||
int cols = width;
|
||||
int rows = height;
|
||||
cv::Mat m(height, width, CV_8UC3);
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
auto &o = operator()(row * cols + col);
|
||||
m.ptr<uint8_t>(row)[3 * col + 2] = (o >> 16) & 0xFF;
|
||||
m.ptr<uint8_t>(row)[3 * col + 1] = (o >> 8) & 0xFF;
|
||||
m.ptr<uint8_t>(row)[3 * col + 0] = (o >> 0) & 0xFF;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
inline void write_mat_bmp(const path &filename, int width, int height, int bits, const uint8_t *b, size_t s)
|
||||
|
|
|
|||
|
|
@ -18,10 +18,11 @@
|
|||
|
||||
#define NOMINMAX
|
||||
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include "mmp.h"
|
||||
|
||||
#include <primitives/filesystem.h>
|
||||
#include <primitives/exceptions.h>
|
||||
#include <primitives/sw/cl.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
|
@ -29,6 +30,8 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
cl::list<int> extend("e", cl::desc("try to extend map for ue4"), cl::value_desc("<quads per section> <sections per component>"), cl::multi_val(2));
|
||||
|
||||
void water_segment::load(const buffer &b)
|
||||
{
|
||||
wg.load(b);
|
||||
|
|
@ -139,6 +142,11 @@ void mmp::loadTextureNames(const path &fn)
|
|||
}
|
||||
}
|
||||
|
||||
static bool is_power_of_two(int x)
|
||||
{
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
void mmp::process()
|
||||
{
|
||||
for (auto &s : segments)
|
||||
|
|
@ -172,8 +180,47 @@ void mmp::process()
|
|||
alpha_maps[t.second.g] = mat<uint32_t>(h.width, h.length);
|
||||
}
|
||||
|
||||
auto wnew = h.width;
|
||||
auto lnew = h.length;
|
||||
|
||||
if (extend.empty())
|
||||
{
|
||||
// defaults
|
||||
//extend.push_back(63);
|
||||
//extend.push_back(4);
|
||||
extend.push_back(127);
|
||||
extend.push_back(1);
|
||||
}
|
||||
|
||||
if (!extend.empty())
|
||||
{
|
||||
int quads_per_sect = extend[0] + 1;
|
||||
int sections_per_comp = extend[1];
|
||||
|
||||
if (!is_power_of_two(quads_per_sect))
|
||||
throw SW_RUNTIME_ERROR("quads per section must be 2^n-1");
|
||||
if (sections_per_comp != 1 && sections_per_comp != 4)
|
||||
throw SW_RUNTIME_ERROR("sections per component must be 1 or 4");
|
||||
|
||||
if (sections_per_comp > 1)
|
||||
sections_per_comp = sqrt(sections_per_comp);
|
||||
|
||||
double mult = quads_per_sect * sections_per_comp - sections_per_comp;
|
||||
int wcomps = ceil(h.width / mult);
|
||||
int lcomps = ceil(h.length / mult);
|
||||
|
||||
if (wcomps * lcomps > 1024)
|
||||
{
|
||||
throw SW_RUNTIME_ERROR("ue4 allows maximum 1024 components while you have: " +
|
||||
std::to_string(wcomps) + "x" + std::to_string(lcomps) + " = " + std::to_string(wcomps * lcomps) + " components");
|
||||
}
|
||||
|
||||
wnew = wcomps * mult + 1;
|
||||
lnew = lcomps * mult + 1;
|
||||
}
|
||||
|
||||
// merge
|
||||
heightmap = decltype(heightmap)(h.width, h.length);
|
||||
heightmap = decltype(heightmap)(wnew, lnew);
|
||||
heightmap32 = decltype(heightmap32)(h.width, h.length);
|
||||
//heightmap_segmented = decltype(heightmap)(segment::len, h.length);
|
||||
texmap = decltype(texmap)(h.width, h.length);
|
||||
|
|
@ -226,7 +273,9 @@ void mmp::process()
|
|||
|
||||
alpha_maps.erase(0);
|
||||
scale16 = 0xffff / (h_max - h_min);
|
||||
const int unreal_koef = 51200; // 51300?
|
||||
// 51300 = -25600..25600? or 51200 = -25500..25600
|
||||
// seems like 51300
|
||||
const int unreal_koef = 51300;
|
||||
const int aim_koef = 10;
|
||||
const double diff = h_max - h_min;
|
||||
scale = aim_koef * diff / unreal_koef;
|
||||
|
|
@ -297,6 +346,40 @@ void mmp::writeTexturesList()
|
|||
}
|
||||
}
|
||||
|
||||
static cv::Mat toCvMat(const mat<uint16_t> &in)
|
||||
{
|
||||
int cols = in.getWidth();
|
||||
int rows = in.getHeight();
|
||||
cv::Mat m(in.getHeight(), in.getWidth(), CV_16UC1);
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
auto &o = in(row * cols + col);
|
||||
m.ptr<uint16_t>(row)[col] = o;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static cv::Mat toCvMat(const mat<uint32_t> &in)
|
||||
{
|
||||
int cols = in.getWidth();
|
||||
int rows = in.getHeight();
|
||||
cv::Mat m(in.getHeight(), in.getWidth(), CV_8UC3);
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
auto &o = in(row * cols + col);
|
||||
m.ptr<uint8_t>(row)[3 * col + 2] = (o >> 16) & 0xFF;
|
||||
m.ptr<uint8_t>(row)[3 * col + 1] = (o >> 8) & 0xFF;
|
||||
m.ptr<uint8_t>(row)[3 * col + 0] = (o >> 0) & 0xFF;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void mmp::writeHeightMap()
|
||||
{
|
||||
auto write_hm = [this](const String &name, const auto &v, auto sz)
|
||||
|
|
@ -310,7 +393,9 @@ void mmp::writeHeightMap()
|
|||
fclose(f);
|
||||
};
|
||||
|
||||
write_hm(".heightmap16.r16", heightmap, sizeof(decltype(heightmap)::type));
|
||||
cv::imwrite((path(filename) += ".heightmap16.png").string(), toCvMat(heightmap));
|
||||
|
||||
//write_hm(".heightmap16.r16", heightmap, sizeof(decltype(heightmap)::type));
|
||||
write_hm(".heightmap32.r32", heightmap32, sizeof(decltype(heightmap32)::type));
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +471,7 @@ void mmp::writeSplitColormap() const
|
|||
for (auto &pixel : m)
|
||||
pixel = pixel == color ? 0x0000FF00 : 0;
|
||||
std::cout << "\r[" << i << "/" << colors.size() << "] Processing color " << ss.str();
|
||||
cv::imwrite(fn.u8string(), cv::Mat(m));
|
||||
cv::imwrite(fn.u8string(), toCvMat(m));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <mat.h>
|
||||
#include <types.h>
|
||||
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <primitives/filesystem.h>
|
||||
|
||||
#include <map>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include "mmp.h"
|
||||
|
||||
#include <primitives/filesystem.h>
|
||||
|
|
@ -37,10 +36,11 @@ int main(int argc, char *argv[])
|
|||
cl::opt<path> p(cl::Positional, cl::desc("<file.mmp or directory>"), cl::Required);
|
||||
cl::opt<path> texture_ids(cl::Positional, cl::desc("<path to texture_ids.txt>"));
|
||||
cl::opt<bool> split_colormap("split_colormap", cl::desc("split colormap into separate images"));
|
||||
cl::opt<bool> tex_al("texture_alphamaps", cl::desc("write texture alpha maps"));
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
auto func = [&texture_ids, &split_colormap](auto &p)
|
||||
auto func = [&texture_ids, &split_colormap, &tex_al](auto &p)
|
||||
{
|
||||
mmp m;
|
||||
if (!texture_ids.empty())
|
||||
|
|
@ -52,6 +52,7 @@ int main(int argc, char *argv[])
|
|||
m.writeHeightMap();
|
||||
//m.writeHeightMapSegmented();
|
||||
m.writeTextureMap();
|
||||
if (tex_al)
|
||||
m.writeTextureAlphaMaps();
|
||||
m.writeTextureMapColored();
|
||||
m.writeColorMap();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WIN64
|
||||
#error "not available in 64-bit mode"
|
||||
#endif
|
||||
|
||||
#define _BYTE uint8_t
|
||||
#define _WORD uint16_t
|
||||
#define _DWORD uint32_t
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
cout << "Usage: " << argv[0] << " archive.pak" << "\n";
|
||||
cerr << "Usage: " << argv[0] << " archive.pak" << "\n";
|
||||
return 1;
|
||||
}
|
||||
unpak(argv[1]);
|
||||
|
|
|
|||
3
sw.cpp
3
sw.cpp
|
|
@ -42,7 +42,8 @@ void build(Solution &s)
|
|||
add_exe_with_common("tm_converter");
|
||||
add_exe("name_generator");
|
||||
add_exe_with_common("save_loader");
|
||||
add_exe("unpaker");
|
||||
if (s.Settings.TargetOS.Arch == ArchType::x86)
|
||||
add_exe("unpaker"); // 32-bit only
|
||||
|
||||
// not so simple targets
|
||||
auto &script2txt = tools.addStaticLibrary("script2txt");
|
||||
|
|
|
|||
Loading…
Reference in a new issue