mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
A new server (dUgcServer, started by master with enable_ugc_server=1) that takes unprocessed ugc and ugc_modular_build rows from the database and makes what the client downloads with UGCUSE3DSERVICES: an optimized NIF (hidden faces removed, ambient occlusion baked into vertex colors) and a 128px DDS icon for player models, rendered by a software rasterizer from the client's LDD brick primitives, and icons for cars and rockets assembled from their modules per ModularBuildComponent/ModuleComponent. It serves them, with the models' LXFML, over HTTP in the client's UGCC<dc>/3DOPTIMIZED and IMAGE128DDS layout with .gz and .checksum files, and keeps its folder under a size cap. Processing state lives in ugc.is_optimized plus new processed_at, process_attempts and process_error columns (and the same on ugc_modular_build). ServiceType::UGC is appended. NifFile moves to dCommon and records named node transforms for the modules' attach points. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
2.0 KiB
C++
64 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include "UgcBricks.h"
|
|
|
|
namespace NifFile {
|
|
struct Model;
|
|
}
|
|
|
|
/**
|
|
* Brick models as triangle meshes: LXFML parts, the mesh built from them (opaque and transparent bricks apart, with
|
|
* the material colors as vertex colors) and the mesh of a client .nif. Pure apart from BrickLibrary's file reads.
|
|
*/
|
|
namespace UgcModel {
|
|
// A brick in a model: its primitive, materials (one per geometry part) and where it is
|
|
struct Part {
|
|
uint32_t designId{};
|
|
std::vector<uint32_t> materials;
|
|
glm::mat4 transform{ 1.0f };
|
|
};
|
|
|
|
// The parts of an LXFML 5 (Bricks/Brick/Part with bones) or 4 (Scene/Model/Group/Part with axis angles) model.
|
|
// Empty with `error` set when it can't be read.
|
|
std::vector<Part> ParseLxfml(std::string_view lxfml, std::string& error);
|
|
|
|
struct Mesh {
|
|
std::vector<glm::vec3> positions;
|
|
std::vector<glm::vec3> normals;
|
|
std::vector<glm::vec4> colors; // sRGB, 0..1, alpha is opacity
|
|
std::vector<uint32_t> indices;
|
|
|
|
size_t TriangleCount() const { return indices.size() / 3; }
|
|
bool Empty() const { return indices.empty(); }
|
|
void Append(const Mesh& other);
|
|
void Transform(const glm::mat4& transform);
|
|
};
|
|
|
|
struct Model {
|
|
Mesh opaque;
|
|
Mesh transparent;
|
|
std::vector<uint32_t> missingDesigns; // designs without geometry in the client, skipped
|
|
size_t bricks{};
|
|
|
|
bool Empty() const { return opaque.Empty() && transparent.Empty(); }
|
|
// The bounds of every vertex; false when there are none
|
|
bool Bounds(glm::vec3& min, glm::vec3& max) const;
|
|
};
|
|
|
|
// The mesh of a model's parts
|
|
Model Build(const std::vector<Part>& parts, UgcBricks::BrickLibrary& library);
|
|
|
|
// A client .nif's meshes as one model (vertex colors times material color; transparent when blended)
|
|
Model FromNif(const NifFile::Model& nif);
|
|
|
|
// Splits a mesh into pieces the .nif format can hold (at most `maxVertices` vertices and `maxTriangles` triangles)
|
|
std::vector<Mesh> Split(const Mesh& mesh, size_t maxVertices = 65535, size_t maxTriangles = 65535);
|
|
}
|