72 lines
3.8 KiB
C++
72 lines
3.8 KiB
C++
// glTF 2.0 -> Dungeon Siege II formats, in process (DS2ModLoader) - a C++ port of the import path of
|
|
// tools/ds2mesh.py (fromgltf / toprs): .asp meshes (static props and skinned), .prs animations, DXT5 .dds textures.
|
|
// The port follows the Python step by step (same double arithmetic in the same order) so that both give the same
|
|
// bytes for the same input; tools/gltf_cpp_check.py builds mods/modloader/test/gltfconv.cpp and compares them.
|
|
// Formats: docs/formats/asp.md, prs.md, gltf-pipeline.md. In-game use: docs/architecture/gltf-loading.md.
|
|
//
|
|
// Nothing here talks to the game: gltf_mods.cpp decides what to convert and where the results go.
|
|
#pragma once
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace gltf {
|
|
|
|
using Bytes = std::vector<uint8_t>;
|
|
|
|
struct Options {
|
|
std::string meshName; // bone name of a static mesh (ds2mesh --name; default: file stem)
|
|
std::vector<std::string> textureNames; // one per material, in material order (ds2mesh --texture)
|
|
bool forceStatic = false; // ds2mesh --static
|
|
double scale = 1.0; // ds2mesh --scale
|
|
int maxTexture = 1024; // ds2mesh --max-texture
|
|
bool loop = false; // ds2mesh --loop (BEGL/ENDL notes in the .prs)
|
|
// If set: the texture names for the materials a mesh uses, given their glTF names in texture order (instead of
|
|
// textureNames / the defaults).
|
|
std::function<std::vector<std::string>(const std::vector<std::string>&)> textureNamer;
|
|
// ConvertAnimation: when no animation has exactly that name, take one whose name matches ignoring case, else the
|
|
// first (ds2mesh toprs fails instead).
|
|
bool animFallbackFirst = false;
|
|
};
|
|
|
|
struct Named {
|
|
std::string name;
|
|
Bytes data;
|
|
};
|
|
|
|
struct Result {
|
|
Bytes asp; // the mesh (empty for ConvertAnimation)
|
|
bool skinned = false;
|
|
std::vector<Named> textures; // texture name -> DDS (DXT5, full mip chain)
|
|
std::vector<Named> anims; // animation name (as in ds2mesh --anims "") -> .prs
|
|
std::vector<std::string> warnings;
|
|
std::vector<std::wstring> dependencies; // external files the glTF referenced (buffers, images)
|
|
};
|
|
|
|
// A glTF (.glb or .gltf) -> .asp + textures; with withAnims also every animation of a skinned model -> .prs.
|
|
// False on any error (message in error); never throws.
|
|
bool ConvertMesh(const std::wstring& path, const Options& opt, bool withAnims, Result& out, std::string& error);
|
|
|
|
// One animation of a skinned glTF -> .prs (ds2mesh toprs). name: animation name or index ("" = the first).
|
|
bool ConvertAnimation(const std::wstring& path, const std::string& name, const Options& opt, Result& out,
|
|
std::string& error);
|
|
|
|
// Texture names ds2mesh fromgltf gives a mesh without --texture: b<rest of the mesh name>[-NN].
|
|
std::vector<std::string> DefaultTextureNames(const std::string& meshName, size_t count);
|
|
|
|
// --- images (gltf_image.cpp) ---------------------------------------------------------------------------------------
|
|
struct Image {
|
|
int w = 0, h = 0;
|
|
std::vector<uint8_t> rgba; // w * h * 4
|
|
};
|
|
// PNG / JPEG / ... (stb_image) -> RGBA. False if the data is not a supported image.
|
|
bool DecodeImage(const uint8_t* data, size_t size, Image& out, std::string& error);
|
|
// Pillow's Image.resize(..., LANCZOS) for an RGBA image (premultiplied alpha, 22-bit fixed point), bit for bit.
|
|
Image ResizeLanczos(const Image& in, int w, int h);
|
|
// ds2mesh write_dds(..., 'dxt5'): sides rounded up to powers of two (at most maxSize), full mip chain, DXT5.
|
|
Bytes WriteDds(Image im, int maxSize);
|
|
// zlib stream -> bytes (for compressed tank entries), via stb_image's inflater. False on bad data.
|
|
bool Inflate(const uint8_t* data, size_t size, size_t expected, Bytes& out);
|
|
|
|
} // namespace gltf
|