#include "dl_actor.h" #ifndef DL_DISABLE_RENDER #include "system/dl_time.h" #include "render/dl_model_data.h" #include "vk/dl_vk.h" #include "math/dl_physics.h" namespace dl { void Actor::Update(FloatTime dt /*= 0*/) { if (!_modelAnimationInstance) { log_warn0("角色没有蒙皮动画,不需要调用Update!"); return; } //更新蒙皮 //更新对应位置ubo if (dt == 0) dt = g_time->GetDelta(); _modelAnimationInstance->Update(dt); } void Actor::Render() { //--------------------rigidBody---------- if (_rigidBody) { _trans->SetPosition(_rigidBody->GetPosition()); _trans->SetRotate(_rigidBody->GetRotate()); } //--------------------render------------- if (_idModel >= g_vk->GetMulModelSize()) { log_warn("错误的Actor!"); return; } std::vector& mul_model = g_vk->GetMulModel(_idModel); //ub骨骼id size_t id_bone = _modelAnimationInstance ? _modelAnimationInstance->_id : -1; { size_t id = g_vk->GetPushConstantNext(); VK::PushConstantData* p = g_vk->GetPushConstant(id); if (p == nullptr) { log_warn0("Actor绘制数量过多,多余的将不会绘制!"); return; } p->_model = _trans->GetMatrixToWorld(); if (_color) { p->_color = *_color; } else p->_color = { 1.0f, 1.0f, 1.0f, 1.0f }; for (auto& iter : mul_model) { iter->_mulInstance.push_back({ id, id_bone }); } if(id_bone != -1) g_vk->UpdateUboBone(id_bone, _modelAnimationInstance->_finalTrans); return; } } size_t Actor::GetAniSize() { if (!_modelAnimationInstance) return 0; return _modelAnimationInstance->_model->_allAnimation.size(); } std::string Actor::GetAniName(size_t i) { if (_no_bone_animation()) return {}; const Model* model = _modelAnimationInstance->_model; if (i >= model->_allAnimation.size()) { log_warn("动画下标越界:{}/{}", i, model->_allAnimation.size()); return {}; } return model->_allAnimation[i]._name; } void Actor::SetAni(std::string_view name) { if (_no_bone_animation()) return; _modelAnimationInstance->Set(name, 0); } std::string Actor::GetAniCurrent() { if (_no_bone_animation()) return {}; return _modelAnimationInstance->Get(); } void Actor::CreateRigidBody(RigidBodyType type, bool active) { if (_rigidBody) { log_warn0("已经存在刚体,无法创建!"); return; } std::vector& mul_model = g_vk->GetMulModel(_idModel); BoundingBox aabb; for (auto& iter : mul_model) { for (auto& iter1 : iter->_treeNode) { if (iter1._aabb._vaild) { Matrix4 mat_to_world; if (_modelAnimationInstance) mat_to_world = iter1.GetMatrixWorld(_modelAnimationInstance); else mat_to_world = iter1.GetMatrixLocal(); aabb.Add(iter1._aabb.getAABB(mat_to_world)); } } } // 没有包围盒,创建一个默认的 if (!aabb._vaild) aabb = BoundingBox({ -1.0f, -1.0f, -1.0f }, { 1.0f, 1.0f, 1.0f }); Position3 aabb_center = (aabb._max + aabb._min) / 2.0f; // JPH::ShapeRefC* ref = g_physics->CreateShapeBox( _idModel, aabb._max - aabb_center, _trans->GetScale(), aabb_center); // _rigidBody = g_physics->CreateRigidBody(ref, _trans->GetPosition(), _trans->GetRotate(), type, active); } Actor::~Actor() { delete _rigidBody; delete _modelAnimationInstance; delete _trans; } bool Actor::_no_bone_animation() { if (!_modelAnimationInstance) { log_err0("角色不存在骨骼动画!"); return true; } return false; } } #endif