diff --git a/rwengine/src/objects/CutsceneObject.cpp b/rwengine/src/objects/CutsceneObject.cpp index 557a0498..c5893929 100644 --- a/rwengine/src/objects/CutsceneObject.cpp +++ b/rwengine/src/objects/CutsceneObject.cpp @@ -14,7 +14,8 @@ CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos, else { setModel(getModelInfo()->getModel()); } - animator = new Animator(getModel()); + setClump(ClumpPtr(getModel()->clone())); + animator = new Animator(getClump().get()); } CutsceneObject::~CutsceneObject() { diff --git a/rwengine/src/objects/CutsceneObject.hpp b/rwengine/src/objects/CutsceneObject.hpp index 566d638f..6a05f4f8 100644 --- a/rwengine/src/objects/CutsceneObject.hpp +++ b/rwengine/src/objects/CutsceneObject.hpp @@ -6,7 +6,7 @@ /** * @brief Object type used for cutscene animations. */ -class CutsceneObject : public GameObject { +class CutsceneObject : public GameObject, public ClumpObject { GameObject* _parent; ModelFrame* _bone; diff --git a/rwengine/src/render/ObjectRenderer.cpp b/rwengine/src/render/ObjectRenderer.cpp index c5346093..c0ac1d9f 100644 --- a/rwengine/src/render/ObjectRenderer.cpp +++ b/rwengine/src/render/ObjectRenderer.cpp @@ -116,14 +116,15 @@ void ObjectRenderer::renderAtomic(Atomic* atomic, RW::BSGeometryBounds& bounds = geometry->geometryBounds; - glm::vec3 boundpos = - bounds.center + glm::vec3(frame->getWorldTransform()[3]); + auto transform = worldtransform * frame->getWorldTransform(); + + glm::vec3 boundpos = bounds.center + glm::vec3(transform[3]); if (!m_camera.frustum.intersects(boundpos, bounds.radius)) { culled++; return; } - renderGeometry(geometry.get(), frame->getWorldTransform(), object, render); + renderGeometry(geometry.get(), transform, object, render); } void ObjectRenderer::renderClump(Clump* model, const glm::mat4& worldtransform, @@ -187,9 +188,8 @@ void ObjectRenderer::renderInstance(InstanceObject* instance, atomic->setGeometry(distanceatomic->getGeometry()); } - const auto& frame = atomic->getFrame()->getTransform(); // Render the atomic the instance thinks it should be - renderAtomic(atomic.get(), frame, instance, outList); + renderAtomic(atomic.get(), glm::mat4(), instance, outList); } void ObjectRenderer::renderCharacter(CharacterObject* pedestrian, @@ -226,7 +226,7 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian, auto handFrame = pedestrian->getClump()->findFrame("srhand"); if (handFrame) { auto simple = - m_world->data->findModelInfo(weapon->modelID); + m_world->data->findModelInfo(weapon->modelID); auto itematomic = simple->getAtomic(0); renderAtomic(itematomic, handFrame->getWorldTransform(), nullptr, outList); } @@ -306,43 +306,21 @@ void ObjectRenderer::renderPickup(PickupObject* pickup, RenderList& outList) { void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene, RenderList& outList) { if (!m_world->state->currentCutscene) return; + const auto& clump = cutscene->getClump(); - if (!cutscene->getModel()) { - return; - } - - glm::mat4 matrixModel; auto cutsceneOffset = m_world->state->currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f); + glm::mat4 cutscenespace; + cutscenespace = glm::translate(cutscenespace, cutsceneOffset); if (cutscene->getParentActor()) { - matrixModel = glm::translate(matrixModel, cutsceneOffset); - // matrixModel = - // cutscene->getParentActor()->getTimeAdjustedTransform(_renderAlpha); - // matrixModel = glm::translate(matrixModel, glm::vec3(0.f, 0.f, - // 1.f)); - glm::mat4 localMatrix; - auto boneframe = cutscene->getParentFrame(); - while (boneframe) { - localMatrix = cutscene->getParentActor()->skeleton->getMatrix( - boneframe->getIndex()) * - localMatrix; - boneframe = boneframe->getParent(); - } - matrixModel = matrixModel * localMatrix; - } else { - matrixModel = glm::translate(matrixModel, cutsceneOffset); + auto parent = cutscene->getParentFrame(); + cutscenespace *= parent->getWorldTransform(); + cutscenespace = + glm::rotate(cutscenespace, glm::half_pi(), {0.f, 1.f, 0.f}); } - auto model = cutscene->getModel(); - if (cutscene->getParentActor()) { - glm::mat4 align; - /// @todo figure out where this 90 degree offset is coming from. - align = glm::rotate(align, glm::half_pi(), {0.f, 1.f, 0.f}); - renderClump(model, matrixModel * align, nullptr, outList); - } else { - renderClump(model, matrixModel, nullptr, outList); - } + renderClump(clump.get(), cutscenespace, nullptr, outList); } void ObjectRenderer::renderProjectile(ProjectileObject* projectile, diff --git a/rwengine/src/script/modules/GTA3ModuleImpl.inl b/rwengine/src/script/modules/GTA3ModuleImpl.inl index 762842df..843558f5 100644 --- a/rwengine/src/script/modules/GTA3ModuleImpl.inl +++ b/rwengine/src/script/modules/GTA3ModuleImpl.inl @@ -8455,11 +8455,15 @@ void opcode_02f4(const ScriptArguments& args, const ScriptObject object0, const RW_UNUSED(model); RW_UNUSED(object1); auto id = args[1].integer; - auto actor = args.getObject(0); + auto actor = static_cast(args.getObject(0)); CutsceneObject* object = args.getWorld()->createCutsceneObject(id, args.getWorld()->state->currentCutscene->meta.sceneOffset ); - auto headframe = actor->getModel()->findFrame("shead"); - actor->skeleton->setEnabled(headframe, false); + auto headframe = actor->getClump()->findFrame("shead"); + for (const auto& atomic : actor->getClump()->getAtomics()) { + if (atomic->getFrame().get() == headframe) { + atomic->setFlag(Atomic::ATOMIC_RENDER, false); + } + } object->setParentActor(actor, headframe); *args[2].globalInteger = object->getGameObjectID();