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>
57 lines
1.9 KiB
C++
57 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include "UgcModel.h"
|
|
|
|
/**
|
|
* A small software rasterizer (no GPU or display needed) for what the UGC server draws: the icons, and the renders
|
|
* from many directions that find the faces nobody can see and bake ambient occlusion into the vertex colors.
|
|
*/
|
|
namespace UgcRender {
|
|
// 8-bit RGBA, rows top to bottom, not premultiplied
|
|
struct Image {
|
|
int width{};
|
|
int height{};
|
|
std::vector<uint8_t> rgba;
|
|
};
|
|
|
|
struct IconOptions {
|
|
int size{ 128 };
|
|
int supersample{ 4 };
|
|
float yawDegrees{ 35.0f }; // camera around the model, from +Z towards +X
|
|
float pitchDegrees{ 25.0f }; // camera above the model
|
|
float fovDegrees{ 30.0f };
|
|
float margin{ 1.03f }; // 1 fills the icon, more leaves a border
|
|
glm::mat4 modelRotation{ 1.0f }; // applied to the model before the camera looks at it
|
|
};
|
|
|
|
// The model drawn from the icon's camera, framed to fit, on a transparent background
|
|
Image RenderIcon(const UgcModel::Model& model, const IconOptions& options);
|
|
|
|
struct OptimizeOptions {
|
|
int resolution{ 1024 }; // of each direction's render
|
|
bool removeHidden{ true };
|
|
bool bakeAo{ true };
|
|
float aoStrength{ 0.6f }; // 0 leaves the colors, 1 makes fully hidden corners black
|
|
};
|
|
|
|
struct OptimizeResult {
|
|
size_t trianglesBefore{};
|
|
size_t trianglesRemoved{};
|
|
};
|
|
|
|
/**
|
|
* Renders the opaque mesh from 42 directions around it: triangles that show in none of them are removed (with a
|
|
* conservative test, so small visible ones stay), and each vertex's share of the directions it can be seen from
|
|
* darkens its color (ambient occlusion). Transparent bricks hide nothing but are darkened too.
|
|
*/
|
|
OptimizeResult Optimize(UgcModel::Model& model, const OptimizeOptions& options);
|
|
|
|
// The 42 directions Optimize renders from (an icosahedron's corners and edge centres), unit length
|
|
std::vector<glm::vec3> SphereDirections();
|
|
}
|