Trying more drastic changes and learnign to use std::chrono the right way

This commit is contained in:
samcake 2018-04-20 17:53:24 -07:00
parent 3d651de797
commit b554aec317
5 changed files with 50 additions and 25 deletions

View file

@ -5369,15 +5369,20 @@ void Application::update(float deltaTime) {
_physicsEngine->dumpStatsIfNecessary();
}
auto t1 = std::chrono::high_resolution_clock::now();
workload::Timings timings(1);
timings[0] = float(std::chrono::nanoseconds(t1 - t0).count() * 0.000001);
_gameWorkload.updateSimulationTimings(timings);
if (!_aboutToQuit) {
// NOTE: the getEntities()->update() call below will wait for lock
// and will provide non-physical entity motion
getEntities()->update(true); // update the models...
}
auto t2 = std::chrono::high_resolution_clock::now();
workload::Timings timings(2);
timings[0] = (t1 - t0);
timings[1] = (t2 - t1);
_gameWorkload.updateSimulationTimings(timings);
}
}
} else {

View file

@ -39,20 +39,18 @@ void ControlViews::run(const workload::WorkloadContextPointer& runContext, const
}
}
float wtf_adjust(float current, float timing) {
float error = -((timing) - 2.0f);
if (error < 0.0f) {
current += 0.2f * (error) / 16.0f;
} else {
current += 0.1f * (error) / 16.0f;
}
glm::vec2 Regulator::run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current) {
glm::vec2 next = current;
if (current > 100.0f) {
current = 100.0f;
} else if (current < 5.0f) {
current = 5.0f;
}
return current;
// Regulate next value based on current moving toward the goal budget
float error_ms = std::chrono::duration<float, std::milli>(_budget - measured).count();
float coef = error_ms / std::chrono::duration<float, std::milli>(regulationDuration).count();
next += coef * (error_ms < 0.0 ? _speedDown : _speedUp);
// Clamp to min max
next = glm::clamp(next, _minRange, _maxRange);
return next;
}
void ControlViews::regulateViews(workload::Views& outViews, const workload::Timings& timings) {
@ -63,12 +61,16 @@ void ControlViews::regulateViews(workload::Views& outViews, const workload::Timi
}
}
auto loopDuration = std::chrono::nanoseconds{ std::chrono::milliseconds(16) };
regionBackFronts[workload::Region::R2] = regionRegulators[workload::Region::R2].run(loopDuration, timings[0], regionBackFronts[workload::Region::R2]);
regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].run(loopDuration, timings[1], regionBackFronts[workload::Region::R3]);
int i = 0;
for (auto& outView : outViews) {
auto current = regionBackFronts[workload::Region::R2].y;
auto newCurrent = wtf_adjust(current, timings[0]);
regionBackFronts[workload::Region::R2].y = newCurrent;
outView.regionBackFronts[workload::Region::R2].y = newCurrent;
outView.regionBackFronts[workload::Region::R1] = regionBackFronts[workload::Region::R1];
outView.regionBackFronts[workload::Region::R2] = regionBackFronts[workload::Region::R2];
outView.regionBackFronts[workload::Region::R3] = regionBackFronts[workload::Region::R3];
workload::View::updateRegionsFromBackFronts(outView);
}
}

View file

@ -60,6 +60,21 @@ signals:
void dirty();
};
struct Regulator {
using Timing_ns = std::chrono::nanoseconds;
Timing_ns _budget{ std::chrono::milliseconds(2) };
glm::vec2 _minRange{ 2.0f, 5.0f };
glm::vec2 _maxRange{ 50.0f, 100.0f };
glm::vec2 _speedDown{ 0.2f };
glm::vec2 _speedUp{ 0.1f };
Regulator() {}
glm::vec2 run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current);
};
class ControlViews {
public:
using Config = ControlViewsConfig;
@ -71,8 +86,9 @@ public:
void configure(const Config& config);
void run(const workload::WorkloadContextPointer& runContext, const Input& inputs, Output& outputs);
glm::vec2 regionBackFronts[workload::Region::NUM_VIEW_REGIONS + 1];
std::array<glm::vec2, workload::Region::NUM_VIEW_REGIONS + 1> regionBackFronts;
std::array<Regulator, workload::Region::NUM_VIEW_REGIONS + 1> regionRegulators;
void regulateViews(workload::Views& views, const workload::Timings& timings);

View file

@ -50,12 +50,13 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
assert(!entity->isDead());
uint8_t region = _space->getRegion(entity->getSpaceIndex());
bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical();
bool canBeKinematic = region <= workload::Region::R3;
if (shouldBePhysical) {
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
if (!motionState) {
_entitiesToAddToPhysics.insert(entity);
}
} else if (entity->isMovingRelativeToParent()) {
} else if (canBeKinematic && entity->isMovingRelativeToParent()) {
_simpleKinematicEntities.insert(entity);
}
}
@ -124,6 +125,7 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
uint8_t region = _space->getRegion(entity->getSpaceIndex());
bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical();
bool canBeKinematic = region <= workload::Region::R3;
if (motionState) {
if (!shouldBePhysical) {
// the entity should be removed from the physical simulation
@ -131,7 +133,7 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
_physicalObjects.remove(motionState);
removeOwnershipData(motionState);
_entitiesToRemoveFromPhysics.insert(entity);
if (entity->isMovingRelativeToParent()) {
if (canBeKinematic && entity->isMovingRelativeToParent()) {
_simpleKinematicEntities.insert(entity);
}
} else {
@ -142,7 +144,7 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
// Perhaps it's shape has changed and it can now be added?
_entitiesToAddToPhysics.insert(entity);
_simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic
} else if (entity->isMovingRelativeToParent()) {
} else if (canBeKinematic && entity->isMovingRelativeToParent()) {
_simpleKinematicEntities.insert(entity);
} else {
_simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic

View file

@ -70,7 +70,7 @@ private:
using SpacePointer = std::shared_ptr<Space>;
using Changes = std::vector<Space::Change>;
using IndexVectors = std::vector<IndexVector>;
using Timings = std::vector<float>;
using Timings = std::vector<std::chrono::nanoseconds>;
} // namespace workload