mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 07:13:57 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into red
This commit is contained in:
commit
0c50903030
15 changed files with 116 additions and 135 deletions
|
@ -136,7 +136,7 @@ Item {
|
|||
Text {
|
||||
color: root.fontColor;
|
||||
font.pixelSize: root.fontSize
|
||||
text: "Velocity: " + root.velocity.toFixed(1)
|
||||
text: "Speed: " + root.speed.toFixed(1)
|
||||
}
|
||||
Text {
|
||||
color: root.fontColor;
|
||||
|
|
|
@ -1085,6 +1085,8 @@ void MyAvatar::harvestResultsFromPhysicsSimulation(float deltaTime) {
|
|||
nextAttitude(position, orientation);
|
||||
_bodySensorMatrix = _follow.postPhysicsUpdate(*this, _bodySensorMatrix);
|
||||
|
||||
setVelocity(_characterController.getLinearVelocity() + _characterController.getFollowVelocity());
|
||||
|
||||
// now that physics has adjusted our position, we can update attachements.
|
||||
Avatar::simulateAttachments(deltaTime);
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ void Stats::updateStats(bool force) {
|
|||
MyAvatar* myAvatar = avatarManager->getMyAvatar();
|
||||
glm::vec3 avatarPos = myAvatar->getPosition();
|
||||
STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
|
||||
STAT_UPDATE_FLOAT(velocity, glm::length(myAvatar->getVelocity()), 0.1f);
|
||||
STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getVelocity()), 0.1f);
|
||||
STAT_UPDATE_FLOAT(yaw, myAvatar->getBodyYaw(), 0.1f);
|
||||
if (_expanded || force) {
|
||||
SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
|
||||
|
|
|
@ -47,7 +47,7 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(int, entitiesPing, 0)
|
||||
STATS_PROPERTY(int, assetPing, 0)
|
||||
STATS_PROPERTY(QVector3D, position, QVector3D(0, 0, 0) )
|
||||
STATS_PROPERTY(float, velocity, 0)
|
||||
STATS_PROPERTY(float, speed, 0)
|
||||
STATS_PROPERTY(float, yaw, 0)
|
||||
STATS_PROPERTY(int, avatarMixerInKbps, 0)
|
||||
STATS_PROPERTY(int, avatarMixerInPps, 0)
|
||||
|
@ -138,7 +138,7 @@ signals:
|
|||
void entitiesPingChanged();
|
||||
void assetPingChanged();
|
||||
void positionChanged();
|
||||
void velocityChanged();
|
||||
void speedChanged();
|
||||
void yawChanged();
|
||||
void avatarMixerInKbpsChanged();
|
||||
void avatarMixerInPpsChanged();
|
||||
|
|
|
@ -246,7 +246,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
|
|||
// deltas up the hierarchy. Its target position is enforced later by shifting the hips.
|
||||
deltaRotation = target.getRotation() * glm::inverse(tipOrientation);
|
||||
float dotSign = copysignf(1.0f, deltaRotation.w);
|
||||
const float ANGLE_DISTRIBUTION_FACTOR = 0.35f;
|
||||
const float ANGLE_DISTRIBUTION_FACTOR = 0.45f;
|
||||
deltaRotation = glm::normalize(glm::lerp(glm::quat(), dotSign * deltaRotation, ANGLE_DISTRIBUTION_FACTOR));
|
||||
}
|
||||
|
||||
|
@ -376,13 +376,26 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
++constraintItr;
|
||||
}
|
||||
} else {
|
||||
// shift the hips according to the offset from the previous frame
|
||||
// shift the everything according to the _hipsOffset from the previous frame
|
||||
float offsetLength = glm::length(_hipsOffset);
|
||||
const float MIN_HIPS_OFFSET_LENGTH = 0.03f;
|
||||
if (offsetLength > MIN_HIPS_OFFSET_LENGTH) {
|
||||
// but only if offset is long enough
|
||||
float scaleFactor = ((offsetLength - MIN_HIPS_OFFSET_LENGTH) / offsetLength);
|
||||
_relativePoses[_hipsIndex].trans = underPoses[_hipsIndex].trans + scaleFactor * _hipsOffset;
|
||||
if (_hipsParentIndex == -1) {
|
||||
// the hips are the root so _hipsOffset is in the correct frame
|
||||
_relativePoses[_hipsIndex].trans = underPoses[_hipsIndex].trans + scaleFactor * _hipsOffset;
|
||||
} else {
|
||||
// the hips are NOT the root so we need to transform _hipsOffset into hips local-frame
|
||||
glm::quat hipsFrameRotation = _relativePoses[_hipsParentIndex].rot;
|
||||
int index = _skeleton->getParentIndex(_hipsParentIndex);
|
||||
while (index != -1) {
|
||||
hipsFrameRotation *= _relativePoses[index].rot;
|
||||
index = _skeleton->getParentIndex(index);
|
||||
}
|
||||
_relativePoses[_hipsIndex].trans = underPoses[_hipsIndex].trans
|
||||
+ glm::inverse(glm::normalize(hipsFrameRotation)) * (scaleFactor * _hipsOffset);
|
||||
}
|
||||
}
|
||||
|
||||
solveWithCyclicCoordinateDescent(targets);
|
||||
|
@ -621,7 +634,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
} else if (baseName.startsWith("Spine", Qt::CaseInsensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
const float MAX_SPINE_TWIST = PI / 8.0f;
|
||||
const float MAX_SPINE_TWIST = PI / 12.0f;
|
||||
stConstraint->setTwistLimits(-MAX_SPINE_TWIST, MAX_SPINE_TWIST);
|
||||
|
||||
std::vector<float> minDots;
|
||||
|
@ -645,11 +658,11 @@ void AnimInverseKinematics::initConstraints() {
|
|||
} else if (0 == baseName.compare("Neck", Qt::CaseInsensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
const float MAX_NECK_TWIST = PI / 6.0f;
|
||||
const float MAX_NECK_TWIST = PI / 9.0f;
|
||||
stConstraint->setTwistLimits(-MAX_NECK_TWIST, MAX_NECK_TWIST);
|
||||
|
||||
std::vector<float> minDots;
|
||||
const float MAX_NECK_SWING = PI / 4.0f;
|
||||
const float MAX_NECK_SWING = PI / 8.0f;
|
||||
minDots.push_back(cosf(MAX_NECK_SWING));
|
||||
stConstraint->setSwingLimits(minDots);
|
||||
|
||||
|
@ -657,11 +670,11 @@ void AnimInverseKinematics::initConstraints() {
|
|||
} else if (0 == baseName.compare("Head", Qt::CaseInsensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
const float MAX_HEAD_TWIST = PI / 8.0f;
|
||||
const float MAX_HEAD_TWIST = PI / 9.0f;
|
||||
stConstraint->setTwistLimits(-MAX_HEAD_TWIST, MAX_HEAD_TWIST);
|
||||
|
||||
std::vector<float> minDots;
|
||||
const float MAX_HEAD_SWING = PI / 6.0f;
|
||||
const float MAX_HEAD_SWING = PI / 10.0f;
|
||||
minDots.push_back(cosf(MAX_HEAD_SWING));
|
||||
stConstraint->setSwingLimits(minDots);
|
||||
|
||||
|
@ -775,9 +788,13 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele
|
|||
initConstraints();
|
||||
_headIndex = _skeleton->nameToJointIndex("Head");
|
||||
_hipsIndex = _skeleton->nameToJointIndex("Hips");
|
||||
|
||||
// also cache the _hipsParentIndex for later
|
||||
_hipsParentIndex = _skeleton->getParentIndex(_hipsIndex);
|
||||
} else {
|
||||
clearConstraints();
|
||||
_headIndex = -1;
|
||||
_hipsIndex = -1;
|
||||
_hipsParentIndex = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,13 +79,14 @@ protected:
|
|||
AnimPoseVec _relativePoses; // current relative poses
|
||||
|
||||
// experimental data for moving hips during IK
|
||||
int _headIndex = -1;
|
||||
int _hipsIndex = -1;
|
||||
glm::vec3 _hipsOffset = Vectors::ZERO;
|
||||
glm::vec3 _hipsOffset { Vectors::ZERO };
|
||||
int _headIndex { -1 };
|
||||
int _hipsIndex { -1 };
|
||||
int _hipsParentIndex { -1 };
|
||||
|
||||
// _maxTargetIndex is tracked to help optimize the recalculation of absolute poses
|
||||
// during the the cyclic coordinate descent algorithm
|
||||
int _maxTargetIndex = 0;
|
||||
int _maxTargetIndex { 0 };
|
||||
};
|
||||
|
||||
#endif // hifi_AnimInverseKinematics_h
|
||||
|
|
|
@ -18,7 +18,7 @@ const float AnimationLoop::MAXIMUM_POSSIBLE_FRAME = 100000.0f;
|
|||
|
||||
AnimationLoop::AnimationLoop() :
|
||||
_fps(30.0f),
|
||||
_loop(false),
|
||||
_loop(true),
|
||||
_hold(false),
|
||||
_startAutomatically(false),
|
||||
_firstFrame(0.0f),
|
||||
|
|
|
@ -181,6 +181,15 @@ int64_t AudioInjector::injectNextFrame() {
|
|||
// make sure we actually have samples downloaded to inject
|
||||
if (_audioData.size()) {
|
||||
|
||||
int sampleSize = (_options.stereo ? 2 : 1) * sizeof(AudioConstants::AudioSample);
|
||||
auto numSamples = static_cast<int>(_audioData.size() / sampleSize);
|
||||
auto targetSize = numSamples * sampleSize;
|
||||
if (targetSize != _audioData.size()) {
|
||||
qDebug() << "Resizing audio that doesn't end at multiple of sample size, resizing from "
|
||||
<< _audioData.size() << " to " << targetSize;
|
||||
_audioData.resize(targetSize);
|
||||
}
|
||||
|
||||
_outgoingSequenceNumber = 0;
|
||||
_nextFrame = 0;
|
||||
|
||||
|
@ -272,7 +281,7 @@ int64_t AudioInjector::injectNextFrame() {
|
|||
_currentPacket->write(_audioData.data() + _currentSendOffset, bytesToCopy);
|
||||
_currentSendOffset += bytesToCopy;
|
||||
totalBytesLeftToCopy -= bytesToCopy;
|
||||
if (_currentSendOffset >= _audioData.size()) {
|
||||
if (_options.loop && _currentSendOffset >= _audioData.size()) {
|
||||
_currentSendOffset = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -390,6 +390,14 @@ glm::quat CharacterController::getFollowAngularDisplacement() const {
|
|||
return bulletToGLM(_followAngularDisplacement);
|
||||
}
|
||||
|
||||
glm::vec3 CharacterController::getFollowVelocity() const {
|
||||
if (_followTime > 0.0f) {
|
||||
return bulletToGLM(_followLinearDisplacement) / _followTime;
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 CharacterController::getLinearVelocity() const {
|
||||
glm::vec3 velocity(0.0f);
|
||||
if (_rigidBody) {
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
float getFollowTime() const { return _followTime; }
|
||||
glm::vec3 getFollowLinearDisplacement() const;
|
||||
glm::quat getFollowAngularDisplacement() const;
|
||||
glm::vec3 getFollowVelocity() const;
|
||||
|
||||
glm::vec3 getLinearVelocity() const;
|
||||
|
||||
|
|
|
@ -90,15 +90,16 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
initDeferredPipelines(*shapePlumber);
|
||||
|
||||
// CPU: Fetch the renderOpaques
|
||||
auto fetchedOpaques = addJob<FetchItems>("FetchOpaque");
|
||||
auto culledOpaques = addJob<CullItems<RenderDetails::OPAQUE_ITEM>>("CullOpaque", fetchedOpaques, cullFunctor);
|
||||
auto opaques = addJob<DepthSortItems>("DepthSortOpaque", culledOpaques);
|
||||
const auto fetchedOpaques = addJob<FetchItems>("FetchOpaque");
|
||||
const auto culledOpaques = addJob<CullItems<RenderDetails::OPAQUE_ITEM>>("CullOpaque", fetchedOpaques, cullFunctor);
|
||||
const auto opaques = addJob<DepthSortItems>("DepthSortOpaque", culledOpaques);
|
||||
|
||||
// CPU only, create the list of renderedTransparents items
|
||||
auto fetchedTransparents = addJob<FetchItems>("FetchTransparent", FetchItems(
|
||||
const auto fetchedTransparents = addJob<FetchItems>("FetchTransparent", FetchItems(
|
||||
ItemFilter::Builder::transparentShape().withoutLayered()));
|
||||
auto culledTransparents = addJob<CullItems<RenderDetails::TRANSLUCENT_ITEM>>("CullTransparent", fetchedTransparents, cullFunctor);
|
||||
auto transparents = addJob<DepthSortItems>("DepthSortTransparent", culledTransparents, DepthSortItems(false));
|
||||
const auto culledTransparents =
|
||||
addJob<CullItems<RenderDetails::TRANSLUCENT_ITEM>>("CullTransparent", fetchedTransparents, cullFunctor);
|
||||
const auto transparents = addJob<DepthSortItems>("DepthSortTransparent", culledTransparents, DepthSortItems(false));
|
||||
|
||||
// GPU Jobs: Start preparing the deferred and lighting buffer
|
||||
addJob<PrepareDeferred>("PrepareDeferred");
|
||||
|
|
|
@ -105,16 +105,16 @@ RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task(std::make_sha
|
|||
}
|
||||
|
||||
// CPU: Fetch shadow-casting opaques
|
||||
auto fetchedItems = addJob<FetchItems>("FetchShadowMap");
|
||||
const auto fetchedItems = addJob<FetchItems>("FetchShadowMap");
|
||||
|
||||
// CPU: Cull against KeyLight frustum (nearby viewing camera)
|
||||
auto culledItems = addJob<CullItems<RenderDetails::SHADOW_ITEM>>("CullShadowMap", fetchedItems, cullFunctor);
|
||||
const auto culledItems = addJob<CullItems<RenderDetails::SHADOW_ITEM>>("CullShadowMap", fetchedItems, cullFunctor);
|
||||
|
||||
// CPU: Sort by pipeline
|
||||
auto sortedShapes = addJob<PipelineSortShapes>("PipelineSortShadowSort", culledItems);
|
||||
const auto sortedShapes = addJob<PipelineSortShapes>("PipelineSortShadowSort", culledItems);
|
||||
|
||||
// CPU: Sort front to back
|
||||
auto shadowShapes = addJob<DepthSortShapes>("DepthSortShadowMap", sortedShapes);
|
||||
const auto shadowShapes = addJob<DepthSortShapes>("DepthSortShadowMap", sortedShapes);
|
||||
|
||||
// GPU: Render to shadow map
|
||||
addJob<RenderShadowMap>("RenderShadowMap", shadowShapes, shapePlumber);
|
||||
|
|
|
@ -52,6 +52,7 @@ protected:
|
|||
|
||||
class Job;
|
||||
class Task;
|
||||
class JobNoIO {};
|
||||
|
||||
// A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled)
|
||||
class JobConfig : public QObject {
|
||||
|
@ -101,16 +102,16 @@ template <class T, class C> void jobConfigure(T& data, const C& configuration) {
|
|||
template<class T> void jobConfigure(T&, const JobConfig&) {
|
||||
// nop, as the default JobConfig was used, so the data does not need a configure method
|
||||
}
|
||||
template <class T> void jobRun(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
template <class T> void jobRun(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const JobNoIO& input, JobNoIO& output) {
|
||||
data.run(sceneContext, renderContext);
|
||||
}
|
||||
template <class T, class I> void jobRunI(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) {
|
||||
template <class T, class I> void jobRun(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, JobNoIO& output) {
|
||||
data.run(sceneContext, renderContext, input);
|
||||
}
|
||||
template <class T, class O> void jobRunO(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
|
||||
template <class T, class O> void jobRun(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const JobNoIO& input, O& output) {
|
||||
data.run(sceneContext, renderContext, output);
|
||||
}
|
||||
template <class T, class I, class O> void jobRunIO(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) {
|
||||
template <class T, class I, class O> void jobRun(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) {
|
||||
data.run(sceneContext, renderContext, input, output);
|
||||
}
|
||||
|
||||
|
@ -118,6 +119,7 @@ class Job {
|
|||
public:
|
||||
using Config = JobConfig;
|
||||
using QConfigPointer = std::shared_ptr<QObject>;
|
||||
using None = JobNoIO;
|
||||
|
||||
// The guts of a job
|
||||
class Concept {
|
||||
|
@ -138,84 +140,7 @@ public:
|
|||
};
|
||||
using ConceptPointer = std::shared_ptr<Concept>;
|
||||
|
||||
template <class T, class C = Config> class Model : public Concept {
|
||||
public:
|
||||
using Data = T;
|
||||
|
||||
Data _data;
|
||||
|
||||
Model(Data data = Data()) : Concept(std::make_shared<C>()), _data(data) {
|
||||
applyConfiguration();
|
||||
}
|
||||
|
||||
void applyConfiguration() {
|
||||
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
|
||||
}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
renderContext->jobConfig = std::static_pointer_cast<Config>(_config);
|
||||
if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->enabled) {
|
||||
jobRun(_data, sceneContext, renderContext);
|
||||
}
|
||||
renderContext->jobConfig.reset();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class C = Config> class ModelI : public Concept {
|
||||
public:
|
||||
using Data = T;
|
||||
using Input = I;
|
||||
|
||||
Data _data;
|
||||
Varying _input;
|
||||
|
||||
const Varying getInput() const { return _input; }
|
||||
|
||||
ModelI(const Varying& input, Data data = Data()) : Concept(std::make_shared<C>()), _data(data), _input(input) {
|
||||
applyConfiguration();
|
||||
}
|
||||
|
||||
void applyConfiguration() {
|
||||
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
|
||||
}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
renderContext->jobConfig = std::static_pointer_cast<Config>(_config);
|
||||
if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->enabled) {
|
||||
jobRunI(_data, sceneContext, renderContext, _input.get<I>());
|
||||
}
|
||||
renderContext->jobConfig.reset();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class O, class C = Config> class ModelO : public Concept {
|
||||
public:
|
||||
using Data = T;
|
||||
using Output = O;
|
||||
|
||||
Data _data;
|
||||
Varying _output;
|
||||
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
ModelO(Data data = Data()) : Concept(std::make_shared<C>()), _data(data), _output(Output()) {
|
||||
applyConfiguration();
|
||||
}
|
||||
|
||||
void applyConfiguration() {
|
||||
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
|
||||
}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
renderContext->jobConfig = std::static_pointer_cast<Config>(_config);
|
||||
if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->enabled) {
|
||||
jobRunO(_data, sceneContext, renderContext, _output.edit<O>());
|
||||
}
|
||||
renderContext->jobConfig.reset();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class O, class C = Config> class ModelIO : public Concept {
|
||||
template <class T, class C = Config, class I = None, class O = None> class Model : public Concept {
|
||||
public:
|
||||
using Data = T;
|
||||
using Input = I;
|
||||
|
@ -228,7 +153,7 @@ public:
|
|||
const Varying getInput() const { return _input; }
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
ModelIO(const Varying& input, Data data = Data()) : Concept(std::make_shared<C>()), _data(data), _input(input), _output(Output()) {
|
||||
Model(const Varying& input, Data data = Data()) : Concept(std::make_shared<C>()), _data(data), _input(input), _output(Output()) {
|
||||
applyConfiguration();
|
||||
}
|
||||
|
||||
|
@ -239,11 +164,14 @@ public:
|
|||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
renderContext->jobConfig = std::static_pointer_cast<Config>(_config);
|
||||
if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->enabled) {
|
||||
jobRunIO(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
|
||||
jobRun(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
|
||||
}
|
||||
renderContext->jobConfig.reset();
|
||||
}
|
||||
};
|
||||
template <class T, class I, class C = Config> using ModelI = Model<T, C, I, None>;
|
||||
template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>;
|
||||
template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
|
||||
|
||||
Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {}
|
||||
|
||||
|
@ -278,17 +206,24 @@ class Task {
|
|||
public:
|
||||
using Config = TaskConfig;
|
||||
using QConfigPointer = Job::QConfigPointer;
|
||||
using None = Job::None;
|
||||
|
||||
template <class T, class C = Config> class Model : public Job::Concept {
|
||||
template <class T, class C = Config, class I = None, class O = None> class Model : public Job::Concept {
|
||||
public:
|
||||
using Data = T;
|
||||
using Input = I;
|
||||
using Output = O;
|
||||
|
||||
Data _data;
|
||||
Varying _input;
|
||||
Varying _output;
|
||||
|
||||
Model(Data data = Data()) : Concept(std::make_shared<C>()), _data(data) {
|
||||
const Varying getInput() const { return _input; }
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
Model(const Varying& input, Data data = Data()) : Concept(std::make_shared<C>()), _data(data), _input(input), _output(Output()) {
|
||||
_config = _data._config; // use the data's config
|
||||
std::static_pointer_cast<Config>(_config)->init(&_data);
|
||||
|
||||
applyConfiguration();
|
||||
}
|
||||
|
||||
|
@ -299,11 +234,14 @@ public:
|
|||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
renderContext->jobConfig = std::static_pointer_cast<Config>(_config);
|
||||
if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->enabled) {
|
||||
jobRun(_data, sceneContext, renderContext);
|
||||
jobRun(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
|
||||
}
|
||||
renderContext->jobConfig.reset();
|
||||
}
|
||||
};
|
||||
template <class T, class I, class C = Config> using ModelI = Model<T, C, I, None>;
|
||||
template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>;
|
||||
template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
|
||||
|
||||
using Jobs = std::vector<Job>;
|
||||
|
||||
|
@ -311,15 +249,21 @@ public:
|
|||
Task() : _config{ std::make_shared<Config>() } {}
|
||||
template <class C> Task(std::shared_ptr<C> config) : _config{ config } {}
|
||||
|
||||
// Queue a new job to the container; returns the job's output
|
||||
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
|
||||
_jobs.emplace_back(name, std::make_shared<typename T::JobModel>(std::forward<A>(args)...));
|
||||
// Create a new job in the container's queue; returns the job's output
|
||||
template <class T, class... A> const Varying addJob(std::string name, const Varying& input, A&&... args) {
|
||||
_jobs.emplace_back(name, std::make_shared<typename T::JobModel>(
|
||||
input,
|
||||
typename T::JobModel::Data(std::forward<A>(args)...)));
|
||||
QConfigPointer config = _jobs.back().getConfiguration();
|
||||
config->setParent(_config.get());
|
||||
config->setObjectName(name.c_str());
|
||||
QObject::connect(config.get(), SIGNAL(dirty()), _config.get(), SLOT(refresh()));
|
||||
return _jobs.back().getOutput();
|
||||
}
|
||||
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
|
||||
const auto input = Varying(typename T::JobModel::Input());
|
||||
return addJob<T>(name, input, std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
std::shared_ptr<Config> getConfiguration() {
|
||||
auto config = std::static_pointer_cast<Config>(_config);
|
||||
|
@ -335,7 +279,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
template <class T, class C> friend class Model;
|
||||
template <class T, class C, class I, class O> friend class Model;
|
||||
|
||||
QConfigPointer _config;
|
||||
Jobs _jobs;
|
||||
|
|
|
@ -1110,9 +1110,9 @@
|
|||
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav",
|
||||
name: "dice",
|
||||
position: {
|
||||
x: 541,
|
||||
y: 494.96,
|
||||
z: 509.1
|
||||
x: 541.61,
|
||||
y: 495.21,
|
||||
z: 508.52
|
||||
},
|
||||
dimensions: {
|
||||
x: 0.09,
|
||||
|
@ -1144,16 +1144,15 @@
|
|||
var dice1 = Entities.addEntity(diceProps);
|
||||
|
||||
diceProps.position = {
|
||||
x: 541.05,
|
||||
y: 494.96,
|
||||
z: 509.0
|
||||
x: 541.52,
|
||||
y: 495.21,
|
||||
z: 508.41
|
||||
};
|
||||
|
||||
var dice2 = Entities.addEntity(diceProps);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createGates() {
|
||||
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx';
|
||||
|
||||
|
|
|
@ -1098,9 +1098,9 @@ MasterReset = function() {
|
|||
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav",
|
||||
name: "dice",
|
||||
position: {
|
||||
x: 541,
|
||||
y: 494.96,
|
||||
z: 509.1
|
||||
x: 541.61,
|
||||
y: 495.21,
|
||||
z: 508.52
|
||||
},
|
||||
dimensions: {
|
||||
x: 0.09,
|
||||
|
@ -1132,16 +1132,15 @@ MasterReset = function() {
|
|||
var dice1 = Entities.addEntity(diceProps);
|
||||
|
||||
diceProps.position = {
|
||||
x: 541.05,
|
||||
y: 494.96,
|
||||
z: 509.0
|
||||
x: 541.52,
|
||||
y: 495.21,
|
||||
z: 508.41
|
||||
};
|
||||
|
||||
var dice2 = Entities.addEntity(diceProps);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function createGates() {
|
||||
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx';
|
||||
|
||||
|
|
Loading…
Reference in a new issue