85 lines
2.3 KiB
C++
85 lines
2.3 KiB
C++
#include "anim_node_sync.h"
|
|
#include "scene/node.h"
|
|
#include "obj/object.h"
|
|
#include "empire.h"
|
|
#include "main/references.h"
|
|
|
|
extern double frameLen_s, frameTime_s;
|
|
|
|
namespace scene {
|
|
|
|
void NodeSyncAnimator::animate(Node* node) {
|
|
Object* obj = node->obj;
|
|
if(obj) {
|
|
auto* player = Empire::getPlayerEmpire();
|
|
|
|
bool vis = false;
|
|
|
|
vis = obj->isVisibleTo(player) && obj->position.distanceToSQ(devices.render->cam_pos) < (node->distanceCutoff * obj->radius * obj->radius);
|
|
bool wasVisible = node->visible;
|
|
|
|
if(!vis && node->getFlag(NF_Memorable) && (node->remembered || obj->isKnownTo(player))) {
|
|
vis = true;
|
|
node->remembered = true;
|
|
}
|
|
else if(vis) {
|
|
node->remembered = false;
|
|
}
|
|
|
|
if(!vis && !wasVisible && node->getFlag(NF_AnimOnlyVisible)) {
|
|
node->visible = false;
|
|
return;
|
|
}
|
|
|
|
if(obj->isFocus()) {
|
|
//TODO: This should be handled better/centrally
|
|
obj->setFlag(objFocus, false);
|
|
}
|
|
|
|
double interpPct = 1.0;
|
|
if(vis && wasVisible) {
|
|
if(obj->lastTick > node->lastUpdate + 1.0/60.0) {
|
|
interpPct = (frameTime_s - node->lastUpdate)/(obj->lastTick - node->lastUpdate);
|
|
node->position = node->position.interpolate(obj->position, interpPct);
|
|
}
|
|
else {
|
|
//Interpolate to a predicted position based on physics data
|
|
double tDiff = frameTime_s - obj->lastTick;
|
|
vec3d predicted = obj->position + (obj->velocity + obj->acceleration * (tDiff * 0.5)) * tDiff;
|
|
//node->position = node->position.interpolate(predicted, (frameTime_s - node->lastUpdate) / tDiff);
|
|
node->position = predicted;
|
|
interpPct = tDiff / (node->lastUpdate - obj->lastTick);
|
|
}
|
|
}
|
|
else {
|
|
double tDiff = frameTime_s - obj->lastTick;
|
|
node->position = obj->position + (obj->velocity + obj->acceleration * (tDiff * 0.5)) * tDiff;
|
|
}
|
|
node->lastUpdate = frameTime_s;
|
|
|
|
node->visible = vis;
|
|
|
|
//Some updates only need performed for visible objects
|
|
if(vis || !node->getFlag(NF_AnimOnlyVisible)) {
|
|
if(!node->remembered && !node->getFlag(NF_CustomColor))
|
|
if(Empire* owner = obj->owner)
|
|
node->color = owner->color;
|
|
|
|
if(wasVisible)
|
|
node->rotation = node->rotation.slerp(obj->rotation, interpPct);
|
|
else
|
|
node->rotation = obj->rotation;
|
|
|
|
node->rebuildTransformation();
|
|
}
|
|
}
|
|
}
|
|
|
|
NodeSyncAnimator syncAnimator;
|
|
|
|
NodeSyncAnimator* NodeSyncAnimator::getSingleton() {
|
|
return &syncAnimator;
|
|
}
|
|
|
|
};
|