mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 10:54:26 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into fixGrabWebSurface-case-16192
This commit is contained in:
commit
1aa8b7c81b
78 changed files with 1172 additions and 540 deletions
|
@ -96,7 +96,6 @@ Agent::Agent(ReceivedMessage& message) :
|
||||||
DependencyManager::set<recording::Recorder>();
|
DependencyManager::set<recording::Recorder>();
|
||||||
DependencyManager::set<recording::ClipCache>();
|
DependencyManager::set<recording::ClipCache>();
|
||||||
|
|
||||||
DependencyManager::set<ScriptCache>();
|
|
||||||
DependencyManager::set<RecordingScriptingInterface>();
|
DependencyManager::set<RecordingScriptingInterface>();
|
||||||
DependencyManager::set<UsersScriptingInterface>();
|
DependencyManager::set<UsersScriptingInterface>();
|
||||||
|
|
||||||
|
@ -177,6 +176,8 @@ void Agent::run() {
|
||||||
// Create ScriptEngines on threaded-assignment thread then move to main thread.
|
// Create ScriptEngines on threaded-assignment thread then move to main thread.
|
||||||
DependencyManager::set<ScriptEngines>(ScriptEngine::AGENT_SCRIPT)->moveToThread(qApp->thread());
|
DependencyManager::set<ScriptEngines>(ScriptEngine::AGENT_SCRIPT)->moveToThread(qApp->thread());
|
||||||
|
|
||||||
|
DependencyManager::set<ScriptCache>();
|
||||||
|
|
||||||
// make sure we request our script once the agent connects to the domain
|
// make sure we request our script once the agent connects to the domain
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
@ -360,154 +361,168 @@ void Agent::scriptRequestFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Agent::executeScript() {
|
void Agent::executeScript() {
|
||||||
_scriptEngine = scriptEngineFactory(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload);
|
// the following block is scoped so that any shared pointers we take here
|
||||||
|
// are cleared before we call setFinished at the end of the function
|
||||||
|
{
|
||||||
|
_scriptEngine = scriptEngineFactory(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload);
|
||||||
|
|
||||||
// setup an Avatar for the script to use
|
// setup an Avatar for the script to use
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
|
|
||||||
scriptedAvatar->setID(getSessionUUID());
|
scriptedAvatar->setID(getSessionUUID());
|
||||||
|
|
||||||
connect(_scriptEngine.data(), SIGNAL(update(float)),
|
connect(_scriptEngine.data(), SIGNAL(update(float)),
|
||||||
scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
|
scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
|
||||||
scriptedAvatar->setForceFaceTrackerConnected(true);
|
scriptedAvatar->setForceFaceTrackerConnected(true);
|
||||||
|
|
||||||
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
||||||
scriptedAvatar->setSkeletonModelURL(QUrl());
|
scriptedAvatar->setSkeletonModelURL(QUrl());
|
||||||
|
|
||||||
// force lazy initialization of the head data for the scripted avatar
|
// force lazy initialization of the head data for the scripted avatar
|
||||||
// since it is referenced below by computeLoudness and getAudioLoudness
|
// since it is referenced below by computeLoudness and getAudioLoudness
|
||||||
scriptedAvatar->getHeadOrientation();
|
scriptedAvatar->getHeadOrientation();
|
||||||
|
|
||||||
// give this AvatarData object to the script engine
|
// give this AvatarData object to the script engine
|
||||||
_scriptEngine->registerGlobalObject("Avatar", scriptedAvatar.data());
|
_scriptEngine->registerGlobalObject("Avatar", scriptedAvatar.data());
|
||||||
|
|
||||||
// give scripts access to the Users object
|
// give scripts access to the Users object
|
||||||
_scriptEngine->registerGlobalObject("Users", DependencyManager::get<UsersScriptingInterface>().data());
|
_scriptEngine->registerGlobalObject("Users", DependencyManager::get<UsersScriptingInterface>().data());
|
||||||
|
|
||||||
auto player = DependencyManager::get<recording::Deck>();
|
auto player = DependencyManager::get<recording::Deck>();
|
||||||
connect(player.data(), &recording::Deck::playbackStateChanged, [=] {
|
connect(player.data(), &recording::Deck::playbackStateChanged, [&player, &scriptedAvatar] {
|
||||||
if (player->isPlaying()) {
|
if (player->isPlaying()) {
|
||||||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||||
if (recordingInterface->getPlayFromCurrentLocation()) {
|
if (recordingInterface->getPlayFromCurrentLocation()) {
|
||||||
scriptedAvatar->setRecordingBasis();
|
scriptedAvatar->setRecordingBasis();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scriptedAvatar->clearRecordingBasis();
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
scriptedAvatar->clearRecordingBasis();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
using namespace recording;
|
using namespace recording;
|
||||||
static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME);
|
static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME);
|
||||||
Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [scriptedAvatar](Frame::ConstPointer frame) {
|
Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [scriptedAvatar](Frame::ConstPointer frame) {
|
||||||
|
|
||||||
|
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||||
|
bool useFrameSkeleton = recordingInterface->getPlayerUseSkeletonModel();
|
||||||
|
|
||||||
|
// FIXME - the ability to switch the avatar URL is not actually supported when playing back from a recording
|
||||||
|
if (!useFrameSkeleton) {
|
||||||
|
static std::once_flag warning;
|
||||||
|
std::call_once(warning, [] {
|
||||||
|
qWarning() << "Recording.setPlayerUseSkeletonModel(false) is not currently supported.";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarData::fromFrame(frame->data, *scriptedAvatar);
|
||||||
|
});
|
||||||
|
|
||||||
|
using namespace recording;
|
||||||
|
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
||||||
|
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) {
|
||||||
|
static quint16 audioSequenceNumber{ 0 };
|
||||||
|
|
||||||
|
QByteArray audio(frame->data);
|
||||||
|
|
||||||
|
if (_isNoiseGateEnabled) {
|
||||||
|
int16_t* samples = reinterpret_cast<int16_t*>(audio.data());
|
||||||
|
int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL;
|
||||||
|
_audioGate.render(samples, samples, numSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
computeLoudness(&audio, scriptedAvatar);
|
||||||
|
|
||||||
|
// state machine to detect gate opening and closing
|
||||||
|
bool audioGateOpen = (scriptedAvatar->getAudioLoudness() != 0.0f);
|
||||||
|
bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened
|
||||||
|
bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed
|
||||||
|
_audioGateOpen = audioGateOpen;
|
||||||
|
Q_UNUSED(openedInLastBlock);
|
||||||
|
|
||||||
|
// the codec must be flushed to silence before sending silent packets,
|
||||||
|
// so delay the transition to silent packets by one packet after becoming silent.
|
||||||
|
auto packetType = PacketType::MicrophoneAudioNoEcho;
|
||||||
|
if (!audioGateOpen && !closedInLastBlock) {
|
||||||
|
packetType = PacketType::SilentAudioFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform audioTransform;
|
||||||
|
auto headOrientation = scriptedAvatar->getHeadOrientation();
|
||||||
|
audioTransform.setTranslation(scriptedAvatar->getWorldPosition());
|
||||||
|
audioTransform.setRotation(headOrientation);
|
||||||
|
|
||||||
|
QByteArray encodedBuffer;
|
||||||
|
if (_encoder) {
|
||||||
|
_encoder->encode(audio, encodedBuffer);
|
||||||
|
} else {
|
||||||
|
encodedBuffer = audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractAudioInterface::emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), audioSequenceNumber, false,
|
||||||
|
audioTransform, scriptedAvatar->getWorldPosition(), glm::vec3(0),
|
||||||
|
packetType, _selectedCodecName);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
||||||
|
_scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data());
|
||||||
|
|
||||||
|
// register ourselves to the script engine
|
||||||
|
_scriptEngine->registerGlobalObject("Agent", new AgentScriptingInterface(this));
|
||||||
|
|
||||||
|
_scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCacheScriptingInterface>().data());
|
||||||
|
_scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data());
|
||||||
|
|
||||||
|
QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor);
|
||||||
|
_scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
||||||
|
|
||||||
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
|
||||||
|
_scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
||||||
|
|
||||||
|
_scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
||||||
|
LocationScriptingInterface::locationSetter);
|
||||||
|
|
||||||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||||
bool useFrameSkeleton = recordingInterface->getPlayerUseSkeletonModel();
|
_scriptEngine->registerGlobalObject("Recording", recordingInterface.data());
|
||||||
|
|
||||||
// FIXME - the ability to switch the avatar URL is not actually supported when playing back from a recording
|
entityScriptingInterface->init();
|
||||||
if (!useFrameSkeleton) {
|
|
||||||
static std::once_flag warning;
|
_entityViewer.init();
|
||||||
std::call_once(warning, [] {
|
|
||||||
qWarning() << "Recording.setPlayerUseSkeletonModel(false) is not currently supported.";
|
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||||
});
|
|
||||||
|
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||||
|
|
||||||
|
_avatarAudioTimer.start();
|
||||||
|
|
||||||
|
// Agents should run at 45hz
|
||||||
|
static const int AVATAR_DATA_HZ = 45;
|
||||||
|
static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ;
|
||||||
|
QTimer* avatarDataTimer = new QTimer(this);
|
||||||
|
connect(avatarDataTimer, &QTimer::timeout, this, &Agent::processAgentAvatar);
|
||||||
|
avatarDataTimer->setSingleShot(false);
|
||||||
|
avatarDataTimer->setInterval(AVATAR_DATA_IN_MSECS);
|
||||||
|
avatarDataTimer->setTimerType(Qt::PreciseTimer);
|
||||||
|
avatarDataTimer->start();
|
||||||
|
|
||||||
|
_scriptEngine->run();
|
||||||
|
|
||||||
|
Frame::clearFrameHandler(AUDIO_FRAME_TYPE);
|
||||||
|
Frame::clearFrameHandler(AVATAR_FRAME_TYPE);
|
||||||
|
|
||||||
|
if (recordingInterface->isPlaying()) {
|
||||||
|
recordingInterface->stopPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarData::fromFrame(frame->data, *scriptedAvatar);
|
if (recordingInterface->isRecording()) {
|
||||||
});
|
recordingInterface->stopRecording();
|
||||||
|
|
||||||
using namespace recording;
|
|
||||||
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
|
||||||
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) {
|
|
||||||
static quint16 audioSequenceNumber{ 0 };
|
|
||||||
|
|
||||||
QByteArray audio(frame->data);
|
|
||||||
|
|
||||||
if (_isNoiseGateEnabled) {
|
|
||||||
int16_t* samples = reinterpret_cast<int16_t*>(audio.data());
|
|
||||||
int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL;
|
|
||||||
_audioGate.render(samples, samples, numSamples);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
computeLoudness(&audio, scriptedAvatar);
|
avatarDataTimer->stop();
|
||||||
|
_avatarAudioTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
// state machine to detect gate opening and closing
|
|
||||||
bool audioGateOpen = (scriptedAvatar->getAudioLoudness() != 0.0f);
|
|
||||||
bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened
|
|
||||||
bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed
|
|
||||||
_audioGateOpen = audioGateOpen;
|
|
||||||
Q_UNUSED(openedInLastBlock);
|
|
||||||
|
|
||||||
// the codec must be flushed to silence before sending silent packets,
|
|
||||||
// so delay the transition to silent packets by one packet after becoming silent.
|
|
||||||
auto packetType = PacketType::MicrophoneAudioNoEcho;
|
|
||||||
if (!audioGateOpen && !closedInLastBlock) {
|
|
||||||
packetType = PacketType::SilentAudioFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform audioTransform;
|
|
||||||
auto headOrientation = scriptedAvatar->getHeadOrientation();
|
|
||||||
audioTransform.setTranslation(scriptedAvatar->getWorldPosition());
|
|
||||||
audioTransform.setRotation(headOrientation);
|
|
||||||
|
|
||||||
QByteArray encodedBuffer;
|
|
||||||
if (_encoder) {
|
|
||||||
_encoder->encode(audio, encodedBuffer);
|
|
||||||
} else {
|
|
||||||
encodedBuffer = audio;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractAudioInterface::emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), audioSequenceNumber, false,
|
|
||||||
audioTransform, scriptedAvatar->getWorldPosition(), glm::vec3(0),
|
|
||||||
packetType, _selectedCodecName);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
|
||||||
_scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data());
|
|
||||||
|
|
||||||
// register ourselves to the script engine
|
|
||||||
_scriptEngine->registerGlobalObject("Agent", new AgentScriptingInterface(this));
|
|
||||||
|
|
||||||
_scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCacheScriptingInterface>().data());
|
|
||||||
_scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data());
|
|
||||||
|
|
||||||
QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor);
|
|
||||||
_scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
|
||||||
|
|
||||||
_scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
|
||||||
|
|
||||||
_scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
|
||||||
LocationScriptingInterface::locationSetter);
|
|
||||||
|
|
||||||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
|
||||||
_scriptEngine->registerGlobalObject("Recording", recordingInterface.data());
|
|
||||||
|
|
||||||
entityScriptingInterface->init();
|
|
||||||
|
|
||||||
_entityViewer.init();
|
|
||||||
|
|
||||||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
|
||||||
|
|
||||||
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
|
|
||||||
|
|
||||||
// Agents should run at 45hz
|
|
||||||
static const int AVATAR_DATA_HZ = 45;
|
|
||||||
static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ;
|
|
||||||
QTimer* avatarDataTimer = new QTimer(this);
|
|
||||||
connect(avatarDataTimer, &QTimer::timeout, this, &Agent::processAgentAvatar);
|
|
||||||
avatarDataTimer->setSingleShot(false);
|
|
||||||
avatarDataTimer->setInterval(AVATAR_DATA_IN_MSECS);
|
|
||||||
avatarDataTimer->setTimerType(Qt::PreciseTimer);
|
|
||||||
avatarDataTimer->start();
|
|
||||||
|
|
||||||
_scriptEngine->run();
|
|
||||||
|
|
||||||
Frame::clearFrameHandler(AUDIO_FRAME_TYPE);
|
|
||||||
Frame::clearFrameHandler(AVATAR_FRAME_TYPE);
|
|
||||||
|
|
||||||
DependencyManager::destroy<RecordingScriptingInterface>();
|
|
||||||
setFinished(true);
|
setFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,17 +874,25 @@ void Agent::aboutToFinish() {
|
||||||
DependencyManager::destroy<SoundCache>();
|
DependencyManager::destroy<SoundCache>();
|
||||||
DependencyManager::destroy<AudioScriptingInterface>();
|
DependencyManager::destroy<AudioScriptingInterface>();
|
||||||
|
|
||||||
|
DependencyManager::destroy<RecordingScriptingInterface>();
|
||||||
DependencyManager::destroy<recording::Deck>();
|
DependencyManager::destroy<recording::Deck>();
|
||||||
DependencyManager::destroy<recording::Recorder>();
|
DependencyManager::destroy<recording::Recorder>();
|
||||||
DependencyManager::destroy<recording::ClipCache>();
|
DependencyManager::destroy<recording::ClipCache>();
|
||||||
DependencyManager::destroy<ScriptEngine>();
|
|
||||||
|
// drop our shared pointer to the script engine, then ask ScriptEngines to shutdown scripting
|
||||||
|
// this ensures that the ScriptEngine goes down before ScriptEngines
|
||||||
|
_scriptEngine.clear();
|
||||||
|
|
||||||
|
{
|
||||||
|
DependencyManager::get<ScriptEngines>()->shutdownScripting();
|
||||||
|
}
|
||||||
|
|
||||||
|
DependencyManager::destroy<ScriptEngines>();
|
||||||
|
|
||||||
DependencyManager::destroy<AssignmentDynamicFactory>();
|
DependencyManager::destroy<AssignmentDynamicFactory>();
|
||||||
|
|
||||||
DependencyManager::destroy<ScriptableAvatar>();
|
DependencyManager::destroy<ScriptableAvatar>();
|
||||||
|
|
||||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "stop");
|
|
||||||
|
|
||||||
// cleanup codec & encoder
|
// cleanup codec & encoder
|
||||||
if (_codec && _encoder) {
|
if (_codec && _encoder) {
|
||||||
_codec->releaseEncoder(_encoder);
|
_codec->releaseEncoder(_encoder);
|
||||||
|
|
|
@ -654,6 +654,15 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage>
|
||||||
|
|
||||||
if (addToIgnore) {
|
if (addToIgnore) {
|
||||||
senderNode->addIgnoredNode(ignoredUUID);
|
senderNode->addIgnoredNode(ignoredUUID);
|
||||||
|
|
||||||
|
if (ignoredNode) {
|
||||||
|
// send a reliable kill packet to remove the sending avatar for the ignored avatar
|
||||||
|
auto killPacket = NLPacket::create(PacketType::KillAvatar,
|
||||||
|
NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true);
|
||||||
|
killPacket->write(senderNode->getUUID().toRfc4122());
|
||||||
|
killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected);
|
||||||
|
nodeList->sendPacket(std::move(killPacket), *ignoredNode);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
senderNode->removeIgnoredNode(ignoredUUID);
|
senderNode->removeIgnoredNode(ignoredUUID);
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
BIN
interface/resources/avatar/animations/jog_bwd.fbx
Normal file
BIN
interface/resources/avatar/animations/jog_bwd.fbx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
interface/resources/avatar/animations/jump_standing_launch.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_standing_launch.fbx
Normal file
Binary file not shown.
Binary file not shown.
BIN
interface/resources/avatar/animations/run_bwd.fbx
Normal file
BIN
interface/resources/avatar/animations/run_bwd.fbx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -585,149 +585,188 @@
|
||||||
"states": [
|
"states": [
|
||||||
{
|
{
|
||||||
"id": "idle",
|
"id": "idle",
|
||||||
"interpTarget": 0,
|
"interpTarget": 20,
|
||||||
"interpDuration": 4,
|
"interpDuration": 8,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isMovingForward", "state": "idleToWalkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "idleToWalkFwd",
|
"id": "idleToWalkFwd",
|
||||||
"interpTarget": 10,
|
"interpTarget": 12,
|
||||||
"interpDuration": 4,
|
"interpDuration": 8,
|
||||||
"interpType": "snapshotPrev",
|
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "idleToWalkFwdOnDone", "state": "walkFwd" },
|
{ "var": "idleToWalkFwdOnDone", "state": "WALKFWD" },
|
||||||
{ "var": "isNotMoving", "state": "idle" },
|
{ "var": "isNotMoving", "state": "idle" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "idleSettle",
|
"id": "idleSettle",
|
||||||
"interpTarget": 10,
|
"interpTarget": 15,
|
||||||
"interpDuration": 10,
|
"interpDuration": 8,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{"var": "idleSettleOnDone", "state": "idle" },
|
{"var": "idleSettleOnDone", "state": "idle" },
|
||||||
{"var": "isMovingForward", "state": "idleToWalkFwd" },
|
{"var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
{ "var": "isInAirRun", "state": "INAIRRUN" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "walkFwd",
|
"id": "WALKFWD",
|
||||||
"interpTarget": 16,
|
"interpTarget": 35,
|
||||||
"interpDuration": 6,
|
"interpDuration": 10,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idleSettle" },
|
{ "var": "isNotMoving", "state": "idleSettle" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "walkBwd",
|
"id": "WALKBWD",
|
||||||
"interpTarget": 8,
|
"interpTarget": 35,
|
||||||
"interpDuration": 6,
|
"interpDuration": 10,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idleSettle" },
|
{ "var": "isNotMoving", "state": "idleSettle" },
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeRight",
|
"id": "STRAFERIGHT",
|
||||||
"interpTarget": 5,
|
"interpTarget": 25,
|
||||||
"interpDuration": 8,
|
"interpDuration": 8,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idleSettle" },
|
{ "var": "isNotMoving", "state": "idleSettle" },
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeLeft",
|
"id": "STRAFELEFT",
|
||||||
"interpTarget": 5,
|
"interpTarget": 25,
|
||||||
"interpDuration": 8,
|
"interpDuration": 8,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idleSettle" },
|
{ "var": "isNotMoving", "state": "idleSettle" },
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "turnRight",
|
||||||
|
"interpTarget": 6,
|
||||||
|
"interpDuration": 8,
|
||||||
|
"transitions": [
|
||||||
|
{ "var": "isNotTurning", "state": "idle" },
|
||||||
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
|
{ "var": "isFlying", "state": "fly" },
|
||||||
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "turnLeft",
|
||||||
|
"interpTarget": 6,
|
||||||
|
"interpDuration": 8,
|
||||||
|
"transitions": [
|
||||||
|
{ "var": "isNotTurning", "state": "idle" },
|
||||||
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
|
{ "var": "isFlying", "state": "fly" },
|
||||||
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
|
@ -739,18 +778,18 @@
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idleSettle" },
|
{ "var": "isNotMoving", "state": "idleSettle" },
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
{ "var": "isInAirRun", "state": "INAIRRUN" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -760,60 +799,18 @@
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idleSettle" },
|
{ "var": "isNotMoving", "state": "idleSettle" },
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
{ "var": "isInAirRun", "state": "INAIRRUN" }
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "turnRight",
|
|
||||||
"interpTarget": 6,
|
|
||||||
"interpDuration": 8,
|
|
||||||
"interpType": "snapshotPrev",
|
|
||||||
"transitions": [
|
|
||||||
{ "var": "isNotTurning", "state": "idle" },
|
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
|
||||||
{ "var": "isFlying", "state": "fly" },
|
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "turnLeft",
|
|
||||||
"interpTarget": 6,
|
|
||||||
"interpDuration": 8,
|
|
||||||
"interpType": "snapshotPrev",
|
|
||||||
"transitions": [
|
|
||||||
{ "var": "isNotTurning", "state": "idle" },
|
|
||||||
{ "var": "isMovingForward", "state": "walkFwd" },
|
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
|
||||||
{ "var": "isFlying", "state": "fly" },
|
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -826,79 +823,79 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "takeoffStand",
|
"id": "takeoffStand",
|
||||||
"interpTarget": 0,
|
"interpTarget": 2,
|
||||||
"interpDuration": 6,
|
"interpDuration": 2,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotTakeoff", "state": "inAirStand" }
|
{ "var": "isNotTakeoff", "state": "inAirStand" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "takeoffRun",
|
"id": "TAKEOFFRUN",
|
||||||
"interpTarget": 0,
|
"interpTarget": 2,
|
||||||
"interpDuration": 6,
|
"interpDuration": 2,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotTakeoff", "state": "inAirRun" }
|
{ "var": "isNotTakeoff", "state": "INAIRRUN" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAirStand",
|
"id": "inAirStand",
|
||||||
"interpTarget": 0,
|
"interpTarget": 3,
|
||||||
"interpDuration": 6,
|
"interpDuration": 3,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotInAir", "state": "landStandImpact" }
|
{ "var": "isNotInAir", "state": "landStandImpact" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAirRun",
|
"id": "INAIRRUN",
|
||||||
"interpTarget": 0,
|
"interpTarget": 3,
|
||||||
"interpDuration": 6,
|
"interpDuration": 3,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotInAir", "state": "landRun" }
|
{ "var": "isNotInAir", "state": "WALKFWD" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "landStandImpact",
|
"id": "landStandImpact",
|
||||||
"interpTarget": 6,
|
"interpTarget": 1,
|
||||||
"interpDuration": 4,
|
"interpDuration": 1,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "landStandImpactOnDone", "state": "landStand" }
|
{ "var": "landStandImpactOnDone", "state": "landStand" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "landStand",
|
"id": "landStand",
|
||||||
"interpTarget": 0,
|
"interpTarget": 1,
|
||||||
"interpDuration": 1,
|
"interpDuration": 1,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isMovingForward", "state": "idleToWalkFwd" },
|
{ "var": "isMovingForward", "state": "WALKFWD" },
|
||||||
{ "var": "isMovingBackward", "state": "walkBwd" },
|
{ "var": "isMovingBackward", "state": "WALKBWD" },
|
||||||
{ "var": "isMovingRight", "state": "strafeRight" },
|
{ "var": "isMovingRight", "state": "STRAFERIGHT" },
|
||||||
{ "var": "isMovingLeft", "state": "strafeLeft" },
|
{ "var": "isMovingLeft", "state": "STRAFELEFT" },
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
{ "var": "isInAirRun", "state": "inAirRun" },
|
{ "var": "isInAirRun", "state": "INAIRRUN" },
|
||||||
{ "var": "landStandOnDone", "state": "idle" },
|
{ "var": "landStandOnDone", "state": "idle" },
|
||||||
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
|
||||||
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "landRun",
|
"id": "LANDRUN",
|
||||||
"interpTarget": 1,
|
"interpTarget": 2,
|
||||||
"interpDuration": 7,
|
"interpDuration": 2,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
{ "var": "isTakeoffRun", "state": "TAKEOFFRUN" },
|
||||||
{ "var": "landRunOnDone", "state": "walkFwd" }
|
{ "var": "landRunOnDone", "state": "WALKFWD" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -913,7 +910,7 @@
|
||||||
{
|
{
|
||||||
"id": "idleStand",
|
"id": "idleStand",
|
||||||
"interpTarget": 6,
|
"interpTarget": 6,
|
||||||
"interpDuration": 6,
|
"interpDuration": 10,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isTalking", "state": "idleTalk" }
|
{ "var": "isTalking", "state": "idleTalk" }
|
||||||
]
|
]
|
||||||
|
@ -921,7 +918,7 @@
|
||||||
{
|
{
|
||||||
"id": "idleTalk",
|
"id": "idleTalk",
|
||||||
"interpTarget": 6,
|
"interpTarget": 6,
|
||||||
"interpDuration": 6,
|
"interpDuration": 10,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "notIsTalking", "state": "idleStand" }
|
{ "var": "notIsTalking", "state": "idleStand" }
|
||||||
]
|
]
|
||||||
|
@ -956,12 +953,12 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "walkFwd",
|
"id": "WALKFWD",
|
||||||
"type": "blendLinearMove",
|
"type": "blendLinearMove",
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
"desiredSpeed": 1.4,
|
"desiredSpeed": 1.4,
|
||||||
"characteristicSpeeds": [0.5, 1.5, 2.5, 3.2, 4.5],
|
"characteristicSpeeds": [0.5, 1.8, 2.3, 3.2, 4.5],
|
||||||
"alphaVar": "moveForwardAlpha",
|
"alphaVar": "moveForwardAlpha",
|
||||||
"desiredSpeedVar": "moveForwardSpeed"
|
"desiredSpeedVar": "moveForwardSpeed"
|
||||||
},
|
},
|
||||||
|
@ -984,7 +981,7 @@
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/walk_fwd.fbx",
|
"url": "qrc:///avatar/animations/walk_fwd.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 35.0,
|
"endFrame": 30.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": true
|
"loopFlag": true
|
||||||
},
|
},
|
||||||
|
@ -1046,25 +1043,25 @@
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/settle_to_idle.fbx",
|
"url": "qrc:///avatar/animations/settle_to_idle.fbx",
|
||||||
"startFrame": 1.0,
|
"startFrame": 1.0,
|
||||||
"endFrame": 48.0,
|
"endFrame": 59.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "walkBwd",
|
"id": "WALKBWD",
|
||||||
"type": "blendLinearMove",
|
"type": "blendLinearMove",
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
"desiredSpeed": 1.4,
|
"desiredSpeed": 1.4,
|
||||||
"characteristicSpeeds": [0.6, 1.7],
|
"characteristicSpeeds": [0.6, 1.6, 2.3, 3.1],
|
||||||
"alphaVar": "moveBackwardAlpha",
|
"alphaVar": "moveBackwardAlpha",
|
||||||
"desiredSpeedVar": "moveBackwardSpeed"
|
"desiredSpeedVar": "moveBackwardSpeed"
|
||||||
},
|
},
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"id": "walkBwdShort",
|
"id": "walkBwdShort_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/walk_short_bwd.fbx",
|
"url": "qrc:///avatar/animations/walk_short_bwd.fbx",
|
||||||
|
@ -1076,7 +1073,7 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "walkBwdNormal",
|
"id": "walkBwdFast_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/walk_bwd_fast.fbx",
|
"url": "qrc:///avatar/animations/walk_bwd_fast.fbx",
|
||||||
|
@ -1086,6 +1083,30 @@
|
||||||
"loopFlag": true
|
"loopFlag": true
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "jogBwd_c",
|
||||||
|
"type": "clip",
|
||||||
|
"data": {
|
||||||
|
"url": "qrc:///avatar/animations/jog_bwd.fbx",
|
||||||
|
"startFrame": 0.0,
|
||||||
|
"endFrame": 24.0,
|
||||||
|
"timeScale": 1.0,
|
||||||
|
"loopFlag": true
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "runBwd_c",
|
||||||
|
"type": "clip",
|
||||||
|
"data": {
|
||||||
|
"url": "qrc:///avatar/animations/run_bwd.fbx",
|
||||||
|
"startFrame": 0.0,
|
||||||
|
"endFrame": 16.0,
|
||||||
|
"timeScale": 1.0,
|
||||||
|
"loopFlag": true
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -1115,18 +1136,18 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeLeft",
|
"id": "STRAFELEFT",
|
||||||
"type": "blendLinearMove",
|
"type": "blendLinearMove",
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
"desiredSpeed": 1.4,
|
"desiredSpeed": 1.4,
|
||||||
"characteristicSpeeds": [0, 0.5, 1.5, 2.6, 3.0],
|
"characteristicSpeeds": [0.1, 0.5, 1.0, 2.6, 3.0],
|
||||||
"alphaVar": "moveLateralAlpha",
|
"alphaVar": "moveLateralAlpha",
|
||||||
"desiredSpeedVar": "moveLateralSpeed"
|
"desiredSpeedVar": "moveLateralSpeed"
|
||||||
},
|
},
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"id": "strafeLeftShort_c",
|
"id": "strafeLeftShortStep_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
|
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
|
||||||
|
@ -1138,7 +1159,7 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeLeft_c",
|
"id": "strafeLeftStep_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/side_step_left.fbx",
|
"url": "qrc:///avatar/animations/side_step_left.fbx",
|
||||||
|
@ -1150,19 +1171,19 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeLeftAnim_c",
|
"id": "strafeLeftWalk_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/walk_left.fbx",
|
"url": "qrc:///avatar/animations/walk_left.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 33.0,
|
"endFrame": 35.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": true
|
"loopFlag": true
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeLeftFast_c",
|
"id": "strafeLeftWalkFast_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/walk_left_fast.fbx",
|
"url": "qrc:///avatar/animations/walk_left_fast.fbx",
|
||||||
|
@ -1188,17 +1209,17 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeRight",
|
"id": "STRAFERIGHT",
|
||||||
"type": "blendLinearMove",
|
"type": "blendLinearMove",
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
"desiredSpeed": 1.4,
|
"desiredSpeed": 1.4,
|
||||||
"characteristicSpeeds": [0, 0.5, 1.5, 2.6, 3.0],
|
"characteristicSpeeds": [0.1, 0.5, 1.0, 2.6, 3.0],
|
||||||
"alphaVar": "moveLateralAlpha",
|
"alphaVar": "moveLateralAlpha",
|
||||||
"desiredSpeedVar": "moveLateralSpeed"
|
"desiredSpeedVar": "moveLateralSpeed"
|
||||||
},
|
},
|
||||||
"children": [ {
|
"children": [ {
|
||||||
"id": "stepRightShort_c",
|
"id": "strafeRightShortStep_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
|
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
|
||||||
|
@ -1211,7 +1232,7 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "stepRight_c",
|
"id": "strafeRightStep_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/side_step_left.fbx",
|
"url": "qrc:///avatar/animations/side_step_left.fbx",
|
||||||
|
@ -1224,12 +1245,12 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "strafeRight_c",
|
"id": "strafeRightWalk_c",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/walk_left.fbx",
|
"url": "qrc:///avatar/animations/walk_left.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 33.0,
|
"endFrame": 35.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": true,
|
"loopFlag": true,
|
||||||
"mirrorFlag": true
|
"mirrorFlag": true
|
||||||
|
@ -1381,22 +1402,22 @@
|
||||||
"id": "takeoffStand",
|
"id": "takeoffStand",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_standing_takeoff.fbx",
|
"url": "qrc:///avatar/animations/jump_standing_launch.fbx",
|
||||||
"startFrame": 17.0,
|
"startFrame": 2.0,
|
||||||
"endFrame": 25.0,
|
"endFrame": 16.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "takeoffRun",
|
"id": "TAKEOFFRUN",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_takeoff.fbx",
|
"url": "qrc:///avatar/animations/jump_running_launch_land.fbx",
|
||||||
"startFrame": 1.0,
|
"startFrame": 4.0,
|
||||||
"endFrame": 2.5,
|
"endFrame": 15.0,
|
||||||
"timeScale": 0.01,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
|
@ -1416,7 +1437,7 @@
|
||||||
"url": "qrc:///avatar/animations/jump_standing_apex.fbx",
|
"url": "qrc:///avatar/animations/jump_standing_apex.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 0.0,
|
"endFrame": 0.0,
|
||||||
"timeScale": 0.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
|
@ -1448,7 +1469,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAirRun",
|
"id": "INAIRRUN",
|
||||||
"type": "blendLinear",
|
"type": "blendLinear",
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
|
@ -1459,10 +1480,10 @@
|
||||||
"id": "inAirRunPreApex",
|
"id": "inAirRunPreApex",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_in_air.fbx",
|
"url": "qrc:///avatar/animations/jump_running_launch_land.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 16.0,
|
||||||
"endFrame": 0.0,
|
"endFrame": 16.0,
|
||||||
"timeScale": 0.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
|
@ -1471,9 +1492,9 @@
|
||||||
"id": "inAirRunApex",
|
"id": "inAirRunApex",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_in_air.fbx",
|
"url": "qrc:///avatar/animations/jump_running_launch_land.fbx",
|
||||||
"startFrame": 6.0,
|
"startFrame": 22.0,
|
||||||
"endFrame": 6.0,
|
"endFrame": 22.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
|
@ -1483,9 +1504,9 @@
|
||||||
"id": "inAirRunPostApex",
|
"id": "inAirRunPostApex",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_in_air.fbx",
|
"url": "qrc:///avatar/animations/jump_running_launch_land.fbx",
|
||||||
"startFrame": 11.0,
|
"startFrame": 33.0,
|
||||||
"endFrame": 11.0,
|
"endFrame": 33.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
|
@ -1497,7 +1518,7 @@
|
||||||
"id": "landStandImpact",
|
"id": "landStandImpact",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_standing_land.fbx",
|
"url": "qrc:///avatar/animations/jump_standing_land_settle.fbx",
|
||||||
"startFrame": 1.0,
|
"startFrame": 1.0,
|
||||||
"endFrame": 6.0,
|
"endFrame": 6.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
|
@ -1509,22 +1530,22 @@
|
||||||
"id": "landStand",
|
"id": "landStand",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_standing_land.fbx",
|
"url": "qrc:///avatar/animations/jump_standing_land_settle.fbx",
|
||||||
"startFrame": 6.0,
|
"startFrame": 6.0,
|
||||||
"endFrame": 28.0,
|
"endFrame": 68.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "landRun",
|
"id": "LANDRUN",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "qrc:///avatar/animations/jump_land.fbx",
|
"url": "qrc:///avatar/animations/jump_running_launch_land.fbx",
|
||||||
"startFrame": 1.0,
|
"startFrame": 29.0,
|
||||||
"endFrame": 6.0,
|
"endFrame": 40.0,
|
||||||
"timeScale": 0.65,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
|
|
157
interface/resources/qml/AnimStats.qml
Normal file
157
interface/resources/qml/AnimStats.qml
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
import Hifi 1.0 as Hifi
|
||||||
|
import QtQuick 2.3
|
||||||
|
import '.'
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: animStats
|
||||||
|
|
||||||
|
anchors.leftMargin: 300
|
||||||
|
objectName: "StatsItem"
|
||||||
|
property int modality: Qt.NonModal
|
||||||
|
implicitHeight: row.height
|
||||||
|
implicitWidth: row.width
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
animStats.parentChanged.connect(fill);
|
||||||
|
fill();
|
||||||
|
}
|
||||||
|
Component.onDestruction: {
|
||||||
|
animStats.parentChanged.disconnect(fill);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fill() {
|
||||||
|
// This will cause a warning at shutdown, need to find another way to remove
|
||||||
|
// the warning other than filling the anchors to the parent
|
||||||
|
anchors.horizontalCenter = parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Hifi.AnimStats {
|
||||||
|
id: root
|
||||||
|
objectName: "AnimStats"
|
||||||
|
implicitHeight: row.height
|
||||||
|
implicitWidth: row.width
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
readonly property string bgColor: "#AA111111"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: row
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: firstCol.width + 8;
|
||||||
|
height: firstCol.height + 8;
|
||||||
|
color: root.bgColor;
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: firstCol
|
||||||
|
spacing: 4; x: 4; y: 4;
|
||||||
|
|
||||||
|
StatText {
|
||||||
|
text: "State Machines:---------------------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
ListView {
|
||||||
|
width: firstCol.width
|
||||||
|
height: root.animStateMachines.length * 15
|
||||||
|
visible: root.animStateMchines.length > 0;
|
||||||
|
model: root.animStateMachines
|
||||||
|
delegate: StatText {
|
||||||
|
text: {
|
||||||
|
return modelData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: secondCol.width + 8
|
||||||
|
height: secondCol.height + 8
|
||||||
|
color: root.bgColor;
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: secondCol
|
||||||
|
spacing: 4; x: 4; y: 4;
|
||||||
|
|
||||||
|
StatText {
|
||||||
|
text: "Anim Vars:--------------------------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
width: secondCol.width
|
||||||
|
height: root.animVars.length * 15
|
||||||
|
visible: root.animVars.length > 0;
|
||||||
|
model: root.animVars
|
||||||
|
delegate: StatText {
|
||||||
|
text: {
|
||||||
|
var actualText = modelData.split("|")[1];
|
||||||
|
if (actualText) {
|
||||||
|
return actualText;
|
||||||
|
} else {
|
||||||
|
return modelData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color: {
|
||||||
|
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||||
|
return Qt.rgba(1.0, 1.0, 1.0, grayScale);
|
||||||
|
}
|
||||||
|
styleColor: {
|
||||||
|
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||||
|
return Qt.rgba(0.0, 0.0, 0.0, grayScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: thirdCol.width + 8
|
||||||
|
height: thirdCol.height + 8
|
||||||
|
color: root.bgColor;
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: thirdCol
|
||||||
|
spacing: 4; x: 4; y: 4;
|
||||||
|
|
||||||
|
StatText {
|
||||||
|
text: "Alpha Values:--------------------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
width: thirdCol.width
|
||||||
|
height: root.animAlphaValues.length * 15
|
||||||
|
visible: root.animAlphaValues.length > 0;
|
||||||
|
model: root.animAlphaValues
|
||||||
|
delegate: StatText {
|
||||||
|
text: {
|
||||||
|
var actualText = modelData.split("|")[1];
|
||||||
|
if (actualText) {
|
||||||
|
return actualText;
|
||||||
|
} else {
|
||||||
|
return modelData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color: {
|
||||||
|
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||||
|
return Qt.rgba(1.0, 1.0, 1.0, grayScale);
|
||||||
|
}
|
||||||
|
styleColor: {
|
||||||
|
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||||
|
return Qt.rgba(0.0, 0.0, 0.0, grayScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.parent
|
||||||
|
onWidthChanged: {
|
||||||
|
root.x = root.parent.width - root.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -192,21 +192,6 @@ Item {
|
||||||
StatText {
|
StatText {
|
||||||
text: "Yaw: " + root.yaw.toFixed(1)
|
text: "Yaw: " + root.yaw.toFixed(1)
|
||||||
}
|
}
|
||||||
StatText {
|
|
||||||
visible: root.animStackNames.length > 0;
|
|
||||||
text: "Anim Stack Names:"
|
|
||||||
}
|
|
||||||
ListView {
|
|
||||||
width: geoCol.width
|
|
||||||
height: root.animStackNames.length * 15
|
|
||||||
visible: root.animStackNames.length > 0;
|
|
||||||
model: root.animStackNames
|
|
||||||
delegate: StatText {
|
|
||||||
text: modelData.length > 30
|
|
||||||
? modelData.substring(0, 5) + "..." + modelData.substring(modelData.length - 22)
|
|
||||||
: modelData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StatText {
|
StatText {
|
||||||
visible: root.expanded;
|
visible: root.expanded;
|
||||||
text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " +
|
text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " +
|
||||||
|
|
|
@ -26,7 +26,7 @@ Rectangle {
|
||||||
HifiConstants { id: hifi; }
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
property var eventBridge;
|
property var eventBridge;
|
||||||
property string title: "Audio Settings - " + AudioScriptingInterface.context;
|
property string title: "Audio Settings"
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
|
|
||||||
color: hifi.colors.baseGray;
|
color: hifi.colors.baseGray;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import "../../windows"
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
objectName: "DCConectionTiming"
|
objectName: "DCConectionTiming"
|
||||||
|
property string title: "Domain Connection Timing"
|
||||||
|
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
property bool isHMD: false
|
property bool isHMD: false
|
||||||
|
@ -33,7 +34,7 @@ Rectangle {
|
||||||
Row {
|
Row {
|
||||||
id: header
|
id: header
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: hifi.dimensions.tabletMenuHeader
|
anchors.topMargin: hifi.dimensions.contentMargin.y
|
||||||
anchors.leftMargin: 5
|
anchors.leftMargin: 5
|
||||||
anchors.rightMargin: 5
|
anchors.rightMargin: 5
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
|
@ -18,6 +18,7 @@ import "../../windows"
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
objectName: "EntityStatistics"
|
objectName: "EntityStatistics"
|
||||||
|
property string title: "Entity Statistics"
|
||||||
|
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
property bool isHMD: false
|
property bool isHMD: false
|
||||||
|
@ -40,6 +41,7 @@ Rectangle {
|
||||||
id: scrollView
|
id: scrollView
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: hifi.dimensions.contentMargin.y
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: hifi.dimensions.tabletMenuHeader
|
anchors.bottomMargin: hifi.dimensions.tabletMenuHeader
|
||||||
contentWidth: column.implicitWidth
|
contentWidth: column.implicitWidth
|
||||||
|
@ -48,10 +50,15 @@ Rectangle {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
anchors.margins: 10
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
y: hifi.dimensions.tabletMenuHeader //-bgNavBar
|
anchors {
|
||||||
|
topMargin: 0
|
||||||
|
leftMargin: 10
|
||||||
|
rightMargin: 10
|
||||||
|
bottomMargin: 0
|
||||||
|
}
|
||||||
spacing: 20
|
spacing: 20
|
||||||
|
|
||||||
TabletEntityStatisticsItem {
|
TabletEntityStatisticsItem {
|
||||||
|
|
|
@ -24,6 +24,8 @@ Item {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
property string title: "Controls"
|
||||||
|
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
|
||||||
TabBar {
|
TabBar {
|
||||||
|
|
|
@ -105,7 +105,6 @@ StackView {
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
onPressed: {
|
onPressed: {
|
||||||
parent.forceActiveFocus();
|
parent.forceActiveFocus();
|
||||||
addressBarDialog.keyboardEnabled = false;
|
|
||||||
mouse.accepted = false;
|
mouse.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +222,6 @@ StackView {
|
||||||
updateLocationText(text.length > 0);
|
updateLocationText(text.length > 0);
|
||||||
}
|
}
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
addressBarDialog.keyboardEnabled = false;
|
|
||||||
toggleOrGo();
|
toggleOrGo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +376,7 @@ StackView {
|
||||||
|
|
||||||
HifiControls.Keyboard {
|
HifiControls.Keyboard {
|
||||||
id: keyboard
|
id: keyboard
|
||||||
raised: parent.keyboardEnabled
|
raised: parent.keyboardEnabled && parent.keyboardRaised
|
||||||
numeric: parent.punctuationMode
|
numeric: parent.punctuationMode
|
||||||
anchors {
|
anchors {
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
|
|
|
@ -23,6 +23,8 @@ FocusScope {
|
||||||
property string subMenu: ""
|
property string subMenu: ""
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
|
|
||||||
|
HifiConstants { id: hifi }
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: bgNavBar
|
id: bgNavBar
|
||||||
height: 90
|
height: 90
|
||||||
|
@ -45,24 +47,22 @@ FocusScope {
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
||||||
Image {
|
HiFiGlyphs {
|
||||||
id: menuRootIcon
|
id: menuRootIcon
|
||||||
width: 40
|
text: breadcrumbText.text !== "Menu" ? hifi.glyphs.backward : ""
|
||||||
height: 40
|
size: 72
|
||||||
source: "../../../icons/tablet-icons/menu-i.svg"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 15
|
width: breadcrumbText.text === "Menu" ? 32 : 50
|
||||||
|
visible: breadcrumbText.text !== "Menu"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onEntered: iconColorOverlay.color = "#1fc6a6";
|
onEntered: iconColorOverlay.color = "#1fc6a6";
|
||||||
onExited: iconColorOverlay.color = "#34a2c7";
|
onExited: iconColorOverlay.color = "#34a2c7";
|
||||||
// navigate back to root level menu
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
buildMenu();
|
menuPopperUpper.closeLastMenu();
|
||||||
breadcrumbText.text = "Menu";
|
|
||||||
tabletRoot.playButtonClickSound();
|
tabletRoot.playButtonClickSound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,23 +79,10 @@ FocusScope {
|
||||||
id: breadcrumbText
|
id: breadcrumbText
|
||||||
text: "Menu"
|
text: "Menu"
|
||||||
size: 26
|
size: 26
|
||||||
color: "#34a2c7"
|
color: "#e3e3e3"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: menuRootIcon.right
|
anchors.left: menuRootIcon.right
|
||||||
anchors.leftMargin: 15
|
anchors.leftMargin: 15
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onEntered: breadcrumbText.color = "#1fc6a6";
|
|
||||||
onExited: breadcrumbText.color = "#34a2c7";
|
|
||||||
// navigate back to parent level menu if there is one
|
|
||||||
onClicked: {
|
|
||||||
if (breadcrumbText.text !== "Menu") {
|
|
||||||
menuPopperUpper.closeLastMenu();
|
|
||||||
}
|
|
||||||
tabletRoot.playButtonClickSound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +90,6 @@ FocusScope {
|
||||||
menuPopperUpper.closeLastMenu();
|
menuPopperUpper.closeLastMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function setRootMenu(rootMenu, subMenu) {
|
function setRootMenu(rootMenu, subMenu) {
|
||||||
tabletMenu.subMenu = subMenu;
|
tabletMenu.subMenu = subMenu;
|
||||||
tabletMenu.rootMenu = rootMenu;
|
tabletMenu.rootMenu = rootMenu;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// MessageDialog.qml
|
// TabletMenuStack.qml
|
||||||
//
|
//
|
||||||
// Created by Dante Ruiz on 13 Feb 2017
|
// Created by Dante Ruiz on 13 Feb 2017
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
@ -66,7 +66,7 @@ Item {
|
||||||
|
|
||||||
function popSource() {
|
function popSource() {
|
||||||
console.log("trying to pop page");
|
console.log("trying to pop page");
|
||||||
d.pop();
|
closeLastMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toModel(items, newMenu) {
|
function toModel(items, newMenu) {
|
||||||
|
|
|
@ -41,7 +41,11 @@ Item {
|
||||||
section.saveAll();
|
section.saveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeDialog();
|
if (HMD.active) {
|
||||||
|
tablet.popFromStack();
|
||||||
|
} else {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreAll() {
|
function restoreAll() {
|
||||||
|
@ -50,7 +54,11 @@ Item {
|
||||||
section.restoreAll();
|
section.restoreAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeDialog();
|
if (HMD.active) {
|
||||||
|
tablet.popFromStack();
|
||||||
|
} else {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDialog() {
|
function closeDialog() {
|
||||||
|
|
|
@ -195,6 +195,7 @@
|
||||||
#include "ui/SnapshotAnimated.h"
|
#include "ui/SnapshotAnimated.h"
|
||||||
#include "ui/StandAloneJSConsole.h"
|
#include "ui/StandAloneJSConsole.h"
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
|
#include "ui/AnimStats.h"
|
||||||
#include "ui/UpdateDialog.h"
|
#include "ui/UpdateDialog.h"
|
||||||
#include "ui/overlays/Overlays.h"
|
#include "ui/overlays/Overlays.h"
|
||||||
#include "ui/DomainConnectionModel.h"
|
#include "ui/DomainConnectionModel.h"
|
||||||
|
@ -3081,8 +3082,10 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
||||||
|
|
||||||
void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
|
void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
|
||||||
Stats::show();
|
Stats::show();
|
||||||
|
AnimStats::show();
|
||||||
auto surfaceContext = DependencyManager::get<OffscreenUi>()->getSurfaceContext();
|
auto surfaceContext = DependencyManager::get<OffscreenUi>()->getSurfaceContext();
|
||||||
surfaceContext->setContextProperty("Stats", Stats::getInstance());
|
surfaceContext->setContextProperty("Stats", Stats::getInstance());
|
||||||
|
surfaceContext->setContextProperty("AnimStats", AnimStats::getInstance());
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
@ -4618,6 +4621,7 @@ void Application::idle() {
|
||||||
checkChangeCursor();
|
checkChangeCursor();
|
||||||
|
|
||||||
Stats::getInstance()->updateStats();
|
Stats::getInstance()->updateStats();
|
||||||
|
AnimStats::getInstance()->updateStats();
|
||||||
|
|
||||||
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||||
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
||||||
|
@ -5855,9 +5859,7 @@ void Application::update(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
|
||||||
updateLOD(deltaTime);
|
updateLOD(deltaTime);
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: break these out into distinct perfTimers when they prove interesting
|
// TODO: break these out into distinct perfTimers when they prove interesting
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,8 +19,11 @@
|
||||||
#include <SimpleMovingAverage.h>
|
#include <SimpleMovingAverage.h>
|
||||||
#include <render/Args.h>
|
#include <render/Args.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
const float LOD_DEFAULT_QUALITY_LEVEL = 0.75f; // default quality level setting is High (lower framerate)
|
||||||
|
#else
|
||||||
const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid
|
const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid
|
||||||
|
#endif
|
||||||
const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps
|
const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps
|
||||||
const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps
|
const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps
|
||||||
const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate
|
const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate
|
||||||
|
|
|
@ -255,7 +255,7 @@ Menu::Menu() {
|
||||||
connect(action, &QAction::triggered, [] {
|
connect(action, &QAction::triggered, [] {
|
||||||
auto tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
|
auto tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
|
||||||
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
||||||
tablet->loadQMLSource("hifi/tablet/ControllerSettings.qml");
|
tablet->pushOntoStack("hifi/tablet/ControllerSettings.qml");
|
||||||
|
|
||||||
if (!hmd->getShouldShowTablet()) {
|
if (!hmd->getShouldShowTablet()) {
|
||||||
hmd->toggleShouldShowTablet();
|
hmd->toggleShouldShowTablet();
|
||||||
|
@ -737,6 +737,7 @@ Menu::Menu() {
|
||||||
|
|
||||||
// Developer > Stats
|
// Developer > Stats
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats);
|
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats);
|
||||||
|
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AnimStats);
|
||||||
|
|
||||||
// Settings > Enable Speech Control API
|
// Settings > Enable Speech Control API
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||||
|
|
|
@ -197,6 +197,7 @@ namespace MenuOption {
|
||||||
const QString SMIEyeTracking = "SMI Eye Tracking";
|
const QString SMIEyeTracking = "SMI Eye Tracking";
|
||||||
const QString SparseTextureManagement = "Enable Sparse Texture Management";
|
const QString SparseTextureManagement = "Enable Sparse Texture Management";
|
||||||
const QString Stats = "Show Statistics";
|
const QString Stats = "Show Statistics";
|
||||||
|
const QString AnimStats = "Show Animation Stats";
|
||||||
const QString StopAllScripts = "Stop All Scripts";
|
const QString StopAllScripts = "Stop All Scripts";
|
||||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||||
const QString ThirdPerson = "Third Person";
|
const QString ThirdPerson = "Third Person";
|
||||||
|
|
|
@ -516,6 +516,10 @@ void MyAvatar::update(float deltaTime) {
|
||||||
head->relax(deltaTime);
|
head->relax(deltaTime);
|
||||||
updateFromTrackers(deltaTime);
|
updateFromTrackers(deltaTime);
|
||||||
|
|
||||||
|
if (getIsInWalkingState() && glm::length(getControllerPoseInAvatarFrame(controller::Action::HEAD).getVelocity()) < DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) {
|
||||||
|
setIsInWalkingState(false);
|
||||||
|
}
|
||||||
|
|
||||||
// Get audio loudness data from audio input device
|
// Get audio loudness data from audio input device
|
||||||
// Also get the AudioClient so we can update the avatar bounding box data
|
// Also get the AudioClient so we can update the avatar bounding box data
|
||||||
// on the AudioClient side.
|
// on the AudioClient side.
|
||||||
|
@ -3678,10 +3682,10 @@ static bool headAngularVelocityBelowThreshold(const controller::Pose& head) {
|
||||||
return isBelowThreshold;
|
return isBelowThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isWithinThresholdHeightMode(const controller::Pose& head,const float& newMode) {
|
static bool isWithinThresholdHeightMode(const controller::Pose& head, const float& newMode, const float& scale) {
|
||||||
bool isWithinThreshold = true;
|
bool isWithinThreshold = true;
|
||||||
if (head.isValid()) {
|
if (head.isValid()) {
|
||||||
isWithinThreshold = (head.getTranslation().y - newMode) > DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD;
|
isWithinThreshold = (head.getTranslation().y - newMode) > (DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD * scale);
|
||||||
}
|
}
|
||||||
return isWithinThreshold;
|
return isWithinThreshold;
|
||||||
}
|
}
|
||||||
|
@ -3802,6 +3806,10 @@ float MyAvatar::getUserEyeHeight() const {
|
||||||
return userHeight - userHeight * ratio;
|
return userHeight - userHeight * ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MyAvatar::getIsInWalkingState() const {
|
||||||
|
return _isInWalkingState;
|
||||||
|
}
|
||||||
|
|
||||||
float MyAvatar::getWalkSpeed() const {
|
float MyAvatar::getWalkSpeed() const {
|
||||||
return _walkSpeed.get() * _walkSpeedScalar;
|
return _walkSpeed.get() * _walkSpeedScalar;
|
||||||
}
|
}
|
||||||
|
@ -3818,6 +3826,10 @@ void MyAvatar::setSprintMode(bool sprint) {
|
||||||
_walkSpeedScalar = sprint ? _sprintSpeed.get() : AVATAR_WALK_SPEED_SCALAR;
|
_walkSpeedScalar = sprint ? _sprintSpeed.get() : AVATAR_WALK_SPEED_SCALAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::setIsInWalkingState(bool isWalking) {
|
||||||
|
_isInWalkingState = isWalking;
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::setWalkSpeed(float value) {
|
void MyAvatar::setWalkSpeed(float value) {
|
||||||
_walkSpeed.set(value);
|
_walkSpeed.set(value);
|
||||||
}
|
}
|
||||||
|
@ -3912,7 +3924,6 @@ void MyAvatar::lateUpdatePalms() {
|
||||||
Avatar::updatePalms();
|
Avatar::updatePalms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const float FOLLOW_TIME = 0.5f;
|
static const float FOLLOW_TIME = 0.5f;
|
||||||
|
|
||||||
MyAvatar::FollowHelper::FollowHelper() {
|
MyAvatar::FollowHelper::FollowHelper() {
|
||||||
|
@ -4004,24 +4015,36 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons
|
||||||
controller::Pose currentRightHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND);
|
controller::Pose currentRightHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND);
|
||||||
|
|
||||||
bool stepDetected = false;
|
bool stepDetected = false;
|
||||||
if (!withinBaseOfSupport(currentHeadPose) &&
|
float myScale = myAvatar.getAvatarScale();
|
||||||
|
|
||||||
|
if (myAvatar.getIsInWalkingState()) {
|
||||||
|
stepDetected = true;
|
||||||
|
} else {
|
||||||
|
if (!withinBaseOfSupport(currentHeadPose) &&
|
||||||
headAngularVelocityBelowThreshold(currentHeadPose) &&
|
headAngularVelocityBelowThreshold(currentHeadPose) &&
|
||||||
isWithinThresholdHeightMode(currentHeadPose, myAvatar.getCurrentStandingHeight()) &&
|
isWithinThresholdHeightMode(currentHeadPose, myAvatar.getCurrentStandingHeight(), myScale) &&
|
||||||
handDirectionMatchesHeadDirection(currentLeftHandPose, currentRightHandPose, currentHeadPose) &&
|
handDirectionMatchesHeadDirection(currentLeftHandPose, currentRightHandPose, currentHeadPose) &&
|
||||||
handAngularVelocityBelowThreshold(currentLeftHandPose, currentRightHandPose) &&
|
handAngularVelocityBelowThreshold(currentLeftHandPose, currentRightHandPose) &&
|
||||||
headVelocityGreaterThanThreshold(currentHeadPose) &&
|
headVelocityGreaterThanThreshold(currentHeadPose) &&
|
||||||
isHeadLevel(currentHeadPose, myAvatar.getAverageHeadRotation())) {
|
isHeadLevel(currentHeadPose, myAvatar.getAverageHeadRotation())) {
|
||||||
// a step is detected
|
// a step is detected
|
||||||
stepDetected = true;
|
|
||||||
} else {
|
|
||||||
glm::vec3 defaultHipsPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Hips"));
|
|
||||||
glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head"));
|
|
||||||
glm::vec3 currentHeadPosition = currentHeadPose.getTranslation();
|
|
||||||
float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition);
|
|
||||||
if (!isActive(Horizontal) &&
|
|
||||||
(glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) {
|
|
||||||
myAvatar.setResetMode(true);
|
|
||||||
stepDetected = true;
|
stepDetected = true;
|
||||||
|
if (glm::length(currentHeadPose.velocity) > DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) {
|
||||||
|
myAvatar.setIsInWalkingState(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glm::vec3 defaultHipsPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Hips"));
|
||||||
|
glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head"));
|
||||||
|
glm::vec3 currentHeadPosition = currentHeadPose.getTranslation();
|
||||||
|
float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition);
|
||||||
|
if (!isActive(Horizontal) &&
|
||||||
|
(glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) {
|
||||||
|
myAvatar.setResetMode(true);
|
||||||
|
stepDetected = true;
|
||||||
|
if (glm::length(currentHeadPose.velocity) > DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) {
|
||||||
|
myAvatar.setIsInWalkingState(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stepDetected;
|
return stepDetected;
|
||||||
|
|
|
@ -1086,6 +1086,8 @@ public:
|
||||||
|
|
||||||
const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
|
const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
|
||||||
|
|
||||||
|
void setIsInWalkingState(bool isWalking);
|
||||||
|
bool getIsInWalkingState() const;
|
||||||
void setWalkSpeed(float value);
|
void setWalkSpeed(float value);
|
||||||
float getWalkSpeed() const;
|
float getWalkSpeed() const;
|
||||||
void setWalkBackwardSpeed(float value);
|
void setWalkBackwardSpeed(float value);
|
||||||
|
@ -1788,6 +1790,7 @@ private:
|
||||||
ThreadSafeValueCache<float> _walkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED };
|
ThreadSafeValueCache<float> _walkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED };
|
||||||
ThreadSafeValueCache<float> _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR };
|
ThreadSafeValueCache<float> _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR };
|
||||||
float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR };
|
float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR };
|
||||||
|
bool _isInWalkingState { false };
|
||||||
|
|
||||||
// load avatar scripts once when rig is ready
|
// load avatar scripts once when rig is ready
|
||||||
bool _shouldLoadScripts { false };
|
bool _shouldLoadScripts { false };
|
||||||
|
|
|
@ -16,8 +16,9 @@ Transform MyAvatarHeadTransformNode::getTransform() {
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
|
||||||
glm::vec3 pos = myAvatar->getHeadPosition();
|
glm::vec3 pos = myAvatar->getHeadPosition();
|
||||||
|
glm::vec3 scale = glm::vec3(myAvatar->scaleForChildren());
|
||||||
glm::quat headOri = myAvatar->getHeadOrientation();
|
glm::quat headOri = myAvatar->getHeadOrientation();
|
||||||
glm::quat ori = headOri * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT);
|
glm::quat ori = headOri * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT);
|
||||||
|
|
||||||
return Transform(ori, glm::vec3(1.0f), pos);
|
return Transform(ori, scale, pos);
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 hipsMat;
|
glm::mat4 hipsMat;
|
||||||
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying) {
|
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState())) {
|
||||||
// then we use center of gravity model
|
// then we use center of gravity model
|
||||||
hipsMat = myAvatar->deriveBodyUsingCgModel();
|
hipsMat = myAvatar->deriveBodyUsingCgModel();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -75,7 +75,6 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
|
||||||
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
||||||
// Only track entities with downloaded collision bodies.
|
// Only track entities with downloaded collision bodies.
|
||||||
_trackedEntities.emplace(entityID, entity);
|
_trackedEntities.emplace(entityID, entity);
|
||||||
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +109,6 @@ bool SafeLanding::isLoadSequenceComplete() {
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
_initialEnd = INVALID_SEQUENCE;
|
||||||
_entityTree = nullptr;
|
_entityTree = nullptr;
|
||||||
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
|
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
|
||||||
qCDebug(interfaceapp) << "Safe Landing: load sequence complete";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !_trackingEntities;
|
return !_trackingEntities;
|
||||||
|
|
|
@ -86,23 +86,23 @@ bool CollisionPick::isLoaded() const {
|
||||||
return !_mathPick.shouldComputeShapeInfo() || (_cachedResource && _cachedResource->isLoaded());
|
return !_mathPick.shouldComputeShapeInfo() || (_cachedResource && _cachedResource->isLoaded());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CollisionPick::getShapeInfoReady() {
|
bool CollisionPick::getShapeInfoReady(const CollisionRegion& pick) {
|
||||||
if (_mathPick.shouldComputeShapeInfo()) {
|
if (_mathPick.shouldComputeShapeInfo()) {
|
||||||
if (_cachedResource && _cachedResource->isLoaded()) {
|
if (_cachedResource && _cachedResource->isLoaded()) {
|
||||||
computeShapeInfo(_mathPick, *_mathPick.shapeInfo, _cachedResource);
|
computeShapeInfo(pick, *_mathPick.shapeInfo, _cachedResource);
|
||||||
_mathPick.loaded = true;
|
_mathPick.loaded = true;
|
||||||
} else {
|
} else {
|
||||||
_mathPick.loaded = false;
|
_mathPick.loaded = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
computeShapeInfoDimensionsOnly(_mathPick, *_mathPick.shapeInfo, _cachedResource);
|
computeShapeInfoDimensionsOnly(pick, *_mathPick.shapeInfo, _cachedResource);
|
||||||
_mathPick.loaded = true;
|
_mathPick.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _mathPick.loaded;
|
return _mathPick.loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionPick::computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
void CollisionPick::computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
||||||
ShapeType type = shapeInfo.getType();
|
ShapeType type = shapeInfo.getType();
|
||||||
glm::vec3 dimensions = pick.transform.getScale();
|
glm::vec3 dimensions = pick.transform.getScale();
|
||||||
QString modelURL = (resource ? resource->getURL().toString() : "");
|
QString modelURL = (resource ? resource->getURL().toString() : "");
|
||||||
|
@ -115,7 +115,7 @@ void CollisionPick::computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionPick::computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource) {
|
||||||
// This code was copied and modified from RenderableModelEntityItem::computeShapeInfo
|
// This code was copied and modified from RenderableModelEntityItem::computeShapeInfo
|
||||||
// TODO: Move to some shared code area (in entities-renderer? model-networking?)
|
// TODO: Move to some shared code area (in entities-renderer? model-networking?)
|
||||||
// after we verify this is working and do a diff comparison with RenderableModelEntityItem::computeShapeInfo
|
// after we verify this is working and do a diff comparison with RenderableModelEntityItem::computeShapeInfo
|
||||||
|
@ -357,12 +357,14 @@ CollisionPick::CollisionPick(const PickFilter& filter, float maxDistance, bool e
|
||||||
CollisionRegion CollisionPick::getMathematicalPick() const {
|
CollisionRegion CollisionPick::getMathematicalPick() const {
|
||||||
CollisionRegion mathPick = _mathPick;
|
CollisionRegion mathPick = _mathPick;
|
||||||
mathPick.loaded = isLoaded();
|
mathPick.loaded = isLoaded();
|
||||||
if (!parentTransform) {
|
if (parentTransform) {
|
||||||
return mathPick;
|
Transform parentTransformValue = parentTransform->getTransform();
|
||||||
} else {
|
mathPick.transform = parentTransformValue.worldTransform(mathPick.transform);
|
||||||
mathPick.transform = parentTransform->getTransform().worldTransform(mathPick.transform);
|
glm::vec3 scale = parentTransformValue.getScale();
|
||||||
return mathPick;
|
float largestDimension = glm::max(glm::max(scale.x, scale.y), scale.z);
|
||||||
|
mathPick.threshold *= largestDimension;
|
||||||
}
|
}
|
||||||
|
return mathPick;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionPick::filterIntersections(std::vector<ContactTestResult>& intersections) const {
|
void CollisionPick::filterIntersections(std::vector<ContactTestResult>& intersections) const {
|
||||||
|
@ -393,9 +395,9 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi
|
||||||
// Cannot compute result
|
// Cannot compute result
|
||||||
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
||||||
}
|
}
|
||||||
getShapeInfoReady();
|
getShapeInfoReady(pick);
|
||||||
|
|
||||||
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *_mathPick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||||
filterIntersections(entityIntersections);
|
filterIntersections(entityIntersections);
|
||||||
return std::make_shared<CollisionPickResult>(pick, entityIntersections, std::vector<ContactTestResult>());
|
return std::make_shared<CollisionPickResult>(pick, entityIntersections, std::vector<ContactTestResult>());
|
||||||
}
|
}
|
||||||
|
@ -409,9 +411,9 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi
|
||||||
// Cannot compute result
|
// Cannot compute result
|
||||||
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
||||||
}
|
}
|
||||||
getShapeInfoReady();
|
getShapeInfoReady(pick);
|
||||||
|
|
||||||
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *_mathPick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||||
filterIntersections(avatarIntersections);
|
filterIntersections(avatarIntersections);
|
||||||
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), avatarIntersections);
|
return std::make_shared<CollisionPickResult>(pick, std::vector<ContactTestResult>(), avatarIntersections);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,9 @@ protected:
|
||||||
// Returns true if the resource for _mathPick.shapeInfo is loaded or if a resource is not needed.
|
// Returns true if the resource for _mathPick.shapeInfo is loaded or if a resource is not needed.
|
||||||
bool isLoaded() const;
|
bool isLoaded() const;
|
||||||
// Returns true if _mathPick.shapeInfo is valid. Otherwise, attempts to get the _mathPick ready for use.
|
// Returns true if _mathPick.shapeInfo is valid. Otherwise, attempts to get the _mathPick ready for use.
|
||||||
bool getShapeInfoReady();
|
bool getShapeInfoReady(const CollisionRegion& pick);
|
||||||
void computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
void computeShapeInfo(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||||
void computeShapeInfoDimensionsOnly(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
void computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||||
void filterIntersections(std::vector<ContactTestResult>& intersections) const;
|
void filterIntersections(std::vector<ContactTestResult>& intersections) const;
|
||||||
|
|
||||||
CollisionRegion _mathPick;
|
CollisionRegion _mathPick;
|
||||||
|
|
|
@ -24,11 +24,14 @@
|
||||||
#include "CollisionPick.h"
|
#include "CollisionPick.h"
|
||||||
|
|
||||||
#include "SpatialParentFinder.h"
|
#include "SpatialParentFinder.h"
|
||||||
#include "NestableTransformNode.h"
|
|
||||||
#include "PickTransformNode.h"
|
#include "PickTransformNode.h"
|
||||||
#include "MouseTransformNode.h"
|
#include "MouseTransformNode.h"
|
||||||
#include "avatar/MyAvatarHeadTransformNode.h"
|
#include "avatar/MyAvatarHeadTransformNode.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
#include "NestableTransformNode.h"
|
||||||
|
#include "avatars-renderer/AvatarTransformNode.h"
|
||||||
|
#include "ui/overlays/OverlayTransformNode.h"
|
||||||
|
#include "EntityTransformNode.h"
|
||||||
|
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
|
|
||||||
|
@ -260,9 +263,16 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
|
||||||
* A set of properties that can be passed to {@link Picks.createPick} to create a new Collision Pick.
|
* A set of properties that can be passed to {@link Picks.createPick} to create a new Collision Pick.
|
||||||
|
|
||||||
* @typedef {object} Picks.CollisionPickProperties
|
* @typedef {object} Picks.CollisionPickProperties
|
||||||
* @property {Shape} shape - The information about the collision region's size and shape.
|
* @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results.
|
||||||
* @property {Vec3} position - The position of the collision region.
|
* @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR.
|
||||||
* @property {Quat} orientation - The orientation of the collision region.
|
* @property {Shape} shape - The information about the collision region's size and shape. Dimensions are in world space, but will scale with the parent if defined.
|
||||||
|
* @property {Vec3} position - The position of the collision region, relative to a parent if defined.
|
||||||
|
* @property {Quat} orientation - The orientation of the collision region, relative to a parent if defined.
|
||||||
|
* @property {float} threshold - The approximate minimum penetration depth for a test object to be considered in contact with the collision region.
|
||||||
|
* The depth is measured in world space, but will scale with the parent if defined.
|
||||||
|
* @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay.
|
||||||
|
* @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint)
|
||||||
|
* @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar.
|
||||||
*/
|
*/
|
||||||
unsigned int PickScriptingInterface::createCollisionPick(const QVariant& properties) {
|
unsigned int PickScriptingInterface::createCollisionPick(const QVariant& properties) {
|
||||||
QVariantMap propMap = properties.toMap();
|
QVariantMap propMap = properties.toMap();
|
||||||
|
@ -375,7 +385,16 @@ std::shared_ptr<TransformNode> PickScriptingInterface::createTransformNode(const
|
||||||
}
|
}
|
||||||
auto sharedNestablePointer = nestablePointer.lock();
|
auto sharedNestablePointer = nestablePointer.lock();
|
||||||
if (success && sharedNestablePointer) {
|
if (success && sharedNestablePointer) {
|
||||||
return std::make_shared<NestableTransformNode>(nestablePointer, parentJointIndex);
|
NestableType nestableType = sharedNestablePointer->getNestableType();
|
||||||
|
if (nestableType == NestableType::Avatar) {
|
||||||
|
return std::make_shared<AvatarTransformNode>(std::static_pointer_cast<Avatar>(sharedNestablePointer), parentJointIndex);
|
||||||
|
} else if (nestableType == NestableType::Overlay) {
|
||||||
|
return std::make_shared<OverlayTransformNode>(std::static_pointer_cast<Base3DOverlay>(sharedNestablePointer), parentJointIndex);
|
||||||
|
} else if (nestableType == NestableType::Entity) {
|
||||||
|
return std::make_shared<EntityTransformNode>(std::static_pointer_cast<EntityItem>(sharedNestablePointer), parentJointIndex);
|
||||||
|
} else {
|
||||||
|
return std::make_shared<NestableTransformNode>(nestablePointer, parentJointIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +413,7 @@ std::shared_ptr<TransformNode> PickScriptingInterface::createTransformNode(const
|
||||||
} else if (!joint.isNull()) {
|
} else if (!joint.isNull()) {
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
int jointIndex = myAvatar->getJointIndex(joint);
|
int jointIndex = myAvatar->getJointIndex(joint);
|
||||||
return std::make_shared<NestableTransformNode>(myAvatar, jointIndex);
|
return std::make_shared<AvatarTransformNode>(myAvatar, jointIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
141
interface/src/ui/AnimStats.cpp
Normal file
141
interface/src/ui/AnimStats.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
//
|
||||||
|
// Created by Anthony J. Thibault 2018/08/06
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AnimStats.h"
|
||||||
|
|
||||||
|
#include <avatar/AvatarManager.h>
|
||||||
|
#include <OffscreenUi.h>
|
||||||
|
#include "Menu.h"
|
||||||
|
|
||||||
|
HIFI_QML_DEF(AnimStats)
|
||||||
|
|
||||||
|
static AnimStats* INSTANCE{ nullptr };
|
||||||
|
|
||||||
|
AnimStats* AnimStats::getInstance() {
|
||||||
|
Q_ASSERT(INSTANCE);
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimStats::AnimStats(QQuickItem* parent) : QQuickItem(parent) {
|
||||||
|
INSTANCE = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStats::updateStats(bool force) {
|
||||||
|
QQuickItem* parent = parentItem();
|
||||||
|
if (!force) {
|
||||||
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::AnimStats)) {
|
||||||
|
if (parent->isVisible()) {
|
||||||
|
parent->setVisible(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (!parent->isVisible()) {
|
||||||
|
parent->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
|
auto myAvatar = avatarManager->getMyAvatar();
|
||||||
|
auto debugAlphaMap = myAvatar->getSkeletonModel()->getRig().getDebugAlphaMap();
|
||||||
|
|
||||||
|
// update animation debug alpha values
|
||||||
|
QStringList newAnimAlphaValues;
|
||||||
|
qint64 now = usecTimestampNow();
|
||||||
|
for (auto& iter : debugAlphaMap) {
|
||||||
|
QString key = iter.first;
|
||||||
|
float alpha = std::get<0>(iter.second);
|
||||||
|
|
||||||
|
auto prevIter = _prevDebugAlphaMap.find(key);
|
||||||
|
if (prevIter != _prevDebugAlphaMap.end()) {
|
||||||
|
float prevAlpha = std::get<0>(iter.second);
|
||||||
|
if (prevAlpha != alpha) {
|
||||||
|
// change detected: reset timer
|
||||||
|
_animAlphaValueChangedTimers[key] = now;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// new value: start timer
|
||||||
|
_animAlphaValueChangedTimers[key] = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimNodeType type = std::get<1>(iter.second);
|
||||||
|
if (type == AnimNodeType::Clip) {
|
||||||
|
|
||||||
|
// figure out the grayScale color of this line.
|
||||||
|
const float LIT_TIME = 2.0f;
|
||||||
|
const float FADE_OUT_TIME = 1.0f;
|
||||||
|
float grayScale = 0.0f;
|
||||||
|
float secondsElapsed = (float)(now - _animAlphaValueChangedTimers[key]) / (float)USECS_PER_SECOND;
|
||||||
|
if (secondsElapsed < LIT_TIME) {
|
||||||
|
grayScale = 1.0f;
|
||||||
|
} else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) {
|
||||||
|
grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME;
|
||||||
|
} else {
|
||||||
|
grayScale = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grayScale > 0.0f) {
|
||||||
|
// append grayScaleColor to start of debug string
|
||||||
|
newAnimAlphaValues << QString::number(grayScale, 'f', 2) + "|" + key + ": " + QString::number(alpha, 'f', 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_animAlphaValues = newAnimAlphaValues;
|
||||||
|
_prevDebugAlphaMap = debugAlphaMap;
|
||||||
|
|
||||||
|
emit animAlphaValuesChanged();
|
||||||
|
|
||||||
|
// update animation anim vars
|
||||||
|
_animVarsList.clear();
|
||||||
|
auto animVars = myAvatar->getSkeletonModel()->getRig().getAnimVars().toDebugMap();
|
||||||
|
for (auto& iter : animVars) {
|
||||||
|
QString key = iter.first;
|
||||||
|
QString value = iter.second;
|
||||||
|
|
||||||
|
auto prevIter = _prevAnimVars.find(key);
|
||||||
|
if (prevIter != _prevAnimVars.end()) {
|
||||||
|
QString prevValue = prevIter->second;
|
||||||
|
if (value != prevValue) {
|
||||||
|
// change detected: reset timer
|
||||||
|
_animVarChangedTimers[key] = now;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// new value: start timer
|
||||||
|
_animVarChangedTimers[key] = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// figure out the grayScale color of this line.
|
||||||
|
const float LIT_TIME = 2.0f;
|
||||||
|
const float FADE_OUT_TIME = 0.5f;
|
||||||
|
float grayScale = 0.0f;
|
||||||
|
float secondsElapsed = (float)(now - _animVarChangedTimers[key]) / (float)USECS_PER_SECOND;
|
||||||
|
if (secondsElapsed < LIT_TIME) {
|
||||||
|
grayScale = 1.0f;
|
||||||
|
} else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) {
|
||||||
|
grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME;
|
||||||
|
} else {
|
||||||
|
grayScale = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grayScale > 0.0f) {
|
||||||
|
// append grayScaleColor to start of debug string
|
||||||
|
_animVarsList << QString::number(grayScale, 'f', 2) + "|" + key + ": " + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_prevAnimVars = animVars;
|
||||||
|
emit animVarsChanged();
|
||||||
|
|
||||||
|
// animation state machines
|
||||||
|
_animStateMachines.clear();
|
||||||
|
auto stateMachineMap = myAvatar->getSkeletonModel()->getRig().getStateMachineMap();
|
||||||
|
for (auto& iter : stateMachineMap) {
|
||||||
|
_animStateMachines << iter.second;
|
||||||
|
}
|
||||||
|
emit animStateMachinesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
55
interface/src/ui/AnimStats.h
Normal file
55
interface/src/ui/AnimStats.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
//
|
||||||
|
// Created by Anthony J. Thibault 2018/08/06
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_AnimStats_h
|
||||||
|
#define hifi_AnimStats_h
|
||||||
|
|
||||||
|
#include <OffscreenQmlElement.h>
|
||||||
|
#include <AnimContext.h>
|
||||||
|
|
||||||
|
class AnimStats : public QQuickItem {
|
||||||
|
Q_OBJECT
|
||||||
|
HIFI_QML_DECL
|
||||||
|
|
||||||
|
Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged)
|
||||||
|
Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged)
|
||||||
|
Q_PROPERTY(QStringList animStateMachines READ animStateMachines NOTIFY animStateMachinesChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static AnimStats* getInstance();
|
||||||
|
|
||||||
|
AnimStats(QQuickItem* parent = nullptr);
|
||||||
|
|
||||||
|
void updateStats(bool force = false);
|
||||||
|
|
||||||
|
QStringList animAlphaValues() { return _animAlphaValues; }
|
||||||
|
QStringList animVars() { return _animVarsList; }
|
||||||
|
QStringList animStateMachines() { return _animStateMachines; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void forceUpdateStats() { updateStats(true); }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void animAlphaValuesChanged();
|
||||||
|
void animVarsChanged();
|
||||||
|
void animStateMachinesChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList _animAlphaValues;
|
||||||
|
AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame
|
||||||
|
std::map<QString, qint64> _animAlphaValueChangedTimers; // last time alpha value has changed
|
||||||
|
|
||||||
|
QStringList _animVarsList;
|
||||||
|
std::map<QString, QString> _prevAnimVars; // anim vars from previous frame
|
||||||
|
std::map<QString, qint64> _animVarChangedTimers; // last time animVar value has changed.
|
||||||
|
|
||||||
|
QStringList _animStateMachines;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_AnimStats_h
|
|
@ -207,14 +207,6 @@ void Stats::updateStats(bool force) {
|
||||||
|
|
||||||
// Third column, avatar stats
|
// Third column, avatar stats
|
||||||
auto myAvatar = avatarManager->getMyAvatar();
|
auto myAvatar = avatarManager->getMyAvatar();
|
||||||
auto animStack = myAvatar->getSkeletonModel()->getRig().getAnimStack();
|
|
||||||
|
|
||||||
_animStackNames.clear();
|
|
||||||
for (auto animStackIterator = animStack.begin(); animStackIterator != animStack.end(); ++animStackIterator) {
|
|
||||||
_animStackNames << animStackIterator->first + ": " + QString::number(animStackIterator->second,'f',3);
|
|
||||||
}
|
|
||||||
emit animStackNamesChanged();
|
|
||||||
|
|
||||||
glm::vec3 avatarPos = myAvatar->getWorldPosition();
|
glm::vec3 avatarPos = myAvatar->getWorldPosition();
|
||||||
STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
|
STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
|
||||||
STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f);
|
STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f);
|
||||||
|
|
|
@ -134,7 +134,6 @@ private: \
|
||||||
* @property {number} batchFrameTime - <em>Read-only.</em>
|
* @property {number} batchFrameTime - <em>Read-only.</em>
|
||||||
* @property {number} engineFrameTime - <em>Read-only.</em>
|
* @property {number} engineFrameTime - <em>Read-only.</em>
|
||||||
* @property {number} avatarSimulationTime - <em>Read-only.</em>
|
* @property {number} avatarSimulationTime - <em>Read-only.</em>
|
||||||
* @property {string[]} animStackNames - <em>Read-only.</em>
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @property {number} x
|
* @property {number} x
|
||||||
|
@ -292,7 +291,6 @@ class Stats : public QQuickItem {
|
||||||
STATS_PROPERTY(float, batchFrameTime, 0)
|
STATS_PROPERTY(float, batchFrameTime, 0)
|
||||||
STATS_PROPERTY(float, engineFrameTime, 0)
|
STATS_PROPERTY(float, engineFrameTime, 0)
|
||||||
STATS_PROPERTY(float, avatarSimulationTime, 0)
|
STATS_PROPERTY(float, avatarSimulationTime, 0)
|
||||||
Q_PROPERTY(QStringList animStackNames READ animStackNames NOTIFY animStackNamesChanged)
|
|
||||||
|
|
||||||
STATS_PROPERTY(int, stylusPicksCount, 0)
|
STATS_PROPERTY(int, stylusPicksCount, 0)
|
||||||
STATS_PROPERTY(int, rayPicksCount, 0)
|
STATS_PROPERTY(int, rayPicksCount, 0)
|
||||||
|
@ -326,7 +324,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList downloadUrls () { return _downloadUrls; }
|
QStringList downloadUrls () { return _downloadUrls; }
|
||||||
QStringList animStackNames() { return _animStackNames; }
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void forceUpdateStats() { updateStats(true); }
|
void forceUpdateStats() { updateStats(true); }
|
||||||
|
@ -1028,13 +1025,6 @@ signals:
|
||||||
*/
|
*/
|
||||||
void avatarSimulationTimeChanged();
|
void avatarSimulationTimeChanged();
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* Triggered when the value of the <code>animStackNames</code> property changes.
|
|
||||||
* @function Stats.animStackNamesChanged
|
|
||||||
* @returns {Signal}
|
|
||||||
*/
|
|
||||||
void animStackNamesChanged();
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when the value of the <code>rectifiedTextureCount</code> property changes.
|
* Triggered when the value of the <code>rectifiedTextureCount</code> property changes.
|
||||||
* @function Stats.rectifiedTextureCountChanged
|
* @function Stats.rectifiedTextureCountChanged
|
||||||
|
@ -1049,7 +1039,6 @@ signals:
|
||||||
*/
|
*/
|
||||||
void decimatedTextureCountChanged();
|
void decimatedTextureCountChanged();
|
||||||
|
|
||||||
|
|
||||||
// QQuickItem signals.
|
// QQuickItem signals.
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -1336,7 +1325,6 @@ private:
|
||||||
QString _monospaceFont;
|
QString _monospaceFont;
|
||||||
const AudioIOStats* _audioStats;
|
const AudioIOStats* _audioStats;
|
||||||
QStringList _downloadUrls = QStringList();
|
QStringList _downloadUrls = QStringList();
|
||||||
QStringList _animStackNames = QStringList();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Stats_h
|
#endif // hifi_Stats_h
|
||||||
|
|
13
interface/src/ui/overlays/OverlayTransformNode.cpp
Normal file
13
interface/src/ui/overlays/OverlayTransformNode.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman 9/5/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "OverlayTransformNode.h"
|
||||||
|
|
||||||
|
template<>
|
||||||
|
glm::vec3 BaseNestableTransformNode<Base3DOverlay>::getActualScale(const std::shared_ptr<Base3DOverlay>& nestablePointer) const {
|
||||||
|
return nestablePointer->getBounds().getScale();
|
||||||
|
}
|
21
interface/src/ui/overlays/OverlayTransformNode.h
Normal file
21
interface/src/ui/overlays/OverlayTransformNode.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman 9/5/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#ifndef hifi_OverlayTransformNode_h
|
||||||
|
#define hifi_OverlayTransformNode_h
|
||||||
|
|
||||||
|
#include "NestableTransformNode.h"
|
||||||
|
|
||||||
|
#include "Base3DOverlay.h"
|
||||||
|
|
||||||
|
// For 3D overlays only
|
||||||
|
class OverlayTransformNode : public BaseNestableTransformNode<Base3DOverlay> {
|
||||||
|
public:
|
||||||
|
OverlayTransformNode(std::weak_ptr<Base3DOverlay> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_OverlayTransformNode_h
|
|
@ -27,7 +27,7 @@ AnimBlendLinear::~AnimBlendLinear() {
|
||||||
const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
|
const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
|
||||||
|
|
||||||
_alpha = animVars.lookup(_alphaVar, _alpha);
|
_alpha = animVars.lookup(_alphaVar, _alpha);
|
||||||
float parentAlpha = _animStack[_id];
|
float parentDebugAlpha = context.getDebugAlpha(_id);
|
||||||
|
|
||||||
if (_children.size() == 0) {
|
if (_children.size() == 0) {
|
||||||
for (auto&& pose : _poses) {
|
for (auto&& pose : _poses) {
|
||||||
|
@ -35,7 +35,7 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con
|
||||||
}
|
}
|
||||||
} else if (_children.size() == 1) {
|
} else if (_children.size() == 1) {
|
||||||
_poses = _children[0]->evaluate(animVars, context, dt, triggersOut);
|
_poses = _children[0]->evaluate(animVars, context, dt, triggersOut);
|
||||||
_animStack[_children[0]->getID()] = parentAlpha;
|
context.setDebugAlpha(_children[0]->getID(), parentDebugAlpha, _children[0]->getType());
|
||||||
} else {
|
} else {
|
||||||
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
|
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
|
||||||
size_t prevPoseIndex = glm::floor(clampedAlpha);
|
size_t prevPoseIndex = glm::floor(clampedAlpha);
|
||||||
|
@ -48,12 +48,12 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con
|
||||||
float weight2 = 0.0f;
|
float weight2 = 0.0f;
|
||||||
if (prevPoseIndex == nextPoseIndex) {
|
if (prevPoseIndex == nextPoseIndex) {
|
||||||
weight2 = 1.0f;
|
weight2 = 1.0f;
|
||||||
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
|
context.setDebugAlpha(_children[nextPoseIndex]->getID(), weight2 * parentDebugAlpha, _children[nextPoseIndex]->getType());
|
||||||
} else {
|
} else {
|
||||||
weight2 = alpha;
|
weight2 = alpha;
|
||||||
weight1 = 1.0f - weight2;
|
weight1 = 1.0f - weight2;
|
||||||
_animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha;
|
context.setDebugAlpha(_children[prevPoseIndex]->getID(), weight1 * parentDebugAlpha, _children[prevPoseIndex]->getType());
|
||||||
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
|
context.setDebugAlpha(_children[nextPoseIndex]->getID(), weight2 * parentDebugAlpha, _children[nextPoseIndex]->getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
processOutputJoints(triggersOut);
|
processOutputJoints(triggersOut);
|
||||||
|
|
|
@ -62,9 +62,7 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
|
||||||
speed = animVars.lookup("moveForwardSpeed", speed);
|
speed = animVars.lookup("moveForwardSpeed", speed);
|
||||||
}
|
}
|
||||||
_alpha = calculateAlpha(speed, _characteristicSpeeds);
|
_alpha = calculateAlpha(speed, _characteristicSpeeds);
|
||||||
float parentAlpha = _animStack[_id];
|
float parentDebugAlpha = context.getDebugAlpha(_id);
|
||||||
|
|
||||||
_animStack["speed"] = speed;
|
|
||||||
|
|
||||||
if (_children.size() == 0) {
|
if (_children.size() == 0) {
|
||||||
for (auto&& pose : _poses) {
|
for (auto&& pose : _poses) {
|
||||||
|
@ -77,7 +75,7 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
|
||||||
float prevDeltaTime, nextDeltaTime;
|
float prevDeltaTime, nextDeltaTime;
|
||||||
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
|
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
|
||||||
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
|
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
|
||||||
_animStack[_children[0]->getID()] = parentAlpha;
|
context.setDebugAlpha(_children[0]->getID(), parentDebugAlpha, _children[0]->getType());
|
||||||
} else {
|
} else {
|
||||||
auto clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
|
auto clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
|
||||||
auto prevPoseIndex = glm::floor(clampedAlpha);
|
auto prevPoseIndex = glm::floor(clampedAlpha);
|
||||||
|
@ -87,17 +85,11 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
|
||||||
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
|
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
|
||||||
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
|
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
|
||||||
|
|
||||||
// weights are for animation stack debug purposes only.
|
|
||||||
float weight1 = 0.0f;
|
|
||||||
float weight2 = 0.0f;
|
|
||||||
if (prevPoseIndex == nextPoseIndex) {
|
if (prevPoseIndex == nextPoseIndex) {
|
||||||
weight2 = 1.0f;
|
context.setDebugAlpha(_children[nextPoseIndex]->getID(), parentDebugAlpha, _children[nextPoseIndex]->getType());
|
||||||
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
|
|
||||||
} else {
|
} else {
|
||||||
weight2 = alpha;
|
context.setDebugAlpha(_children[prevPoseIndex]->getID(), (1.0f - alpha) * parentDebugAlpha, _children[prevPoseIndex]->getType());
|
||||||
weight1 = 1.0f - weight2;
|
context.setDebugAlpha(_children[nextPoseIndex]->getID(), alpha * parentDebugAlpha, _children[nextPoseIndex]->getType());
|
||||||
_animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha;
|
|
||||||
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,27 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
enum class AnimNodeType {
|
||||||
|
Clip = 0,
|
||||||
|
BlendLinear,
|
||||||
|
BlendLinearMove,
|
||||||
|
Overlay,
|
||||||
|
StateMachine,
|
||||||
|
Manipulator,
|
||||||
|
InverseKinematics,
|
||||||
|
DefaultPose,
|
||||||
|
TwoBoneIK,
|
||||||
|
PoleVectorConstraint,
|
||||||
|
NumTypes
|
||||||
|
};
|
||||||
|
|
||||||
class AnimContext {
|
class AnimContext {
|
||||||
public:
|
public:
|
||||||
|
AnimContext() {}
|
||||||
AnimContext(bool enableDebugDrawIKTargets, bool enableDebugDrawIKConstraints, bool enableDebugDrawIKChains,
|
AnimContext(bool enableDebugDrawIKTargets, bool enableDebugDrawIKConstraints, bool enableDebugDrawIKChains,
|
||||||
const glm::mat4& geometryToRigMatrix, const glm::mat4& rigToWorldMatrix);
|
const glm::mat4& geometryToRigMatrix, const glm::mat4& rigToWorldMatrix);
|
||||||
|
|
||||||
|
@ -25,6 +44,39 @@ public:
|
||||||
const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; }
|
const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; }
|
||||||
const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; }
|
const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; }
|
||||||
|
|
||||||
|
float getDebugAlpha(const QString& key) const {
|
||||||
|
auto it = _debugAlphaMap.find(key);
|
||||||
|
if (it != _debugAlphaMap.end()) {
|
||||||
|
return std::get<0>(it->second);
|
||||||
|
} else {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using DebugAlphaMapValue = std::tuple<float, AnimNodeType>;
|
||||||
|
using DebugAlphaMap = std::map<QString, DebugAlphaMapValue>;
|
||||||
|
|
||||||
|
void setDebugAlpha(const QString& key, float alpha, AnimNodeType type) const {
|
||||||
|
_debugAlphaMap[key] = DebugAlphaMapValue(alpha, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DebugAlphaMap& getDebugAlphaMap() const {
|
||||||
|
return _debugAlphaMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
using DebugStateMachineMapValue = QString;
|
||||||
|
using DebugStateMachineMap = std::map<QString, DebugStateMachineMapValue>;
|
||||||
|
|
||||||
|
void addStateMachineInfo(const QString& stateMachineName, const QString& currentState, const QString& previousState, bool duringInterp, float alpha) const {
|
||||||
|
if (duringInterp) {
|
||||||
|
_stateMachineMap[stateMachineName] = QString("%1: %2 -> %3 (%4)").arg(stateMachineName).arg(previousState).arg(currentState).arg(QString::number(alpha, 'f', 2));
|
||||||
|
} else {
|
||||||
|
_stateMachineMap[stateMachineName] = QString("%1: %2").arg(stateMachineName).arg(currentState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DebugStateMachineMap& getStateMachineMap() const { return _stateMachineMap; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool _enableDebugDrawIKTargets { false };
|
bool _enableDebugDrawIKTargets { false };
|
||||||
|
@ -32,6 +84,10 @@ protected:
|
||||||
bool _enableDebugDrawIKChains { false };
|
bool _enableDebugDrawIKChains { false };
|
||||||
glm::mat4 _geometryToRigMatrix;
|
glm::mat4 _geometryToRigMatrix;
|
||||||
glm::mat4 _rigToWorldMatrix;
|
glm::mat4 _rigToWorldMatrix;
|
||||||
|
|
||||||
|
// used for debugging internal state of animation system.
|
||||||
|
mutable DebugAlphaMap _debugAlphaMap;
|
||||||
|
mutable DebugStateMachineMap _stateMachineMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AnimContext_h
|
#endif // hifi_AnimContext_h
|
||||||
|
|
|
@ -12,10 +12,6 @@
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
std::map<QString, float> AnimNode::_animStack = {
|
|
||||||
{"none", 0.0f}
|
|
||||||
};
|
|
||||||
|
|
||||||
AnimNode::Pointer AnimNode::getParent() {
|
AnimNode::Pointer AnimNode::getParent() {
|
||||||
return _parent.lock();
|
return _parent.lock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,19 +36,7 @@ class QJsonObject;
|
||||||
|
|
||||||
class AnimNode : public std::enable_shared_from_this<AnimNode> {
|
class AnimNode : public std::enable_shared_from_this<AnimNode> {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
using Type = AnimNodeType;
|
||||||
Clip = 0,
|
|
||||||
BlendLinear,
|
|
||||||
BlendLinearMove,
|
|
||||||
Overlay,
|
|
||||||
StateMachine,
|
|
||||||
Manipulator,
|
|
||||||
InverseKinematics,
|
|
||||||
DefaultPose,
|
|
||||||
TwoBoneIK,
|
|
||||||
PoleVectorConstraint,
|
|
||||||
NumTypes
|
|
||||||
};
|
|
||||||
using Pointer = std::shared_ptr<AnimNode>;
|
using Pointer = std::shared_ptr<AnimNode>;
|
||||||
using ConstPointer = std::shared_ptr<const AnimNode>;
|
using ConstPointer = std::shared_ptr<const AnimNode>;
|
||||||
|
|
||||||
|
@ -84,7 +72,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrentFrame(float frame);
|
void setCurrentFrame(float frame);
|
||||||
const std::map<QString, float> getAnimStack() { return _animStack; }
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool traverse(F func) {
|
bool traverse(F func) {
|
||||||
|
@ -127,9 +114,6 @@ protected:
|
||||||
std::weak_ptr<AnimNode> _parent;
|
std::weak_ptr<AnimNode> _parent;
|
||||||
std::vector<QString> _outputJointNames;
|
std::vector<QString> _outputJointNames;
|
||||||
|
|
||||||
// global available to Stats.h
|
|
||||||
static std::map<QString, float> _animStack;
|
|
||||||
|
|
||||||
// no copies
|
// no copies
|
||||||
AnimNode(const AnimNode&) = delete;
|
AnimNode(const AnimNode&) = delete;
|
||||||
AnimNode& operator=(const AnimNode&) = delete;
|
AnimNode& operator=(const AnimNode&) = delete;
|
||||||
|
|
|
@ -23,9 +23,7 @@ AnimStateMachine::~AnimStateMachine() {
|
||||||
|
|
||||||
const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
|
const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
|
||||||
|
|
||||||
if (_id.contains("userAnimStateMachine")) {
|
float parentDebugAlpha = context.getDebugAlpha(_id);
|
||||||
_animStack.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
|
QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
|
||||||
if (_currentState->getID() != desiredStateID) {
|
if (_currentState->getID() != desiredStateID) {
|
||||||
|
@ -33,8 +31,6 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
|
||||||
bool foundState = false;
|
bool foundState = false;
|
||||||
for (auto& state : _states) {
|
for (auto& state : _states) {
|
||||||
if (state->getID() == desiredStateID) {
|
if (state->getID() == desiredStateID) {
|
||||||
// parenthesis means previous state, which is a snapshot.
|
|
||||||
_previousStateID = "(" + _currentState->getID() + ")";
|
|
||||||
switchState(animVars, context, state);
|
switchState(animVars, context, state);
|
||||||
foundState = true;
|
foundState = true;
|
||||||
break;
|
break;
|
||||||
|
@ -48,8 +44,6 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
|
||||||
// evaluate currentState transitions
|
// evaluate currentState transitions
|
||||||
auto desiredState = evaluateTransitions(animVars);
|
auto desiredState = evaluateTransitions(animVars);
|
||||||
if (desiredState != _currentState) {
|
if (desiredState != _currentState) {
|
||||||
// parenthesis means previous state, which is a snapshot.
|
|
||||||
_previousStateID = "(" + _currentState->getID() + ")";
|
|
||||||
switchState(animVars, context, desiredState);
|
switchState(animVars, context, desiredState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,17 +51,8 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
|
||||||
auto currentStateNode = _children[_currentState->getChildIndex()];
|
auto currentStateNode = _children[_currentState->getChildIndex()];
|
||||||
assert(currentStateNode);
|
assert(currentStateNode);
|
||||||
|
|
||||||
if (!_previousStateID.contains("none")) {
|
|
||||||
_animStack[_previousStateID] = 1.0f - _alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_duringInterp) {
|
if (_duringInterp) {
|
||||||
_alpha += _alphaVel * dt;
|
_alpha += _alphaVel * dt;
|
||||||
if (_alpha > 1.0f) {
|
|
||||||
_animStack[_currentState->getID()] = 1.0f;
|
|
||||||
} else {
|
|
||||||
_animStack[_currentState->getID()] = _alpha;
|
|
||||||
}
|
|
||||||
if (_alpha < 1.0f) {
|
if (_alpha < 1.0f) {
|
||||||
AnimPoseVec* nextPoses = nullptr;
|
AnimPoseVec* nextPoses = nullptr;
|
||||||
AnimPoseVec* prevPoses = nullptr;
|
AnimPoseVec* prevPoses = nullptr;
|
||||||
|
@ -88,26 +73,27 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
|
||||||
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
|
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
|
||||||
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
|
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
|
||||||
}
|
}
|
||||||
|
context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
|
||||||
} else {
|
} else {
|
||||||
_duringInterp = false;
|
_duringInterp = false;
|
||||||
if (_animStack.count(_previousStateID) > 0) {
|
|
||||||
_animStack.erase(_previousStateID);
|
|
||||||
}
|
|
||||||
_previousStateID = "none";
|
|
||||||
_prevPoses.clear();
|
_prevPoses.clear();
|
||||||
_nextPoses.clear();
|
_nextPoses.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_duringInterp) {
|
if (!_duringInterp) {
|
||||||
_animStack[_currentState->getID()] = 1.0f;
|
context.setDebugAlpha(_currentState->getID(), parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
|
||||||
_poses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
|
_poses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
|
||||||
}
|
}
|
||||||
processOutputJoints(triggersOut);
|
processOutputJoints(triggersOut);
|
||||||
|
|
||||||
|
context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha);
|
||||||
|
|
||||||
return _poses;
|
return _poses;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimStateMachine::setCurrentState(State::Pointer state) {
|
void AnimStateMachine::setCurrentState(State::Pointer state) {
|
||||||
|
_previousState = _currentState ? _currentState : state;
|
||||||
_currentState = state;
|
_currentState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +138,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
|
||||||
qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID() << "duration =" << duration << "targetFrame =" << desiredState->_interpTarget << "interpType = " << (int)_interpType;
|
qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID() << "duration =" << duration << "targetFrame =" << desiredState->_interpTarget << "interpType = " << (int)_interpType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_currentState = desiredState;
|
setCurrentState(desiredState);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimStateMachine::State::Pointer AnimStateMachine::evaluateTransitions(const AnimVariantMap& animVars) const {
|
AnimStateMachine::State::Pointer AnimStateMachine::evaluateTransitions(const AnimVariantMap& animVars) const {
|
||||||
|
|
|
@ -138,9 +138,9 @@ protected:
|
||||||
float _alpha = 0.0f;
|
float _alpha = 0.0f;
|
||||||
AnimPoseVec _prevPoses;
|
AnimPoseVec _prevPoses;
|
||||||
AnimPoseVec _nextPoses;
|
AnimPoseVec _nextPoses;
|
||||||
QString _previousStateID { "none" };
|
|
||||||
|
|
||||||
State::Pointer _currentState;
|
State::Pointer _currentState;
|
||||||
|
State::Pointer _previousState;
|
||||||
std::vector<State::Pointer> _states;
|
std::vector<State::Pointer> _states;
|
||||||
|
|
||||||
QString _currentStateVar;
|
QString _currentStateVar;
|
||||||
|
|
|
@ -67,6 +67,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine,
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimVariantMap::copyVariantsFrom(const AnimVariantMap& other) {
|
void AnimVariantMap::copyVariantsFrom(const AnimVariantMap& other) {
|
||||||
for (auto& pair : other._map) {
|
for (auto& pair : other._map) {
|
||||||
_map[pair.first] = pair.second;
|
_map[pair.first] = pair.second;
|
||||||
|
@ -124,3 +125,43 @@ void AnimVariantMap::animVariantMapFromScriptValue(const QScriptValue& source) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<QString, QString> AnimVariantMap::toDebugMap() const {
|
||||||
|
std::map<QString, QString> result;
|
||||||
|
for (auto& pair : _map) {
|
||||||
|
switch (pair.second.getType()) {
|
||||||
|
case AnimVariant::Type::Bool:
|
||||||
|
result[pair.first] = QString("%1").arg(pair.second.getBool());
|
||||||
|
break;
|
||||||
|
case AnimVariant::Type::Int:
|
||||||
|
result[pair.first] = QString("%1").arg(pair.second.getInt());
|
||||||
|
break;
|
||||||
|
case AnimVariant::Type::Float:
|
||||||
|
result[pair.first] = QString::number(pair.second.getFloat(), 'f', 3);
|
||||||
|
break;
|
||||||
|
case AnimVariant::Type::Vec3: {
|
||||||
|
glm::vec3 value = pair.second.getVec3();
|
||||||
|
result[pair.first] = QString("(%1, %2, %3)").
|
||||||
|
arg(QString::number(value.x, 'f', 3)).
|
||||||
|
arg(QString::number(value.y, 'f', 3)).
|
||||||
|
arg(QString::number(value.z, 'f', 3));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AnimVariant::Type::Quat: {
|
||||||
|
glm::quat value = pair.second.getQuat();
|
||||||
|
result[pair.first] = QString("(%1, %2, %3, %4)").
|
||||||
|
arg(QString::number(value.x, 'f', 3)).
|
||||||
|
arg(QString::number(value.y, 'f', 3)).
|
||||||
|
arg(QString::number(value.z, 'f', 3)).
|
||||||
|
arg(QString::number(value.w, 'f', 3));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AnimVariant::Type::String:
|
||||||
|
result[pair.first] = pair.second.getString();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(("invalid AnimVariant::Type", false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -235,6 +235,9 @@ public:
|
||||||
void animVariantMapFromScriptValue(const QScriptValue& object);
|
void animVariantMapFromScriptValue(const QScriptValue& object);
|
||||||
void copyVariantsFrom(const AnimVariantMap& other);
|
void copyVariantsFrom(const AnimVariantMap& other);
|
||||||
|
|
||||||
|
// For stat debugging.
|
||||||
|
std::map<QString, QString> toDebugMap() const;
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
void dump() const {
|
void dump() const {
|
||||||
qCDebug(animation) << "AnimVariantMap =";
|
qCDebug(animation) << "AnimVariantMap =";
|
||||||
|
|
|
@ -1061,8 +1061,10 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons
|
||||||
// animations haven't fully loaded yet.
|
// animations haven't fully loaded yet.
|
||||||
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
||||||
}
|
}
|
||||||
|
_lastAnimVars = _animVars;
|
||||||
_animVars.clearTriggers();
|
_animVars.clearTriggers();
|
||||||
_animVars = triggersOut;
|
_animVars = triggersOut;
|
||||||
|
_lastContext = context;
|
||||||
}
|
}
|
||||||
applyOverridePoses();
|
applyOverridePoses();
|
||||||
buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses);
|
buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses);
|
||||||
|
|
|
@ -222,7 +222,10 @@ public:
|
||||||
// input assumed to be in rig space
|
// input assumed to be in rig space
|
||||||
void computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut) const;
|
void computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut) const;
|
||||||
|
|
||||||
const std::map<QString, float> getAnimStack() { return _animNode->getAnimStack(); }
|
// used to debug animation playback
|
||||||
|
const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); }
|
||||||
|
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
||||||
|
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
||||||
|
|
||||||
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
|
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
|
||||||
signals:
|
signals:
|
||||||
|
@ -388,6 +391,9 @@ protected:
|
||||||
|
|
||||||
int _rigId;
|
int _rigId;
|
||||||
bool _headEnabled { false };
|
bool _headEnabled { false };
|
||||||
|
|
||||||
|
AnimContext _lastContext;
|
||||||
|
AnimVariantMap _lastAnimVars;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Rig__) */
|
#endif /* defined(__hifi__Rig__) */
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman 9/5/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "AvatarTransformNode.h"
|
||||||
|
|
||||||
|
template<>
|
||||||
|
glm::vec3 BaseNestableTransformNode<Avatar>::getActualScale(const std::shared_ptr<Avatar>& nestablePointer) const {
|
||||||
|
return nestablePointer->scaleForChildren();
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman 9/5/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#ifndef hifi_AvatarTransformNode_h
|
||||||
|
#define hifi_AvatarTransformNode_h
|
||||||
|
|
||||||
|
#include "NestableTransformNode.h"
|
||||||
|
|
||||||
|
#include "Avatar.h"
|
||||||
|
|
||||||
|
class AvatarTransformNode : public BaseNestableTransformNode<Avatar> {
|
||||||
|
public:
|
||||||
|
AvatarTransformNode(std::weak_ptr<Avatar> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_AvatarTransformNode_h
|
|
@ -14,7 +14,6 @@
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <recording/Deck.h>
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
#include <trackers/FaceTracker.h>
|
#include <trackers/FaceTracker.h>
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "AvatarLogging.h"
|
#include "AvatarLogging.h"
|
||||||
#include "AvatarTraits.h"
|
#include "AvatarTraits.h"
|
||||||
|
|
||||||
|
#include "Profile.h"
|
||||||
|
|
||||||
void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) {
|
void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) {
|
||||||
if (parentID == QUuid()) {
|
if (parentID == QUuid()) {
|
||||||
|
@ -214,6 +215,7 @@ AvatarSharedPointer AvatarHashMap::findAvatar(const QUuid& sessionUUID) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||||
|
DETAILED_PROFILE_RANGE(network, __FUNCTION__);
|
||||||
PerformanceTimer perfTimer("receiveAvatar");
|
PerformanceTimer perfTimer("receiveAvatar");
|
||||||
// enumerate over all of the avatars in this packet
|
// enumerate over all of the avatars in this packet
|
||||||
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
|
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
|
||||||
|
|
13
libraries/entities/src/EntityTransformNode.cpp
Normal file
13
libraries/entities/src/EntityTransformNode.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman 9/5/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "EntityTransformNode.h"
|
||||||
|
|
||||||
|
template<>
|
||||||
|
glm::vec3 BaseNestableTransformNode<EntityItem>::getActualScale(const std::shared_ptr<EntityItem>& nestablePointer) const {
|
||||||
|
return nestablePointer->getScaledDimensions();
|
||||||
|
}
|
20
libraries/entities/src/EntityTransformNode.h
Normal file
20
libraries/entities/src/EntityTransformNode.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman 9/5/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#ifndef hifi_EntityTransformNode_h
|
||||||
|
#define hifi_EntityTransformNode_h
|
||||||
|
|
||||||
|
#include "NestableTransformNode.h"
|
||||||
|
|
||||||
|
#include "EntityItem.h"
|
||||||
|
|
||||||
|
class EntityTransformNode : public BaseNestableTransformNode<EntityItem> {
|
||||||
|
public:
|
||||||
|
EntityTransformNode(std::weak_ptr<EntityItem> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_EntityTransformNode_h
|
|
@ -56,13 +56,20 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
|
||||||
qRegisterMetaType<ConnectionStep>("ConnectionStep");
|
qRegisterMetaType<ConnectionStep>("ConnectionStep");
|
||||||
auto port = (socketListenPort != INVALID_PORT) ? socketListenPort : LIMITED_NODELIST_LOCAL_PORT.get();
|
auto port = (socketListenPort != INVALID_PORT) ? socketListenPort : LIMITED_NODELIST_LOCAL_PORT.get();
|
||||||
_nodeSocket.bind(QHostAddress::AnyIPv4, port);
|
_nodeSocket.bind(QHostAddress::AnyIPv4, port);
|
||||||
qCDebug(networking) << "NodeList socket is listening on" << _nodeSocket.localPort();
|
quint16 assignedPort = _nodeSocket.localPort();
|
||||||
|
if (socketListenPort != INVALID_PORT && socketListenPort != 0 && socketListenPort != assignedPort) {
|
||||||
|
qCCritical(networking) << "NodeList is unable to assign requested port of" << socketListenPort;
|
||||||
|
}
|
||||||
|
qCDebug(networking) << "NodeList socket is listening on" << assignedPort;
|
||||||
|
|
||||||
if (dtlsListenPort != INVALID_PORT) {
|
if (dtlsListenPort != INVALID_PORT) {
|
||||||
// only create the DTLS socket during constructor if a custom port is passed
|
// only create the DTLS socket during constructor if a custom port is passed
|
||||||
_dtlsSocket = new QUdpSocket(this);
|
_dtlsSocket = new QUdpSocket(this);
|
||||||
|
|
||||||
_dtlsSocket->bind(QHostAddress::AnyIPv4, dtlsListenPort);
|
_dtlsSocket->bind(QHostAddress::AnyIPv4, dtlsListenPort);
|
||||||
|
if (dtlsListenPort != 0 && _dtlsSocket->localPort() != dtlsListenPort) {
|
||||||
|
qCDebug(networking) << "NodeList is unable to assign requested DTLS port of" << dtlsListenPort;
|
||||||
|
}
|
||||||
qCDebug(networking) << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort();
|
qCDebug(networking) << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ void DeferredFramebuffer::allocate() {
|
||||||
_deferredFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
_deferredFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||||
|
|
||||||
|
|
||||||
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT);
|
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP);
|
||||||
|
|
||||||
_lightingTexture = gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, gpu::Texture::SINGLE_MIP, smoothSampler);
|
_lightingTexture = gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, gpu::Texture::SINGLE_MIP, smoothSampler);
|
||||||
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("lighting"));
|
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("lighting"));
|
||||||
|
|
|
@ -108,6 +108,10 @@ public:
|
||||||
Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback);
|
Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback);
|
||||||
|
|
||||||
#if (PR_BUILD || DEV_BUILD)
|
#if (PR_BUILD || DEV_BUILD)
|
||||||
|
/**
|
||||||
|
* This function is purely for development purposes, and not meant for use in a
|
||||||
|
* production context. It is not a public-facing API, so it should not contain jsdoc.
|
||||||
|
*/
|
||||||
Q_INVOKABLE void sendFakedHandshake();
|
Q_INVOKABLE void sendFakedHandshake();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ void ScriptEngine::disconnectNonEssentialSignals() {
|
||||||
// Ensure the thread should be running, and does exist
|
// Ensure the thread should be running, and does exist
|
||||||
if (_isRunning && _isThreaded && (workerThread = thread())) {
|
if (_isRunning && _isThreaded && (workerThread = thread())) {
|
||||||
connect(this, &ScriptEngine::doneRunning, workerThread, &QThread::quit);
|
connect(this, &ScriptEngine::doneRunning, workerThread, &QThread::quit);
|
||||||
connect(this, &QObject::destroyed, workerThread, &QObject::deleteLater);
|
connect(workerThread, &QThread::finished, workerThread, &QObject::deleteLater);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ void ScriptEngine::runInThread() {
|
||||||
// disconnectNonEssentialSignals() method
|
// disconnectNonEssentialSignals() method
|
||||||
connect(workerThread, &QThread::started, this, &ScriptEngine::run);
|
connect(workerThread, &QThread::started, this, &ScriptEngine::run);
|
||||||
connect(this, &ScriptEngine::doneRunning, workerThread, &QThread::quit);
|
connect(this, &ScriptEngine::doneRunning, workerThread, &QThread::quit);
|
||||||
connect(this, &QObject::destroyed, workerThread, &QObject::deleteLater);
|
connect(workerThread, &QThread::finished, workerThread, &QObject::deleteLater);
|
||||||
|
|
||||||
workerThread->start();
|
workerThread->start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ const glm::quat DEFAULT_AVATAR_RIGHTFOOT_ROT { -0.4016716778278351f, 0.915461599
|
||||||
const float DEFAULT_AVATAR_MAX_WALKING_SPEED = 2.6f; // meters / second
|
const float DEFAULT_AVATAR_MAX_WALKING_SPEED = 2.6f; // meters / second
|
||||||
const float DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.2f; // meters / second
|
const float DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.2f; // meters / second
|
||||||
const float DEFAULT_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second
|
const float DEFAULT_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second
|
||||||
|
const float DEFAULT_AVATAR_WALK_SPEED_THRESHOLD = 0.15f;
|
||||||
|
|
||||||
const float DEFAULT_AVATAR_GRAVITY = -5.0f; // meters / second^2
|
const float DEFAULT_AVATAR_GRAVITY = -5.0f; // meters / second^2
|
||||||
const float DEFAULT_AVATAR_JUMP_SPEED = 3.5f; // meters / second
|
const float DEFAULT_AVATAR_JUMP_SPEED = 3.5f; // meters / second
|
||||||
|
|
|
@ -8,24 +8,7 @@
|
||||||
|
|
||||||
#include "NestableTransformNode.h"
|
#include "NestableTransformNode.h"
|
||||||
|
|
||||||
NestableTransformNode::NestableTransformNode(SpatiallyNestableWeakPointer spatiallyNestable, int jointIndex) :
|
template<>
|
||||||
_spatiallyNestable(spatiallyNestable),
|
glm::vec3 BaseNestableTransformNode<SpatiallyNestable>::getActualScale(const std::shared_ptr<SpatiallyNestable>& nestablePointer) const {
|
||||||
_jointIndex(jointIndex)
|
return nestablePointer->getAbsoluteJointScaleInObjectFrame(_jointIndex);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform NestableTransformNode::getTransform() {
|
|
||||||
auto nestable = _spatiallyNestable.lock();
|
|
||||||
if (!nestable) {
|
|
||||||
return Transform();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success;
|
|
||||||
Transform jointWorldTransform = nestable->getTransform(_jointIndex, success);
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
return jointWorldTransform;
|
|
||||||
} else {
|
|
||||||
return Transform();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -12,14 +12,48 @@
|
||||||
|
|
||||||
#include "SpatiallyNestable.h"
|
#include "SpatiallyNestable.h"
|
||||||
|
|
||||||
class NestableTransformNode : public TransformNode {
|
template <typename T>
|
||||||
|
class BaseNestableTransformNode : public TransformNode {
|
||||||
public:
|
public:
|
||||||
NestableTransformNode(SpatiallyNestableWeakPointer spatiallyNestable, int jointIndex);
|
BaseNestableTransformNode(std::weak_ptr<T> spatiallyNestable, int jointIndex) :
|
||||||
Transform getTransform() override;
|
_spatiallyNestable(spatiallyNestable),
|
||||||
|
_jointIndex(jointIndex) {
|
||||||
|
auto nestablePointer = _spatiallyNestable.lock();
|
||||||
|
if (nestablePointer) {
|
||||||
|
glm::vec3 nestableDimensions = getActualScale(nestablePointer);
|
||||||
|
_baseScale = glm::max(glm::vec3(0.001f), nestableDimensions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform getTransform() override {
|
||||||
|
std::shared_ptr<T> nestable = _spatiallyNestable.lock();
|
||||||
|
if (!nestable) {
|
||||||
|
return Transform();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success;
|
||||||
|
Transform jointWorldTransform = nestable->getTransform(_jointIndex, success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return Transform();
|
||||||
|
}
|
||||||
|
|
||||||
|
jointWorldTransform.setScale(getActualScale(nestable) / _baseScale);
|
||||||
|
|
||||||
|
return jointWorldTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getActualScale(const std::shared_ptr<T>& nestablePointer) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SpatiallyNestableWeakPointer _spatiallyNestable;
|
std::weak_ptr<T> _spatiallyNestable;
|
||||||
int _jointIndex;
|
int _jointIndex;
|
||||||
|
glm::vec3 _baseScale { 1.0f };
|
||||||
|
};
|
||||||
|
|
||||||
|
class NestableTransformNode : public BaseNestableTransformNode<SpatiallyNestable> {
|
||||||
|
public:
|
||||||
|
NestableTransformNode(std::weak_ptr<SpatiallyNestable> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_NestableTransformNode_h
|
#endif // hifi_NestableTransformNode_h
|
|
@ -259,10 +259,11 @@ public:
|
||||||
* A CollisionRegion defines a volume for checking collisions in the physics simulation.
|
* A CollisionRegion defines a volume for checking collisions in the physics simulation.
|
||||||
|
|
||||||
* @typedef {object} CollisionRegion
|
* @typedef {object} CollisionRegion
|
||||||
* @property {Shape} shape - The information about the collision region's size and shape.
|
* @property {Shape} shape - The information about the collision region's size and shape. Dimensions are in world space, but will scale with the parent if defined.
|
||||||
* @property {Vec3} position - The position of the collision region, relative to a parent if defined.
|
* @property {Vec3} position - The position of the collision region, relative to a parent if defined.
|
||||||
* @property {Quat} orientation - The orientation of the collision region, relative to a parent if defined.
|
* @property {Quat} orientation - The orientation of the collision region, relative to a parent if defined.
|
||||||
* @property {float} threshold - The approximate minimum penetration depth for a test object to be considered in contact with the collision region.
|
* @property {float} threshold - The approximate minimum penetration depth for a test object to be considered in contact with the collision region.
|
||||||
|
* The depth is measured in world space, but will scale with the parent if defined.
|
||||||
* @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay.
|
* @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay.
|
||||||
* @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint)
|
* @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint)
|
||||||
* @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar.
|
* @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar.
|
||||||
|
|
|
@ -23,7 +23,7 @@ if (scripts.length >= 2) {
|
||||||
var qml = Script.resolvePath('debugWindow.qml');
|
var qml = Script.resolvePath('debugWindow.qml');
|
||||||
|
|
||||||
var HMD_DEBUG_WINDOW_GEOMETRY_KEY = 'hmdDebugWindowGeometry';
|
var HMD_DEBUG_WINDOW_GEOMETRY_KEY = 'hmdDebugWindowGeometry';
|
||||||
var hmdDebugWindowGeometryValue = Settings.getValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY)
|
var hmdDebugWindowGeometryValue = Settings.getValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY);
|
||||||
|
|
||||||
var windowWidth = 400;
|
var windowWidth = 400;
|
||||||
var windowHeight = 900;
|
var windowHeight = 900;
|
||||||
|
@ -34,12 +34,13 @@ var windowY = 0;
|
||||||
|
|
||||||
if (hmdDebugWindowGeometryValue !== '') {
|
if (hmdDebugWindowGeometryValue !== '') {
|
||||||
var geometry = JSON.parse(hmdDebugWindowGeometryValue);
|
var geometry = JSON.parse(hmdDebugWindowGeometryValue);
|
||||||
|
if ((geometry.x !== 0) && (geometry.y !== 0)) {
|
||||||
windowWidth = geometry.width
|
windowWidth = geometry.width;
|
||||||
windowHeight = geometry.height
|
windowHeight = geometry.height;
|
||||||
windowX = geometry.x
|
windowX = geometry.x;
|
||||||
windowY = geometry.y
|
windowY = geometry.y;
|
||||||
hasPosition = true;
|
hasPosition = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var window = new OverlayWindow({
|
var window = new OverlayWindow({
|
||||||
|
@ -52,6 +53,12 @@ if (hasPosition) {
|
||||||
window.setPosition(windowX, windowY);
|
window.setPosition(windowX, windowY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.visibleChanged.connect(function() {
|
||||||
|
if (!window.visible) {
|
||||||
|
window.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.closed.connect(function () { Script.stop(); });
|
window.closed.connect(function () { Script.stop(); });
|
||||||
|
|
||||||
var getFormattedDate = function() {
|
var getFormattedDate = function() {
|
||||||
|
@ -93,10 +100,10 @@ Script.scriptEnding.connect(function () {
|
||||||
y: window.position.y,
|
y: window.position.y,
|
||||||
width: window.size.x,
|
width: window.size.x,
|
||||||
height: window.size.y
|
height: window.size.y
|
||||||
})
|
});
|
||||||
|
|
||||||
Settings.setValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY, geometry);
|
Settings.setValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY, geometry);
|
||||||
window.close();
|
window.close();
|
||||||
})
|
});
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -1739,7 +1739,6 @@ function getPositionToCreateEntity(extra) {
|
||||||
position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getForward(Camera.orientation), CREATE_DISTANCE + delta));
|
position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getForward(Camera.orientation), CREATE_DISTANCE + delta));
|
||||||
} else {
|
} else {
|
||||||
position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getForward(MyAvatar.orientation), CREATE_DISTANCE + delta));
|
position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getForward(MyAvatar.orientation), CREATE_DISTANCE + delta));
|
||||||
position.y += 0.5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) {
|
if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) {
|
||||||
|
|
|
@ -125,6 +125,9 @@ module.exports = (function() {
|
||||||
|
|
||||||
Script.scriptEnding.connect(this, function() {
|
Script.scriptEnding.connect(this, function() {
|
||||||
this.window.close();
|
this.window.close();
|
||||||
|
// FIXME: temp solution for reload crash (MS18269),
|
||||||
|
// we should decide on proper object ownership strategy for InteractiveWindow API
|
||||||
|
this.window = null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setVisible: function(visible) {
|
setVisible: function(visible) {
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stories[story.id] = story;
|
stories[story.id] = story;
|
||||||
var message = story.username + " says something is happening in " + story.place_name + ". Open GOTO to join them.";
|
var message = story.username + " " + story.action_string + " in " + story.place_name + ". Open GOTO to join them.";
|
||||||
Window.displayAnnouncement(message);
|
Window.displayAnnouncement(message);
|
||||||
didNotify = true;
|
didNotify = true;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue