Merge pull request #978 from MihailRis/entity-lighting-mode

add 'lighting-mode' entity property
This commit is contained in:
MihailRis 2026-09-19 19:21:52 +03:00 • committed by GitHub
commit 4a2d03b29b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 71 additions and 18 deletions

View file

@ -127,6 +127,11 @@ Defines the entity's material (same as for blocks).
The default value is the same as the entity name. Determines which skeleton will be used by the entity. See [rigging](rigging.md).
### *lighting-mode*
- *bone-based* - lighting is calculated for each skeletal bone separately.
- *solid* - lighting is calculated for the entire entity.
## Saving/Loading
In addition to custom components, the engine automatically saves data from the built-in ones: transform, rigidbody, skeleton.

View file

@ -127,6 +127,11 @@
Значение по-умолчанию совпадает с именем сущности. Определяет то, какой скелет будет использоваться сущностью. См. [риггинг](rigging.md).
### Тип освещения - *lighting-mode*
- *bone-based* - освещение рассчитывается для каждой кости скелета отдельно.
- *solid* - освещение рассчитывается для всей сущности в целом.
## Сохранение/загрузка
Кроме данных пользовательских компонентов, движок автоматически сохраняет данные встроенных: transform, rigidbody, skeleton.

View file

@ -177,6 +177,7 @@ void SkeletonConfig::render(
const Assets& assets,
ModelBatch& batch,
Skeleton& skeleton,
ModelLightingMode lightingMode,
const glm::mat3& rotation,
const glm::vec3& position,
const glm::vec3& scale
@ -203,16 +204,24 @@ void SkeletonConfig::render(
if (auto foundOverride = modelOverride.model.lock()) {
model = foundOverride.get();
}
if (model) {
batch.draw(
skeleton.calculated.matrices[i],
skeleton.tint * skeleton.boneTints[i],
model,
&skeleton.textures
);
} else if (!node->model.name.empty()) {
node->model.updateFlag = true;
}
if (model == nullptr) {
if (!node->model.name.empty()) {
node->model.updateFlag = true;
}
continue;
}
batch.draw(
skeleton.calculated.matrices[i],
skeleton.tint * skeleton.boneTints[i],
lightingMode == ModelLightingMode::SOLID
? position - glm::vec3(
skeleton.calculated.matrices[i] *
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
)
: glm::vec3(),
model,
&skeleton.textures
);
}
}

View file

@ -11,6 +11,7 @@
#include "typedefs.hpp"
#include "data/dv_fwd.hpp"
#include "util/Interpolation.hpp"
#include "util/EnumMetadata.hpp"
class Assets;
class ModelBatch;
@ -19,6 +20,16 @@ namespace model {
struct Model;
}
enum class ModelLightingMode {
BONE_BASED,
SOLID,
};
VC_ENUM_METADATA(ModelLightingMode)
{"bone-based", ModelLightingMode::BONE_BASED},
{"solid", ModelLightingMode::SOLID},
VC_ENUM_END
namespace rigging {
struct Skeleton;
class SkeletonConfig;
@ -132,6 +143,7 @@ namespace rigging {
const Assets& assets,
ModelBatch& batch,
Skeleton& skeleton,
ModelLightingMode lightingMode,
const glm::mat3& rotation,
const glm::vec3& position,
const glm::vec3& scale

View file

@ -94,4 +94,8 @@ template<> void ContentUnitLoader<EntityDef>::loadUnit(
root.at("mass").get(def.mass);
root.at("elasticity").get(def.elasticity);
root.at("step-height").get(def.stepHeight);
std::string lightingModeName;
root.at("lighting-mode").get(lightingModeName);
ModelLightingModeMeta.getItem(lightingModeName, def.lightingMode);
}

View file

@ -30,6 +30,7 @@ void HandsRenderer::render(const Camera& camera) {
assets,
modelBatch,
skeleton,
ModelLightingMode::SOLID,
glm::mat3(1.0f),
glm::vec3(),
glm::vec3(1.0f)

View file

@ -100,13 +100,18 @@ void ModelBatch::draw(
void ModelBatch::draw(
const glm::mat4& matrix,
const glm::vec4& tint,
const glm::vec3& lightSampleOffset,
const model::Model* model,
const TextureNamesMap* varTextures
) {
for (const auto& mesh : model->meshes) {
entries.push_back({
matrix, extract_rotation(matrix), tint, &mesh, varTextures
});
entries.push_back(DrawEntry {
matrix,
extract_rotation(matrix),
tint,
lightSampleOffset,
&mesh,
varTextures});
}
}
@ -118,6 +123,7 @@ void ModelBatch::render() {
);
bool backlight = settings.graphics.backlight.get();
for (auto& entry : entries) {
setLightsOffset(entry.lightSampleOffset);
draw(
*entry.mesh,
entry.matrix,
@ -126,6 +132,7 @@ void ModelBatch::render() {
entry.varTextures,
backlight
);
setLightsOffset(glm::vec3());
}
batch->flush();
entries.clear();

View file

@ -33,6 +33,7 @@ public:
void draw(
const glm::mat4& matrix,
const glm::vec4& tint,
const glm::vec3& lightSampleOffset,
const model::Model* model,
const TextureNamesMap* varTextures
);
@ -66,6 +67,7 @@ private:
glm::mat4 matrix;
glm::mat3 rotation;
glm::vec4 tint;
glm::vec3 lightSampleOffset;
const model::Mesh* mesh;
const TextureNamesMap* varTextures;
};

View file

@ -482,6 +482,7 @@ void Entities::render(
if (eid.uid == fpsEntity) {
continue;
}
const auto& def = eid.def;
const auto& pos = transform.pos;
const auto& size = transform.size;
if (frustum && !frustum->isBoxVisible(pos - size, pos + size)) {
@ -491,7 +492,13 @@ void Entities::render(
const auto& rigConfig = skeleton.config;
if (rigConfig) {
rigConfig->render(
assets, batch, skeleton, transform.rot, pos, size
assets,
batch,
skeleton,
def.lightingMode,
transform.rot,
pos,
size
);
}
}

View file

@ -14,4 +14,5 @@ void EntityDef::cloneTo(EntityDef& dst) {
dst.elasticity = elasticity;
dst.stepHeight = stepHeight;
dst.save = save;
dst.lightingMode = lightingMode;
}

View file

@ -8,10 +8,7 @@
#include "data/dv.hpp"
#include "maths/aabb.hpp"
#include "physics/Hitbox.hpp"
namespace rigging {
class SkeletonConfig;
}
#include "animation/rigging.hpp"
struct ComponentInstance {
std::string component;
@ -42,6 +39,9 @@ struct EntityDef {
/// @brief Solid entity material material
std::string material;
/// @brief Model lighting mode
ModelLightingMode lightingMode = ModelLightingMode::BONE_BASED;
/// @brief Can the entity be interacted with cursor (on_attack, on_use)
bool selectable = true;