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). 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 ## Saving/Loading
In addition to custom components, the engine automatically saves data from the built-in ones: transform, rigidbody, skeleton. 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). Значение по-умолчанию совпадает с именем сущности. Определяет то, какой скелет будет использоваться сущностью. См. [риггинг](rigging.md).
### Тип освещения - *lighting-mode*
- *bone-based* - освещение рассчитывается для каждой кости скелета отдельно.
- *solid* - освещение рассчитывается для всей сущности в целом.
## Сохранение/загрузка ## Сохранение/загрузка
Кроме данных пользовательских компонентов, движок автоматически сохраняет данные встроенных: transform, rigidbody, skeleton. Кроме данных пользовательских компонентов, движок автоматически сохраняет данные встроенных: transform, rigidbody, skeleton.

View file

@ -177,6 +177,7 @@ void SkeletonConfig::render(
const Assets& assets, const Assets& assets,
ModelBatch& batch, ModelBatch& batch,
Skeleton& skeleton, Skeleton& skeleton,
ModelLightingMode lightingMode,
const glm::mat3& rotation, const glm::mat3& rotation,
const glm::vec3& position, const glm::vec3& position,
const glm::vec3& scale const glm::vec3& scale
@ -203,16 +204,24 @@ void SkeletonConfig::render(
if (auto foundOverride = modelOverride.model.lock()) { if (auto foundOverride = modelOverride.model.lock()) {
model = foundOverride.get(); model = foundOverride.get();
} }
if (model) { if (model == nullptr) {
batch.draw( if (!node->model.name.empty()) {
skeleton.calculated.matrices[i], node->model.updateFlag = true;
skeleton.tint * skeleton.boneTints[i], }
model, continue;
&skeleton.textures
);
} else if (!node->model.name.empty()) {
node->model.updateFlag = true;
} }
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 "typedefs.hpp"
#include "data/dv_fwd.hpp" #include "data/dv_fwd.hpp"
#include "util/Interpolation.hpp" #include "util/Interpolation.hpp"
#include "util/EnumMetadata.hpp"
class Assets; class Assets;
class ModelBatch; class ModelBatch;
@ -19,6 +20,16 @@ namespace model {
struct 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 { namespace rigging {
struct Skeleton; struct Skeleton;
class SkeletonConfig; class SkeletonConfig;
@ -132,6 +143,7 @@ namespace rigging {
const Assets& assets, const Assets& assets,
ModelBatch& batch, ModelBatch& batch,
Skeleton& skeleton, Skeleton& skeleton,
ModelLightingMode lightingMode,
const glm::mat3& rotation, const glm::mat3& rotation,
const glm::vec3& position, const glm::vec3& position,
const glm::vec3& scale const glm::vec3& scale

View file

@ -94,4 +94,8 @@ template<> void ContentUnitLoader<EntityDef>::loadUnit(
root.at("mass").get(def.mass); root.at("mass").get(def.mass);
root.at("elasticity").get(def.elasticity); root.at("elasticity").get(def.elasticity);
root.at("step-height").get(def.stepHeight); 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, assets,
modelBatch, modelBatch,
skeleton, skeleton,
ModelLightingMode::SOLID,
glm::mat3(1.0f), glm::mat3(1.0f),
glm::vec3(), glm::vec3(),
glm::vec3(1.0f) glm::vec3(1.0f)

View file

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

View file

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

View file

@ -482,6 +482,7 @@ void Entities::render(
if (eid.uid == fpsEntity) { if (eid.uid == fpsEntity) {
continue; continue;
} }
const auto& def = eid.def;
const auto& pos = transform.pos; const auto& pos = transform.pos;
const auto& size = transform.size; const auto& size = transform.size;
if (frustum && !frustum->isBoxVisible(pos - size, pos + size)) { if (frustum && !frustum->isBoxVisible(pos - size, pos + size)) {
@ -491,7 +492,13 @@ void Entities::render(
const auto& rigConfig = skeleton.config; const auto& rigConfig = skeleton.config;
if (rigConfig) { if (rigConfig) {
rigConfig->render( 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.elasticity = elasticity;
dst.stepHeight = stepHeight; dst.stepHeight = stepHeight;
dst.save = save; dst.save = save;
dst.lightingMode = lightingMode;
} }

View file

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