refactor: Update visiblity per frame in a centralized fashion
This commit is contained in:
parent
bd41f7c9a2
commit
139b5656e2
6 changed files with 76 additions and 50 deletions
|
@ -22,6 +22,7 @@
|
|||
#include <boost/format.hpp>
|
||||
|
||||
#include "glm/gtx/intersect.hpp"
|
||||
#include "glm/gtx/norm.hpp"
|
||||
|
||||
#include "../../render/models.h"
|
||||
#include "../../render/walkmeshes.h"
|
||||
|
@ -451,18 +452,21 @@ bool Area::getElevationAt(const glm::vec2 &position, Room *&room, float &z) cons
|
|||
}
|
||||
|
||||
void Area::update(const UpdateContext &updateCtx) {
|
||||
Object::update(updateCtx);
|
||||
_actionExecutor.executeActions(*this, updateCtx.deltaTime);
|
||||
|
||||
for (auto &room : _rooms) {
|
||||
room.second->update(updateCtx.deltaTime);
|
||||
}
|
||||
for (auto &object : _objects) {
|
||||
object->update(updateCtx);
|
||||
_actionExecutor.executeActions(*object, updateCtx.deltaTime);
|
||||
}
|
||||
doDestroyObjects();
|
||||
|
||||
float dt = updateCtx.deltaTime;
|
||||
Object::update(dt);
|
||||
_actionExecutor.executeActions(*this, dt);
|
||||
|
||||
for (auto &room : _rooms) {
|
||||
room.second->update(dt);
|
||||
}
|
||||
updateVisibility(updateCtx);
|
||||
|
||||
for (auto &object : _objects) {
|
||||
object->update(dt);
|
||||
_actionExecutor.executeActions(*object, dt);
|
||||
}
|
||||
_objectSelector.update();
|
||||
_game->sceneGraph().prepare();
|
||||
}
|
||||
|
@ -617,7 +621,6 @@ void Area::onPartyLeaderMoved() {
|
|||
if (!partyLeader) return;
|
||||
|
||||
update3rdPersonCameraTarget();
|
||||
updateRoomVisibility();
|
||||
_objectSelector.selectNearest();
|
||||
updateTriggers(*partyLeader);
|
||||
}
|
||||
|
@ -636,24 +639,52 @@ void Area::update3rdPersonCameraTarget() {
|
|||
_thirdPersonCamera->setTargetPosition(position);
|
||||
}
|
||||
|
||||
void Area::updateRoomVisibility() {
|
||||
void Area::updateVisibility(const UpdateContext &ctx) {
|
||||
shared_ptr<Creature> partyLeader(_game->party().leader());
|
||||
if (!partyLeader) return;
|
||||
Room *leaderRoom = partyLeader ? partyLeader->room() : nullptr;
|
||||
bool allVisible = !leaderRoom || _cameraType == CameraType::FirstPerson;
|
||||
|
||||
Room *leaderRoom = partyLeader->room();
|
||||
if (!leaderRoom) return;
|
||||
|
||||
for (auto &room : _rooms) {
|
||||
room.second->setVisible(false);
|
||||
}
|
||||
leaderRoom->setVisible(true);
|
||||
|
||||
auto adjRooms = _visibility->equal_range(leaderRoom->name());
|
||||
for (auto adjRoom = adjRooms.first; adjRoom != adjRooms.second; adjRoom++) {
|
||||
auto room = _rooms.find(adjRoom->second);
|
||||
if (room != _rooms.end()) {
|
||||
room->second->setVisible(true);
|
||||
if (allVisible) {
|
||||
for (auto &room : _rooms) {
|
||||
room.second->setVisible(true);
|
||||
}
|
||||
} else {
|
||||
auto adjRoomNames = _visibility->equal_range(leaderRoom->name());
|
||||
for (auto &room : _rooms) {
|
||||
bool visible = !leaderRoom || room.second.get() == leaderRoom;
|
||||
if (!visible) {
|
||||
for (auto adjRoom = adjRoomNames.first; adjRoom != adjRoomNames.second; adjRoom++) {
|
||||
if (adjRoom->second == room.first) {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
room.second->setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec4 viewport(-1.0f, -1.0f, 1.0f, 1.0f);
|
||||
for (auto &object : _objects) {
|
||||
if (!object->visible()) continue;
|
||||
|
||||
shared_ptr<ModelSceneNode> model(object->model());
|
||||
if (!model) continue;
|
||||
|
||||
glm::vec3 position(object->position());
|
||||
float drawDistance = object->drawDistance();
|
||||
float fadeDistance = object->fadeDistance();
|
||||
|
||||
glm::vec3 screenCoords = glm::project(position, ctx.view, ctx.projection, viewport);
|
||||
float distanceToCamera = glm::distance2(position, ctx.cameraPosition);
|
||||
bool onScreen = distanceToCamera < drawDistance && screenCoords.z < 1.0f;
|
||||
float alpha = 1.0f;
|
||||
|
||||
if (drawDistance != fadeDistance && distanceToCamera > fadeDistance) {
|
||||
alpha = 1.0f - (distanceToCamera - fadeDistance) / (drawDistance - fadeDistance);
|
||||
}
|
||||
model->setOnScreen(onScreen);
|
||||
model->setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
Area(uint32_t id, Game *game);
|
||||
|
||||
void load(const std::string &name, const resource::GffStruct &are, const resource::GffStruct &git);
|
||||
|
||||
bool handle(const SDL_Event &event);
|
||||
void update(const UpdateContext &updateCtx);
|
||||
|
||||
|
@ -144,8 +145,8 @@ private:
|
|||
void doDestroyObject(uint32_t objectId);
|
||||
void doDestroyObjects();
|
||||
void landObject(SpatialObject &object);
|
||||
void updateRoomVisibility();
|
||||
void updateTriggers(const Creature &creature);
|
||||
void updateVisibility(const UpdateContext &ctx);
|
||||
|
||||
bool findCameraObstacle(const glm::vec3 &origin, const glm::vec3 &dest, glm::vec3 &intersection) const;
|
||||
bool findCreatureObstacle(const Creature &creature, const glm::vec3 &dest) const;
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::render;
|
||||
using namespace reone::resource;
|
||||
using namespace reone::script;
|
||||
|
||||
namespace reone {
|
||||
|
@ -34,7 +32,7 @@ namespace game {
|
|||
Object::Object(uint32_t id, ObjectType type) : _id(id), _type(type) {
|
||||
}
|
||||
|
||||
void Object::update(const UpdateContext &ctx) {
|
||||
void Object::update(float dt) {
|
||||
_actionQueue.update();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "../actionqueue.h"
|
||||
#include "../types.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
@ -34,7 +33,7 @@ class Object {
|
|||
public:
|
||||
virtual ~Object() = default;
|
||||
|
||||
virtual void update(const UpdateContext &ctx);
|
||||
virtual void update(float dt);
|
||||
|
||||
void runUserDefinedEvent(int eventNumber);
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "spatial.h"
|
||||
|
||||
#include "glm/gtx/euler_angles.hpp"
|
||||
#include "glm/gtx/norm.hpp"
|
||||
|
||||
#include "../room.h"
|
||||
|
||||
|
@ -66,23 +65,11 @@ void SpatialObject::moveItemsTo(SpatialObject &other) {
|
|||
_items.clear();
|
||||
}
|
||||
|
||||
void SpatialObject::update(const UpdateContext &ctx) {
|
||||
Object::update(ctx);
|
||||
|
||||
if (!_model) return;
|
||||
|
||||
glm::vec4 viewport(-1.0f, -1.0f, 1.0f, 1.0f);
|
||||
glm::vec3 screenCoords = glm::project(_position, ctx.view, ctx.projection, viewport);
|
||||
float distanceToCamera = glm::distance2(_position, ctx.cameraPosition);
|
||||
bool onScreen = distanceToCamera < _drawDistance && screenCoords.z < 1.0f;
|
||||
float alpha = 1.0f;
|
||||
|
||||
if (_drawDistance != _fadeDistance && distanceToCamera > _fadeDistance) {
|
||||
alpha = 1.0f - (distanceToCamera - _fadeDistance) / (_drawDistance - _fadeDistance);
|
||||
void SpatialObject::update(float dt) {
|
||||
Object::update(dt);
|
||||
if (_model) {
|
||||
_model->update(dt);
|
||||
}
|
||||
_model->setOnScreen(onScreen);
|
||||
_model->setAlpha(alpha);
|
||||
_model->update(ctx.deltaTime);
|
||||
}
|
||||
|
||||
void SpatialObject::playAnimation(const string &name, int flags, float speed) {
|
||||
|
@ -131,6 +118,14 @@ glm::vec3 SpatialObject::selectablePosition() const {
|
|||
return _model->getCenterOfAABB();
|
||||
}
|
||||
|
||||
float SpatialObject::drawDistance() const {
|
||||
return _drawDistance;
|
||||
}
|
||||
|
||||
float SpatialObject::fadeDistance() const {
|
||||
return _fadeDistance;
|
||||
}
|
||||
|
||||
void SpatialObject::setRoom(Room *room) {
|
||||
if (_room) {
|
||||
_room->removeTenant(this);
|
||||
|
|
|
@ -40,7 +40,7 @@ class Room;
|
|||
|
||||
class SpatialObject : public Object {
|
||||
public:
|
||||
void update(const UpdateContext &ctx) override;
|
||||
void update(float dt) override;
|
||||
|
||||
virtual void playAnimation(const std::string &name, int flags = 0, float speed = 1.0f);
|
||||
|
||||
|
@ -62,6 +62,8 @@ public:
|
|||
std::shared_ptr<render::Walkmesh> walkmesh() const;
|
||||
const std::vector<std::shared_ptr<Item>> &items() const;
|
||||
virtual glm::vec3 selectablePosition() const;
|
||||
float drawDistance() const;
|
||||
float fadeDistance() const;
|
||||
|
||||
void setRoom(Room *room);
|
||||
void setPosition(const glm::vec3 &position);
|
||||
|
|
Loading…
Reference in a new issue