diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index c9af474949..0ef2db3b9d 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -7,6 +7,8 @@ if (APPLE) set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH "@executable_path/../Frameworks") endif () +setup_memory_debugger() + # link in the shared libraries link_hifi_libraries( audio avatars octree gpu model fbx entities diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 260a6d6825..8aec5adb1f 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -62,7 +62,7 @@ Agent::Agent(ReceivedMessage& message) : _entityEditSender.setPacketsPerSecond(DEFAULT_ENTITY_PPS_PER_SCRIPT); DependencyManager::get()->setPacketSender(&_entityEditSender); - ResourceManager::init(); + DependencyManager::set(); DependencyManager::registerInheritance(); @@ -199,7 +199,7 @@ void Agent::requestScript() { return; } - auto request = ResourceManager::createResourceRequest(this, scriptURL); + auto request = DependencyManager::get()->createResourceRequest(this, scriptURL); if (!request) { qWarning() << "Could not create ResourceRequest for Agent script at" << scriptURL.toString(); @@ -779,7 +779,7 @@ void Agent::aboutToFinish() { // our entity tree is going to go away so tell that to the EntityScriptingInterface DependencyManager::get()->setEntityTree(nullptr); - ResourceManager::cleanup(); + DependencyManager::get()->cleanup(); // cleanup the AudioInjectorManager (and any still running injectors) DependencyManager::destroy(); diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 7e9042e609..bd656ceb09 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -9,8 +9,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include -#include +#include "AssignmentClientApp.h" + +#include +#include +#include +#include #include #include @@ -20,10 +24,6 @@ #include "Assignment.h" #include "AssignmentClient.h" #include "AssignmentClientMonitor.h" -#include "AssignmentClientApp.h" -#include -#include - AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : QCoreApplication(argc, argv) @@ -87,6 +87,9 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : const QCommandLineOption logDirectoryOption(ASSIGNMENT_LOG_DIRECTORY, "directory to store logs", "log-directory"); parser.addOption(logDirectoryOption); + const QCommandLineOption parentPIDOption(PARENT_PID_OPTION, "PID of the parent process", "parent-pid"); + parser.addOption(parentPIDOption); + if (!parser.parse(QCoreApplication::arguments())) { qCritical() << parser.errorText() << endl; parser.showHelp(); @@ -203,6 +206,16 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : } } + if (parser.isSet(parentPIDOption)) { + bool ok = false; + int parentPID = parser.value(parentPIDOption).toInt(&ok); + + if (ok) { + qDebug() << "Parent process PID is" << parentPID; + watchParentProcess(parentPID); + } + } + QThread::currentThread()->setObjectName("main thread"); DependencyManager::registerInheritance(); diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 1ee876ceea..070034d54b 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -131,7 +131,6 @@ void AssignmentClientMonitor::aboutToQuit() { void AssignmentClientMonitor::spawnChildClient() { QProcess* assignmentClient = new QProcess(this); - // unparse the parts of the command-line that the child cares about QStringList _childArguments; if (_assignmentPool != "") { @@ -160,6 +159,9 @@ void AssignmentClientMonitor::spawnChildClient() { _childArguments.append("--" + ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION); _childArguments.append(QString::number(DependencyManager::get()->getLocalSockAddr().getPort())); + _childArguments.append("--" + PARENT_PID_OPTION); + _childArguments.append(QString::number(QCoreApplication::applicationPid())); + QString nowString, stdoutFilenameTemp, stderrFilenameTemp, stdoutPathTemp, stderrPathTemp; diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index 2d800c3561..ed63bbc298 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -497,13 +497,14 @@ float computeGain(const AvatarAudioStream& listeningNodeStream, const Positional // avatar: apply fixed off-axis attenuation to make them quieter as they turn away } else if (!isEcho && (streamToAdd.getType() == PositionalAudioStream::Microphone)) { glm::vec3 rotatedListenerPosition = glm::inverse(streamToAdd.getOrientation()) * relativePosition; - float angleOfDelivery = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f), - glm::normalize(rotatedListenerPosition)); + + // source directivity is based on angle of emission, in local coordinates + glm::vec3 direction = glm::normalize(rotatedListenerPosition); + float angleOfDelivery = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" const float MAX_OFF_AXIS_ATTENUATION = 0.2f; const float OFF_AXIS_ATTENUATION_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f; - float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + - (angleOfDelivery * (OFF_AXIS_ATTENUATION_STEP / PI_OVER_TWO)); + float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + (angleOfDelivery * (OFF_AXIS_ATTENUATION_STEP / PI_OVER_TWO)); gain *= offAxisCoefficient; } @@ -545,7 +546,6 @@ float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const Positio const glm::vec3& relativePosition) { glm::quat inverseOrientation = glm::inverse(listeningNodeStream.getOrientation()); - // Compute sample delay for the two ears to create phase panning glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition; // project the rotated source position vector onto the XZ plane @@ -553,11 +553,16 @@ float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const Positio const float SOURCE_DISTANCE_THRESHOLD = 1e-30f; - if (glm::length2(rotatedSourcePosition) > SOURCE_DISTANCE_THRESHOLD) { + float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition); + if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) { + // produce an oriented angle about the y-axis - return glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), glm::normalize(rotatedSourcePosition), glm::vec3(0.0f, -1.0f, 0.0f)); - } else { - // there is no distance between listener and source - return no azimuth - return 0; + glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2)); + float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" + return (direction.x < 0.0f) ? -angle : angle; + + } else { + // no azimuth if they are in same spot + return 0.0f; } } diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 3a5116a2e9..b4aae40c10 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -229,7 +229,7 @@ void AvatarMixer::start() { auto start = usecTimestampNow(); nodeList->nestedEach([&](NodeList::const_iterator cbegin, NodeList::const_iterator cend) { std::for_each(cbegin, cend, [&](const SharedNodePointer& node) { - if (node->getType() == NodeType::Agent && !node->isUpstream()) { + if (node->getType() == NodeType::Agent) { manageIdentityData(node); } @@ -285,6 +285,13 @@ void AvatarMixer::start() { // is guaranteed to not be accessed by other thread void AvatarMixer::manageIdentityData(const SharedNodePointer& node) { AvatarMixerClientData* nodeData = reinterpret_cast(node->getLinkedData()); + + // there is no need to manage identity data we haven't received yet + // so bail early if we've never received an identity packet for this avatar + if (!nodeData || !nodeData->getAvatar().hasProcessedFirstIdentity()) { + return; + } + bool sendIdentity = false; if (nodeData && nodeData->getAvatarSessionDisplayNameMustChange()) { AvatarData& avatar = nodeData->getAvatar(); @@ -325,8 +332,8 @@ void AvatarMixer::manageIdentityData(const SharedNodePointer& node) { sendIdentity = true; } } - if (sendIdentity) { - + if (sendIdentity && !node->isUpstream()) { + sendIdentityPacket(nodeData, node); // Tell node whose name changed about its new session display name or avatar. // since this packet includes a change to either the skeleton model URL or the display name // it needs a new sequence number nodeData->getAvatar().pushIdentitySequenceNumber(); diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index bbf68f0e22..7e37f583ff 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -81,7 +81,7 @@ int AvatarMixerSlave::sendIdentityPacket(const AvatarMixerClientData* nodeData, int AvatarMixerSlave::sendReplicatedIdentityPacket(const Node& agentNode, const AvatarMixerClientData* nodeData, const Node& destinationNode) { if (AvatarMixer::shouldReplicateTo(agentNode, destinationNode)) { - QByteArray individualData = nodeData->getConstAvatarData()->identityByteArray(); + QByteArray individualData = nodeData->getConstAvatarData()->identityByteArray(true); individualData.replace(0, NUM_BYTES_RFC4122_UUID, nodeData->getNodeID().toRfc4122()); // FIXME, this looks suspicious auto identityPacket = NLPacketList::create(PacketType::ReplicatedAvatarIdentity, QByteArray(), true, true); identityPacket->write(individualData); @@ -320,14 +320,18 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) ++numOtherAvatars; const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); + const AvatarData* otherAvatar = otherNodeData->getConstAvatarData(); // If the time that the mixer sent AVATAR DATA about Avatar B to Avatar A is BEFORE OR EQUAL TO // the time that Avatar B flagged an IDENTITY DATA change, send IDENTITY DATA about Avatar B to Avatar A. - if (nodeData->getLastBroadcastTime(otherNode->getUUID()) <= otherNodeData->getIdentityChangeTimestamp()) { + if (otherAvatar->hasProcessedFirstIdentity() + && nodeData->getLastBroadcastTime(otherNode->getUUID()) <= otherNodeData->getIdentityChangeTimestamp()) { identityBytesSent += sendIdentityPacket(otherNodeData, node); + + // remember the last time we sent identity details about this other node to the receiver + nodeData->setLastBroadcastTime(otherNode->getUUID(), usecTimestampNow()); } - const AvatarData* otherAvatar = otherNodeData->getConstAvatarData(); glm::vec3 otherPosition = otherAvatar->getClientGlobalPosition(); // determine if avatar is in view, to determine how much data to include... @@ -400,9 +404,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // set the last sent sequence number for this sender on the receiver nodeData->setLastBroadcastSequenceNumber(otherNode->getUUID(), otherNodeData->getLastReceivedSequenceNumber()); - - // remember the last time we sent details about this other node to the receiver - nodeData->setLastBroadcastTime(otherNode->getUUID(), start); } } diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index dc0a2add3a..ac686e2e0a 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -31,7 +31,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : OctreeServer(message), _entitySimulation(NULL) { - ResourceManager::init(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 1b226ab642..489478ff9a 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -54,7 +54,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig DependencyManager::get()->setPacketSender(&_entityEditSender); - ResourceManager::init(); + DependencyManager::set(); DependencyManager::registerInheritance(); @@ -67,7 +67,6 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig DependencyManager::set(); DependencyManager::set(ScriptEngine::ENTITY_SERVER_SCRIPT); - auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, this, "handleOctreePacket"); @@ -493,7 +492,7 @@ void EntityScriptServer::checkAndCallPreload(const EntityItemID& entityID, bool if (entity && (reload || notRunning || details.scriptText != entity->getServerScripts())) { QString scriptUrl = entity->getServerScripts(); if (!scriptUrl.isEmpty()) { - scriptUrl = ResourceManager::normalizeURL(scriptUrl); + scriptUrl = DependencyManager::get()->normalizeURL(scriptUrl); qCDebug(entity_script_server) << "Loading entity server script" << scriptUrl << "for" << entityID; _entitiesScriptEngine->loadEntityScript(entityID, scriptUrl, reload); } @@ -551,7 +550,7 @@ void EntityScriptServer::aboutToFinish() { // our entity tree is going to go away so tell that to the EntityScriptingInterface DependencyManager::get()->setEntityTree(nullptr); - ResourceManager::cleanup(); + DependencyManager::get()->cleanup(); // cleanup the AudioInjectorManager (and any still running injectors) DependencyManager::destroy(); diff --git a/cmake/macros/TargetLeapMotion.cmake b/cmake/macros/TargetLeapMotion.cmake new file mode 100644 index 0000000000..674ec8f62d --- /dev/null +++ b/cmake/macros/TargetLeapMotion.cmake @@ -0,0 +1,12 @@ +# +# Created by David Rowe on 16 Jun 2017. +# Copyright 2017 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 +# + +macro(TARGET_LEAPMOTION) + target_include_directories(${TARGET_NAME} PRIVATE ${LEAPMOTION_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${LEAPMOTION_LIBRARIES}) +endmacro() diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 2ce537a5a0..c1e275e4d3 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -14,6 +14,8 @@ if (APPLE) set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH "@executable_path/../Frameworks") endif () +setup_memory_debugger() + # TODO: find a solution that will handle web file changes in resources on windows without a re-build. # Currently the resources are only copied on post-build. If one is changed but the domain-server is not, they will # not be re-copied. This is worked-around on OS X/UNIX by using a symlink. diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index c19cefa397..eee5673af3 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -171,7 +171,7 @@ void DomainMetadata::maybeUpdateUsers() { if (linkedData) { auto nodeData = static_cast(linkedData); - if (!nodeData->wasAssigned()) { + if (!nodeData->wasAssigned() && node->getType() == NodeType::Agent) { ++numConnected; if (nodeData->getUsername().isEmpty()) { diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 8e3d04897b..095613a473 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -221,6 +221,8 @@ void DomainServer::parseCommandLine() { const QCommandLineOption masterConfigOption("master-config", "Deprecated config-file option"); parser.addOption(masterConfigOption); + const QCommandLineOption parentPIDOption(PARENT_PID_OPTION, "PID of the parent process", "parent-pid"); + parser.addOption(parentPIDOption); if (!parser.parse(QCoreApplication::arguments())) { qWarning() << parser.errorText() << endl; @@ -249,6 +251,17 @@ void DomainServer::parseCommandLine() { _overrideDomainID = true; qDebug() << "domain-server ID is" << _overridingDomainID; } + + + if (parser.isSet(parentPIDOption)) { + bool ok = false; + int parentPID = parser.value(parentPIDOption).toInt(&ok); + + if (ok) { + qDebug() << "Parent process PID is" << parentPID; + watchParentProcess(parentPID); + } + } } DomainServer::~DomainServer() { diff --git a/ice-server/CMakeLists.txt b/ice-server/CMakeLists.txt index e5bdffe2e2..07b90b369e 100644 --- a/ice-server/CMakeLists.txt +++ b/ice-server/CMakeLists.txt @@ -18,5 +18,7 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") +setup_memory_debugger() + # append OpenSSL to our list of libraries to link target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES}) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 71341f3f11..dcb1cacef9 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -4,6 +4,8 @@ project(${TARGET_NAME}) # set a default root dir for each of our optional externals if it was not passed set(OPTIONAL_EXTERNALS "LeapMotion") +setup_memory_debugger() + foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) diff --git a/interface/external/leapmotion/readme.txt b/interface/external/leapmotion/readme.txt index 51a65caf22..97502d694c 100644 --- a/interface/external/leapmotion/readme.txt +++ b/interface/external/leapmotion/readme.txt @@ -10,7 +10,7 @@ Interface has been tested with SDK versions: 1. Copy the LeapSDK folders from the LeapDeveloperKit installation directory (Lib, Include) into the interface/externals/leapmotion folder. This readme.txt should be there as well. - The files neeeded in the folders are: + The files needed in the folders are: include/ - Leap.h @@ -21,8 +21,8 @@ Interface has been tested with SDK versions: x86/ - Leap.dll - Leap.lib - - mscvcp120.dll (optional if you already have the Msdev 2012 SDK redistriuable installed) - - mscvcr120.dll (optional if you already have the Msdev 2012 SDK redistriuable installed) + - mscvcp120.dll (optional if you already have the Msdev 2012 SDK redistributable installed) + - mscvcr120.dll (optional if you already have the Msdev 2012 SDK redistributable installed) - lipLeap.dylib libc++/ -libLeap.dylib @@ -30,4 +30,4 @@ Interface has been tested with SDK versions: You may optionally choose to copy the SDK folders to a location outside the repository (so you can re-use with different checkouts and different projects). If so our CMake find module expects you to set the ENV variable 'HIFI_LIB_DIR' to a directory containing a subfolder 'leapmotion' that contains the 2 folders mentioned above (Include, Lib). -2. Clear your build directory, run cmake and build, and you should be all set. \ No newline at end of file +2. Clear your build directory, run cmake and build, and you should be all set. diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 1412b45968..a493d8e9af 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -68,7 +68,10 @@ "typeVar": "rightHandType", "weightVar": "rightHandWeight", "weight": 1.0, - "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0] + "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0], + "poleVectorEnabledVar": "rightHandPoleVectorEnabled", + "poleReferenceVectorVar": "rightHandPoleReferenceVector", + "poleVectorVar": "rightHandPoleVector" }, { "jointName": "LeftHand", @@ -77,7 +80,10 @@ "typeVar": "leftHandType", "weightVar": "leftHandWeight", "weight": 1.0, - "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0] + "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0], + "poleVectorEnabledVar": "leftHandPoleVectorEnabled", + "poleReferenceVectorVar": "leftHandPoleReferenceVector", + "poleVectorVar": "leftHandPoleVector" }, { "jointName": "RightFoot", @@ -86,7 +92,10 @@ "typeVar": "rightFootType", "weightVar": "rightFootWeight", "weight": 1.0, - "flexCoefficients": [1, 0.45, 0.45] + "flexCoefficients": [1, 0.45, 0.45], + "poleVectorEnabledVar": "rightFootPoleVectorEnabled", + "poleReferenceVectorVar": "rightFootPoleReferenceVector", + "poleVectorVar": "rightFootPoleVector" }, { "jointName": "LeftFoot", @@ -95,7 +104,10 @@ "typeVar": "leftFootType", "weightVar": "leftFootWeight", "weight": 1.0, - "flexCoefficients": [1, 0.45, 0.45] + "flexCoefficients": [1, 0.45, 0.45], + "poleVectorEnabledVar": "leftFootPoleVectorEnabled", + "poleReferenceVectorVar": "leftFootPoleReferenceVector", + "poleVectorVar": "leftFootPoleVector" }, { "jointName": "Spine2", @@ -138,28 +150,19 @@ "children": [] }, { - "id": "hipsManipulatorOverlay", + "id": "defaultPoseOverlay", "type": "overlay", "data": { "alpha": 0.0, - "boneSet": "hipsOnly" + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" }, "children": [ { - "id": "hipsManipulator", - "type": "manipulator", + "id": "defaultPose", + "type": "defaultPose", "data": { - "alpha": 0.0, - "alphaVar": "hipsManipulatorAlpha", - "joints": [ - { - "jointName": "Hips", - "rotationType": "absolute", - "translationType": "absolute", - "rotationVar": "hipsManipulatorRotation", - "translationVar": "hipsManipulatorPosition" - } - ] }, "children": [] }, diff --git a/interface/resources/controllers/leapmotion.json b/interface/resources/controllers/leapmotion.json new file mode 100644 index 0000000000..25cb575946 --- /dev/null +++ b/interface/resources/controllers/leapmotion.json @@ -0,0 +1,48 @@ +{ + "name": "Leap Motion to Standard", + "channels": [ + { "from": "LeapMotion.LeftHand", "to": "Standard.LeftHand" }, + { "from": "LeapMotion.LeftHandThumb1", "to": "Standard.LeftHandThumb1"}, + { "from": "LeapMotion.LeftHandThumb2", "to": "Standard.LeftHandThumb2"}, + { "from": "LeapMotion.LeftHandThumb3", "to": "Standard.LeftHandThumb3"}, + { "from": "LeapMotion.LeftHandThumb4", "to": "Standard.LeftHandThumb4"}, + { "from": "LeapMotion.LeftHandIndex1", "to": "Standard.LeftHandIndex1"}, + { "from": "LeapMotion.LeftHandIndex2", "to": "Standard.LeftHandIndex2"}, + { "from": "LeapMotion.LeftHandIndex3", "to": "Standard.LeftHandIndex3"}, + { "from": "LeapMotion.LeftHandIndex4", "to": "Standard.LeftHandIndex4"}, + { "from": "LeapMotion.LeftHandMiddle1", "to": "Standard.LeftHandMiddle1"}, + { "from": "LeapMotion.LeftHandMiddle2", "to": "Standard.LeftHandMiddle2"}, + { "from": "LeapMotion.LeftHandMiddle3", "to": "Standard.LeftHandMiddle3"}, + { "from": "LeapMotion.LeftHandMiddle4", "to": "Standard.LeftHandMiddle4"}, + { "from": "LeapMotion.LeftHandRing1", "to": "Standard.LeftHandRing1"}, + { "from": "LeapMotion.LeftHandRing2", "to": "Standard.LeftHandRing2"}, + { "from": "LeapMotion.LeftHandRing3", "to": "Standard.LeftHandRing3"}, + { "from": "LeapMotion.LeftHandRing4", "to": "Standard.LeftHandRing4"}, + { "from": "LeapMotion.LeftHandPinky1", "to": "Standard.LeftHandPinky1"}, + { "from": "LeapMotion.LeftHandPinky2", "to": "Standard.LeftHandPinky2"}, + { "from": "LeapMotion.LeftHandPinky3", "to": "Standard.LeftHandPinky3"}, + { "from": "LeapMotion.LeftHandPinky4", "to": "Standard.LeftHandPinky4"}, + + { "from": "LeapMotion.RightHand", "to": "Standard.RightHand" }, + { "from": "LeapMotion.RightHandThumb1", "to": "Standard.RightHandThumb1"}, + { "from": "LeapMotion.RightHandThumb2", "to": "Standard.RightHandThumb2"}, + { "from": "LeapMotion.RightHandThumb3", "to": "Standard.RightHandThumb3"}, + { "from": "LeapMotion.RightHandThumb4", "to": "Standard.RightHandThumb4"}, + { "from": "LeapMotion.RightHandIndex1", "to": "Standard.RightHandIndex1"}, + { "from": "LeapMotion.RightHandIndex2", "to": "Standard.RightHandIndex2"}, + { "from": "LeapMotion.RightHandIndex3", "to": "Standard.RightHandIndex3"}, + { "from": "LeapMotion.RightHandIndex4", "to": "Standard.RightHandIndex4"}, + { "from": "LeapMotion.RightHandMiddle1", "to": "Standard.RightHandMiddle1"}, + { "from": "LeapMotion.RightHandMiddle2", "to": "Standard.RightHandMiddle2"}, + { "from": "LeapMotion.RightHandMiddle3", "to": "Standard.RightHandMiddle3"}, + { "from": "LeapMotion.RightHandMiddle4", "to": "Standard.RightHandMiddle4"}, + { "from": "LeapMotion.RightHandRing1", "to": "Standard.RightHandRing1"}, + { "from": "LeapMotion.RightHandRing2", "to": "Standard.RightHandRing2"}, + { "from": "LeapMotion.RightHandRing3", "to": "Standard.RightHandRing3"}, + { "from": "LeapMotion.RightHandRing4", "to": "Standard.RightHandRing4"}, + { "from": "LeapMotion.RightHandPinky1", "to": "Standard.RightHandPinky1"}, + { "from": "LeapMotion.RightHandPinky2", "to": "Standard.RightHandPinky2"}, + { "from": "LeapMotion.RightHandPinky3", "to": "Standard.RightHandPinky3"}, + { "from": "LeapMotion.RightHandPinky4", "to": "Standard.RightHandPinky4"} + ] +} diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json index 75b4821118..166f1a6869 100644 --- a/interface/resources/controllers/standard.json +++ b/interface/resources/controllers/standard.json @@ -58,7 +58,48 @@ { "from": "Standard.RT", "to": "Actions.RightHandClick" }, { "from": "Standard.LeftHand", "to": "Actions.LeftHand" }, + { "from": "Standard.LeftHandThumb1", "to": "Actions.LeftHandThumb1"}, + { "from": "Standard.LeftHandThumb2", "to": "Actions.LeftHandThumb2"}, + { "from": "Standard.LeftHandThumb3", "to": "Actions.LeftHandThumb3"}, + { "from": "Standard.LeftHandThumb4", "to": "Actions.LeftHandThumb4"}, + { "from": "Standard.LeftHandIndex1", "to": "Actions.LeftHandIndex1"}, + { "from": "Standard.LeftHandIndex2", "to": "Actions.LeftHandIndex2"}, + { "from": "Standard.LeftHandIndex3", "to": "Actions.LeftHandIndex3"}, + { "from": "Standard.LeftHandIndex4", "to": "Actions.LeftHandIndex4"}, + { "from": "Standard.LeftHandMiddle1", "to": "Actions.LeftHandMiddle1"}, + { "from": "Standard.LeftHandMiddle2", "to": "Actions.LeftHandMiddle2"}, + { "from": "Standard.LeftHandMiddle3", "to": "Actions.LeftHandMiddle3"}, + { "from": "Standard.LeftHandMiddle4", "to": "Actions.LeftHandMiddle4"}, + { "from": "Standard.LeftHandRing1", "to": "Actions.LeftHandRing1"}, + { "from": "Standard.LeftHandRing2", "to": "Actions.LeftHandRing2"}, + { "from": "Standard.LeftHandRing3", "to": "Actions.LeftHandRing3"}, + { "from": "Standard.LeftHandRing4", "to": "Actions.LeftHandRing4"}, + { "from": "Standard.LeftHandPinky1", "to": "Actions.LeftHandPinky1"}, + { "from": "Standard.LeftHandPinky2", "to": "Actions.LeftHandPinky2"}, + { "from": "Standard.LeftHandPinky3", "to": "Actions.LeftHandPinky3"}, + { "from": "Standard.LeftHandPinky4", "to": "Actions.LeftHandPinky4"}, + { "from": "Standard.RightHand", "to": "Actions.RightHand" }, + { "from": "Standard.RightHandThumb1", "to": "Actions.RightHandThumb1"}, + { "from": "Standard.RightHandThumb2", "to": "Actions.RightHandThumb2"}, + { "from": "Standard.RightHandThumb3", "to": "Actions.RightHandThumb3"}, + { "from": "Standard.RightHandThumb4", "to": "Actions.RightHandThumb4"}, + { "from": "Standard.RightHandIndex1", "to": "Actions.RightHandIndex1"}, + { "from": "Standard.RightHandIndex2", "to": "Actions.RightHandIndex2"}, + { "from": "Standard.RightHandIndex3", "to": "Actions.RightHandIndex3"}, + { "from": "Standard.RightHandIndex4", "to": "Actions.RightHandIndex4"}, + { "from": "Standard.RightHandMiddle1", "to": "Actions.RightHandMiddle1"}, + { "from": "Standard.RightHandMiddle2", "to": "Actions.RightHandMiddle2"}, + { "from": "Standard.RightHandMiddle3", "to": "Actions.RightHandMiddle3"}, + { "from": "Standard.RightHandMiddle4", "to": "Actions.RightHandMiddle4"}, + { "from": "Standard.RightHandRing1", "to": "Actions.RightHandRing1"}, + { "from": "Standard.RightHandRing2", "to": "Actions.RightHandRing2"}, + { "from": "Standard.RightHandRing3", "to": "Actions.RightHandRing3"}, + { "from": "Standard.RightHandRing4", "to": "Actions.RightHandRing4"}, + { "from": "Standard.RightHandPinky1", "to": "Actions.RightHandPinky1"}, + { "from": "Standard.RightHandPinky2", "to": "Actions.RightHandPinky2"}, + { "from": "Standard.RightHandPinky3", "to": "Actions.RightHandPinky3"}, + { "from": "Standard.RightHandPinky4", "to": "Actions.RightHandPinky4"}, { "from": "Standard.LeftFoot", "to": "Actions.LeftFoot" }, { "from": "Standard.RightFoot", "to": "Actions.RightFoot" }, diff --git a/interface/resources/qml/controls-uit/ComboBox.qml b/interface/resources/qml/controls-uit/ComboBox.qml index 3ce297ef80..d672fa6387 100644 --- a/interface/resources/qml/controls-uit/ComboBox.qml +++ b/interface/resources/qml/controls-uit/ComboBox.qml @@ -217,7 +217,7 @@ FocusScope { anchors.leftMargin: hifi.dimensions.textPadding anchors.verticalCenter: parent.verticalCenter id: popupText - text: listView.model[index] ? listView.model[index] : (listView.model.get(index).text ? listView.model.get(index).text : "") + text: listView.model[index] ? listView.model[index] : (listView.model.get && listView.model.get(index).text ? listView.model.get(index).text : "") size: hifi.fontSizes.textFieldInput color: hifi.colors.baseGray } diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 0886a25949..106e067968 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -34,6 +34,8 @@ ModalWindow { HifiConstants { id: hifi } + property var filesModel: ListModel { } + Settings { category: "FileDialog" property alias width: root.width @@ -253,7 +255,9 @@ ModalWindow { } currentSelectionUrl = helper.pathToUrl(fileTableView.model.get(row).filePath); - currentSelectionIsFolder = fileTableView.model.isFolder(row); + currentSelectionIsFolder = fileTableView.model !== filesModel ? + fileTableView.model.isFolder(row) : + fileTableModel.isFolder(row); if (root.selectDirectory || !currentSelectionIsFolder) { currentSelection.text = capitalizeDrive(helper.urlToPath(currentSelectionUrl)); } else { @@ -331,7 +335,12 @@ ModalWindow { } } - ListModel { + Component { + id: filesModelBuilder + ListModel { } + } + + QtObject { id: fileTableModel // FolderListModel has a couple of problems: @@ -383,7 +392,11 @@ ModalWindow { if (row === -1) { return false; } - return get(row).fileIsDir; + return filesModel.get(row).fileIsDir; + } + + function get(row) { + return filesModel.get(row) } function update() { @@ -401,7 +414,7 @@ ModalWindow { rows = 0, i; - clear(); + var newFilesModel = filesModelBuilder.createObject(root); comparisonFunction = sortOrder === Qt.AscendingOrder ? function(a, b) { return a < b; } @@ -423,7 +436,7 @@ ModalWindow { while (lower < upper) { middle = Math.floor((lower + upper) / 2); var lessThan; - if (comparisonFunction(sortValue, get(middle)[sortField])) { + if (comparisonFunction(sortValue, newFilesModel.get(middle)[sortField])) { lessThan = true; upper = middle; } else { @@ -432,7 +445,7 @@ ModalWindow { } } - insert(lower, { + newFilesModel.insert(lower, { fileName: fileName, fileModified: (fileIsDir ? new Date(0) : model.getItem(i, "fileModified")), fileSize: model.getItem(i, "fileSize"), @@ -443,6 +456,7 @@ ModalWindow { rows++; } + filesModel = newFilesModel; d.clearSelection(); } @@ -469,7 +483,7 @@ ModalWindow { sortIndicatorOrder: Qt.AscendingOrder sortIndicatorVisible: true - model: fileTableModel + model: filesModel function updateSort() { model.sortOrder = sortIndicatorOrder; @@ -561,11 +575,12 @@ ModalWindow { } function navigateToCurrentRow() { + var currentModel = fileTableView.model !== filesModel ? fileTableView.model : fileTableModel var row = fileTableView.currentRow - var isFolder = model.isFolder(row); - var file = model.get(row).filePath; + var isFolder = currentModel.isFolder(row); + var file = currentModel.get(row).filePath; if (isFolder) { - fileTableView.model.folder = helper.pathToUrl(file); + currentModel.folder = helper.pathToUrl(file); } else { okAction.trigger(); } @@ -580,7 +595,8 @@ ModalWindow { var newPrefix = prefix + event.text.toLowerCase(); var matchedIndex = -1; for (var i = 0; i < model.count; ++i) { - var name = model.get(i).fileName.toLowerCase(); + var name = model !== filesModel ? model.get(i).fileName.toLowerCase() : + filesModel.get(i).fileName.toLowerCase(); if (0 === name.indexOf(newPrefix)) { matchedIndex = i; break; diff --git a/interface/resources/qml/dialogs/TabletFileDialog.qml b/interface/resources/qml/dialogs/TabletFileDialog.qml index 5e33663436..9e1d0a9f5a 100644 --- a/interface/resources/qml/dialogs/TabletFileDialog.qml +++ b/interface/resources/qml/dialogs/TabletFileDialog.qml @@ -25,11 +25,14 @@ import "fileDialog" //FIXME implement shortcuts for favorite location TabletModalWindow { id: root + anchors.fill: parent width: parent.width height: parent.height HifiConstants { id: hifi } + property var filesModel: ListModel { } + Settings { category: "FileDialog" property alias width: root.width @@ -250,7 +253,9 @@ TabletModalWindow { } currentSelectionUrl = helper.pathToUrl(fileTableView.model.get(row).filePath); - currentSelectionIsFolder = fileTableView.model.isFolder(row); + currentSelectionIsFolder = fileTableView.model !== filesModel ? + fileTableView.model.isFolder(row) : + fileTableModel.isFolder(row); if (root.selectDirectory || !currentSelectionIsFolder) { currentSelection.text = capitalizeDrive(helper.urlToPath(currentSelectionUrl)); } else { @@ -288,7 +293,7 @@ TabletModalWindow { } onFolderChanged: { - fileTableModel.update(); // Update once the data from the folder change is available. + fileTableModel.update() } function getItem(index, field) { @@ -328,7 +333,12 @@ TabletModalWindow { } } - ListModel { + Component { + id: filesModelBuilder + ListModel { } + } + + QtObject { id: fileTableModel // FolderListModel has a couple of problems: @@ -359,17 +369,16 @@ TabletModalWindow { } onFolderChanged: { + if (folder === rootFolder) { model = driveListModel; helper.monitorDirectory(""); update(); } else { var needsUpdate = model === driveListModel && folder === folderListModel.folder; - model = folderListModel; folderListModel.folder = folder; helper.monitorDirectory(helper.urlToPath(folder)); - if (needsUpdate) { update(); } @@ -380,7 +389,11 @@ TabletModalWindow { if (row === -1) { return false; } - return get(row).fileIsDir; + return filesModel.get(row).fileIsDir; + } + + function get(row) { + return filesModel.get(row) } function update() { @@ -398,7 +411,7 @@ TabletModalWindow { rows = 0, i; - clear(); + var newFilesModel = filesModelBuilder.createObject(root); comparisonFunction = sortOrder === Qt.AscendingOrder ? function(a, b) { return a < b; } @@ -420,7 +433,7 @@ TabletModalWindow { while (lower < upper) { middle = Math.floor((lower + upper) / 2); var lessThan; - if (comparisonFunction(sortValue, get(middle)[sortField])) { + if (comparisonFunction(sortValue, newFilesModel.get(middle)[sortField])) { lessThan = true; upper = middle; } else { @@ -429,7 +442,7 @@ TabletModalWindow { } } - insert(lower, { + newFilesModel.insert(lower, { fileName: fileName, fileModified: (fileIsDir ? new Date(0) : model.getItem(i, "fileModified")), fileSize: model.getItem(i, "fileSize"), @@ -440,6 +453,7 @@ TabletModalWindow { rows++; } + filesModel = newFilesModel; d.clearSelection(); } @@ -467,7 +481,7 @@ TabletModalWindow { sortIndicatorOrder: Qt.AscendingOrder sortIndicatorVisible: true - model: fileTableModel + model: filesModel function updateSort() { model.sortOrder = sortIndicatorOrder; @@ -559,11 +573,12 @@ TabletModalWindow { } function navigateToCurrentRow() { + var currentModel = fileTableView.model !== filesModel ? fileTableView.model : fileTableModel var row = fileTableView.currentRow - var isFolder = model.isFolder(row); - var file = model.get(row).filePath; + var isFolder = currentModel.isFolder(row); + var file = currentModel.get(row).filePath; if (isFolder) { - fileTableView.model.folder = helper.pathToUrl(file); + currentModel.folder = helper.pathToUrl(file); } else { okAction.trigger(); } @@ -578,7 +593,8 @@ TabletModalWindow { var newPrefix = prefix + event.text.toLowerCase(); var matchedIndex = -1; for (var i = 0; i < model.count; ++i) { - var name = model.get(i).fileName.toLowerCase(); + var name = model !== filesModel ? model.get(i).fileName.toLowerCase() : + filesModel.get(i).fileName.toLowerCase(); if (0 === name.indexOf(newPrefix)) { matchedIndex = i; break; diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 91c1d99cf5..65517f5a73 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -43,6 +43,7 @@ Item { property bool selected: false property bool isAdmin: false property bool isPresent: true + property bool isReplicated: false property string placeName: "" property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent")) property alias avImage: avatarImage diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index bbb42e61ac..8db04a0f5b 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -473,6 +473,7 @@ Rectangle { visible: !isCheckBox && !isButton && !isAvgAudio; uuid: model ? model.sessionId : ""; selected: styleData.selected; + isReplicated: model.isReplicated; isAdmin: model && model.admin; isPresent: model && model.isPresent; // Size @@ -553,6 +554,7 @@ Rectangle { id: actionButton; color: 2; // Red visible: isButton; + enabled: !nameCard.isReplicated; anchors.centerIn: parent; width: 32; height: 32; diff --git a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml index 44cae95696..cabc09e49b 100644 --- a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml +++ b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml @@ -17,7 +17,7 @@ PreferencesDialog { id: root objectName: "GeneralPreferencesDialog" title: "General Settings" - showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Sixense Controllers", "Perception Neuron", "Kinect"] + showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Sixense Controllers", "Perception Neuron", "Kinect", "Leap Motion"] property var settings: Settings { category: root.objectName property alias x: root.x diff --git a/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml b/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml index fe043f6ac7..18e7898dd0 100644 --- a/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml @@ -32,6 +32,6 @@ StackView { TabletPreferencesDialog { id: root objectName: "TabletGeneralPreferences" - showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Sixense Controllers", "Perception Neuron", "Kinect", "Vive Pucks Configuration"] + showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Sixense Controllers", "Perception Neuron", "Kinect", "Vive Pucks Configuration", "Leap Motion"] } } diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/TabletFileDialog.qml b/interface/resources/qml/hifi/tablet/tabletWindows/TabletFileDialog.qml index 26e35c4dcf..7b91cfeba9 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/TabletFileDialog.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/TabletFileDialog.qml @@ -23,11 +23,13 @@ import "../../../windows" import "../../../dialogs/fileDialog" //FIXME implement shortcuts for favorite location -Item { +Rectangle { id: root - anchors.top: parent.top + anchors.top: parent ? parent.top : undefined HifiConstants { id: hifi } + color: hifi.colors.baseGray; + Settings { category: "FileDialog" property alias width: root.width diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ae240e53ff..ee7b0cfa82 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -37,8 +37,6 @@ #include #include -#include - #include #include @@ -147,7 +145,6 @@ #include "avatar/MyHead.h" #include "CrashHandler.h" #include "devices/DdeFaceTracker.h" -#include "devices/Leapmotion.h" #include "DiscoverabilityManager.h" #include "GLCanvas.h" #include "InterfaceDynamicFactory.h" @@ -486,11 +483,11 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { Setting::init(); // Tell the plugin manager about our statically linked plugins - PluginManager::setInputPluginProvider([] { return getInputPlugins(); }); - PluginManager::setDisplayPluginProvider([] { return getDisplayPlugins(); }); - PluginManager::setInputPluginSettingsPersister([](const InputPluginList& plugins) { saveInputPluginSettings(plugins); }); - - if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { + auto pluginManager = PluginManager::getInstance(); + pluginManager->setInputPluginProvider([] { return getInputPlugins(); }); + pluginManager->setDisplayPluginProvider([] { return getDisplayPlugins(); }); + pluginManager->setInputPluginSettingsPersister([](const InputPluginList& plugins) { saveInputPluginSettings(plugins); }); + if (auto steamClient = pluginManager->getSteamClientPlugin()) { steamClient->init(); } @@ -584,6 +581,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -723,9 +721,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo updateHeartbeat(); // setup a timer for domain-server check ins - QTimer* domainCheckInTimer = new QTimer(nodeList.data()); + QTimer* domainCheckInTimer = new QTimer(this); connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); + connect(this, &QCoreApplication::aboutToQuit, [domainCheckInTimer] { + domainCheckInTimer->stop(); + domainCheckInTimer->deleteLater(); + }); auto audioIO = DependencyManager::get(); @@ -774,7 +776,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(this, &Application::activeDisplayPluginChanged, reinterpret_cast(audioScriptingInterface.data()), &scripting::Audio::onContextChanged); - ResourceManager::init(); // Make sure we don't time out during slow operations at startup updateHeartbeat(); @@ -913,11 +914,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _saveAvatarOverrideUrl = true; } - QString defaultScriptsLocation = getCmdOption(argc, constArgv, "--scripts"); - if (!defaultScriptsLocation.isEmpty()) { - PathUtils::defaultScriptsLocation(defaultScriptsLocation); - } - _glWidget = new GLCanvas(); getApplicationCompositor().setRenderingWidget(_glWidget); _window->setCentralWidget(_glWidget); @@ -1178,7 +1174,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // do this as late as possible so that all required subsystems are initialized // If we've overridden the default scripts location, just load default scripts // otherwise, load 'em all - if (!defaultScriptsLocation.isEmpty()) { + + // we just want to see if --scripts was set, we've already parsed it and done + // the change in PathUtils. Rather than pass that in the constructor, lets just + // look (this could be debated) + QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH); + QDir defaultScriptsLocation(getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str())); + if (!defaultScriptsLocation.exists()) { scriptEngines->loadDefaultScripts(); scriptEngines->defaultScriptsLocationOverridden(true); } else { @@ -1879,13 +1881,11 @@ Application::~Application() { DependencyManager::destroy(); DependencyManager::destroy(); - ResourceManager::cleanup(); + DependencyManager::get()->cleanup(); // remove the NodeList from the DependencyManager DependencyManager::destroy(); - Leapmotion::destroy(); - if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { steamClient->shutdown(); } @@ -4055,8 +4055,6 @@ void Application::init() { qCDebug(interfaceapp) << "Loaded settings"; - Leapmotion::init(); - // fire off an immediate domain-server check in now that settings are loaded DependencyManager::get()->sendDomainServerCheckIn(); @@ -4095,7 +4093,10 @@ void Application::init() { EntityTreePointer tree = getEntities()->getTree(); if (auto entity = tree->findEntityByEntityItemID(id)) { auto sound = DependencyManager::get()->getSound(newURL); - entity->setCollisionSound(sound); + auto renderable = entity->getRenderableInterface(); + if (renderable) { + renderable->setCollisionSound(sound); + } } }, Qt::QueuedConnection); connect(getMyAvatar().get(), &MyAvatar::newCollisionSoundURL, this, [this](QUrl newURL) { @@ -4196,7 +4197,7 @@ void Application::updateMyAvatarLookAtPosition() { lookAtSpot = transformPoint(worldHeadMat, glm::vec3(0.0f, 0.0f, TREE_SCALE)); } else { lookAtSpot = myAvatar->getHead()->getEyePosition() + - (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, TREE_SCALE)); + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } } @@ -4520,7 +4521,6 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("devices"); - DeviceTracker::updateAll(); FaceTracker* tracker = getSelectedFaceTracker(); if (tracker && Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking) != tracker->isMuted()) { @@ -4589,8 +4589,6 @@ void Application::update(float deltaTime) { keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData); } - _controllerScriptingInterface->updateInputControllers(); - // Transfer the user inputs to the driveKeys // FIXME can we drop drive keys and just have the avatar read the action states directly? myAvatar->clearDriveKeys(); @@ -4615,6 +4613,31 @@ void Application::update(float deltaTime) { auto avatarToSensorMatrix = worldToSensorMatrix * myAvatarMatrix; myAvatar->setHandControllerPosesInSensorFrame(leftHandPose.transform(avatarToSensorMatrix), rightHandPose.transform(avatarToSensorMatrix)); + // If have previously done finger poses or there are new valid finger poses, update finger pose values. This so that if + // fingers are not being controlled, finger joints are not updated in MySkeletonModel. + // Assumption: Finger poses are either all present and valid or not present at all; thus can test just one joint. + MyAvatar::FingerPosesMap leftHandFingerPoses; + if (myAvatar->getLeftHandFingerControllerPosesInSensorFrame().size() > 0 + || userInputMapper->getPoseState(controller::Action::LEFT_HAND_THUMB1).isValid()) { + for (int i = (int)controller::Action::LEFT_HAND_THUMB1; i <= (int)controller::Action::LEFT_HAND_PINKY4; i++) { + leftHandFingerPoses[i] = { + userInputMapper->getPoseState((controller::Action)i).transform(avatarToSensorMatrix), + userInputMapper->getActionName((controller::Action)i) + }; + } + } + MyAvatar::FingerPosesMap rightHandFingerPoses; + if (myAvatar->getRightHandFingerControllerPosesInSensorFrame().size() > 0 + || userInputMapper->getPoseState(controller::Action::RIGHT_HAND_THUMB1).isValid()) { + for (int i = (int)controller::Action::RIGHT_HAND_THUMB1; i <= (int)controller::Action::RIGHT_HAND_PINKY4; i++) { + rightHandFingerPoses[i] = { + userInputMapper->getPoseState((controller::Action)i).transform(avatarToSensorMatrix), + userInputMapper->getActionName((controller::Action)i) + }; + } + } + myAvatar->setFingerControllerPosesInSensorFrame(leftHandFingerPoses, rightHandFingerPoses); + controller::Pose leftFootPose = userInputMapper->getPoseState(controller::Action::LEFT_FOOT); controller::Pose rightFootPose = userInputMapper->getPoseState(controller::Action::RIGHT_FOOT); myAvatar->setFootControllerPosesInSensorFrame(leftFootPose.transform(avatarToSensorMatrix), rightFootPose.transform(avatarToSensorMatrix)); @@ -5941,7 +5964,7 @@ void Application::addAssetToWorldFromURL(QString url) { addAssetToWorldInfo(filename, "Downloading model file " + filename + "."); - auto request = ResourceManager::createResourceRequest(nullptr, QUrl(url)); + auto request = DependencyManager::get()->createResourceRequest(nullptr, QUrl(url)); connect(request, &ResourceRequest::finished, this, &Application::addAssetToWorldFromURLRequestFinished); request->send(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 72c3dbe037..eb77855b2b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -96,6 +96,7 @@ static const UINT UWM_SHOW_APPLICATION = #endif static const QString RUNNING_MARKER_FILENAME = "Interface.running"; +static const QString SCRIPTS_SWITCH = "scripts"; class Application; #if defined(qApp) @@ -298,6 +299,7 @@ public: void setAvatarOverrideUrl(const QUrl& url, bool save); QUrl getAvatarOverrideUrl() { return _avatarOverrideUrl; } bool getSaveAvatarOverrideUrl() { return _saveAvatarOverrideUrl; } + void setCacheOverrideDir(const QString& dirName) { _cacheDir = dirName; } signals: void svoImportRequested(const QString& url); @@ -689,5 +691,7 @@ private: QUrl _avatarOverrideUrl; bool _saveAvatarOverrideUrl { false }; + + QString _cacheDir; }; #endif // hifi_Application_h diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index db2a240b92..73192b0bef 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,8 @@ #include "AvatarBookmarks.h" #include "InterfaceLogging.h" +#include "QVariantGLM.h" + #include AvatarBookmarks::AvatarBookmarks() { @@ -58,16 +61,48 @@ void AvatarBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteAvatarBookmark); QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); - Bookmarks::setupMenus(menubar, menu); + for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it) { + addBookmarkToMenu(menubar, it.key(), it.value()); + } + Bookmarks::sortActions(menubar, _bookmarksMenu); } void AvatarBookmarks::changeToBookmarkedAvatar() { QAction* action = qobject_cast(sender()); - const QString& address = action->data().toString(); - auto myAvatar = DependencyManager::get()->getMyAvatar(); - myAvatar->useFullAvatarURL(address); + + + + if (action->data().type() == QVariant::String) { + // TODO: Phase this out eventually. + // Legacy avatar bookmark. + + myAvatar->useFullAvatarURL(action->data().toString()); + qCDebug(interfaceapp) << " Using Legacy V1 Avatar Bookmark "; + } else { + + const QMap bookmark = action->data().toMap(); + // Not magic value. This is the current made version, and if it changes this interpreter should be updated to + // handle the new one separately. + // This is where the avatar bookmark entry is parsed. If adding new Value, make sure to have backward compatability with previous + if (bookmark.value(ENTRY_VERSION) == 3) { + const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); + myAvatar->useFullAvatarURL(avatarUrl); + qCDebug(interfaceapp) << "Avatar On " << avatarUrl; + const QList& attachments = bookmark.value(ENTRY_AVATAR_ATTACHMENTS, QList()).toList(); + + qCDebug(interfaceapp) << "Attach " << attachments; + myAvatar->setAttachmentsVariant(attachments); + + const float& qScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat(); + myAvatar->setAvatarScale(qScale); + + } else { + qCDebug(interfaceapp) << " Bookmark entry does not match client version, make sure client has a handler for the new AvatarBookmark"; + } + } + } void AvatarBookmarks::addBookmark() { @@ -83,13 +118,23 @@ void AvatarBookmarks::addBookmark() { } auto myAvatar = DependencyManager::get()->getMyAvatar(); - const QString& bookmarkAddress = myAvatar->getSkeletonModelURL().toString(); - Bookmarks::addBookmarkToFile(bookmarkName, bookmarkAddress); + + const QString& avatarUrl = myAvatar->getSkeletonModelURL().toString(); + const QVariant& avatarScale = myAvatar->getAvatarScale(); + + // If Avatar attachments ever change, this is where to update them, when saving remember to also append to AVATAR_BOOKMARK_VERSION + QVariantMap *bookmark = new QVariantMap; + bookmark->insert(ENTRY_VERSION, AVATAR_BOOKMARK_VERSION); + bookmark->insert(ENTRY_AVATAR_URL, avatarUrl); + bookmark->insert(ENTRY_AVATAR_SCALE, avatarScale); + bookmark->insert(ENTRY_AVATAR_ATTACHMENTS, myAvatar->getAttachmentsVariant()); + + Bookmarks::addBookmarkToFile(bookmarkName, *bookmark); } -void AvatarBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) { +void AvatarBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) { QAction* changeAction = _bookmarksMenu->newAction(); - changeAction->setData(address); + changeAction->setData(bookmark); connect(changeAction, SIGNAL(triggered()), this, SLOT(changeToBookmarkedAvatar())); if (!_isMenuSorted) { menubar->addActionToQMenuAndActionHash(_bookmarksMenu, changeAction, name, 0, QAction::NoRole); diff --git a/interface/src/AvatarBookmarks.h b/interface/src/AvatarBookmarks.h index dc5a0aee6e..0529eeb516 100644 --- a/interface/src/AvatarBookmarks.h +++ b/interface/src/AvatarBookmarks.h @@ -21,18 +21,23 @@ class AvatarBookmarks: public Bookmarks, public Dependency { public: AvatarBookmarks(); - void setupMenus(Menu* menubar, MenuWrapper* menu) override; public slots: void addBookmark(); protected: - void addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) override; - void readFromFile(); + void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) override; + void readFromFile() override; private: const QString AVATARBOOKMARKS_FILENAME = "avatarbookmarks.json"; + const QString ENTRY_AVATAR_URL = "avatarUrl"; + const QString ENTRY_AVATAR_ATTACHMENTS = "attachments"; + const QString ENTRY_AVATAR_SCALE = "avatarScale"; + const QString ENTRY_VERSION = "version"; + + const int AVATAR_BOOKMARK_VERSION = 3; private slots: void changeToBookmarkedAvatar(); diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index 4cbc17f8ce..0bd6b01128 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -28,19 +28,6 @@ Bookmarks::Bookmarks() : _isMenuSorted(false) { } - -void Bookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { - // Enable/Disable menus as needed - enableMenuItems(_bookmarks.count() > 0); - - // Load Bookmarks - for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it) { - QString bookmarkName = it.key(); - QString bookmarkAddress = it.value().toString(); - addBookmarkToMenu(menubar, bookmarkName, bookmarkAddress); - } -} - void Bookmarks::deleteBookmark() { QStringList bookmarkList; QList menuItems = _bookmarksMenu->actions(); @@ -67,7 +54,7 @@ void Bookmarks::deleteBookmark() { } } -void Bookmarks::addBookmarkToFile(const QString& bookmarkName, const QString& bookmarkAddress) { +void Bookmarks::addBookmarkToFile(const QString& bookmarkName, const QVariant& bookmark) { Menu* menubar = Menu::getInstance(); if (contains(bookmarkName)) { auto offscreenUi = DependencyManager::get(); @@ -75,7 +62,6 @@ void Bookmarks::addBookmarkToFile(const QString& bookmarkName, const QString& bo "The bookmark name you entered already exists in your list.", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); duplicateBookmarkMessage->setProperty("informativeText", "Would you like to overwrite it?"); - auto result = offscreenUi->waitForMessageBoxResult(duplicateBookmarkMessage); if (result != QMessageBox::Yes) { return; @@ -83,19 +69,20 @@ void Bookmarks::addBookmarkToFile(const QString& bookmarkName, const QString& bo removeBookmarkFromMenu(menubar, bookmarkName); } - addBookmarkToMenu(menubar, bookmarkName, bookmarkAddress); - insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName. + addBookmarkToMenu(menubar, bookmarkName, bookmark); + insert(bookmarkName, bookmark); // Overwrites any item with the same bookmarkName. enableMenuItems(true); } -void Bookmarks::insert(const QString& name, const QString& address) { - _bookmarks.insert(name, address); +void Bookmarks::insert(const QString& name, const QVariant& bookmark) { + _bookmarks.insert(name, bookmark); if (contains(name)) { - qCDebug(interfaceapp) << "Added bookmark:" << name << "," << address; + qCDebug(interfaceapp) << "Added bookmark:" << name; persistToFile(); - } else { - qWarning() << "Couldn't add bookmark: " << name << "," << address; + } + else { + qWarning() << "Couldn't add bookmark: " << name; } } diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h index 6c322197cc..dd47a286bf 100644 --- a/interface/src/Bookmarks.h +++ b/interface/src/Bookmarks.h @@ -27,18 +27,20 @@ class Bookmarks: public QObject { public: Bookmarks(); - virtual void setupMenus(Menu* menubar, MenuWrapper* menu); + virtual void setupMenus(Menu* menubar, MenuWrapper* menu) = 0; QString addressForBookmark(const QString& name) const; protected: - virtual void addBookmarkToFile(const QString& bookmarkName, const QString& bookmarkAddress); - virtual void addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) = 0; + void addBookmarkToFile(const QString& bookmarkName, const QVariant& bookmark); + virtual void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) = 0; void enableMenuItems(bool enabled); - void readFromFile(); - void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name. + virtual void readFromFile(); + void insert(const QString& name, const QVariant& address); // Overwrites any existing entry with same name. void sortActions(Menu* menubar, MenuWrapper* menu); int getMenuItemLocation(QList actions, const QString& name) const; - + + bool contains(const QString& name) const; + QVariantMap _bookmarks; // { name: url, ... } QPointer _bookmarksMenu; QPointer _deleteBookmarksAction; @@ -50,7 +52,6 @@ protected slots: private: void remove(const QString& name); - bool contains(const QString& name) const; static bool sortOrder(QAction* a, QAction* b); void persistToFile(); diff --git a/interface/src/LocationBookmarks.cpp b/interface/src/LocationBookmarks.cpp index b79adcf1b7..eee6cdf3c8 100644 --- a/interface/src/LocationBookmarks.cpp +++ b/interface/src/LocationBookmarks.cpp @@ -41,13 +41,25 @@ void LocationBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark); QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); - Bookmarks::setupMenus(menubar, menu); + // Legacy Location to Bookmark. + + // Enable/Disable menus as needed + enableMenuItems(_bookmarks.count() > 0); + + // Load Bookmarks + for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it) { + QString bookmarkName = it.key(); + QString bookmarkAddress = it.value().toString(); + addBookmarkToMenu(menubar, bookmarkName, bookmarkAddress); + } + Bookmarks::sortActions(menubar, _bookmarksMenu); } void LocationBookmarks::setHomeLocation() { auto addressManager = DependencyManager::get(); QString bookmarkAddress = addressManager->currentAddress().toString(); + Bookmarks::addBookmarkToFile(HOME_BOOKMARK, bookmarkAddress); } @@ -74,7 +86,7 @@ void LocationBookmarks::addBookmark() { Bookmarks::addBookmarkToFile(bookmarkName, bookmarkAddress); } -void LocationBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) { +void LocationBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& address) { QAction* teleportAction = _bookmarksMenu->newAction(); teleportAction->setData(address); connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark())); @@ -85,4 +97,4 @@ void LocationBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, co menubar->addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, name, 0, QAction::NoRole); Bookmarks::sortActions(menubar, _bookmarksMenu); } -} +} \ No newline at end of file diff --git a/interface/src/LocationBookmarks.h b/interface/src/LocationBookmarks.h index 1324e96574..6cac56ae04 100644 --- a/interface/src/LocationBookmarks.h +++ b/interface/src/LocationBookmarks.h @@ -29,7 +29,7 @@ public slots: void addBookmark(); protected: - void addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) override; + void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& address) override; private: const QString LOCATIONBOOKMARKS_FILENAME = "bookmarks.json"; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5ef95cffeb..c673b6bc43 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -571,9 +571,6 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false, avatar.get(), SLOT(setEnableDebugDrawHandControllers(bool))); - MenuWrapper* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion"); - addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false); - // Developer > Entities >>> MenuWrapper* entitiesOptionsMenu = developerMenu->addMenu("Entities"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 560a1568a5..43611eab70 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -114,7 +114,6 @@ namespace MenuOption { const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IndependentMode = "Independent Mode"; const QString ActionMotorControl = "Enable Default Motor Control"; - const QString LeapMotionOnHMD = "Leap Motion on HMD"; const QString LoadScript = "Open and Run Script File..."; const QString LoadScriptURL = "Open and Run Script from URL..."; const QString LodTools = "LOD Tools"; diff --git a/interface/src/SecondaryCamera.cpp b/interface/src/SecondaryCamera.cpp index f6ee8caa61..f59d2fcc7a 100644 --- a/interface/src/SecondaryCamera.cpp +++ b/interface/src/SecondaryCamera.cpp @@ -79,6 +79,7 @@ public: gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { batch.disableContextStereo(); + batch.disableContextViewCorrection(); }); auto srcViewFrustum = args->getViewFrustum(); @@ -112,6 +113,7 @@ public: gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { batch.restoreContextStereo(); + batch.restoreContextViewCorrection(); }); } }; diff --git a/interface/src/assets/ATPAssetMigrator.cpp b/interface/src/assets/ATPAssetMigrator.cpp index e0e9d5a73a..667c2587b0 100644 --- a/interface/src/assets/ATPAssetMigrator.cpp +++ b/interface/src/assets/ATPAssetMigrator.cpp @@ -106,7 +106,8 @@ void ATPAssetMigrator::loadEntityServerFile() { jsonValue = entityObject; } else if (wantsToMigrateResource(migrationURL)) { - auto request = ResourceManager::createResourceRequest(this, migrationURL); + auto request = + DependencyManager::get()->createResourceRequest(this, migrationURL); if (request) { qCDebug(asset_migrator) << "Requesting" << migrationURL << "for ATP asset migration"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3ca1009e4f..ab1e644420 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1474,6 +1474,19 @@ controller::Pose MyAvatar::getRightHandControllerPoseInAvatarFrame() const { return getRightHandControllerPoseInWorldFrame().transform(invAvatarMatrix); } +void MyAvatar::setFingerControllerPosesInSensorFrame(const FingerPosesMap& left, const FingerPosesMap& right) { + _leftHandFingerPosesInSensorFramceCache.set(left); + _rightHandFingerPosesInSensorFramceCache.set(right); +} + +MyAvatar::FingerPosesMap MyAvatar::getLeftHandFingerControllerPosesInSensorFrame() const { + return _leftHandFingerPosesInSensorFramceCache.get(); +} + +MyAvatar::FingerPosesMap MyAvatar::getRightHandFingerControllerPosesInSensorFrame() const { + return _rightHandFingerPosesInSensorFramceCache.get(); +} + void MyAvatar::setFootControllerPosesInSensorFrame(const controller::Pose& left, const controller::Pose& right) { _leftFootControllerPoseInSensorFrameCache.set(left); _rightFootControllerPoseInSensorFrameCache.set(right); @@ -2544,6 +2557,21 @@ bool MyAvatar::getFlyingEnabled() { return _enableFlying; } +// Public interface for targetscale +float MyAvatar::getAvatarScale() { + return getTargetScale(); +} + +void MyAvatar::setAvatarScale(float val) { + + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setAvatarScale", Q_ARG(float, val)); + return; + } + + setTargetScale(val); +} + void MyAvatar::setCollisionsEnabled(bool enabled) { if (QThread::currentThread() != thread()) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index b78016376e..d94d4f11b7 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -370,7 +370,7 @@ public: float getDriveKey(DriveKeys key) const; Q_INVOKABLE float getRawDriveKey(DriveKeys key) const; void relayDriveKeysToCharacterController(); - + Q_INVOKABLE void disableDriveKey(DriveKeys key); Q_INVOKABLE void enableDriveKey(DriveKeys key); Q_INVOKABLE bool isDriveKeyDisabled(DriveKeys key) const; @@ -479,6 +479,11 @@ public: controller::Pose getLeftHandControllerPoseInAvatarFrame() const; controller::Pose getRightHandControllerPoseInAvatarFrame() const; + typedef std::map> FingerPosesMap; + void setFingerControllerPosesInSensorFrame(const FingerPosesMap& left, const FingerPosesMap& right); + FingerPosesMap getLeftHandFingerControllerPosesInSensorFrame() const; + FingerPosesMap getRightHandFingerControllerPosesInSensorFrame() const; + void setFootControllerPosesInSensorFrame(const controller::Pose& left, const controller::Pose& right); controller::Pose getLeftFootControllerPoseInSensorFrame() const; controller::Pose getRightFootControllerPoseInSensorFrame() const; @@ -517,6 +522,9 @@ public: Q_INVOKABLE void setFlyingEnabled(bool enabled); Q_INVOKABLE bool getFlyingEnabled(); + Q_INVOKABLE float getAvatarScale(); + Q_INVOKABLE void setAvatarScale(float scale); + Q_INVOKABLE void setCollisionsEnabled(bool enabled); Q_INVOKABLE bool getCollisionsEnabled(); Q_INVOKABLE void setCharacterControllerEnabled(bool enabled); // deprecated @@ -793,13 +801,15 @@ private: // These are stored in SENSOR frame ThreadSafeValueCache _leftHandControllerPoseInSensorFrameCache { controller::Pose() }; ThreadSafeValueCache _rightHandControllerPoseInSensorFrameCache { controller::Pose() }; - ThreadSafeValueCache _leftFootControllerPoseInSensorFrameCache{ controller::Pose() }; - ThreadSafeValueCache _rightFootControllerPoseInSensorFrameCache{ controller::Pose() }; - ThreadSafeValueCache _hipsControllerPoseInSensorFrameCache{ controller::Pose() }; - ThreadSafeValueCache _spine2ControllerPoseInSensorFrameCache{ controller::Pose() }; - ThreadSafeValueCache _headControllerPoseInSensorFrameCache{ controller::Pose() }; - ThreadSafeValueCache _leftArmControllerPoseInSensorFrameCache{ controller::Pose() }; - ThreadSafeValueCache _rightArmControllerPoseInSensorFrameCache{ controller::Pose() }; + ThreadSafeValueCache _leftHandFingerPosesInSensorFramceCache { }; + ThreadSafeValueCache _rightHandFingerPosesInSensorFramceCache { }; + ThreadSafeValueCache _leftFootControllerPoseInSensorFrameCache { controller::Pose() }; + ThreadSafeValueCache _rightFootControllerPoseInSensorFrameCache { controller::Pose() }; + ThreadSafeValueCache _hipsControllerPoseInSensorFrameCache { controller::Pose() }; + ThreadSafeValueCache _spine2ControllerPoseInSensorFrameCache { controller::Pose() }; + ThreadSafeValueCache _headControllerPoseInSensorFrameCache { controller::Pose() }; + ThreadSafeValueCache _leftArmControllerPoseInSensorFrameCache { controller::Pose() }; + ThreadSafeValueCache _rightArmControllerPoseInSensorFrameCache { controller::Pose() }; bool _hmdLeanRecenterEnabled = true; AnimPose _prePhysicsRoomPose; diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index e74df4cf0f..97309d9678 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -47,110 +47,113 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { MyAvatar* myAvatar = static_cast(_owningAvatar); - Rig::HeadParameters headParams; + Rig::ControllerParameters params; + + AnimPose avatarToRigPose(glm::vec3(1.0f), Quaternions::Y_180, glm::vec3(0.0f)); // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getHeadControllerPoseInAvatarFrame(); if (avatarHeadPose.isValid()) { - glm::mat4 rigHeadMat = Matrices::Y_180 * - createMatFromQuatAndPos(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); - headParams.rigHeadPosition = extractTranslation(rigHeadMat); - headParams.rigHeadOrientation = glmExtractRotation(rigHeadMat); - headParams.headEnabled = true; + AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_Head] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_Head] = true; } else { // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and // down in desktop mode. // preMult 180 is necessary to convert from avatar to rig coordinates. // postMult 180 is necessary to convert head from -z forward to z forward. - headParams.rigHeadOrientation = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180; - headParams.headEnabled = false; + glm::quat headRot = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180; + params.controllerPoses[Rig::ControllerType_Head] = AnimPose(glm::vec3(1.0f), headRot, glm::vec3(0.0f)); + params.controllerActiveFlags[Rig::ControllerType_Head] = false; } auto avatarHipsPose = myAvatar->getHipsControllerPoseInAvatarFrame(); if (avatarHipsPose.isValid()) { - glm::mat4 rigHipsMat = Matrices::Y_180 * createMatFromQuatAndPos(avatarHipsPose.getRotation(), avatarHipsPose.getTranslation()); - headParams.hipsMatrix = rigHipsMat; - headParams.hipsEnabled = true; + AnimPose pose(avatarHipsPose.getRotation(), avatarHipsPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_Hips] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_Hips] = true; } else { - headParams.hipsEnabled = false; + params.controllerPoses[Rig::ControllerType_Hips] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_Hips] = false; } auto avatarSpine2Pose = myAvatar->getSpine2ControllerPoseInAvatarFrame(); if (avatarSpine2Pose.isValid()) { - glm::mat4 rigSpine2Mat = Matrices::Y_180 * createMatFromQuatAndPos(avatarSpine2Pose.getRotation(), avatarSpine2Pose.getTranslation()); - headParams.spine2Matrix = rigSpine2Mat; - headParams.spine2Enabled = true; + AnimPose pose(avatarSpine2Pose.getRotation(), avatarSpine2Pose.getTranslation()); + params.controllerPoses[Rig::ControllerType_Spine2] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_Spine2] = true; } else { - headParams.spine2Enabled = false; + params.controllerPoses[Rig::ControllerType_Spine2] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_Spine2] = false; } auto avatarRightArmPose = myAvatar->getRightArmControllerPoseInAvatarFrame(); if (avatarRightArmPose.isValid()) { - glm::mat4 rightArmMat = Matrices::Y_180 * createMatFromQuatAndPos(avatarRightArmPose.getRotation(), avatarRightArmPose.getTranslation()); - headParams.rightArmPosition = extractTranslation(rightArmMat); - headParams.rightArmRotation = glmExtractRotation(rightArmMat); - headParams.rightArmEnabled = true; + AnimPose pose(avatarRightArmPose.getRotation(), avatarRightArmPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_RightArm] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_RightArm] = true; } else { - headParams.rightArmEnabled = false; + params.controllerPoses[Rig::ControllerType_RightArm] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_RightArm] = false; } auto avatarLeftArmPose = myAvatar->getLeftArmControllerPoseInAvatarFrame(); if (avatarLeftArmPose.isValid()) { - glm::mat4 leftArmMat = Matrices::Y_180 * createMatFromQuatAndPos(avatarLeftArmPose.getRotation(), avatarLeftArmPose.getTranslation()); - headParams.leftArmPosition = extractTranslation(leftArmMat); - headParams.leftArmRotation = glmExtractRotation(leftArmMat); - headParams.leftArmEnabled = true; + AnimPose pose(avatarLeftArmPose.getRotation(), avatarLeftArmPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_LeftArm] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_LeftArm] = true; } else { - headParams.leftArmEnabled = false; + params.controllerPoses[Rig::ControllerType_LeftArm] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_LeftArm] = false; } - headParams.isTalking = head->getTimeWithoutTalking() <= 1.5f; - - _rig.updateFromHeadParameters(headParams, deltaTime); - - Rig::HandAndFeetParameters handAndFeetParams; - - auto leftPose = myAvatar->getLeftHandControllerPoseInAvatarFrame(); - if (leftPose.isValid()) { - handAndFeetParams.isLeftEnabled = true; - handAndFeetParams.leftPosition = Quaternions::Y_180 * leftPose.getTranslation(); - handAndFeetParams.leftOrientation = Quaternions::Y_180 * leftPose.getRotation(); + auto avatarLeftHandPose = myAvatar->getLeftHandControllerPoseInAvatarFrame(); + if (avatarLeftHandPose.isValid()) { + AnimPose pose(avatarLeftHandPose.getRotation(), avatarLeftHandPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_LeftHand] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_LeftHand] = true; } else { - handAndFeetParams.isLeftEnabled = false; + params.controllerPoses[Rig::ControllerType_LeftHand] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_LeftHand] = false; } - auto rightPose = myAvatar->getRightHandControllerPoseInAvatarFrame(); - if (rightPose.isValid()) { - handAndFeetParams.isRightEnabled = true; - handAndFeetParams.rightPosition = Quaternions::Y_180 * rightPose.getTranslation(); - handAndFeetParams.rightOrientation = Quaternions::Y_180 * rightPose.getRotation(); + auto avatarRightHandPose = myAvatar->getRightHandControllerPoseInAvatarFrame(); + if (avatarRightHandPose.isValid()) { + AnimPose pose(avatarRightHandPose.getRotation(), avatarRightHandPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_RightHand] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_RightHand] = true; } else { - handAndFeetParams.isRightEnabled = false; + params.controllerPoses[Rig::ControllerType_RightHand] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_RightHand] = false; } - auto leftFootPose = myAvatar->getLeftFootControllerPoseInAvatarFrame(); - if (leftFootPose.isValid()) { - handAndFeetParams.isLeftFootEnabled = true; - handAndFeetParams.leftFootPosition = Quaternions::Y_180 * leftFootPose.getTranslation(); - handAndFeetParams.leftFootOrientation = Quaternions::Y_180 * leftFootPose.getRotation(); + auto avatarLeftFootPose = myAvatar->getLeftFootControllerPoseInAvatarFrame(); + if (avatarLeftFootPose.isValid()) { + AnimPose pose(avatarLeftFootPose.getRotation(), avatarLeftFootPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_LeftFoot] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_LeftFoot] = true; } else { - handAndFeetParams.isLeftFootEnabled = false; + params.controllerPoses[Rig::ControllerType_LeftFoot] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_LeftFoot] = false; } - auto rightFootPose = myAvatar->getRightFootControllerPoseInAvatarFrame(); - if (rightFootPose.isValid()) { - handAndFeetParams.isRightFootEnabled = true; - handAndFeetParams.rightFootPosition = Quaternions::Y_180 * rightFootPose.getTranslation(); - handAndFeetParams.rightFootOrientation = Quaternions::Y_180 * rightFootPose.getRotation(); + auto avatarRightFootPose = myAvatar->getRightFootControllerPoseInAvatarFrame(); + if (avatarRightFootPose.isValid()) { + AnimPose pose(avatarRightFootPose.getRotation(), avatarRightFootPose.getTranslation()); + params.controllerPoses[Rig::ControllerType_RightFoot] = avatarToRigPose * pose; + params.controllerActiveFlags[Rig::ControllerType_RightFoot] = true; } else { - handAndFeetParams.isRightFootEnabled = false; + params.controllerPoses[Rig::ControllerType_RightFoot] = AnimPose::identity; + params.controllerActiveFlags[Rig::ControllerType_RightFoot] = false; } - handAndFeetParams.bodyCapsuleRadius = myAvatar->getCharacterController()->getCapsuleRadius(); - handAndFeetParams.bodyCapsuleHalfHeight = myAvatar->getCharacterController()->getCapsuleHalfHeight(); - handAndFeetParams.bodyCapsuleLocalOffset = myAvatar->getCharacterController()->getCapsuleLocalOffset(); + params.bodyCapsuleRadius = myAvatar->getCharacterController()->getCapsuleRadius(); + params.bodyCapsuleHalfHeight = myAvatar->getCharacterController()->getCapsuleHalfHeight(); + params.bodyCapsuleLocalOffset = myAvatar->getCharacterController()->getCapsuleLocalOffset(); - _rig.updateFromHandAndFeetParameters(handAndFeetParams, deltaTime); + params.isTalking = head->getTimeWithoutTalking() <= 1.5f; + + _rig.updateFromControllerParameters(params, deltaTime); Rig::CharacterControllerState ccState = convertCharacterControllerState(myAvatar->getCharacterController()->getState()); @@ -171,5 +174,50 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex; _rig.updateFromEyeParameters(eyeParams); + + updateFingers(myAvatar->getLeftHandFingerControllerPosesInSensorFrame()); + updateFingers(myAvatar->getRightHandFingerControllerPosesInSensorFrame()); } + +void MySkeletonModel::updateFingers(const MyAvatar::FingerPosesMap& fingerPoses) { + // Assumes that finger poses are kept in order in the poses map. + + if (fingerPoses.size() == 0) { + return; +} + + auto posesMapItr = fingerPoses.begin(); + + bool isLeftHand = posesMapItr->first < (int)controller::Action::RIGHT_HAND_THUMB1; + + MyAvatar* myAvatar = static_cast(_owningAvatar); + auto handPose = isLeftHand + ? myAvatar->getLeftHandControllerPoseInSensorFrame() + : myAvatar->getRightHandControllerPoseInSensorFrame(); + auto handJointRotation = handPose.getRotation(); + + bool isHandValid = handPose.isValid(); + bool isFingerValid = false; + glm::quat previousJointRotation; + + while (posesMapItr != fingerPoses.end()) { + auto jointName = posesMapItr->second.second; + if (isHandValid && jointName.right(1) == "1") { + isFingerValid = posesMapItr->second.first.isValid(); + previousJointRotation = handJointRotation; + } + + if (isHandValid && isFingerValid) { + auto thisJointRotation = posesMapItr->second.first.getRotation(); + const float CONTROLLER_PRIORITY = 2.0f; + _rig.setJointRotation(_rig.indexOfJoint(jointName), true, glm::inverse(previousJointRotation) * thisJointRotation, + CONTROLLER_PRIORITY); + previousJointRotation = thisJointRotation; + } else { + _rig.clearJointAnimationPriority(_rig.indexOfJoint(jointName)); + } + + posesMapItr++; + } +} diff --git a/interface/src/avatar/MySkeletonModel.h b/interface/src/avatar/MySkeletonModel.h index 12aba6b545..6867c596af 100644 --- a/interface/src/avatar/MySkeletonModel.h +++ b/interface/src/avatar/MySkeletonModel.h @@ -10,6 +10,7 @@ #define hifi_MySkeletonModel_h #include +#include "MyAvatar.h" /// A skeleton loaded from a model. class MySkeletonModel : public SkeletonModel { @@ -21,6 +22,9 @@ private: public: MySkeletonModel(Avatar* owningAvatar, QObject* parent = nullptr); void updateRig(float deltaTime, glm::mat4 parentTransform) override; + +private: + void updateFingers(const MyAvatar::FingerPosesMap& fingerPoses); }; #endif // hifi_MySkeletonModel_h diff --git a/interface/src/devices/Leapmotion.cpp b/interface/src/devices/Leapmotion.cpp deleted file mode 100644 index c643042300..0000000000 --- a/interface/src/devices/Leapmotion.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// -// Created by Sam Cake on 6/2/2014 -// Copyright 2014 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 "Leapmotion.h" - -#include - -#include "Menu.h" - -const int PALMROOT_NUM_JOINTS = 3; -const int FINGER_NUM_JOINTS = 4; -const int HAND_NUM_JOINTS = FINGER_NUM_JOINTS*5+PALMROOT_NUM_JOINTS; - -const DeviceTracker::Name Leapmotion::NAME = "Leapmotion"; - -// find the index of a joint from -// the side: true = right -// the finger & the bone: -// finger in [0..4] : bone in [0..3] a finger phalange -// [-1] up the hand branch : bone in [0..2] <=> [ hand, forearm, arm] -MotionTracker::Index evalJointIndex(bool isRightSide, int finger, int bone) { - - MotionTracker::Index offset = 1 // start after root - + (int(isRightSide) * HAND_NUM_JOINTS) // then offset for side - + PALMROOT_NUM_JOINTS; // then add the arm/forearm/hand chain - if (finger >= 0) { - // from there go down in the correct finger and bone - return offset + (finger * FINGER_NUM_JOINTS) + bone; - } else { - // or go back up for the correct root bone - return offset - 1 - bone; - } -} - -// static -void Leapmotion::init() { - DeviceTracker* device = DeviceTracker::getDevice(NAME); - - if (!device) { - // create a new Leapmotion and register it - Leapmotion* leap = new Leapmotion(); - DeviceTracker::registerDevice(NAME, leap); - } -} - -// static -void Leapmotion::destroy() { - DeviceTracker::destroyDevice(NAME); -} - -// static -Leapmotion* Leapmotion::getInstance() { - DeviceTracker* device = DeviceTracker::getDevice(NAME); - if (!device) { - // create a new Leapmotion and register it - device = new Leapmotion(); - DeviceTracker::registerDevice(NAME, device); - } - return dynamic_cast< Leapmotion* > (device); -} - -Leapmotion::Leapmotion() : - MotionTracker(), - _active(false) -{ - // Create the Leapmotion joint hierarchy - std::vector< Semantic > sides; - sides.push_back("joint_L_"); - sides.push_back("joint_R_"); - - std::vector< Semantic > rootBones; - rootBones.push_back("elbow"); - rootBones.push_back("wrist"); - rootBones.push_back("hand"); - - std::vector< Semantic > fingers; - fingers.push_back("thumb"); - fingers.push_back("index"); - fingers.push_back("middle"); - fingers.push_back("ring"); - fingers.push_back("pinky"); - - std::vector< Semantic > fingerBones; - fingerBones.push_back("1"); - fingerBones.push_back("2"); - fingerBones.push_back("3"); - fingerBones.push_back("4"); - - std::vector< Index > palms; - for (unsigned int s = 0; s < sides.size(); s++) { - Index rootJoint = 0; - for (unsigned int rb = 0; rb < rootBones.size(); rb++) { - rootJoint = addJoint(sides[s] + rootBones[rb], rootJoint); - } - - // capture the hand index for debug - palms.push_back(rootJoint); - - for (unsigned int f = 0; f < fingers.size(); f++) { - for (unsigned int b = 0; b < fingerBones.size(); b++) { - rootJoint = addJoint(sides[s] + fingers[f] + fingerBones[b], rootJoint); - } - } - } - -#ifdef HAVE_LEAPMOTION - if (Menu::getInstance()->isOptionChecked(MenuOption::LeapMotionOnHMD)) { - _controller.setPolicyFlags(Leap::Controller::POLICY_OPTIMIZE_HMD); - } -#endif -} - -Leapmotion::~Leapmotion() { -} - -#ifdef HAVE_LEAPMOTION -glm::quat quatFromLeapBase(float sideSign, const Leap::Matrix& basis) { - - // fix the handness to right and always... - glm::vec3 xAxis = glm::normalize(sideSign * glm::vec3(basis.xBasis.x, basis.xBasis.y, basis.xBasis.z)); - glm::vec3 yAxis = glm::normalize(glm::vec3(basis.yBasis.x, basis.yBasis.y, basis.yBasis.z)); - glm::vec3 zAxis = glm::normalize(glm::vec3(basis.zBasis.x, basis.zBasis.y, basis.zBasis.z)); - - xAxis = glm::normalize(glm::cross(yAxis, zAxis)); - - glm::quat orientation = (glm::quat_cast(glm::mat3(xAxis, yAxis, zAxis))); - return orientation; -} - -glm::vec3 vec3FromLeapVector(const Leap::Vector& vec) { - return glm::vec3(vec.x * METERS_PER_MILLIMETER, vec.y * METERS_PER_MILLIMETER, vec.z * METERS_PER_MILLIMETER); -} - -#endif - -void Leapmotion::update() { -#ifdef HAVE_LEAPMOTION - bool wasActive = _active; - _active = _controller.isConnected(); - - if (_active || wasActive) { - // Go through all the joints and increment their counter since last update. - // Increment all counters once after controller first becomes inactive so that each joint reports itself as inactive. - // TODO C++11 for (auto jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { - for (JointTracker::Vector::iterator jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { - (*jointIt).tickNewFrame(); - } - } - - if (!_active) { - return; - } - - // Get the most recent frame and report some basic information - const Leap::Frame frame = _controller.frame(); - static int64_t lastFrameID = -1; - int64_t newFrameID = frame.id(); - - // If too soon then exit - if (lastFrameID >= newFrameID) - return; - - glm::vec3 delta(0.0f); - glm::quat handOri; - if (!frame.hands().isEmpty()) { - for (int handNum = 0; handNum < frame.hands().count(); handNum++) { - - const Leap::Hand hand = frame.hands()[handNum]; - int side = (hand.isRight() ? 1 : -1); - - JointTracker* parentJointTracker = _jointsArray.data(); - - - int rootBranchIndex = -1; - - Leap::Arm arm = hand.arm(); - if (arm.isValid()) { - glm::quat ori = quatFromLeapBase(float(side), arm.basis()); - glm::vec3 pos = vec3FromLeapVector(arm.elbowPosition()); - JointTracker* elbow = editJointTracker(evalJointIndex((side > 0), rootBranchIndex, 2)); // 2 is the index of the elbow joint - elbow->editAbsFrame().setTranslation(pos); - elbow->editAbsFrame().setRotation(ori); - elbow->updateLocFromAbsTransform(parentJointTracker); - elbow->activeFrame(); - parentJointTracker = elbow; - - pos = vec3FromLeapVector(arm.wristPosition()); - JointTracker* wrist = editJointTracker(evalJointIndex((side > 0), rootBranchIndex, 1)); // 1 is the index of the wrist joint - wrist->editAbsFrame().setTranslation(pos); - wrist->editAbsFrame().setRotation(ori); - wrist->updateLocFromAbsTransform(parentJointTracker); - wrist->activeFrame(); - parentJointTracker = wrist; - } - - JointTracker* palmJoint = NULL; - { - glm::vec3 pos = vec3FromLeapVector(hand.palmPosition()); - glm::quat ori = quatFromLeapBase(float(side), hand.basis()); - - palmJoint = editJointTracker(evalJointIndex((side > 0), rootBranchIndex, 0)); // 0 is the index of the palm joint - palmJoint->editAbsFrame().setTranslation(pos); - palmJoint->editAbsFrame().setRotation(ori); - palmJoint->updateLocFromAbsTransform(parentJointTracker); - palmJoint->activeFrame(); - } - - // Check if the hand has any fingers - const Leap::FingerList fingers = hand.fingers(); - if (!fingers.isEmpty()) { - // For every fingers in the list - for (int i = 0; i < fingers.count(); ++i) { - // Reset the parent joint to the palmJoint for every finger traversal - parentJointTracker = palmJoint; - - // surprisingly, Leap::Finger::Type start at 0 for thumb a until 4 for the pinky - Index fingerIndex = evalJointIndex((side > 0), int(fingers[i].type()), 0); - - // let's update the finger's joints - for (int b = 0; b < FINGER_NUM_JOINTS; b++) { - Leap::Bone::Type type = Leap::Bone::Type(b + Leap::Bone::TYPE_METACARPAL); - Leap::Bone bone = fingers[i].bone(type); - JointTracker* ljointTracker = editJointTracker(fingerIndex + b); - if (bone.isValid()) { - Leap::Vector bp = bone.nextJoint(); - - ljointTracker->editAbsFrame().setTranslation(vec3FromLeapVector(bp)); - ljointTracker->editAbsFrame().setRotation(quatFromLeapBase(float(side), bone.basis())); - ljointTracker->updateLocFromAbsTransform(parentJointTracker); - ljointTracker->activeFrame(); - } - parentJointTracker = ljointTracker; - } - } - } - } - } - - lastFrameID = newFrameID; -#endif -} diff --git a/interface/src/devices/Leapmotion.h b/interface/src/devices/Leapmotion.h deleted file mode 100644 index a119821846..0000000000 --- a/interface/src/devices/Leapmotion.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// Created by Sam Cake on 6/2/2014 -// Copyright 2014 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_Leapmotion_h -#define hifi_Leapmotion_h - -#include - -#include - -#ifdef HAVE_LEAPMOTION -#include -#endif - -/// Handles interaction with the Leapmotion skeleton tracking suit. -class Leapmotion : public MotionTracker { -public: - static const Name NAME; - - static void init(); - static void destroy(); - - /// Leapmotion MotionTracker factory - static Leapmotion* getInstance(); - - bool isActive() const { return _active; } - - virtual void update() override; - -protected: - Leapmotion(); - virtual ~Leapmotion(); - -private: -#ifdef HAVE_LEAPMOTION - Leap::Listener _listener; - Leap::Controller _controller; -#endif - - bool _active; -}; - -#endif // hifi_Leapmotion_h diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 83cac6d9bb..42ceb756b9 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "AddressManager.h" #include "Application.h" @@ -71,15 +72,19 @@ int main(int argc, const char* argv[]) { QCommandLineOption runServerOption("runServer", "Whether to run the server"); QCommandLineOption serverContentPathOption("serverContentPath", "Where to find server content", "serverContentPath"); QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run"); + QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache ", "dir"); + QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts ", "path"); parser.addOption(urlOption); parser.addOption(noUpdaterOption); parser.addOption(checkMinSpecOption); parser.addOption(runServerOption); parser.addOption(serverContentPathOption); + parser.addOption(overrideAppLocalDataPathOption); + parser.addOption(overrideScriptsPathOption); parser.addOption(allowMultipleInstancesOption); parser.parse(arguments); - + const QString& applicationName = getInterfaceSharedMemoryName(); bool instanceMightBeRunning = true; #ifdef Q_OS_WIN @@ -96,6 +101,29 @@ int main(int argc, const char* argv[]) { if (allowMultipleInstances) { instanceMightBeRunning = false; } + // this needs to be done here in main, as the mechanism for setting the + // scripts directory appears not to work. See the bug report + // https://highfidelity.fogbugz.com/f/cases/5759/Issues-changing-scripts-directory-in-ScriptsEngine + if (parser.isSet(overrideScriptsPathOption)) { + QDir scriptsPath(parser.value(overrideScriptsPathOption)); + if (scriptsPath.exists()) { + PathUtils::defaultScriptsLocation(scriptsPath.path()); + } + } + + if (parser.isSet(overrideAppLocalDataPathOption)) { + // get dir to use for cache + QString cacheDir = parser.value(overrideAppLocalDataPathOption); + if (!cacheDir.isEmpty()) { + // tell everyone to use the right cache location + // + // this handles data8 and prepared + DependencyManager::get()->setCacheDir(cacheDir); + + // this does the ktx_cache + PathUtils::getAppLocalDataPath(cacheDir); + } + } if (instanceMightBeRunning) { // Try to connect and send message to existing interface instance @@ -179,7 +207,7 @@ int main(int argc, const char* argv[]) { QString openvrDllPath = appPath + "/plugins/openvr.dll"; HMODULE openvrDll; CHECKMINSPECPROC checkMinSpecPtr; - if ((openvrDll = LoadLibrary(openvrDllPath.toLocal8Bit().data())) && + if ((openvrDll = LoadLibrary(openvrDllPath.toLocal8Bit().data())) && (checkMinSpecPtr = (CHECKMINSPECPROC)GetProcAddress(openvrDll, "CheckMinSpec"))) { if (!checkMinSpecPtr()) { return -1; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index f3ec3cd79d..9fbd01817a 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -17,7 +17,6 @@ #include #include "Application.h" -#include void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) { if (event->type() == HFActionEvent::startType()) { @@ -97,86 +96,6 @@ QVariant ControllerScriptingInterface::getRecommendedOverlayRect() const { return qRectToVariant(rect); } -controller::InputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) { - // This is where we retrieve the Device Tracker category and then the sub tracker within it - auto icIt = _inputControllers.find(0); - if (icIt != _inputControllers.end()) { - return (*icIt).second.get(); - } - - // Look for device - DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString()); - if (deviceID < 0) { - deviceID = 0; - } - // TODO in this current implementation, we just pick the device assuming there is one (normally the Leapmotion) - // in the near future we need to change that to a real mapping between the devices and the deviceName - // ALso we need to expand the spec so we can fall back on the "default" controller per categories - - if (deviceID >= 0) { - // TODO here again the assumption it's the LeapMotion and so it's a MOtionTracker, this would need to be changed to support different types of devices - MotionTracker* motionTracker = dynamic_cast< MotionTracker* > (DeviceTracker::getDevice(deviceID)); - if (motionTracker) { - MotionTracker::Index trackerID = motionTracker->findJointIndex(tracker.toStdString()); - if (trackerID >= 0) { - controller::InputController::Pointer inputController = std::make_shared(deviceID, trackerID, this); - controller::InputController::Key key = inputController->getKey(); - _inputControllers.insert(InputControllerMap::value_type(key, inputController)); - return inputController.get(); - } - } - } - - return nullptr; -} - -void ControllerScriptingInterface::releaseInputController(controller::InputController* input) { - _inputControllers.erase(input->getKey()); -} - -void ControllerScriptingInterface::updateInputControllers() { - for (auto it = _inputControllers.begin(); it != _inputControllers.end(); it++) { - (*it).second->update(); - } -} - -InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) : - _deviceTrackerId(deviceTrackerId), - _subTrackerId(subTrackerId), - _isActive(false) -{ -} - -void InputController::update() { - _isActive = false; - - // TODO for now the InputController is only supporting a JointTracker from a MotionTracker - MotionTracker* motionTracker = dynamic_cast< MotionTracker*> (DeviceTracker::getDevice(_deviceTrackerId)); - if (motionTracker) { - if ((int)_subTrackerId < motionTracker->numJointTrackers()) { - const MotionTracker::JointTracker* joint = motionTracker->getJointTracker(_subTrackerId); - - if (joint->isActive()) { - joint->getAbsFrame().getTranslation(_eventCache.absTranslation); - joint->getAbsFrame().getRotation(_eventCache.absRotation); - joint->getLocFrame().getTranslation(_eventCache.locTranslation); - joint->getLocFrame().getRotation(_eventCache.locRotation); - - _isActive = true; - //emit spatialEvent(_eventCache); - } - } - } -} - -const unsigned int INPUTCONTROLLER_KEY_DEVICE_OFFSET = 16; -const unsigned int INPUTCONTROLLER_KEY_DEVICE_MASK = 16; - -InputController::Key InputController::getKey() const { - return (((_deviceTrackerId & INPUTCONTROLLER_KEY_DEVICE_MASK) << INPUTCONTROLLER_KEY_DEVICE_OFFSET) | _subTrackerId); -} - - void ControllerScriptingInterface::emitKeyPressEvent(QKeyEvent* event) { emit keyPressEvent(KeyEvent(*event)); } void ControllerScriptingInterface::emitKeyReleaseEvent(QKeyEvent* event) { emit keyReleaseEvent(KeyEvent(*event)); } diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index 996ccabb20..6d197477bb 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -25,38 +25,6 @@ #include class ScriptEngine; -class PalmData; - -class InputController : public controller::InputController { - Q_OBJECT - -public: - InputController(int deviceTrackerId, int subTrackerId, QObject* parent = NULL); - - virtual void update() override; - virtual Key getKey() const override; - -public slots: - - virtual bool isActive() const override { return _isActive; } - virtual glm::vec3 getAbsTranslation() const override { return _eventCache.absTranslation; } - virtual glm::quat getAbsRotation() const override { return _eventCache.absRotation; } - virtual glm::vec3 getLocTranslation() const override { return _eventCache.locTranslation; } - virtual glm::quat getLocRotation() const override { return _eventCache.locRotation; } - -private: - - int _deviceTrackerId; - uint _subTrackerId; - - // cache for the spatial - SpatialEvent _eventCache; - bool _isActive; - -signals: -}; - - /// handles scripting of input controller commands from JS class ControllerScriptingInterface : public controller::ScriptingInterface { Q_OBJECT @@ -86,8 +54,6 @@ public: bool isJoystickCaptured(int joystickIndex) const; bool areEntityClicksCaptured() const; - void updateInputControllers(); - public slots: virtual void captureKeyEvents(const KeyEvent& event); @@ -102,10 +68,6 @@ public slots: virtual glm::vec2 getViewportDimensions() const; virtual QVariant getRecommendedOverlayRect() const; - /// Factory to create an InputController - virtual controller::InputController* createInputController(const QString& deviceName, const QString& tracker); - virtual void releaseInputController(controller::InputController* input); - signals: void keyPressEvent(const KeyEvent& event); void keyReleaseEvent(const KeyEvent& event); @@ -135,8 +97,6 @@ private: bool _captureEntityClicks; using InputKey = controller::InputController::Key; - using InputControllerMap = std::map; - InputControllerMap _inputControllers; }; const int NUMBER_OF_SPATIALCONTROLS_PER_PALM = 2; // the hand and the tip diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index b8892fae7e..84c742d0ab 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -62,7 +62,7 @@ bool TestScriptingInterface::loadTestScene(QString scene) { static const QString TEST_SCRIPTS_ROOT = TEST_ROOT + "scripts/"; static const QString TEST_SCENES_ROOT = TEST_ROOT + "scenes/"; return DependencyManager::get()->returnFromUiThread([scene]()->QVariant { - ResourceManager::setUrlPrefixOverride("atp:/", TEST_BINARY_ROOT + scene + ".atp/"); + DependencyManager::get()->setUrlPrefixOverride("atp:/", TEST_BINARY_ROOT + scene + ".atp/"); auto tree = qApp->getEntities()->getTree(); auto treeIsClient = tree->getIsClient(); // Force the tree to accept the load regardless of permissions diff --git a/libraries/animation/src/AnimDefaultPose.cpp b/libraries/animation/src/AnimDefaultPose.cpp new file mode 100644 index 0000000000..70bcbe7c21 --- /dev/null +++ b/libraries/animation/src/AnimDefaultPose.cpp @@ -0,0 +1,34 @@ +// +// AnimDefaultPose.cpp +// +// Created by Anthony J. Thibault on 6/26/17. +// Copyright (c) 2017 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimDefaultPose.h" + +AnimDefaultPose::AnimDefaultPose(const QString& id) : + AnimNode(AnimNode::Type::DefaultPose, id) +{ + +} + +AnimDefaultPose::~AnimDefaultPose() { + +} + +const AnimPoseVec& AnimDefaultPose::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) { + if (_skeleton) { + _poses = _skeleton->getRelativeDefaultPoses(); + } else { + _poses.clear(); + } + return _poses; +} + +const AnimPoseVec& AnimDefaultPose::getPosesInternal() const { + return _poses; +} diff --git a/libraries/animation/src/AnimDefaultPose.h b/libraries/animation/src/AnimDefaultPose.h new file mode 100644 index 0000000000..eefefac7af --- /dev/null +++ b/libraries/animation/src/AnimDefaultPose.h @@ -0,0 +1,36 @@ +// +// AnimDefaultPose.h +// +// Created by Anthony J. Thibault on 6/26/17. +// Copyright (c) 2017 High Fidelity, Inc. All rights reserved. +// +// 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_AnimDefaultPose_h +#define hifi_AnimDefaultPose_h + +#include +#include "AnimNode.h" + +// Always returns the default pose of the current skeleton. + +class AnimDefaultPose : public AnimNode { +public: + AnimDefaultPose(const QString& id); + virtual ~AnimDefaultPose() override; + + virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override; +protected: + // for AnimDebugDraw rendering + virtual const AnimPoseVec& getPosesInternal() const override; + + AnimPoseVec _poses; + + // no copies + AnimDefaultPose(const AnimDefaultPose&) = delete; + AnimDefaultPose& operator=(const AnimDefaultPose&) = delete; +}; + +#endif // hifi_AnimDefaultPose_h diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 77437e79b9..d7076a443e 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -23,13 +23,40 @@ #include "CubicHermiteSpline.h" #include "AnimUtil.h" +static void lookupJointChainInfo(AnimInverseKinematics::JointChainInfo* jointChainInfos, size_t numJointChainInfos, + int indexA, int indexB, + AnimInverseKinematics::JointChainInfo** jointChainInfoA, + AnimInverseKinematics::JointChainInfo** jointChainInfoB) { + *jointChainInfoA = nullptr; + *jointChainInfoB = nullptr; + for (size_t i = 0; i < numJointChainInfos; i++) { + if (jointChainInfos[i].jointIndex == indexA) { + *jointChainInfoA = jointChainInfos + i; + } + if (jointChainInfos[i].jointIndex == indexB) { + *jointChainInfoB = jointChainInfos + i; + } + if (*jointChainInfoA && *jointChainInfoB) { + break; + } + } +} + +static float easeOutExpo(float t) { + return 1.0f - powf(2, -10.0f * t); +} + AnimInverseKinematics::IKTargetVar::IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn, - const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector& flexCoefficientsIn) : + const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector& flexCoefficientsIn, + const QString& poleVectorEnabledVarIn, const QString& poleReferenceVectorVarIn, const QString& poleVectorVarIn) : jointName(jointNameIn), positionVar(positionVarIn), rotationVar(rotationVarIn), typeVar(typeVarIn), weightVar(weightVarIn), + poleVectorEnabledVar(poleVectorEnabledVarIn), + poleReferenceVectorVar(poleReferenceVectorVarIn), + poleVectorVar(poleVectorVarIn), weight(weightIn), numFlexCoefficients(flexCoefficientsIn.size()), jointIndex(-1) @@ -46,6 +73,9 @@ AnimInverseKinematics::IKTargetVar::IKTargetVar(const IKTargetVar& orig) : rotationVar(orig.rotationVar), typeVar(orig.typeVar), weightVar(orig.weightVar), + poleVectorEnabledVar(orig.poleVectorEnabledVar), + poleReferenceVectorVar(orig.poleReferenceVectorVar), + poleVectorVar(orig.poleVectorVar), weight(orig.weight), numFlexCoefficients(orig.numFlexCoefficients), jointIndex(orig.jointIndex) @@ -99,8 +129,9 @@ void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) con } void AnimInverseKinematics::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, - const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients) { - IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients); + const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, + const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar) { + IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients, poleVectorEnabledVar, poleReferenceVectorVar, poleVectorVar); // if there are dups, last one wins. bool found = false; @@ -138,9 +169,9 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: IKTarget target; target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition)); if (target.getType() != IKTarget::Type::Unknown) { - AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); - glm::quat rotation = animVars.lookupRigToGeometry(targetVar.rotationVar, defaultPose.rot()); - glm::vec3 translation = animVars.lookupRigToGeometry(targetVar.positionVar, defaultPose.trans()); + AnimPose absPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); + glm::quat rotation = animVars.lookupRigToGeometry(targetVar.rotationVar, absPose.rot()); + glm::vec3 translation = animVars.lookupRigToGeometry(targetVar.positionVar, absPose.trans()); float weight = animVars.lookup(targetVar.weightVar, targetVar.weight); target.setPose(rotation, translation); @@ -148,6 +179,15 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: target.setWeight(weight); target.setFlexCoefficients(targetVar.numFlexCoefficients, targetVar.flexCoefficients); + bool poleVectorEnabled = animVars.lookup(targetVar.poleVectorEnabledVar, false); + target.setPoleVectorEnabled(poleVectorEnabled); + + glm::vec3 poleVector = animVars.lookupRigToGeometryVector(targetVar.poleVectorVar, Vectors::UNIT_Z); + target.setPoleVector(glm::normalize(poleVector)); + + glm::vec3 poleReferenceVector = animVars.lookupRigToGeometryVector(targetVar.poleReferenceVectorVar, Vectors::UNIT_Z); + target.setPoleReferenceVector(glm::normalize(poleReferenceVector)); + targets.push_back(target); if (targetVar.jointIndex > _maxTargetIndex) { @@ -298,7 +338,8 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const // the tip's parent-relative as we proceed up the chain glm::quat tipParentOrientation = absolutePoses[pivotIndex].rot(); - std::map debugJointMap; + const size_t MAX_CHAIN_DEPTH = 30; + JointChainInfo jointChainInfos[MAX_CHAIN_DEPTH]; // NOTE: if this code is removed, the head will remain rigid, causing the spine/hips to thrust forward backward // as the head is nodded. @@ -326,15 +367,8 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const } } - // store the relative rotation change in the accumulator - _rotationAccumulators[tipIndex].add(tipRelativeRotation, target.getWeight()); - glm::vec3 tipRelativeTranslation = _relativePoses[target.getIndex()].trans(); - _translationAccumulators[tipIndex].add(tipRelativeTranslation); - - if (debug) { - debugJointMap[tipIndex] = DebugJoint(tipRelativeRotation, tipRelativeTranslation, constrained); - } + jointChainInfos[chainDepth] = { tipRelativeRotation, tipRelativeTranslation, target.getWeight(), tipIndex, constrained }; } // cache tip absolute position @@ -344,6 +378,9 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const // descend toward root, pivoting each joint to get tip closer to target position while (pivotIndex != _hipsIndex && pivotsParentIndex != -1) { + + assert(chainDepth < MAX_CHAIN_DEPTH); + // compute the two lines that should be aligned glm::vec3 jointPosition = absolutePoses[pivotIndex].trans(); glm::vec3 leverArm = tipPosition - jointPosition; @@ -357,6 +394,7 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const const float MIN_AXIS_LENGTH = 1.0e-4f; RotationConstraint* constraint = getConstraint(pivotIndex); + // only allow swing on lowerSpine if there is a hips IK target. if (_hipsTargetIndex < 0 && constraint && constraint->isLowerSpine() && tipIndex != _headIndex) { // for these types of targets we only allow twist at the lower-spine @@ -382,6 +420,7 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const float cosAngle = glm::clamp(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f, 1.0f); float angle = acosf(cosAngle); const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; + if (angle > MIN_ADJUSTMENT_ANGLE) { // reduce angle by a flexCoefficient angle *= target.getFlexCoefficient(chainDepth); @@ -440,15 +479,8 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const } } - // store the relative rotation change in the accumulator - _rotationAccumulators[pivotIndex].add(newRot, target.getWeight()); - glm::vec3 newTrans = _relativePoses[pivotIndex].trans(); - _translationAccumulators[pivotIndex].add(newTrans); - - if (debug) { - debugJointMap[pivotIndex] = DebugJoint(newRot, newTrans, constrained); - } + jointChainInfos[chainDepth] = { newRot, newTrans, target.getWeight(), pivotIndex, constrained }; // keep track of tip's new transform as we descend towards root tipPosition = jointPosition + deltaRotation * (tipPosition - jointPosition); @@ -461,8 +493,127 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const chainDepth++; } + if (target.getPoleVectorEnabled()) { + int topJointIndex = target.getIndex(); + int midJointIndex = _skeleton->getParentIndex(topJointIndex); + if (midJointIndex != -1) { + int baseJointIndex = _skeleton->getParentIndex(midJointIndex); + if (baseJointIndex != -1) { + int baseParentJointIndex = _skeleton->getParentIndex(baseJointIndex); + AnimPose topPose, midPose, basePose; + int topChainIndex = -1, baseChainIndex = -1; + AnimPose postAbsPoses[MAX_CHAIN_DEPTH]; + AnimPose accum = absolutePoses[_hipsIndex]; + AnimPose baseParentPose = absolutePoses[_hipsIndex]; + for (int i = (int)chainDepth - 1; i >= 0; i--) { + accum = accum * AnimPose(glm::vec3(1.0f), jointChainInfos[i].relRot, jointChainInfos[i].relTrans); + postAbsPoses[i] = accum; + if (jointChainInfos[i].jointIndex == topJointIndex) { + topChainIndex = i; + topPose = accum; + } + if (jointChainInfos[i].jointIndex == midJointIndex) { + midPose = accum; + } + if (jointChainInfos[i].jointIndex == baseJointIndex) { + baseChainIndex = i; + basePose = accum; + } + if (jointChainInfos[i].jointIndex == baseParentJointIndex) { + baseParentPose = accum; + } + } + + glm::quat poleRot = Quaternions::IDENTITY; + glm::vec3 d = basePose.trans() - topPose.trans(); + float dLen = glm::length(d); + if (dLen > EPSILON) { + glm::vec3 dUnit = d / dLen; + glm::vec3 e = midPose.xformVector(target.getPoleReferenceVector()); + glm::vec3 eProj = e - glm::dot(e, dUnit) * dUnit; + float eProjLen = glm::length(eProj); + + const float MIN_EPROJ_LEN = 0.5f; + if (eProjLen < MIN_EPROJ_LEN) { + glm::vec3 midPoint = topPose.trans() + d * 0.5f; + e = midPose.trans() - midPoint; + eProj = e - glm::dot(e, dUnit) * dUnit; + eProjLen = glm::length(eProj); + } + + glm::vec3 p = target.getPoleVector(); + glm::vec3 pProj = p - glm::dot(p, dUnit) * dUnit; + float pProjLen = glm::length(pProj); + + if (eProjLen > EPSILON && pProjLen > EPSILON) { + // as pProjLen become orthognal to d, reduce the amount of rotation. + float magnitude = easeOutExpo(pProjLen); + float dot = glm::clamp(glm::dot(eProj / eProjLen, pProj / pProjLen), 0.0f, 1.0f); + float theta = acosf(dot); + glm::vec3 cross = glm::cross(eProj, pProj); + const float MIN_ADJUSTMENT_ANGLE = 0.001745f; // 0.1 degree + if (theta > MIN_ADJUSTMENT_ANGLE) { + glm::vec3 axis = dUnit; + if (glm::dot(cross, dUnit) < 0) { + axis = -dUnit; + } + poleRot = glm::angleAxis(magnitude * theta, axis); + } + } + } + + if (debug) { + const vec4 RED(1.0f, 0.0f, 0.0f, 1.0f); + const vec4 GREEN(0.0f, 1.0f, 0.0f, 1.0f); + const vec4 BLUE(0.0f, 0.0f, 1.0f, 1.0f); + const vec4 YELLOW(1.0f, 1.0f, 0.0f, 1.0f); + const vec4 WHITE(1.0f, 1.0f, 1.0f, 1.0f); + + AnimPose geomToWorldPose = AnimPose(context.getRigToWorldMatrix() * context.getGeometryToRigMatrix()); + + glm::vec3 dUnit = d / dLen; + glm::vec3 e = midPose.xformVector(target.getPoleReferenceVector()); + glm::vec3 eProj = e - glm::dot(e, dUnit) * dUnit; + float eProjLen = glm::length(eProj); + const float MIN_EPROJ_LEN = 0.5f; + if (eProjLen < MIN_EPROJ_LEN) { + glm::vec3 midPoint = topPose.trans() + d * 0.5f; + e = midPose.trans() - midPoint; + eProj = e - glm::dot(e, dUnit) * dUnit; + eProjLen = glm::length(eProj); + } + + glm::vec3 p = target.getPoleVector(); + const float PROJ_VECTOR_LEN = 10.0f; + const float POLE_VECTOR_LEN = 100.0f; + glm::vec3 midPoint = (basePose.trans() + topPose.trans()) * 0.5f; + DebugDraw::getInstance().drawRay(geomToWorldPose.xformPoint(basePose.trans()), + geomToWorldPose.xformPoint(topPose.trans()), + YELLOW); + DebugDraw::getInstance().drawRay(geomToWorldPose.xformPoint(midPoint), + geomToWorldPose.xformPoint(midPoint + PROJ_VECTOR_LEN * glm::normalize(e)), + RED); + DebugDraw::getInstance().drawRay(geomToWorldPose.xformPoint(midPoint), + geomToWorldPose.xformPoint(midPoint + POLE_VECTOR_LEN * glm::normalize(p)), + BLUE); + } + + glm::quat newBaseRelRot = glm::inverse(baseParentPose.rot()) * poleRot * basePose.rot(); + jointChainInfos[baseChainIndex].relRot = newBaseRelRot; + + glm::quat newTopRelRot = glm::inverse(midPose.rot()) * glm::inverse(poleRot) * topPose.rot(); + jointChainInfos[topChainIndex].relRot = newTopRelRot; + } + } + } + + for (size_t i = 0; i < chainDepth; i++) { + _rotationAccumulators[jointChainInfos[i].jointIndex].add(jointChainInfos[i].relRot, jointChainInfos[i].weight); + _translationAccumulators[jointChainInfos[i].jointIndex].add(jointChainInfos[i].relTrans, jointChainInfos[i].weight); + } + if (debug) { - debugDrawIKChain(debugJointMap, context); + debugDrawIKChain(jointChainInfos, chainDepth, context); } } @@ -548,7 +699,8 @@ const std::vector* AnimInverseKinematics void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug) { - std::map debugJointMap; + const size_t MAX_CHAIN_DEPTH = 30; + JointChainInfo jointChainInfos[MAX_CHAIN_DEPTH]; const int baseIndex = _hipsIndex; @@ -608,7 +760,6 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, target.getFlexCoefficient(i), &flexedAbsPose); AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; - _rotationAccumulators[splineJointInfo.jointIndex].add(relPose.rot(), target.getWeight()); bool constrained = false; if (splineJointInfo.jointIndex != _hipsIndex) { @@ -632,18 +783,19 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co } } - _translationAccumulators[splineJointInfo.jointIndex].add(relPose.trans(), target.getWeight()); - - if (debug) { - debugJointMap[splineJointInfo.jointIndex] = DebugJoint(relPose.rot(), relPose.trans(), constrained); - } + jointChainInfos[i] = { relPose.rot(), relPose.trans(), target.getWeight(), splineJointInfo.jointIndex, constrained }; parentAbsPose = flexedAbsPose; } } + for (size_t i = 0; i < splineJointInfoVec->size(); i++) { + _rotationAccumulators[jointChainInfos[i].jointIndex].add(jointChainInfos[i].relRot, jointChainInfos[i].weight); + _translationAccumulators[jointChainInfos[i].jointIndex].add(jointChainInfos[i].relTrans, jointChainInfos[i].weight); + } + if (debug) { - debugDrawIKChain(debugJointMap, context); + debugDrawIKChain(jointChainInfos, splineJointInfoVec->size(), context); } } @@ -654,6 +806,7 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar return _relativePoses; } + //virtual const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { // allows solutionSource to be overridden by an animVar @@ -717,9 +870,9 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars float scaleFactor = ((offsetLength - MIN_HIPS_OFFSET_LENGTH) / offsetLength); glm::vec3 hipsOffset = scaleFactor * _hipsOffset; if (_hipsParentIndex == -1) { - _relativePoses[_hipsIndex].trans() = underPoses[_hipsIndex].trans() + hipsOffset; + _relativePoses[_hipsIndex].trans() = _relativePoses[_hipsIndex].trans() + hipsOffset; } else { - auto absHipsPose = _skeleton->getAbsolutePose(_hipsIndex, underPoses); + auto absHipsPose = _skeleton->getAbsolutePose(_hipsIndex, _relativePoses); absHipsPose.trans() += hipsOffset; _relativePoses[_hipsIndex] = _skeleton->getAbsolutePose(_hipsParentIndex, _relativePoses).inverse() * absHipsPose; } @@ -767,6 +920,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars { PROFILE_RANGE_EX(simulation_animation, "ik/ccd", 0xffff00ff, 0); + preconditionRelativePosesToAvoidLimbLock(context, targets); solve(context, targets); } @@ -921,7 +1075,7 @@ void AnimInverseKinematics::initConstraints() { // y | // | | // | O---O---O RightUpLeg - // z | | Hips2 | + // z | | Hips | // \ | | | // \| | | // x -----+ O O RightLeg @@ -966,7 +1120,9 @@ void AnimInverseKinematics::initConstraints() { if (0 == baseName.compare("Arm", Qt::CaseSensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot()); - stConstraint->setTwistLimits(-PI / 2.0f, PI / 2.0f); + //stConstraint->setTwistLimits(-PI / 2.0f, PI / 2.0f); + const float TWIST_LIMIT = 5.0f * PI / 8.0f; + stConstraint->setTwistLimits(-TWIST_LIMIT, TWIST_LIMIT); /* KEEP THIS CODE for future experimentation // these directions are approximate swing limits in root-frame @@ -992,7 +1148,7 @@ void AnimInverseKinematics::initConstraints() { // simple cone std::vector minDots; - const float MAX_HAND_SWING = PI / 2.0f; + const float MAX_HAND_SWING = 5.0f * PI / 8.0f; minDots.push_back(cosf(MAX_HAND_SWING)); stConstraint->setSwingLimits(minDots); @@ -1000,7 +1156,7 @@ void AnimInverseKinematics::initConstraints() { } else if (0 == baseName.compare("UpLeg", Qt::CaseSensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot()); - stConstraint->setTwistLimits(-PI / 4.0f, PI / 4.0f); + stConstraint->setTwistLimits(-PI / 2.0f, PI / 2.0f); std::vector swungDirections; float deltaTheta = PI / 4.0f; @@ -1142,7 +1298,7 @@ void AnimInverseKinematics::initConstraints() { // we determine the max/min angles by rotating the swing limit lines from parent- to child-frame // then measure the angles to swing the yAxis into alignment glm::vec3 hingeAxis = - mirror * Vectors::UNIT_Z; - const float MIN_ELBOW_ANGLE = 0.05f; + const float MIN_ELBOW_ANGLE = 0.0f; const float MAX_ELBOW_ANGLE = 11.0f * PI / 12.0f; glm::quat invReferenceRotation = glm::inverse(referenceRotation); glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_ELBOW_ANGLE, hingeAxis) * Vectors::UNIT_Y; @@ -1173,8 +1329,8 @@ void AnimInverseKinematics::initConstraints() { // we determine the max/min angles by rotating the swing limit lines from parent- to child-frame // then measure the angles to swing the yAxis into alignment - const float MIN_KNEE_ANGLE = 0.097f; // ~5 deg - const float MAX_KNEE_ANGLE = 7.0f * PI / 8.0f; + const float MIN_KNEE_ANGLE = 0.0f; + const float MAX_KNEE_ANGLE = 7.0f * PI / 8.0f; // 157.5 deg glm::quat invReferenceRotation = glm::inverse(referenceRotation); glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_KNEE_ANGLE, hingeAxis) * Vectors::UNIT_Y; glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_KNEE_ANGLE, hingeAxis) * Vectors::UNIT_Y; @@ -1308,6 +1464,7 @@ void AnimInverseKinematics::debugDrawRelativePoses(const AnimContext& context) c // convert relative poses to absolute _skeleton->convertRelativePosesToAbsolute(poses); + mat4 geomToWorldMatrix = context.getRigToWorldMatrix() * context.getGeometryToRigMatrix(); const vec4 RED(1.0f, 0.0f, 0.0f, 1.0f); @@ -1338,13 +1495,14 @@ void AnimInverseKinematics::debugDrawRelativePoses(const AnimContext& context) c } } -void AnimInverseKinematics::debugDrawIKChain(std::map& debugJointMap, const AnimContext& context) const { +void AnimInverseKinematics::debugDrawIKChain(JointChainInfo* jointChainInfos, size_t numJointChainInfos, const AnimContext& context) const { AnimPoseVec poses = _relativePoses; // copy debug joint rotations into the relative poses - for (auto& debugJoint : debugJointMap) { - poses[debugJoint.first].rot() = debugJoint.second.relRot; - poses[debugJoint.first].trans() = debugJoint.second.relTrans; + for (size_t i = 0; i < numJointChainInfos; i++) { + const JointChainInfo& info = jointChainInfos[i]; + poses[info.jointIndex].rot() = info.relRot; + poses[info.jointIndex].trans() = info.relTrans; } // convert relative poses to absolute @@ -1360,11 +1518,11 @@ void AnimInverseKinematics::debugDrawIKChain(std::map& debugJoi // draw each pose for (int i = 0; i < (int)poses.size(); i++) { - - // only draw joints that are actually in debugJointMap, or their parents - auto iter = debugJointMap.find(i); - auto parentIter = debugJointMap.find(_skeleton->getParentIndex(i)); - if (iter != debugJointMap.end() || parentIter != debugJointMap.end()) { + int parentIndex = _skeleton->getParentIndex(i); + JointChainInfo* jointInfo = nullptr; + JointChainInfo* parentJointInfo = nullptr; + lookupJointChainInfo(jointChainInfos, numJointChainInfos, i, parentIndex, &jointInfo, &parentJointInfo); + if (jointInfo && parentJointInfo) { // transform local axes into world space. auto pose = poses[i]; @@ -1377,13 +1535,12 @@ void AnimInverseKinematics::debugDrawIKChain(std::map& debugJoi DebugDraw::getInstance().drawRay(pos, pos + AXIS_LENGTH * zAxis, BLUE); // draw line to parent - int parentIndex = _skeleton->getParentIndex(i); if (parentIndex != -1) { glm::vec3 parentPos = transformPoint(geomToWorldMatrix, poses[parentIndex].trans()); glm::vec4 color = GRAY; // draw constrained joints with a RED link to their parent. - if (parentIter != debugJointMap.end() && parentIter->second.constrained) { + if (parentJointInfo->constrained) { color = RED; } DebugDraw::getInstance().drawRay(pos, parentPos, color); @@ -1486,7 +1643,7 @@ void AnimInverseKinematics::debugDrawConstraints(const AnimContext& context) con glm::vec3 worldSwungAxis = transformVectorFast(geomToWorldMatrix, parentAbsRot * refRot * swungAxis); glm::vec3 swingTip = pos + SWING_LENGTH * worldSwungAxis; - float prevPhi = acos(swingTwistConstraint->getMinDots()[j]); + float prevPhi = acosf(swingTwistConstraint->getMinDots()[j]); float prevTheta = theta - D_THETA; glm::vec3 prevSwungAxis = sphericalToCartesian(prevPhi, prevTheta - PI_2); glm::vec3 prevWorldSwungAxis = transformVectorFast(geomToWorldMatrix, parentAbsRot * refRot * prevSwungAxis); @@ -1521,6 +1678,50 @@ void AnimInverseKinematics::blendToPoses(const AnimPoseVec& targetPoses, const A } } +void AnimInverseKinematics::preconditionRelativePosesToAvoidLimbLock(const AnimContext& context, const std::vector& targets) { + const int NUM_LIMBS = 4; + std::pair limbs[NUM_LIMBS] = { + {_skeleton->nameToJointIndex("LeftHand"), _skeleton->nameToJointIndex("LeftArm")}, + {_skeleton->nameToJointIndex("RightHand"), _skeleton->nameToJointIndex("RightArm")}, + {_skeleton->nameToJointIndex("LeftFoot"), _skeleton->nameToJointIndex("LeftUpLeg")}, + {_skeleton->nameToJointIndex("RightFoot"), _skeleton->nameToJointIndex("RightUpLeg")} + }; + const float MIN_AXIS_LENGTH = 1.0e-4f; + + for (auto& target : targets) { + if (target.getIndex() != -1) { + for (int i = 0; i < NUM_LIMBS; i++) { + if (limbs[i].first == target.getIndex()) { + int tipIndex = limbs[i].first; + int baseIndex = limbs[i].second; + + // TODO: as an optimization, these poses can be computed in one pass down the chain, instead of three. + AnimPose tipPose = _skeleton->getAbsolutePose(tipIndex, _relativePoses); + AnimPose basePose = _skeleton->getAbsolutePose(baseIndex, _relativePoses); + AnimPose baseParentPose = _skeleton->getAbsolutePose(_skeleton->getParentIndex(baseIndex), _relativePoses); + + // to help reduce limb locking, and to help the CCD solver converge faster + // rotate the limbs leverArm over the targetLine. + glm::vec3 targetLine = target.getTranslation() - basePose.trans(); + glm::vec3 leverArm = tipPose.trans() - basePose.trans(); + glm::vec3 axis = glm::cross(leverArm, targetLine); + float axisLength = glm::length(axis); + if (axisLength > MIN_AXIS_LENGTH) { + // compute angle of rotation that brings tip to target + axis /= axisLength; + float cosAngle = glm::clamp(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f, 1.0f); + float angle = acosf(cosAngle); + glm::quat newBaseRotation = glm::angleAxis(angle, axis) * basePose.rot(); + + // convert base rotation into relative space of base. + _relativePoses[baseIndex].rot() = glm::inverse(baseParentPose.rot()) * newBaseRotation; + } + } + } + } + } +} + void AnimInverseKinematics::initRelativePosesFromSolutionSource(SolutionSource solutionSource, const AnimPoseVec& underPoses) { const float RELAX_BLEND_FACTOR = (1.0f / 16.0f); const float COPY_BLEND_FACTOR = 1.0f; @@ -1531,6 +1732,10 @@ void AnimInverseKinematics::initRelativePosesFromSolutionSource(SolutionSource s break; case SolutionSource::RelaxToLimitCenterPoses: blendToPoses(_limitCenterPoses, underPoses, RELAX_BLEND_FACTOR); + // special case for hips: copy over hips pose whether or not IK is enabled. + if (_hipsIndex >= 0 && _hipsIndex < (int)_relativePoses.size()) { + _relativePoses[_hipsIndex] = _limitCenterPoses[_hipsIndex]; + } break; case SolutionSource::PreviousSolution: // do nothing... _relativePoses is already the previous solution @@ -1540,7 +1745,7 @@ void AnimInverseKinematics::initRelativePosesFromSolutionSource(SolutionSource s break; case SolutionSource::LimitCenterPoses: // essentially copy limitCenterPoses over to _relativePoses. - blendToPoses(_limitCenterPoses, underPoses, COPY_BLEND_FACTOR); + blendToPoses(underPoses, _limitCenterPoses, COPY_BLEND_FACTOR); break; } } diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index cc919c1684..d473ae3698 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -26,6 +26,14 @@ class RotationConstraint; class AnimInverseKinematics : public AnimNode { public: + struct JointChainInfo { + glm::quat relRot; + glm::vec3 relTrans; + float weight; + int jointIndex; + bool constrained; + }; + explicit AnimInverseKinematics(const QString& id); virtual ~AnimInverseKinematics() override; @@ -34,7 +42,8 @@ public: void computeAbsolutePoses(AnimPoseVec& absolutePoses) const; void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, - const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients); + const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, + const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar); virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimNode::Triggers& triggersOut) override; virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override; @@ -67,19 +76,13 @@ protected: void solveTargetWithCCD(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug); void solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug); virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; - struct DebugJoint { - DebugJoint() : relRot(), constrained(false) {} - DebugJoint(const glm::quat& relRotIn, const glm::vec3& relTransIn, bool constrainedIn) : relRot(relRotIn), relTrans(relTransIn), constrained(constrainedIn) {} - glm::quat relRot; - glm::vec3 relTrans; - bool constrained; - }; - void debugDrawIKChain(std::map& debugJointMap, const AnimContext& context) const; + void debugDrawIKChain(JointChainInfo* jointChainInfos, size_t numJointChainInfos, const AnimContext& context) const; void debugDrawRelativePoses(const AnimContext& context) const; void debugDrawConstraints(const AnimContext& context) const; void debugDrawSpineSplines(const AnimContext& context, const std::vector& targets) const; void initRelativePosesFromSolutionSource(SolutionSource solutionSource, const AnimPoseVec& underPose); void blendToPoses(const AnimPoseVec& targetPoses, const AnimPoseVec& underPose, float blendFactor); + void preconditionRelativePosesToAvoidLimbLock(const AnimContext& context, const std::vector& targets); // used to pre-compute information about each joint influeced by a spline IK target. struct SplineJointInfo { @@ -107,7 +110,8 @@ protected: enum FlexCoefficients { MAX_FLEX_COEFFICIENTS = 10 }; struct IKTargetVar { IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn, - const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector& flexCoefficientsIn); + const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector& flexCoefficientsIn, + const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar); IKTargetVar(const IKTargetVar& orig); QString jointName; @@ -115,6 +119,9 @@ protected: QString rotationVar; QString typeVar; QString weightVar; + QString poleVectorEnabledVar; + QString poleReferenceVectorVar; + QString poleVectorVar; float weight; float flexCoefficients[MAX_FLEX_COEFFICIENTS]; size_t numFlexCoefficients; diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index 10db38f42e..6d9d35b19b 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -44,6 +44,7 @@ public: StateMachine, Manipulator, InverseKinematics, + DefaultPose, NumTypes }; using Pointer = std::shared_ptr; diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 44ed8c6053..33f3d72756 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -23,6 +23,7 @@ #include "AnimStateMachine.h" #include "AnimManipulator.h" #include "AnimInverseKinematics.h" +#include "AnimDefaultPose.h" using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); using NodeProcessFunc = bool (*)(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); @@ -35,6 +36,7 @@ static AnimNode::Pointer loadOverlayNode(const QJsonObject& jsonObj, const QStri static AnimNode::Pointer loadStateMachineNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); +static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); // called after children have been loaded // returns node on success, nullptr on failure. @@ -50,6 +52,7 @@ static const char* animNodeTypeToString(AnimNode::Type type) { case AnimNode::Type::StateMachine: return "stateMachine"; case AnimNode::Type::Manipulator: return "manipulator"; case AnimNode::Type::InverseKinematics: return "inverseKinematics"; + case AnimNode::Type::DefaultPose: return "defaultPose"; case AnimNode::Type::NumTypes: return nullptr; }; return nullptr; @@ -109,6 +112,7 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) { case AnimNode::Type::StateMachine: return loadStateMachineNode; case AnimNode::Type::Manipulator: return loadManipulatorNode; case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode; + case AnimNode::Type::DefaultPose: return loadDefaultPoseNode; case AnimNode::Type::NumTypes: return nullptr; }; return nullptr; @@ -123,6 +127,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { case AnimNode::Type::StateMachine: return processStateMachineNode; case AnimNode::Type::Manipulator: return processDoNothing; case AnimNode::Type::InverseKinematics: return processDoNothing; + case AnimNode::Type::DefaultPose: return processDoNothing; case AnimNode::Type::NumTypes: return nullptr; }; return nullptr; @@ -347,7 +352,8 @@ static const char* boneSetStrings[AnimOverlay::NumBoneSets] = { "empty", "leftHand", "rightHand", - "hipsOnly" + "hipsOnly", + "bothFeet" }; static AnimOverlay::BoneSet stringToBoneSetEnum(const QString& str) { @@ -479,6 +485,9 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS READ_OPTIONAL_STRING(typeVar, targetObj); READ_OPTIONAL_STRING(weightVar, targetObj); READ_OPTIONAL_FLOAT(weight, targetObj, 1.0f); + READ_OPTIONAL_STRING(poleVectorEnabledVar, targetObj); + READ_OPTIONAL_STRING(poleReferenceVectorVar, targetObj); + READ_OPTIONAL_STRING(poleVectorVar, targetObj); auto flexCoefficientsValue = targetObj.value("flexCoefficients"); if (!flexCoefficientsValue.isArray()) { @@ -491,7 +500,7 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS flexCoefficients.push_back((float)value.toDouble()); } - node->setTargetVars(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients); + node->setTargetVars(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients, poleVectorEnabledVar, poleReferenceVectorVar, poleVectorVar); }; READ_OPTIONAL_STRING(solutionSource, jsonObj); @@ -514,6 +523,11 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS return node; } +static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { + auto node = std::make_shared(id); + return node; +} + void buildChildMap(std::map& map, AnimNode::Pointer node) { for (int i = 0; i < (int)node->getChildCount(); ++i) { map.insert(std::pair(node->getChild(i)->getID(), i)); diff --git a/libraries/animation/src/AnimOverlay.cpp b/libraries/animation/src/AnimOverlay.cpp index e086413dde..10594af20a 100644 --- a/libraries/animation/src/AnimOverlay.cpp +++ b/libraries/animation/src/AnimOverlay.cpp @@ -35,6 +35,7 @@ void AnimOverlay::buildBoneSet(BoneSet boneSet) { case LeftHandBoneSet: buildLeftHandBoneSet(); break; case RightHandBoneSet: buildRightHandBoneSet(); break; case HipsOnlyBoneSet: buildHipsOnlyBoneSet(); break; + case BothFeetBoneSet: buildBothFeetBoneSet(); break; default: case EmptyBoneSet: buildEmptyBoneSet(); break; } @@ -196,6 +197,20 @@ void AnimOverlay::buildHipsOnlyBoneSet() { _boneSetVec[hipsJoint] = 1.0f; } +void AnimOverlay::buildBothFeetBoneSet() { + assert(_skeleton); + buildEmptyBoneSet(); + int rightFoot = _skeleton->nameToJointIndex("RightFoot"); + for_each_child_joint(_skeleton, rightFoot, [&](int i) { + _boneSetVec[i] = 1.0f; + }); + int leftFoot = _skeleton->nameToJointIndex("LeftFoot"); + for_each_child_joint(_skeleton, leftFoot, [&](int i) { + _boneSetVec[i] = 1.0f; + }); +} + + // for AnimDebugDraw rendering const AnimPoseVec& AnimOverlay::getPosesInternal() const { return _poses; diff --git a/libraries/animation/src/AnimOverlay.h b/libraries/animation/src/AnimOverlay.h index ed9439feb7..8b6e1529fc 100644 --- a/libraries/animation/src/AnimOverlay.h +++ b/libraries/animation/src/AnimOverlay.h @@ -38,6 +38,7 @@ public: LeftHandBoneSet, RightHandBoneSet, HipsOnlyBoneSet, + BothFeetBoneSet, NumBoneSets }; @@ -77,6 +78,7 @@ public: void buildLeftHandBoneSet(); void buildRightHandBoneSet(); void buildHipsOnlyBoneSet(); + void buildBothFeetBoneSet(); // no copies AnimOverlay(const AnimOverlay&) = delete; diff --git a/libraries/animation/src/AnimPose.h b/libraries/animation/src/AnimPose.h index a2e22a24be..2df3d1f2e4 100644 --- a/libraries/animation/src/AnimPose.h +++ b/libraries/animation/src/AnimPose.h @@ -21,6 +21,8 @@ class AnimPose { public: AnimPose() {} explicit AnimPose(const glm::mat4& mat); + explicit AnimPose(const glm::quat& rotIn) : _scale(1.0f), _rot(rotIn), _trans(0.0f) {} + AnimPose(const glm::quat& rotIn, const glm::vec3& transIn) : _scale(1.0f), _rot(rotIn), _trans(transIn) {} AnimPose(const glm::vec3& scaleIn, const glm::quat& rotIn, const glm::vec3& transIn) : _scale(scaleIn), _rot(rotIn), _trans(transIn) {} static const AnimPose identity; diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 350fe8a534..062e016660 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -76,11 +76,11 @@ const QString& AnimSkeleton::getJointName(int jointIndex) const { return _joints[jointIndex].name; } -AnimPose AnimSkeleton::getAbsolutePose(int jointIndex, const AnimPoseVec& poses) const { - if (jointIndex < 0 || jointIndex >= (int)poses.size() || jointIndex >= _jointsSize) { +AnimPose AnimSkeleton::getAbsolutePose(int jointIndex, const AnimPoseVec& relativePoses) const { + if (jointIndex < 0 || jointIndex >= (int)relativePoses.size() || jointIndex >= _jointsSize) { return AnimPose::identity; } else { - return getAbsolutePose(_joints[jointIndex].parentIndex, poses) * poses[jointIndex]; + return getAbsolutePose(_joints[jointIndex].parentIndex, relativePoses) * relativePoses[jointIndex]; } } diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 0988c26bdb..6315f2d62b 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -50,7 +50,7 @@ public: int getParentIndex(int jointIndex) const; - AnimPose getAbsolutePose(int jointIndex, const AnimPoseVec& poses) const; + AnimPose getAbsolutePose(int jointIndex, const AnimPoseVec& relativePoses) const; void convertRelativePosesToAbsolute(AnimPoseVec& poses) const; void convertAbsolutePosesToRelative(AnimPoseVec& poses) const; diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 6594482085..7d4c0f4e92 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -144,38 +144,3 @@ void Animation::animationParseError(int error, QString str) { finishedLoading(false); } -AnimationDetails::AnimationDetails() : - role(), url(), fps(0.0f), priority(0.0f), loop(false), hold(false), - startAutomatically(false), firstFrame(0.0f), lastFrame(0.0f), running(false), currentFrame(0.0f) -{ -} - -AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, - bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame) : - role(role), url(url), fps(fps), priority(priority), loop(loop), hold(hold), - startAutomatically(startAutomatically), firstFrame(firstFrame), lastFrame(lastFrame), - running(running), currentFrame(currentFrame) -{ -} - - -QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& details) { - QScriptValue obj = engine->newObject(); - obj.setProperty("role", details.role); - obj.setProperty("url", details.url.toString()); - obj.setProperty("fps", details.fps); - obj.setProperty("priority", details.priority); - obj.setProperty("loop", details.loop); - obj.setProperty("hold", details.hold); - obj.setProperty("startAutomatically", details.startAutomatically); - obj.setProperty("firstFrame", details.firstFrame); - obj.setProperty("lastFrame", details.lastFrame); - obj.setProperty("running", details.running); - obj.setProperty("currentFrame", details.currentFrame); - return obj; -} - -void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& details) { - // nothing for now... -} - diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index 0e6a94c1b8..490bb7dcd8 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -107,26 +107,5 @@ private: QByteArray _data; }; -class AnimationDetails { -public: - AnimationDetails(); - AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, - bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame); - - QString role; - QUrl url; - float fps; - float priority; - bool loop; - bool hold; - bool startAutomatically; - float firstFrame; - float lastFrame; - bool running; - float currentFrame; -}; -Q_DECLARE_METATYPE(AnimationDetails); -QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event); -void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& event); #endif // hifi_AnimationCache_h diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h index 011175aedf..5567539659 100644 --- a/libraries/animation/src/IKTarget.h +++ b/libraries/animation/src/IKTarget.h @@ -30,10 +30,16 @@ public: const glm::vec3& getTranslation() const { return _pose.trans(); } const glm::quat& getRotation() const { return _pose.rot(); } const AnimPose& getPose() const { return _pose; } + glm::vec3 getPoleVector() const { return _poleVector; } + glm::vec3 getPoleReferenceVector() const { return _poleReferenceVector; } + bool getPoleVectorEnabled() const { return _poleVectorEnabled; } int getIndex() const { return _index; } Type getType() const { return _type; } void setPose(const glm::quat& rotation, const glm::vec3& translation); + void setPoleVector(const glm::vec3& poleVector) { _poleVector = poleVector; } + void setPoleReferenceVector(const glm::vec3& poleReferenceVector) { _poleReferenceVector = poleReferenceVector; } + void setPoleVectorEnabled(bool poleVectorEnabled) { _poleVectorEnabled = poleVectorEnabled; } void setIndex(int index) { _index = index; } void setType(int); void setFlexCoefficients(size_t numFlexCoefficientsIn, const float* flexCoefficientsIn); @@ -46,8 +52,11 @@ public: private: AnimPose _pose; - int _index{-1}; - Type _type{Type::RotationAndPosition}; + glm::vec3 _poleVector; + glm::vec3 _poleReferenceVector; + bool _poleVectorEnabled { false }; + int _index { -1 }; + Type _type { Type::RotationAndPosition }; float _weight; float _flexCoefficients[MAX_FLEX_COEFFICIENTS]; size_t _numFlexCoefficients; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index fbb3d24298..3d04b0b26f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -27,6 +27,7 @@ #include "AnimationLogging.h" #include "AnimClip.h" #include "AnimInverseKinematics.h" +#include "AnimOverlay.h" #include "AnimSkeleton.h" #include "AnimUtil.h" #include "IKTarget.h" @@ -479,12 +480,6 @@ bool Rig::getAbsoluteJointPoseInRigFrame(int jointIndex, AnimPose& returnPose) c } } -bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { - // AJT: TODO: used by attachments - ASSERT(false); - return false; -} - void Rig::calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const { ASSERT(referenceSpeeds.size() > 0); @@ -950,6 +945,7 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons // evaluate the animation AnimNode::Triggers triggersOut; + _internalPoseSet._relativePoses = _animNode->evaluate(_animVars, context, deltaTime, triggersOut); if ((int)_internalPoseSet._relativePoses.size() != _animSkeleton->getNumJoints()) { // animations haven't fully loaded yet. @@ -1015,46 +1011,6 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { return glm::quat(); } -void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { - updateHeadAnimVars(params); - - _animVars.set("isTalking", params.isTalking); - _animVars.set("notIsTalking", !params.isTalking); - - if (params.hipsEnabled) { - _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses); - _animVars.set("hipsType", (int)IKTarget::Type::RotationAndPosition); - _animVars.set("hipsPosition", extractTranslation(params.hipsMatrix)); - _animVars.set("hipsRotation", glmExtractRotation(params.hipsMatrix)); - } else { - _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses); - _animVars.set("hipsType", (int)IKTarget::Type::Unknown); - } - - if (params.hipsEnabled && params.spine2Enabled) { - _animVars.set("spine2Type", (int)IKTarget::Type::Spline); - _animVars.set("spine2Position", extractTranslation(params.spine2Matrix)); - _animVars.set("spine2Rotation", glmExtractRotation(params.spine2Matrix)); - } else { - _animVars.set("spine2Type", (int)IKTarget::Type::Unknown); - } - - if (params.leftArmEnabled) { - _animVars.set("leftArmType", (int)IKTarget::Type::RotationAndPosition); - _animVars.set("leftArmPosition", params.leftArmPosition); - _animVars.set("leftArmRotation", params.leftArmRotation); - } else { - _animVars.set("leftArmType", (int)IKTarget::Type::Unknown); - } - - if (params.rightArmEnabled) { - _animVars.set("rightArmType", (int)IKTarget::Type::RotationAndPosition); - _animVars.set("rightArmPosition", params.rightArmPosition); - _animVars.set("rightArmRotation", params.rightArmRotation); - } else { - _animVars.set("rightArmType", (int)IKTarget::Type::Unknown); - } -} void Rig::updateFromEyeParameters(const EyeParameters& params) { updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade); @@ -1086,12 +1042,12 @@ void Rig::computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut headOrientationOut = hmdOrientation; } -void Rig::updateHeadAnimVars(const HeadParameters& params) { +void Rig::updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headPose) { if (_animSkeleton) { - if (params.headEnabled) { - _animVars.set("headPosition", params.rigHeadPosition); - _animVars.set("headRotation", params.rigHeadOrientation); - if (params.hipsEnabled) { + if (headEnabled) { + _animVars.set("headPosition", headPose.trans()); + _animVars.set("headRotation", headPose.rot()); + if (hipsEnabled) { // Since there is an explicit hips ik target, switch the head to use the more flexible Spline IK chain type. // this will allow the spine to compress/expand and bend more natrually, ensuring that it can reach the head target position. _animVars.set("headType", (int)IKTarget::Type::Spline); @@ -1104,12 +1060,271 @@ void Rig::updateHeadAnimVars(const HeadParameters& params) { } } else { _animVars.unset("headPosition"); - _animVars.set("headRotation", params.rigHeadOrientation); + _animVars.set("headRotation", headPose.rot()); _animVars.set("headType", (int)IKTarget::Type::RotationOnly); } } } +void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool leftArmEnabled, bool rightArmEnabled, float dt, + const AnimPose& leftHandPose, const AnimPose& rightHandPose, + float bodyCapsuleRadius, float bodyCapsuleHalfHeight, const glm::vec3& bodyCapsuleLocalOffset) { + + // Use this capsule to represent the avatar body. + int hipsIndex = indexOfJoint("Hips"); + glm::vec3 hipsTrans; + if (hipsIndex >= 0) { + hipsTrans = _internalPoseSet._absolutePoses[hipsIndex].trans(); + } + + const glm::vec3 bodyCapsuleCenter = hipsTrans - bodyCapsuleLocalOffset; + const glm::vec3 bodyCapsuleStart = bodyCapsuleCenter - glm::vec3(0, bodyCapsuleHalfHeight, 0); + const glm::vec3 bodyCapsuleEnd = bodyCapsuleCenter + glm::vec3(0, bodyCapsuleHalfHeight, 0); + + const float HAND_RADIUS = 0.05f; + + const float RELAX_DURATION = 0.6f; + const float CONTROL_DURATION = 0.4f; + const bool TO_CONTROLLED = true; + const bool FROM_CONTROLLED = false; + const bool LEFT_HAND = true; + const bool RIGHT_HAND = false; + + const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f; + + if (leftHandEnabled) { + if (!_isLeftHandControlled) { + _leftHandControlTimeRemaining = CONTROL_DURATION; + _isLeftHandControlled = true; + } + + glm::vec3 handPosition = leftHandPose.trans(); + glm::quat handRotation = leftHandPose.rot(); + + if (_leftHandControlTimeRemaining > 0.0f) { + // Move hand from non-controlled position to controlled position. + _leftHandControlTimeRemaining = std::max(_leftHandControlTimeRemaining - dt, 0.0f); + AnimPose handPose(Vectors::ONE, handRotation, handPosition); + if (transitionHandPose(_leftHandControlTimeRemaining, CONTROL_DURATION, handPose, + LEFT_HAND, TO_CONTROLLED, handPose)) { + handPosition = handPose.trans(); + handRotation = handPose.rot(); + } + } + + if (!hipsEnabled) { + // prevent the hand IK targets from intersecting the body capsule + glm::vec3 displacement; + if (findSphereCapsulePenetration(handPosition, HAND_RADIUS, bodyCapsuleStart, bodyCapsuleEnd, bodyCapsuleRadius, displacement)) { + handPosition -= displacement; + } + } + + _animVars.set("leftHandPosition", handPosition); + _animVars.set("leftHandRotation", handRotation); + _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); + + _lastLeftHandControlledPose = AnimPose(Vectors::ONE, handRotation, handPosition); + _isLeftHandControlled = true; + + // compute pole vector + int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand"); + int armJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); + int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); + if (!leftArmEnabled && elbowJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) { + glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, true); + + // smooth toward desired pole vector from previous pole vector... to reduce jitter + if (!_prevLeftHandPoleVectorValid) { + _prevLeftHandPoleVectorValid = true; + _prevLeftHandPoleVector = poleVector; + } + glm::quat deltaRot = rotationBetween(_prevLeftHandPoleVector, poleVector); + glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR); + _prevLeftHandPoleVector = smoothDeltaRot * _prevLeftHandPoleVector; + + _animVars.set("leftHandPoleVectorEnabled", true); + _animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X); + _animVars.set("leftHandPoleVector", _prevLeftHandPoleVector); + } else { + _prevLeftHandPoleVectorValid = false; + _animVars.set("leftHandPoleVectorEnabled", false); + } + } else { + _prevLeftHandPoleVectorValid = false; + _animVars.set("leftHandPoleVectorEnabled", false); + + if (_isLeftHandControlled) { + _leftHandRelaxTimeRemaining = RELAX_DURATION; + _isLeftHandControlled = false; + } + + if (_leftHandRelaxTimeRemaining > 0.0f) { + // Move hand from controlled position to non-controlled position. + _leftHandRelaxTimeRemaining = std::max(_leftHandRelaxTimeRemaining - dt, 0.0f); + AnimPose handPose; + if (transitionHandPose(_leftHandRelaxTimeRemaining, RELAX_DURATION, _lastLeftHandControlledPose, + LEFT_HAND, FROM_CONTROLLED, handPose)) { + _animVars.set("leftHandPosition", handPose.trans()); + _animVars.set("leftHandRotation", handPose.rot()); + _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); + } + } else { + _animVars.unset("leftHandPosition"); + _animVars.unset("leftHandRotation"); + _animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); + } + } + + if (rightHandEnabled) { + if (!_isRightHandControlled) { + _rightHandControlTimeRemaining = CONTROL_DURATION; + _isRightHandControlled = true; + } + + glm::vec3 handPosition = rightHandPose.trans(); + glm::quat handRotation = rightHandPose.rot(); + + if (_rightHandControlTimeRemaining > 0.0f) { + // Move hand from non-controlled position to controlled position. + _rightHandControlTimeRemaining = std::max(_rightHandControlTimeRemaining - dt, 0.0f); + AnimPose handPose(Vectors::ONE, handRotation, handPosition); + if (transitionHandPose(_rightHandControlTimeRemaining, CONTROL_DURATION, handPose, RIGHT_HAND, TO_CONTROLLED, handPose)) { + handPosition = handPose.trans(); + handRotation = handPose.rot(); + } + } + + if (!hipsEnabled) { + // prevent the hand IK targets from intersecting the body capsule + glm::vec3 displacement; + if (findSphereCapsulePenetration(handPosition, HAND_RADIUS, bodyCapsuleStart, bodyCapsuleEnd, bodyCapsuleRadius, displacement)) { + handPosition -= displacement; + } + } + + _animVars.set("rightHandPosition", handPosition); + _animVars.set("rightHandRotation", handRotation); + _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); + + _lastRightHandControlledPose = AnimPose(Vectors::ONE, handRotation, handPosition); + _isRightHandControlled = true; + + // compute pole vector + int handJointIndex = _animSkeleton->nameToJointIndex("RightHand"); + int armJointIndex = _animSkeleton->nameToJointIndex("RightArm"); + int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm"); + if (!rightArmEnabled && elbowJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) { + glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, false); + + // smooth toward desired pole vector from previous pole vector... to reduce jitter + if (!_prevRightHandPoleVectorValid) { + _prevRightHandPoleVectorValid = true; + _prevRightHandPoleVector = poleVector; + } + glm::quat deltaRot = rotationBetween(_prevRightHandPoleVector, poleVector); + glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR); + _prevRightHandPoleVector = smoothDeltaRot * _prevRightHandPoleVector; + + _animVars.set("rightHandPoleVectorEnabled", true); + _animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X); + _animVars.set("rightHandPoleVector", _prevRightHandPoleVector); + } else { + _prevRightHandPoleVectorValid = false; + _animVars.set("rightHandPoleVectorEnabled", false); + } + } else { + _prevRightHandPoleVectorValid = false; + _animVars.set("rightHandPoleVectorEnabled", false); + + if (_isRightHandControlled) { + _rightHandRelaxTimeRemaining = RELAX_DURATION; + _isRightHandControlled = false; + } + + if (_rightHandRelaxTimeRemaining > 0.0f) { + // Move hand from controlled position to non-controlled position. + _rightHandRelaxTimeRemaining = std::max(_rightHandRelaxTimeRemaining - dt, 0.0f); + AnimPose handPose; + if (transitionHandPose(_rightHandRelaxTimeRemaining, RELAX_DURATION, _lastRightHandControlledPose, RIGHT_HAND, FROM_CONTROLLED, handPose)) { + _animVars.set("rightHandPosition", handPose.trans()); + _animVars.set("rightHandRotation", handPose.rot()); + _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); + } + } else { + _animVars.unset("rightHandPosition"); + _animVars.unset("rightHandRotation"); + _animVars.set("rightHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); + } + } +} + +void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose) { + + const float KNEE_POLE_VECTOR_BLEND_FACTOR = 0.95f; + + int hipsIndex = indexOfJoint("Hips"); + + if (leftFootEnabled) { + _animVars.set("leftFootPosition", leftFootPose.trans()); + _animVars.set("leftFootRotation", leftFootPose.rot()); + _animVars.set("leftFootType", (int)IKTarget::Type::RotationAndPosition); + + int footJointIndex = _animSkeleton->nameToJointIndex("LeftFoot"); + int kneeJointIndex = _animSkeleton->nameToJointIndex("LeftLeg"); + int upLegJointIndex = _animSkeleton->nameToJointIndex("LeftUpLeg"); + glm::vec3 poleVector = calculateKneePoleVector(footJointIndex, kneeJointIndex, upLegJointIndex, hipsIndex, leftFootPose); + + // smooth toward desired pole vector from previous pole vector... to reduce jitter + if (!_prevLeftFootPoleVectorValid) { + _prevLeftFootPoleVectorValid = true; + _prevLeftFootPoleVector = poleVector; + } + glm::quat deltaRot = rotationBetween(_prevLeftFootPoleVector, poleVector); + glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, KNEE_POLE_VECTOR_BLEND_FACTOR); + _prevLeftFootPoleVector = smoothDeltaRot * _prevLeftFootPoleVector; + + _animVars.set("leftFootPoleVectorEnabled", true); + _animVars.set("leftFootPoleReferenceVector", Vectors::UNIT_Z); + _animVars.set("leftFootPoleVector", _prevLeftFootPoleVector); + } else { + _animVars.unset("leftFootPosition"); + _animVars.unset("leftFootRotation"); + _animVars.set("leftFootType", (int)IKTarget::Type::RotationAndPosition); + _animVars.set("leftFootPoleVectorEnabled", false); + _prevLeftFootPoleVectorValid = false; + } + + if (rightFootEnabled) { + _animVars.set("rightFootPosition", rightFootPose.trans()); + _animVars.set("rightFootRotation", rightFootPose.rot()); + _animVars.set("rightFootType", (int)IKTarget::Type::RotationAndPosition); + + int footJointIndex = _animSkeleton->nameToJointIndex("RightFoot"); + int kneeJointIndex = _animSkeleton->nameToJointIndex("RightLeg"); + int upLegJointIndex = _animSkeleton->nameToJointIndex("RightUpLeg"); + glm::vec3 poleVector = calculateKneePoleVector(footJointIndex, kneeJointIndex, upLegJointIndex, hipsIndex, rightFootPose); + + // smooth toward desired pole vector from previous pole vector... to reduce jitter + if (!_prevRightFootPoleVectorValid) { + _prevRightFootPoleVectorValid = true; + _prevRightFootPoleVector = poleVector; + } + glm::quat deltaRot = rotationBetween(_prevRightFootPoleVector, poleVector); + glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, KNEE_POLE_VECTOR_BLEND_FACTOR); + _prevRightFootPoleVector = smoothDeltaRot * _prevRightFootPoleVector; + + _animVars.set("rightFootPoleVectorEnabled", true); + _animVars.set("rightFootPoleReferenceVector", Vectors::UNIT_Z); + _animVars.set("rightFootPoleVector", _prevRightFootPoleVector); + } else { + _animVars.unset("rightFootPosition"); + _animVars.unset("rightFootRotation"); + _animVars.set("rightFootPoleVectorEnabled", false); + _animVars.set("rightFootType", (int)IKTarget::Type::RotationAndPosition); + } +} + void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) { // TODO: does not properly handle avatar scale. @@ -1145,162 +1360,153 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } -void Rig::updateFromHandAndFeetParameters(const HandAndFeetParameters& params, float dt) { - if (_animSkeleton && _animNode) { - const float HAND_RADIUS = 0.05f; - int hipsIndex = indexOfJoint("Hips"); - glm::vec3 hipsTrans; - if (hipsIndex >= 0) { - hipsTrans = _internalPoseSet._absolutePoses[hipsIndex].trans(); - } +static glm::quat quatLerp(const glm::quat& q1, const glm::quat& q2, float alpha) { + float dot = glm::dot(q1, q2); + glm::quat temp; + if (dot < 0.0f) { + temp = -q2; + } else { + temp = q2; + } + return glm::normalize(glm::lerp(q1, temp, alpha)); +} - // Use this capsule to represent the avatar body. - const float bodyCapsuleRadius = params.bodyCapsuleRadius; - const glm::vec3 bodyCapsuleCenter = hipsTrans - params.bodyCapsuleLocalOffset; - const glm::vec3 bodyCapsuleStart = bodyCapsuleCenter - glm::vec3(0, params.bodyCapsuleHalfHeight, 0); - const glm::vec3 bodyCapsuleEnd = bodyCapsuleCenter + glm::vec3(0, params.bodyCapsuleHalfHeight, 0); +glm::vec3 Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int hipsIndex, bool isLeft) const { + AnimPose hipsPose = _externalPoseSet._absolutePoses[hipsIndex]; + AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; + AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; + AnimPose armPose = _externalPoseSet._absolutePoses[armIndex]; - // TODO: add isHipsEnabled - bool bodySensorTrackingEnabled = params.isLeftFootEnabled || params.isRightFootEnabled; + // ray from hand to arm. + glm::vec3 d = glm::normalize(handPose.trans() - armPose.trans()); - const float RELAX_DURATION = 0.6f; - const float CONTROL_DURATION = 0.4f; - const bool TO_CONTROLLED = true; - const bool FROM_CONTROLLED = false; - const bool LEFT_HAND = true; - const bool RIGHT_HAND = false; + float sign = isLeft ? 1.0f : -1.0f; - if (params.isLeftEnabled) { - if (!_isLeftHandControlled) { - _leftHandControlTimeRemaining = CONTROL_DURATION; - _isLeftHandControlled = true; - } + // form a plane normal to the hips x-axis. + glm::vec3 n = hipsPose.rot() * Vectors::UNIT_X; + glm::vec3 y = hipsPose.rot() * Vectors::UNIT_Y; - glm::vec3 handPosition = params.leftPosition; - glm::quat handRotation = params.leftOrientation; + // project d onto this plane + glm::vec3 dProj = d - glm::dot(d, n) * n; - if (_leftHandControlTimeRemaining > 0.0f) { - // Move hand from non-controlled position to controlled position. - _leftHandControlTimeRemaining = std::max(_leftHandControlTimeRemaining - dt, 0.0f); - AnimPose handPose(Vectors::ONE, handRotation, handPosition); - if (transitionHandPose(_leftHandControlTimeRemaining, CONTROL_DURATION, handPose, LEFT_HAND, TO_CONTROLLED, - handPose)) { - handPosition = handPose.trans(); - handRotation = handPose.rot(); - } - } + // give dProj a bit of offset away from the body. + float avatarScale = extractUniformScale(_modelOffset); + const float LATERAL_OFFSET = 1.0f * avatarScale; + const float VERTICAL_OFFSET = -0.333f * avatarScale; + glm::vec3 dProjWithOffset = dProj + sign * LATERAL_OFFSET * n + y * VERTICAL_OFFSET; - if (!bodySensorTrackingEnabled) { - // prevent the hand IK targets from intersecting the body capsule - glm::vec3 displacement; - if (findSphereCapsulePenetration(handPosition, HAND_RADIUS, bodyCapsuleStart, bodyCapsuleEnd, bodyCapsuleRadius, displacement)) { - handPosition -= displacement; - } - } + // rotate dProj by 90 degrees to get the poleVector. + glm::vec3 poleVector = glm::angleAxis(PI / 2.0f, n) * dProjWithOffset; - _animVars.set("leftHandPosition", handPosition); - _animVars.set("leftHandRotation", handRotation); - _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); + // blend the wrist oreintation into the pole vector to reduce the painfully bent wrist problem. + glm::quat elbowToHandDelta = handPose.rot() * glm::inverse(elbowPose.rot()); + const float WRIST_POLE_ADJUST_FACTOR = 0.5f; + glm::quat poleAdjust = quatLerp(Quaternions::IDENTITY, elbowToHandDelta, WRIST_POLE_ADJUST_FACTOR); - _lastLeftHandControlledPose = AnimPose(Vectors::ONE, handRotation, handPosition); - } else { - if (_isLeftHandControlled) { - _leftHandRelaxTimeRemaining = RELAX_DURATION; - _isLeftHandControlled = false; - } + return glm::normalize(poleAdjust * poleVector); +} - if (_leftHandRelaxTimeRemaining > 0.0f) { - // Move hand from controlled position to non-controlled position. - _leftHandRelaxTimeRemaining = std::max(_leftHandRelaxTimeRemaining - dt, 0.0f); - AnimPose handPose; - if (transitionHandPose(_leftHandRelaxTimeRemaining, RELAX_DURATION, _lastLeftHandControlledPose, LEFT_HAND, - FROM_CONTROLLED, handPose)) { - _animVars.set("leftHandPosition", handPose.trans()); - _animVars.set("leftHandRotation", handPose.rot()); - _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); - } - } else { - _animVars.unset("leftHandPosition"); - _animVars.unset("leftHandRotation"); - _animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); - } - } +glm::vec3 Rig::calculateKneePoleVector(int footJointIndex, int kneeIndex, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const { - if (params.isRightEnabled) { - if (!_isRightHandControlled) { - _rightHandControlTimeRemaining = CONTROL_DURATION; - _isRightHandControlled = true; - } + AnimPose hipsPose = _externalPoseSet._absolutePoses[hipsIndex]; + AnimPose footPose = targetFootPose; + AnimPose kneePose = _externalPoseSet._absolutePoses[kneeIndex]; + AnimPose upLegPose = _externalPoseSet._absolutePoses[upLegIndex]; - glm::vec3 handPosition = params.rightPosition; - glm::quat handRotation = params.rightOrientation; + // ray from foot to upLeg + glm::vec3 d = glm::normalize(footPose.trans() - upLegPose.trans()); - if (_rightHandControlTimeRemaining > 0.0f) { - // Move hand from non-controlled position to controlled position. - _rightHandControlTimeRemaining = std::max(_rightHandControlTimeRemaining - dt, 0.0f); - AnimPose handPose(Vectors::ONE, handRotation, handPosition); - if (transitionHandPose(_rightHandControlTimeRemaining, CONTROL_DURATION, handPose, RIGHT_HAND, TO_CONTROLLED, - handPose)) { - handPosition = handPose.trans(); - handRotation = handPose.rot(); - } - } + // form a plane normal to the hips x-axis + glm::vec3 n = hipsPose.rot() * Vectors::UNIT_X; - if (!bodySensorTrackingEnabled) { - // prevent the hand IK targets from intersecting the body capsule - glm::vec3 displacement; - if (findSphereCapsulePenetration(handPosition, HAND_RADIUS, bodyCapsuleStart, bodyCapsuleEnd, bodyCapsuleRadius, displacement)) { - handPosition -= displacement; - } - } + // project d onto this plane + glm::vec3 dProj = d - glm::dot(d, n) * n; - _animVars.set("rightHandPosition", handPosition); - _animVars.set("rightHandRotation", handRotation); - _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); + // rotate dProj by 90 degrees to get the poleVector. + glm::vec3 poleVector = glm::angleAxis(-PI / 2.0f, n) * dProj; - _lastRightHandControlledPose = AnimPose(Vectors::ONE, handRotation, handPosition); - } else { - if (_isRightHandControlled) { - _rightHandRelaxTimeRemaining = RELAX_DURATION; - _isRightHandControlled = false; - } + // blend the foot oreintation into the pole vector + glm::quat kneeToFootDelta = footPose.rot() * glm::inverse(kneePose.rot()); + const float WRIST_POLE_ADJUST_FACTOR = 0.5f; + glm::quat poleAdjust = quatLerp(Quaternions::IDENTITY, kneeToFootDelta, WRIST_POLE_ADJUST_FACTOR); - if (_rightHandRelaxTimeRemaining > 0.0f) { - // Move hand from controlled position to non-controlled position. - _rightHandRelaxTimeRemaining = std::max(_rightHandRelaxTimeRemaining - dt, 0.0f); - AnimPose handPose; - if (transitionHandPose(_rightHandRelaxTimeRemaining, RELAX_DURATION, _lastRightHandControlledPose, RIGHT_HAND, - FROM_CONTROLLED, handPose)) { - _animVars.set("rightHandPosition", handPose.trans()); - _animVars.set("rightHandRotation", handPose.rot()); - _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); - } - } else { - _animVars.unset("rightHandPosition"); - _animVars.unset("rightHandRotation"); - _animVars.set("rightHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); - } - } + return glm::normalize(poleAdjust * poleVector); +} - if (params.isLeftFootEnabled) { - _animVars.set("leftFootPosition", params.leftFootPosition); - _animVars.set("leftFootRotation", params.leftFootOrientation); - _animVars.set("leftFootType", (int)IKTarget::Type::RotationAndPosition); - } else { - _animVars.unset("leftFootPosition"); - _animVars.unset("leftFootRotation"); - _animVars.set("leftFootType", (int)IKTarget::Type::RotationAndPosition); - } +void Rig::updateFromControllerParameters(const ControllerParameters& params, float dt) { + if (!_animSkeleton || !_animNode) { + return; + } - if (params.isRightFootEnabled) { - _animVars.set("rightFootPosition", params.rightFootPosition); - _animVars.set("rightFootRotation", params.rightFootOrientation); - _animVars.set("rightFootType", (int)IKTarget::Type::RotationAndPosition); - } else { - _animVars.unset("rightFootPosition"); - _animVars.unset("rightFootRotation"); - _animVars.set("rightFootType", (int)IKTarget::Type::RotationAndPosition); - } + _animVars.set("isTalking", params.isTalking); + _animVars.set("notIsTalking", !params.isTalking); + + bool headEnabled = params.controllerActiveFlags[ControllerType_Head]; + bool leftHandEnabled = params.controllerActiveFlags[ControllerType_LeftHand]; + bool rightHandEnabled = params.controllerActiveFlags[ControllerType_RightHand]; + bool hipsEnabled = params.controllerActiveFlags[ControllerType_Hips]; + bool leftFootEnabled = params.controllerActiveFlags[ControllerType_LeftFoot]; + bool rightFootEnabled = params.controllerActiveFlags[ControllerType_RightFoot]; + bool leftArmEnabled = params.controllerActiveFlags[ControllerType_LeftArm]; + bool rightArmEnabled = params.controllerActiveFlags[ControllerType_RightArm]; + bool spine2Enabled = params.controllerActiveFlags[ControllerType_Spine2]; + + updateHead(headEnabled, hipsEnabled, params.controllerPoses[ControllerType_Head]); + + updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, leftArmEnabled, rightArmEnabled, dt, + params.controllerPoses[ControllerType_LeftHand], params.controllerPoses[ControllerType_RightHand], + params.bodyCapsuleRadius, params.bodyCapsuleHalfHeight, params.bodyCapsuleLocalOffset); + + updateFeet(leftFootEnabled, rightFootEnabled, + params.controllerPoses[ControllerType_LeftFoot], params.controllerPoses[ControllerType_RightFoot]); + + // if the hips or the feet are being controlled. + if (hipsEnabled || rightFootEnabled || leftFootEnabled) { + // for more predictable IK solve from the center of the joint limits, not from the underpose + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses); + + // replace the feet animation with the default pose, this is to prevent unexpected toe wiggling. + _animVars.set("defaultPoseOverlayAlpha", 1.0f); + _animVars.set("defaultPoseOverlayBoneSet", (int)AnimOverlay::BothFeetBoneSet); + } else { + // augment the IK with the underPose. + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses); + + // feet should follow source animation + _animVars.unset("defaultPoseOverlayAlpha"); + _animVars.unset("defaultPoseOverlayBoneSet"); + } + + if (hipsEnabled) { + _animVars.set("hipsType", (int)IKTarget::Type::RotationAndPosition); + _animVars.set("hipsPosition", params.controllerPoses[ControllerType_Hips].trans()); + _animVars.set("hipsRotation", params.controllerPoses[ControllerType_Hips].rot()); + } else { + _animVars.set("hipsType", (int)IKTarget::Type::Unknown); + } + + if (hipsEnabled && spine2Enabled) { + _animVars.set("spine2Type", (int)IKTarget::Type::Spline); + _animVars.set("spine2Position", params.controllerPoses[ControllerType_Spine2].trans()); + _animVars.set("spine2Rotation", params.controllerPoses[ControllerType_Spine2].rot()); + } else { + _animVars.set("spine2Type", (int)IKTarget::Type::Unknown); + } + + if (leftArmEnabled) { + _animVars.set("leftArmType", (int)IKTarget::Type::RotationAndPosition); + _animVars.set("leftArmPosition", params.controllerPoses[ControllerType_LeftArm].trans()); + _animVars.set("leftArmRotation", params.controllerPoses[ControllerType_LeftArm].rot()); + } else { + _animVars.set("leftArmType", (int)IKTarget::Type::Unknown); + } + + if (rightArmEnabled) { + _animVars.set("rightArmType", (int)IKTarget::Type::RotationAndPosition); + _animVars.set("rightArmPosition", params.controllerPoses[ControllerType_RightArm].trans()); + _animVars.set("rightArmRotation", params.controllerPoses[ControllerType_RightArm].rot()); + } else { + _animVars.set("rightArmType", (int)IKTarget::Type::Unknown); } } @@ -1486,22 +1692,18 @@ void Rig::computeAvatarBoundingCapsule( AnimInverseKinematics ikNode("boundingShape"); ikNode.setSkeleton(_animSkeleton); - ikNode.setTargetVars("LeftHand", - "leftHandPosition", - "leftHandRotation", - "leftHandType", "leftHandWeight", 1.0f, {}); - ikNode.setTargetVars("RightHand", - "rightHandPosition", - "rightHandRotation", - "rightHandType", "rightHandWeight", 1.0f, {}); - ikNode.setTargetVars("LeftFoot", - "leftFootPosition", - "leftFootRotation", - "leftFootType", "leftFootWeight", 1.0f, {}); - ikNode.setTargetVars("RightFoot", - "rightFootPosition", - "rightFootRotation", - "rightFootType", "rightFootWeight", 1.0f, {}); + ikNode.setTargetVars("LeftHand", "leftHandPosition", "leftHandRotation", + "leftHandType", "leftHandWeight", 1.0f, {}, + QString(), QString(), QString()); + ikNode.setTargetVars("RightHand", "rightHandPosition", "rightHandRotation", + "rightHandType", "rightHandWeight", 1.0f, {}, + QString(), QString(), QString()); + ikNode.setTargetVars("LeftFoot", "leftFootPosition", "leftFootRotation", + "leftFootType", "leftFootWeight", 1.0f, {}, + QString(), QString(), QString()); + ikNode.setTargetVars("RightFoot", "rightFootPosition", "rightFootRotation", + "rightFootType", "rightFootWeight", 1.0f, {}, + QString(), QString(), QString()); AnimPose geometryToRig = _modelOffset * _geometryOffset; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index b5b69fc018..c17a7b9c8f 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -41,21 +41,26 @@ public: bool useNames; }; - struct HeadParameters { - glm::mat4 hipsMatrix = glm::mat4(); // rig space - glm::mat4 spine2Matrix = glm::mat4(); // rig space - glm::quat rigHeadOrientation = glm::quat(); // rig space (-z forward) - glm::vec3 rigHeadPosition = glm::vec3(); // rig space - glm::vec3 rightArmPosition = glm::vec3(); // rig space - glm::quat rightArmRotation = glm::quat(); // rig space - glm::vec3 leftArmPosition = glm::vec3(); // rig space - glm::quat leftArmRotation = glm::quat(); // rig space - bool hipsEnabled = false; - bool headEnabled = false; - bool spine2Enabled = false; - bool leftArmEnabled = false; - bool rightArmEnabled = false; - bool isTalking = false; + enum ControllerType { + ControllerType_Head = 0, + ControllerType_LeftHand, + ControllerType_RightHand, + ControllerType_Hips, + ControllerType_LeftFoot, + ControllerType_RightFoot, + ControllerType_LeftArm, + ControllerType_RightArm, + ControllerType_Spine2, + NumControllerTypes + }; + + struct ControllerParameters { + AnimPose controllerPoses[NumControllerTypes]; // rig space + bool controllerActiveFlags[NumControllerTypes]; + bool isTalking; + float bodyCapsuleRadius; + float bodyCapsuleHalfHeight; + glm::vec3 bodyCapsuleLocalOffset; }; struct EyeParameters { @@ -67,25 +72,6 @@ public: int rightEyeJointIndex = -1; }; - struct HandAndFeetParameters { - bool isLeftEnabled; - bool isRightEnabled; - float bodyCapsuleRadius; - float bodyCapsuleHalfHeight; - glm::vec3 bodyCapsuleLocalOffset; - glm::vec3 leftPosition = glm::vec3(); // rig space - glm::quat leftOrientation = glm::quat(); // rig space (z forward) - glm::vec3 rightPosition = glm::vec3(); // rig space - glm::quat rightOrientation = glm::quat(); // rig space (z forward) - - bool isLeftFootEnabled; - bool isRightFootEnabled; - glm::vec3 leftFootPosition = glm::vec3(); // rig space - glm::quat leftFootOrientation = glm::quat(); // rig space (z forward) - glm::vec3 rightFootPosition = glm::vec3(); // rig space - glm::quat rightFootOrientation = glm::quat(); // rig space (z forward) - }; - enum class CharacterControllerState { Ground = 0, Takeoff, @@ -153,9 +139,6 @@ public: bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const; bool getAbsoluteJointPoseInRigFrame(int jointIndex, AnimPose& returnPose) const; - // legacy - bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; - // rig space glm::mat4 getJointTransform(int jointIndex) const; @@ -195,9 +178,8 @@ public: // legacy void clearJointStatePriorities(); - void updateFromHeadParameters(const HeadParameters& params, float dt); + void updateFromControllerParameters(const ControllerParameters& params, float dt); void updateFromEyeParameters(const EyeParameters& params); - void updateFromHandAndFeetParameters(const HandAndFeetParameters& params, float dt); void initAnimGraph(const QUrl& url); @@ -247,11 +229,18 @@ protected: void applyOverridePoses(); void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut); - void updateHeadAnimVars(const HeadParameters& params); + void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix); + void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool leftArmEnabled, bool rightArmEnabled, float dt, + const AnimPose& leftHandPose, const AnimPose& rightHandPose, + float bodyCapsuleRadius, float bodyCapsuleHalfHeight, const glm::vec3& bodyCapsuleLocalOffset); + void updateFeet(bool leftFootEnabled, bool rightFootEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose); void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::vec3& lookAt, const glm::vec3& saccade); void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; + glm::vec3 calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int hipsIndex, bool isLeft) const; + glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const; + AnimPose _modelOffset; // model to rig space AnimPose _geometryOffset; // geometry to model space (includes unit offset & fst offsets) AnimPose _invGeometryOffset; @@ -347,13 +336,12 @@ protected: bool _enableDebugDrawIKConstraints { false }; bool _enableDebugDrawIKChains { false }; -private: QMap _stateHandlers; int _nextStateHandlerId { 0 }; QMutex _stateMutex; - bool transitionHandPose(float deltaTime, float totalDuration, AnimPose& controlledHandPose, bool isLeftHand, - bool isToControlled, AnimPose& returnHandPose); + bool transitionHandPose(float deltaTime, float totalDuration, AnimPose& controlledHandPose, bool isLeftHand, + bool isToControlled, AnimPose& returnHandPose); bool _isLeftHandControlled { false }; bool _isRightHandControlled { false }; @@ -363,6 +351,18 @@ private: float _rightHandRelaxTimeRemaining { 0.0f }; AnimPose _lastLeftHandControlledPose; AnimPose _lastRightHandControlledPose; + + glm::vec3 _prevRightFootPoleVector { Vectors::UNIT_Z }; + bool _prevRightFootPoleVectorValid { false }; + + glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; + bool _prevLeftFootPoleVectorValid { false }; + + glm::vec3 _prevRightHandPoleVector { -Vectors::UNIT_Z }; + bool _prevRightHandPoleVectorValid { false }; + + glm::vec3 _prevLeftHandPoleVector { -Vectors::UNIT_Z }; + bool _prevLeftHandPoleVectorValid { false }; }; #endif /* defined(__hifi__Rig__) */ diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index fc54a04a5e..43af7afdef 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -48,6 +48,7 @@ #include "AudioClientLogging.h" #include "AudioLogging.h" +#include "AudioHelpers.h" #include "AudioClient.h" @@ -1688,23 +1689,24 @@ int AudioClient::calculateNumberOfFrameSamples(int numBytes) const { } float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { - // copied from AudioMixer, more or less glm::quat inverseOrientation = glm::inverse(_orientationGetter()); - // compute sample delay for the 2 ears to create phase panning glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition; - // project the rotated source position vector onto x-y plane + // project the rotated source position vector onto the XZ plane rotatedSourcePosition.y = 0.0f; static const float SOURCE_DISTANCE_THRESHOLD = 1e-30f; - if (glm::length2(rotatedSourcePosition) > SOURCE_DISTANCE_THRESHOLD) { + float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition); + if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) { // produce an oriented angle about the y-axis - return glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), glm::normalize(rotatedSourcePosition), glm::vec3(0.0f, -1.0f, 0.0f)); - } else { - + glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2)); + float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" + return (direction.x < 0.0f) ? -angle : angle; + + } else { // no azimuth if they are in same spot return 0.0f; } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b07af35acf..1631de3307 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1511,6 +1511,7 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide >> identity.attachmentData >> identity.displayName >> identity.sessionDisplayName + >> identity.isReplicated >> identity.avatarEntityData >> identity.lookAtSnappingEnabled ; @@ -1535,6 +1536,11 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide } maybeUpdateSessionDisplayNameFromTransport(identity.sessionDisplayName); + if (identity.isReplicated != _isReplicated) { + _isReplicated = identity.isReplicated; + identityChanged = true; + } + if (identity.attachmentData != _attachmentData) { setAttachmentData(identity.attachmentData); identityChanged = true; @@ -1570,7 +1576,7 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide } } -QByteArray AvatarData::identityByteArray() const { +QByteArray AvatarData::identityByteArray(bool setIsReplicated) const { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); const QUrl& urlToSend = cannonicalSkeletonModelURL(emptyURL); // depends on _skeletonModelURL @@ -1585,6 +1591,7 @@ QByteArray AvatarData::identityByteArray() const { << _attachmentData << _displayName << getSessionDisplayNameForTransport() // depends on _sessionDisplayName + << (_isReplicated || setIsReplicated) << _avatarEntityData << _lookAtSnappingEnabled ; @@ -1982,7 +1989,7 @@ JointData jointDataFromJsonValue(const QJsonValue& json) { result.rotation = quatFromJsonValue(array[0]); result.rotationSet = true; result.translation = vec3FromJsonValue(array[1]); - result.translationSet = false; + result.translationSet = true; } return result; } @@ -2150,12 +2157,9 @@ void AvatarData::fromJson(const QJsonObject& json, bool useFrameSkeleton) { QVector jointArray; QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray(); jointArray.reserve(jointArrayJson.size()); - int i = 0; for (const auto& jointJson : jointArrayJson) { auto joint = jointDataFromJsonValue(jointJson); jointArray.push_back(joint); - setJointData(i, joint.rotation, joint.translation); - i++; } setRawJointData(jointArray); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index e2032d063e..afd4d06791 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -533,6 +533,7 @@ public: QVector attachmentData; QString displayName; QString sessionDisplayName; + bool isReplicated; AvatarEntityMap avatarEntityData; bool lookAtSnappingEnabled; }; @@ -542,7 +543,7 @@ public: void processAvatarIdentity(const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged, bool& skeletonModelUrlChanged); - QByteArray identityByteArray() const; + QByteArray identityByteArray(bool setIsReplicated = false) const; const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } const QString& getDisplayName() const { return _displayName; } @@ -630,9 +631,12 @@ public: void markIdentityDataChanged() { _identityDataChanged = true; } void pushIdentitySequenceNumber() { ++_identitySequenceNumber; }; + bool hasProcessedFirstIdentity() const { return _hasProcessedFirstIdentity; } float getDensity() const { return _density; } + bool getIsReplicated() const { return _isReplicated; } + signals: void displayNameChanged(); void lookAtSnappingChanged(bool enabled); @@ -670,6 +674,10 @@ protected: bool hasParent() const { return !getParentID().isNull(); } bool hasFaceTracker() const { return _headData ? _headData->_isFaceTrackerConnected : false; } + // isReplicated will be true on downstream Avatar Mixers and their clients, but false on the upstream "master" + // Audio Mixer that the replicated avatar is connected to. + bool _isReplicated{ false }; + glm::vec3 _handPosition; virtual const QString& getSessionDisplayNameForTransport() const { return _sessionDisplayName; } virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) { } // No-op in AvatarMixer diff --git a/libraries/avatars/src/ScriptAvatarData.cpp b/libraries/avatars/src/ScriptAvatarData.cpp index 49e53952d4..d0643d28f8 100644 --- a/libraries/avatars/src/ScriptAvatarData.cpp +++ b/libraries/avatars/src/ScriptAvatarData.cpp @@ -153,6 +153,15 @@ QString ScriptAvatarData::getSessionDisplayName() const { return QString(); } } + +bool ScriptAvatarData::getIsReplicated() const { + if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) { + return sharedAvatarData->getIsReplicated(); + } else { + return false; + } +} + bool ScriptAvatarData::getLookAtSnappingEnabled() const { if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) { return sharedAvatarData->getLookAtSnappingEnabled(); diff --git a/libraries/avatars/src/ScriptAvatarData.h b/libraries/avatars/src/ScriptAvatarData.h index 4a95333402..46dfb5325f 100644 --- a/libraries/avatars/src/ScriptAvatarData.h +++ b/libraries/avatars/src/ScriptAvatarData.h @@ -45,6 +45,7 @@ class ScriptAvatarData : public QObject { Q_PROPERTY(QUuid sessionUUID READ getSessionUUID) Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged) Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName) + Q_PROPERTY(bool isReplicated READ getIsReplicated) Q_PROPERTY(bool lookAtSnappingEnabled READ getLookAtSnappingEnabled NOTIFY lookAtSnappingChanged) // @@ -96,6 +97,7 @@ public: QUuid getSessionUUID() const; QString getDisplayName() const; QString getSessionDisplayName() const; + bool getIsReplicated() const; bool getLookAtSnappingEnabled() const; // diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp index 96e433bcc8..b3c0ed3f05 100644 --- a/libraries/controllers/src/controllers/Actions.cpp +++ b/libraries/controllers/src/controllers/Actions.cpp @@ -59,6 +59,48 @@ namespace controller { makePosePair(Action::SPINE2, "Spine2"), makePosePair(Action::HEAD, "Head"), + makePosePair(Action::LEFT_HAND_THUMB1, "LeftHandThumb1"), + makePosePair(Action::LEFT_HAND_THUMB2, "LeftHandThumb2"), + makePosePair(Action::LEFT_HAND_THUMB3, "LeftHandThumb3"), + makePosePair(Action::LEFT_HAND_THUMB4, "LeftHandThumb4"), + makePosePair(Action::LEFT_HAND_INDEX1, "LeftHandIndex1"), + makePosePair(Action::LEFT_HAND_INDEX2, "LeftHandIndex2"), + makePosePair(Action::LEFT_HAND_INDEX3, "LeftHandIndex3"), + makePosePair(Action::LEFT_HAND_INDEX4, "LeftHandIndex4"), + makePosePair(Action::LEFT_HAND_MIDDLE1, "LeftHandMiddle1"), + makePosePair(Action::LEFT_HAND_MIDDLE2, "LeftHandMiddle2"), + makePosePair(Action::LEFT_HAND_MIDDLE3, "LeftHandMiddle3"), + makePosePair(Action::LEFT_HAND_MIDDLE4, "LeftHandMiddle4"), + makePosePair(Action::LEFT_HAND_RING1, "LeftHandRing1"), + makePosePair(Action::LEFT_HAND_RING2, "LeftHandRing2"), + makePosePair(Action::LEFT_HAND_RING3, "LeftHandRing3"), + makePosePair(Action::LEFT_HAND_RING4, "LeftHandRing4"), + makePosePair(Action::LEFT_HAND_PINKY1, "LeftHandPinky1"), + makePosePair(Action::LEFT_HAND_PINKY2, "LeftHandPinky2"), + makePosePair(Action::LEFT_HAND_PINKY3, "LeftHandPinky3"), + makePosePair(Action::LEFT_HAND_PINKY4, "LeftHandPinky4"), + + makePosePair(Action::RIGHT_HAND_THUMB1, "RightHandThumb1"), + makePosePair(Action::RIGHT_HAND_THUMB2, "RightHandThumb2"), + makePosePair(Action::RIGHT_HAND_THUMB3, "RightHandThumb3"), + makePosePair(Action::RIGHT_HAND_THUMB4, "RightHandThumb4"), + makePosePair(Action::RIGHT_HAND_INDEX1, "RightHandIndex1"), + makePosePair(Action::RIGHT_HAND_INDEX2, "RightHandIndex2"), + makePosePair(Action::RIGHT_HAND_INDEX3, "RightHandIndex3"), + makePosePair(Action::RIGHT_HAND_INDEX4, "RightHandIndex4"), + makePosePair(Action::RIGHT_HAND_MIDDLE1, "RightHandMiddle1"), + makePosePair(Action::RIGHT_HAND_MIDDLE2, "RightHandMiddle2"), + makePosePair(Action::RIGHT_HAND_MIDDLE3, "RightHandMiddle3"), + makePosePair(Action::RIGHT_HAND_MIDDLE4, "RightHandMiddle4"), + makePosePair(Action::RIGHT_HAND_RING1, "RightHandRing1"), + makePosePair(Action::RIGHT_HAND_RING2, "RightHandRing2"), + makePosePair(Action::RIGHT_HAND_RING3, "RightHandRing3"), + makePosePair(Action::RIGHT_HAND_RING4, "RightHandRing4"), + makePosePair(Action::RIGHT_HAND_PINKY1, "RightHandPinky1"), + makePosePair(Action::RIGHT_HAND_PINKY2, "RightHandPinky2"), + makePosePair(Action::RIGHT_HAND_PINKY3, "RightHandPinky3"), + makePosePair(Action::RIGHT_HAND_PINKY4, "RightHandPinky4"), + makeButtonPair(Action::LEFT_HAND_CLICK, "LeftHandClick"), makeButtonPair(Action::RIGHT_HAND_CLICK, "RightHandClick"), diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index 2cb500c42a..ec4800c9aa 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -104,6 +104,47 @@ enum class Action { LEFT_ARM, RIGHT_ARM, + LEFT_HAND_THUMB1, + LEFT_HAND_THUMB2, + LEFT_HAND_THUMB3, + LEFT_HAND_THUMB4, + LEFT_HAND_INDEX1, + LEFT_HAND_INDEX2, + LEFT_HAND_INDEX3, + LEFT_HAND_INDEX4, + LEFT_HAND_MIDDLE1, + LEFT_HAND_MIDDLE2, + LEFT_HAND_MIDDLE3, + LEFT_HAND_MIDDLE4, + LEFT_HAND_RING1, + LEFT_HAND_RING2, + LEFT_HAND_RING3, + LEFT_HAND_RING4, + LEFT_HAND_PINKY1, + LEFT_HAND_PINKY2, + LEFT_HAND_PINKY3, + LEFT_HAND_PINKY4, + + RIGHT_HAND_THUMB1, + RIGHT_HAND_THUMB2, + RIGHT_HAND_THUMB3, + RIGHT_HAND_THUMB4, + RIGHT_HAND_INDEX1, + RIGHT_HAND_INDEX2, + RIGHT_HAND_INDEX3, + RIGHT_HAND_INDEX4, + RIGHT_HAND_MIDDLE1, + RIGHT_HAND_MIDDLE2, + RIGHT_HAND_MIDDLE3, + RIGHT_HAND_MIDDLE4, + RIGHT_HAND_RING1, + RIGHT_HAND_RING2, + RIGHT_HAND_RING3, + RIGHT_HAND_RING4, + RIGHT_HAND_PINKY1, + RIGHT_HAND_PINKY2, + RIGHT_HAND_PINKY3, + RIGHT_HAND_PINKY4, NUM_ACTIONS, }; diff --git a/libraries/controllers/src/controllers/Input.cpp b/libraries/controllers/src/controllers/Input.cpp index 6f8bd547a2..dbc9071f43 100644 --- a/libraries/controllers/src/controllers/Input.cpp +++ b/libraries/controllers/src/controllers/Input.cpp @@ -9,9 +9,14 @@ #include "Input.h" namespace controller { - const Input Input::INVALID_INPUT = Input(0x7fffffff); + const Input Input::INVALID_INPUT = invalidInput(); const uint16_t Input::INVALID_DEVICE = Input::INVALID_INPUT.device; const uint16_t Input::INVALID_CHANNEL = Input::INVALID_INPUT.channel; const uint16_t Input::INVALID_TYPE = Input::INVALID_INPUT.type; + + const Input& Input::invalidInput() { + static const Input INVALID_INPUT = Input(0x7fffffff); + return INVALID_INPUT; + } } diff --git a/libraries/controllers/src/controllers/Input.h b/libraries/controllers/src/controllers/Input.h index b74ad48c6f..3ca4076de2 100644 --- a/libraries/controllers/src/controllers/Input.h +++ b/libraries/controllers/src/controllers/Input.h @@ -83,6 +83,8 @@ struct Input { using NamedPair = QPair; using NamedVector = QVector; + + static const Input& invalidInput(); }; } diff --git a/libraries/controllers/src/controllers/StandardController.cpp b/libraries/controllers/src/controllers/StandardController.cpp index 8e49bb0ebf..40b87bc6b2 100644 --- a/libraries/controllers/src/controllers/StandardController.cpp +++ b/libraries/controllers/src/controllers/StandardController.cpp @@ -101,7 +101,47 @@ Input::NamedVector StandardController::getAvailableInputs() const { // Poses makePair(LEFT_HAND, "LeftHand"), + makePair(LEFT_HAND_THUMB1, "LeftHandThumb1"), + makePair(LEFT_HAND_THUMB2, "LeftHandThumb2"), + makePair(LEFT_HAND_THUMB3, "LeftHandThumb3"), + makePair(LEFT_HAND_THUMB4, "LeftHandThumb4"), + makePair(LEFT_HAND_INDEX1, "LeftHandIndex1"), + makePair(LEFT_HAND_INDEX2, "LeftHandIndex2"), + makePair(LEFT_HAND_INDEX3, "LeftHandIndex3"), + makePair(LEFT_HAND_INDEX4, "LeftHandIndex4"), + makePair(LEFT_HAND_MIDDLE1, "LeftHandMiddle1"), + makePair(LEFT_HAND_MIDDLE2, "LeftHandMiddle2"), + makePair(LEFT_HAND_MIDDLE3, "LeftHandMiddle3"), + makePair(LEFT_HAND_MIDDLE4, "LeftHandMiddle4"), + makePair(LEFT_HAND_RING1, "LeftHandRing1"), + makePair(LEFT_HAND_RING2, "LeftHandRing2"), + makePair(LEFT_HAND_RING3, "LeftHandRing3"), + makePair(LEFT_HAND_RING4, "LeftHandRing4"), + makePair(LEFT_HAND_PINKY1, "LeftHandPinky1"), + makePair(LEFT_HAND_PINKY2, "LeftHandPinky2"), + makePair(LEFT_HAND_PINKY3, "LeftHandPinky3"), + makePair(LEFT_HAND_PINKY4, "LeftHandPinky4"), makePair(RIGHT_HAND, "RightHand"), + makePair(RIGHT_HAND_THUMB1, "RightHandThumb1"), + makePair(RIGHT_HAND_THUMB2, "RightHandThumb2"), + makePair(RIGHT_HAND_THUMB3, "RightHandThumb3"), + makePair(RIGHT_HAND_THUMB4, "RightHandThumb4"), + makePair(RIGHT_HAND_INDEX1, "RightHandIndex1"), + makePair(RIGHT_HAND_INDEX2, "RightHandIndex2"), + makePair(RIGHT_HAND_INDEX3, "RightHandIndex3"), + makePair(RIGHT_HAND_INDEX4, "RightHandIndex4"), + makePair(RIGHT_HAND_MIDDLE1, "RightHandMiddle1"), + makePair(RIGHT_HAND_MIDDLE2, "RightHandMiddle2"), + makePair(RIGHT_HAND_MIDDLE3, "RightHandMiddle3"), + makePair(RIGHT_HAND_MIDDLE4, "RightHandMiddle4"), + makePair(RIGHT_HAND_RING1, "RightHandRing1"), + makePair(RIGHT_HAND_RING2, "RightHandRing2"), + makePair(RIGHT_HAND_RING3, "RightHandRing3"), + makePair(RIGHT_HAND_RING4, "RightHandRing4"), + makePair(RIGHT_HAND_PINKY1, "RightHandPinky1"), + makePair(RIGHT_HAND_PINKY2, "RightHandPinky2"), + makePair(RIGHT_HAND_PINKY3, "RightHandPinky3"), + makePair(RIGHT_HAND_PINKY4, "RightHandPinky4"), makePair(LEFT_FOOT, "LeftFoot"), makePair(RIGHT_FOOT, "RightFoot"), makePair(RIGHT_ARM, "RightArm"), diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 79f4325ae6..29f011fba2 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -47,8 +47,8 @@ namespace controller { const uint16_t UserInputMapper::STANDARD_DEVICE = 0; - const uint16_t UserInputMapper::ACTIONS_DEVICE = Input::INVALID_DEVICE - 0x00FF; - const uint16_t UserInputMapper::STATE_DEVICE = Input::INVALID_DEVICE - 0x0100; + const uint16_t UserInputMapper::ACTIONS_DEVICE = Input::invalidInput().device - 0x00FF; + const uint16_t UserInputMapper::STATE_DEVICE = Input::invalidInput().device - 0x0100; } // Default contruct allocate the poutput size with the current hardcoded action channels diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index ffaac3bf3e..1684c06512 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -163,7 +163,6 @@ void EntityTreeRenderer::reloadEntityScripts() { void EntityTreeRenderer::init() { OctreeProcessor::init(); EntityTreePointer entityTree = std::static_pointer_cast(_tree); - entityTree->setFBXService(this); if (_wantScripts) { resetEntitiesScriptEngine(); @@ -188,7 +187,6 @@ void EntityTreeRenderer::shutdown() { void EntityTreeRenderer::setTree(OctreePointer newTree) { OctreeProcessor::setTree(newTree); - std::static_pointer_cast(_tree)->setFBXService(this); } void EntityTreeRenderer::update() { @@ -373,31 +371,6 @@ bool EntityTreeRenderer::applyLayeredZones() { return true; } -const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) { - const FBXGeometry* result = NULL; - - if (entityItem->getType() == EntityTypes::Model) { - std::shared_ptr modelEntityItem = - std::dynamic_pointer_cast(entityItem); - assert(modelEntityItem); // we need this!!! - ModelPointer model = modelEntityItem->getModel(getSharedFromThis()); - if (model && model->isLoaded()) { - result = &model->getFBXGeometry(); - } - } - return result; -} - -ModelPointer EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityItem) { - ModelPointer result = nullptr; - if (entityItem->getType() == EntityTypes::Model) { - std::shared_ptr modelEntityItem = - std::dynamic_pointer_cast(entityItem); - result = modelEntityItem->getModel(getSharedFromThis()); - } - return result; -} - void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) { std::static_pointer_cast(_tree)->processEraseMessage(message, sourceNode); } @@ -880,7 +853,7 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool entity->scriptHasUnloaded(); } if (shouldLoad) { - scriptUrl = ResourceManager::normalizeURL(scriptUrl); + scriptUrl = DependencyManager::get()->normalizeURL(scriptUrl); _entitiesScriptEngine->loadEntityScript(entityID, scriptUrl, reload); entity->scriptHasPreloaded(); } @@ -889,7 +862,12 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool void EntityTreeRenderer::playEntityCollisionSound(EntityItemPointer entity, const Collision& collision) { assert((bool)entity); - SharedSoundPointer collisionSound = entity->getCollisionSound(); + auto renderable = entity->getRenderableInterface(); + if (!renderable) { + return; + } + + SharedSoundPointer collisionSound = renderable->getCollisionSound(); if (!collisionSound) { return; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 5dcbd1aeb9..f4909a2036 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -39,7 +39,7 @@ using ModelWeakPointer = std::weak_ptr; using CalculateEntityLoadingPriority = std::function; // Generic client side Octree renderer class. -class EntityTreeRenderer : public OctreeProcessor, public EntityItemFBXService, public Dependency { +class EntityTreeRenderer : public OctreeProcessor, public Dependency { Q_OBJECT public: EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState, @@ -68,9 +68,6 @@ public: virtual void init() override; - virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) override; - virtual ModelPointer getModelForEntityItem(EntityItemPointer entityItem) override; - /// clears the tree virtual void clear() override; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 244a850d67..c848b10f6a 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -14,6 +14,7 @@ #include #include +#include #include "AbstractViewStateInterface.h" #include "EntitiesRendererLogging.h" @@ -40,7 +41,11 @@ public: virtual void render(RenderArgs* args) {}; virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) = 0; virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) = 0; + const SharedSoundPointer& getCollisionSound() { return _collisionSound; } + void setCollisionSound(const SharedSoundPointer& sound) { _collisionSound = sound; } virtual RenderableEntityInterface* getRenderableInterface() { return nullptr; } +private: + SharedSoundPointer _collisionSound; }; class RenderableEntityItemProxy { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f343fdb155..0547c60364 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -69,11 +69,9 @@ void RenderableModelEntityItem::setModelURL(const QString& url) { void RenderableModelEntityItem::loader() { _needsModelReload = true; - auto renderer = DependencyManager::get(); - assert(renderer); { PerformanceTimer perfTimer("getModel"); - getModel(renderer); + getModel(); } } @@ -390,8 +388,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (!_model || _needsModelReload) { // TODO: this getModel() appears to be about 3% of model render time. We should optimize PerformanceTimer perfTimer("getModel"); - auto renderer = qSharedPointerCast(args->_renderData); - getModel(renderer); + getModel(); // Remap textures immediately after loading to avoid flicker remapTextures(); @@ -483,7 +480,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { auto& currentURL = getParsedModelURL(); if (currentURL != _model->getURL()) { // Defer setting the url to the render thread - getModel(_myRenderer); + getModel(); } } } @@ -492,16 +489,11 @@ ModelPointer RenderableModelEntityItem::getModelNotSafe() { return _model; } -ModelPointer RenderableModelEntityItem::getModel(QSharedPointer renderer) { - if (!renderer) { - return nullptr; - } - +ModelPointer RenderableModelEntityItem::getModel() { // make sure our renderer is setup if (!_myRenderer) { - _myRenderer = renderer; + _myRenderer = DependencyManager::get(); } - assert(_myRenderer == renderer); // you should only ever render on one renderer if (!_myRenderer || QThread::currentThread() != _myRenderer->thread()) { return _model; @@ -513,7 +505,7 @@ ModelPointer RenderableModelEntityItem::getModel(QSharedPointerallocateModel(getModelURL(), renderer->getEntityLoadingPriority(*this), this); + _model = _myRenderer->allocateModel(getModelURL(), _myRenderer->getEntityLoadingPriority(*this), this); _needsInitialSimulation = true; // If we need to change URLs, update it *after rendering* (to avoid access violations) } else if (QUrl(getModelURL()) != _model->getURL()) { @@ -587,6 +579,17 @@ EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlag properties.setRenderInfoHasTransparent(_model->getRenderInfoHasTransparent()); } + + if (_model && _model->isLoaded()) { + // TODO: improve naturalDimensions in the future, + // for now we've added this hack for setting natural dimensions of models + Extents meshExtents = _model->getFBXGeometry().getUnscaledMeshExtents(); + properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); + properties.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum); + } + + + return properties; } @@ -1255,3 +1258,27 @@ QStringList RenderableModelEntityItem::getJointNames() const { } return result; } + +void RenderableModelEntityItem::mapJoints(const QStringList& modelJointNames) { + // if we don't have animation, or we're already joint mapped then bail early + if (!hasAnimation() || jointsMapped()) { + return; + } + + if (!_animation || _animation->getURL().toString() != getAnimationURL()) { + _animation = DependencyManager::get()->getAnimation(getAnimationURL()); + } + + if (_animation && _animation->isLoaded()) { + QStringList animationJointNames = _animation->getJointNames(); + + if (modelJointNames.size() > 0 && animationJointNames.size() > 0) { + _jointMapping.resize(modelJointNames.size()); + for (int i = 0; i < modelJointNames.size(); i++) { + _jointMapping[i] = animationJointNames.indexOf(modelJointNames[i]); + } + _jointMappingCompleted = true; + _jointMappingURL = _animationProperties.getURL(); + } + } +} diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 2bbb51b3f0..2d240c01a6 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -16,6 +16,7 @@ #include #include +#include class Model; class EntityTreeRenderer; @@ -53,7 +54,7 @@ public: bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const override; - ModelPointer getModel(QSharedPointer renderer); + ModelPointer getModel(); ModelPointer getModelNotSafe(); virtual bool needsToCallUpdate() const override; @@ -106,6 +107,15 @@ public: // Transparency is handled in ModelMeshPartPayload bool isTransparent() override { return false; } + void mapJoints(const QStringList& modelJointNames); + bool jointsMapped() const { + return _jointMappingURL == getAnimationURL() && _jointMappingCompleted; + } + + AnimationPointer getAnimation() const { + return _animation; + } + private: QVariantMap parseTexturesToMap(QString textures); void remapTextures(); @@ -131,6 +141,12 @@ private: bool _needsJointSimulation { false }; bool _showCollisionGeometry { false }; const void* _collisionMeshKey { nullptr }; + + // used on client side + bool _jointMappingCompleted { false }; + QVector _jointMapping; // domain is index into model-joints, range is index into animation-joints + QString _jointMappingURL; + AnimationPointer _animation; }; #endif // hifi_RenderableModelEntityItem_h diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 6cda472d96..88a5d2b873 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -9,11 +9,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + +#include "RenderablePolyVoxEntityItem.h" + #include #include #include #include #include +#include #include "ModelScriptingInterface.h" #if defined(__GNUC__) && !defined(__clang__) @@ -52,7 +56,6 @@ #include "EntityTreeRenderer.h" #include "polyvox_vert.h" #include "polyvox_frag.h" -#include "RenderablePolyVoxEntityItem.h" #include "EntityEditPacketSender.h" #include "PhysicalEntitySimulation.h" @@ -1626,6 +1629,7 @@ void RenderablePolyVoxEntityItem::locationChanged(bool tellPhysics) { scene->enqueueTransaction(transaction); } + bool RenderablePolyVoxEntityItem::getMeshes(MeshProxyList& result) { if (!updateDependents()) { return false; @@ -1645,7 +1649,7 @@ bool RenderablePolyVoxEntityItem::getMeshes(MeshProxyList& result) { } else { success = true; // the mesh will be in voxel-space. transform it into object-space - meshProxy = new MeshProxy( + meshProxy = new SimpleMeshProxy( _mesh->map([=](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); }, [=](glm::vec3 normal){ return glm::normalize(glm::vec3(transform * glm::vec4(normal, 0.0f))); }, [&](uint32_t index){ return index; })); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 174d6338d3..45625ada6d 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -12,17 +12,19 @@ #ifndef hifi_RenderablePolyVoxEntityItem_h #define hifi_RenderablePolyVoxEntityItem_h -#include #include +#include + #include #include +#include +#include #include +#include -#include "PolyVoxEntityItem.h" #include "RenderableEntityItem.h" -#include "gpu/Context.h" class PolyVoxPayload { public: diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index ddb5fbaf73..19341ec3e2 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -1,9 +1,3 @@ set(TARGET_NAME entities) setup_hifi_library(Network Script) -link_hifi_libraries(avatars shared audio octree model model-networking fbx networking animation) -include_hifi_library_headers(networking) -include_hifi_library_headers(gpu) - -target_bullet() - -include_hifi_library_headers(render) +link_hifi_libraries(shared networking octree avatars) diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index f6d08ad8b9..848d4352a7 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -9,12 +9,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "AnimationPropertyGroup.h" + #include #include -#include -#include "AnimationPropertyGroup.h" #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index c6d386d2ef..c0086b41b3 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -19,7 +19,7 @@ #include -#include "AnimationLoop.h" +#include // for Animation, AnimationCache, and AnimationPointer classes #include "EntityItemPropertiesMacros.h" #include "PropertyGroup.h" diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index d62495d95e..5359ebd31b 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -132,7 +132,7 @@ void EntityEditFilters::addFilter(EntityItemID entityID, QString filterURL) { _filterDataMap.insert(entityID, filterData); _lock.unlock(); - auto scriptRequest = ResourceManager::createResourceRequest(this, scriptURL); + auto scriptRequest = DependencyManager::get()->createResourceRequest(this, scriptURL); if (!scriptRequest) { qWarning() << "Could not create ResourceRequest for Entity Edit filter script at" << scriptURL.toString(); scriptRequestFinished(entityID); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 17de15e32b..23ce097cc2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -23,8 +23,8 @@ #include #include #include // usecTimestampNow() -#include #include +#include #include "EntityScriptingInterface.h" #include "EntitiesLogging.h" @@ -988,21 +988,6 @@ void EntityItem::setCollisionSoundURL(const QString& value) { } } -SharedSoundPointer EntityItem::getCollisionSound() { - SharedSoundPointer result; - withReadLock([&] { - result = _collisionSound; - }); - - if (!result) { - result = DependencyManager::get()->getSound(_collisionSoundURL); - withWriteLock([&] { - _collisionSound = result; - }); - } - return result; -} - void EntityItem::simulate(const quint64& now) { if (getLastSimulated() == 0) { setLastSimulated(now); @@ -2650,12 +2635,6 @@ QString EntityItem::getCollisionSoundURL() const { return result; } -void EntityItem::setCollisionSound(SharedSoundPointer sound) { - withWriteLock([&] { - _collisionSound = sound; - }); -} - glm::vec3 EntityItem::getRegistrationPoint() const { glm::vec3 result; withReadLock([&] { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 0318c72991..92c83651aa 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -19,14 +19,13 @@ #include -#include // for Animation, AnimationCache, and AnimationPointer classes +#include // for Animation, AnimationCache, and AnimationPointer classes #include // for EncodeBitstreamParams class #include // for OctreeElement::AppendState #include #include #include #include -#include #include #include @@ -260,9 +259,6 @@ public: QString getCollisionSoundURL() const; void setCollisionSoundURL(const QString& value); - SharedSoundPointer getCollisionSound(); - void setCollisionSound(SharedSoundPointer sound); - glm::vec3 getRegistrationPoint() const; /// registration point as ratio of entity /// registration point as ratio of entity @@ -526,7 +522,6 @@ protected: quint64 _loadedScriptTimestamp { ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP + 1 }; QString _collisionSoundURL; - SharedSoundPointer _collisionSound; glm::vec3 _registrationPoint; float _angularDamping; bool _visible; diff --git a/libraries/entities/src/EntityItemID.cpp b/libraries/entities/src/EntityItemID.cpp index 5f07019db4..3b4ca1cea0 100644 --- a/libraries/entities/src/EntityItemID.cpp +++ b/libraries/entities/src/EntityItemID.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "EntityItemID.h" #include #include @@ -17,7 +18,6 @@ #include #include "RegisteredMetaTypes.h" -#include "EntityItemID.h" int entityItemIDTypeID = qRegisterMetaType(); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 1ed020e592..a207902789 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "EntitiesLogging.h" #include "EntityItem.h" diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 590298e102..b526ac663c 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -15,6 +15,7 @@ #include #include +#include #include #include diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 90dc6893b4..7351d49dff 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include "EntitiesLogging.h" #include "EntityDynamicFactoryInterface.h" @@ -298,18 +297,6 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit } results = entity->getProperties(desiredProperties); - - // TODO: improve naturalDimensions in the future, - // for now we've added this hack for setting natural dimensions of models - if (entity->getType() == EntityTypes::Model) { - const FBXGeometry* geometry = _entityTree->getGeometryForEntity(entity); - if (geometry) { - Extents meshExtents = geometry->getUnscaledMeshExtents(); - results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); - results.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum); - } - } - } }); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 11694c4cea..4773f45af7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -9,11 +9,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include -#include +#include "EntityTree.h" +#include +#include + #include -#include "EntityTree.h" +#include +#include + #include "EntitySimulation.h" #include "VariantMapToScriptValue.h" @@ -55,9 +59,7 @@ public: EntityTree::EntityTree(bool shouldReaverage) : - Octree(shouldReaverage), - _fbxService(NULL), - _simulation(NULL) + Octree(shouldReaverage) { resetClientEditStats(); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8e3c9f5412..24e6c364b1 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -41,13 +41,6 @@ public: virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) = 0; }; -class EntityItemFBXService { -public: - virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0; - virtual ModelPointer getModelForEntityItem(EntityItemPointer entityItem) = 0; -}; - - class SendEntitiesOperationArgs { public: glm::vec3 root; @@ -189,15 +182,6 @@ public: int processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode); int processEraseMessageDetails(const QByteArray& buffer, const SharedNodePointer& sourceNode); - EntityItemFBXService* getFBXService() const { return _fbxService; } - void setFBXService(EntityItemFBXService* service) { _fbxService = service; } - const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) { - return _fbxService ? _fbxService->getGeometryForEntity(entityItem) : NULL; - } - ModelPointer getModelForEntityItem(EntityItemPointer entityItem) { - return _fbxService ? _fbxService->getModelForEntityItem(entityItem) : NULL; - } - EntityTreeElementPointer getContainingElement(const EntityItemID& entityItemID) /*const*/; void setContainingElement(const EntityItemID& entityItemID, EntityTreeElementPointer element); void debugDumpMap(); @@ -325,8 +309,6 @@ protected: _deletedEntityItemIDs << id; } - EntityItemFBXService* _fbxService; - mutable QReadWriteLock _entityToElementLock; QHash _entityToElementMap; diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 0dc42717f5..cce7ee006f 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -9,17 +9,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "EntityTreeElement.h" + #include -#include #include #include +#include #include "EntitiesLogging.h" #include "EntityNodeData.h" #include "EntityItemProperties.h" #include "EntityTree.h" -#include "EntityTreeElement.h" #include "EntityTypes.h" EntityTreeElement::EntityTreeElement(unsigned char* octalCode) : OctreeElement() { diff --git a/libraries/entities/src/KeyLightPropertyGroup.cpp b/libraries/entities/src/KeyLightPropertyGroup.cpp index 1011094266..f0d059af67 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.cpp +++ b/libraries/entities/src/KeyLightPropertyGroup.cpp @@ -9,12 +9,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "KeyLightPropertyGroup.h" + #include #include -#include - -#include "KeyLightPropertyGroup.h" #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 89213459fa..b5e759d2d8 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -37,7 +37,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem( _animationLoop.setResetOnRunning(false); _type = EntityTypes::Model; - _jointMappingCompleted = false; _lastKnownCurrentFrame = -1; _color[0] = _color[1] = _color[2] = 0; } @@ -204,30 +203,6 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit } -void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { - // if we don't have animation, or we're already joint mapped then bail early - if (!hasAnimation() || jointsMapped()) { - return; - } - - if (!_animation || _animation->getURL().toString() != getAnimationURL()) { - _animation = DependencyManager::get()->getAnimation(getAnimationURL()); - } - - if (_animation && _animation->isLoaded()) { - QStringList animationJointNames = _animation->getJointNames(); - - if (modelJointNames.size() > 0 && animationJointNames.size() > 0) { - _jointMapping.resize(modelJointNames.size()); - for (int i = 0; i < modelJointNames.size(); i++) { - _jointMapping[i] = animationJointNames.indexOf(modelJointNames[i]); - } - _jointMappingCompleted = true; - _jointMappingURL = _animationProperties.getURL(); - } - } -} - bool ModelEntityItem::isAnimatingSomething() const { return getAnimationIsPlaying() && getAnimationFPS() != 0.0f && diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 5076a43892..0c6132e211 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -12,8 +12,6 @@ #ifndef hifi_ModelEntityItem_h #define hifi_ModelEntityItem_h -#include - #include "EntityItem.h" #include "AnimationPropertyGroup.h" @@ -103,10 +101,7 @@ public: void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); } float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } - void mapJoints(const QStringList& modelJointNames); - bool jointsMapped() const { return _jointMappingURL == getAnimationURL() && _jointMappingCompleted; } - AnimationPointer getAnimation() const { return _animation; } bool getAnimationIsPlaying() const { return _animationLoop.getRunning(); } float getAnimationCurrentFrame() const { return _animationLoop.getCurrentFrame(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } @@ -158,7 +153,6 @@ protected: QUrl _parsedModelURL; QString _compoundShapeURL; - AnimationPointer _animation; AnimationPropertyGroup _animationProperties; AnimationLoop _animationLoop; @@ -166,11 +160,6 @@ protected: QString _textures; ShapeType _shapeType = SHAPE_TYPE_NONE; - - // used on client side - bool _jointMappingCompleted; - QVector _jointMapping; // domain is index into model-joints, range is index into animation-joints - QString _jointMappingURL; }; #endif // hifi_ModelEntityItem_h diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 1445d14d84..417901b9ab 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -202,7 +202,7 @@ bool OBJReader::isValidTexture(const QByteArray &filename) { } QUrl candidateUrl = _url.resolved(QUrl(filename)); - return ResourceManager::resourceExists(candidateUrl); + return DependencyManager::get()->resourceExists(candidateUrl); } void OBJReader::parseMaterialLibrary(QIODevice* device) { @@ -267,7 +267,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { } std::tuple requestData(QUrl& url) { - auto request = ResourceManager::createResourceRequest(nullptr, url); + auto request = DependencyManager::get()->createResourceRequest(nullptr, url); if (!request) { return std::make_tuple(false, QByteArray()); diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index 791130ef6e..11e67811b6 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -114,7 +114,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::gl::GLBackend::do_getQuery), (&::gpu::gl::GLBackend::do_resetStages), - + + (&::gpu::gl::GLBackend::do_disableContextViewCorrection), + (&::gpu::gl::GLBackend::do_restoreContextViewCorrection), (&::gpu::gl::GLBackend::do_disableContextStereo), (&::gpu::gl::GLBackend::do_restoreContextStereo), @@ -178,6 +180,11 @@ void GLBackend::init() { int swapInterval = wglGetSwapIntervalEXT(); qCDebug(gpugllogging, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); }*/ +#endif +#if THREADED_TEXTURE_BUFFERING + // This has to happen on the main thread in order to give the thread + // pool a reasonable parent object + GLVariableAllocationSupport::TransferJob::startBufferingThread(); #endif }); } @@ -369,6 +376,13 @@ void GLBackend::do_resetStages(const Batch& batch, size_t paramOffset) { resetStages(); } +void GLBackend::do_disableContextViewCorrection(const Batch& batch, size_t paramOffset) { + _transform._viewCorrectionEnabled = false; +} + +void GLBackend::do_restoreContextViewCorrection(const Batch& batch, size_t paramOffset) { + _transform._viewCorrectionEnabled = true; +} void GLBackend::do_disableContextStereo(const Batch& batch, size_t paramOffset) { diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index 96217555e1..88aecda617 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -143,6 +143,10 @@ public: // Reset stages virtual void do_resetStages(const Batch& batch, size_t paramOffset) final; + + virtual void do_disableContextViewCorrection(const Batch& batch, size_t paramOffset) final; + virtual void do_restoreContextViewCorrection(const Batch& batch, size_t paramOffset) final; + virtual void do_disableContextStereo(const Batch& batch, size_t paramOffset) final; virtual void do_restoreContextStereo(const Batch& batch, size_t paramOffset) final; @@ -333,6 +337,8 @@ protected: bool _skybox { false }; Transform _view; CameraCorrection _correction; + bool _viewCorrectionEnabled{ true }; + Mat4 _projection; Vec4i _viewport { 0, 0, 1, 1 }; @@ -400,6 +406,7 @@ protected: bool _invalidProgram { false }; BufferView _cameraCorrectionBuffer { gpu::BufferView(std::make_shared(sizeof(CameraCorrection), nullptr )) }; + BufferView _cameraCorrectionBufferIdentity { gpu::BufferView(std::make_shared(sizeof(CameraCorrection), nullptr )) }; State::Data _stateCache{ State::DEFAULT }; State::Signature _stateSignatureCache { 0 }; @@ -409,6 +416,8 @@ protected: PipelineStageState() { _cameraCorrectionBuffer.edit() = CameraCorrection(); + _cameraCorrectionBufferIdentity.edit() = CameraCorrection(); + _cameraCorrectionBufferIdentity._buffer->flush(); } } _pipeline; diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp index 2d71e8ed78..7ef64343ea 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp @@ -77,8 +77,14 @@ void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) { if (_pipeline._invalidProgram) { glUseProgram(_pipeline._program); if (_pipeline._cameraCorrectionLocation != -1) { - auto cameraCorrectionBuffer = syncGPUObject(*_pipeline._cameraCorrectionBuffer._buffer); + gl::GLBuffer* cameraCorrectionBuffer = nullptr; + if (_transform._viewCorrectionEnabled) { + cameraCorrectionBuffer = syncGPUObject(*_pipeline._cameraCorrectionBuffer._buffer); + } else { + cameraCorrectionBuffer = syncGPUObject(*_pipeline._cameraCorrectionBufferIdentity._buffer); + } glBindBufferRange(GL_UNIFORM_BUFFER, _pipeline._cameraCorrectionLocation, cameraCorrectionBuffer->_id, 0, sizeof(CameraCorrection)); + } (void) CHECK_GL_ERROR(); _pipeline._invalidProgram = false; diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp index 01f055e0d9..f286a5cca9 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp @@ -102,7 +102,7 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo if (_invalidView) { // Apply the correction - if (_viewIsCamera && _correction.correction != glm::mat4()) { + if (_viewIsCamera && (_viewCorrectionEnabled && _correction.correction != glm::mat4())) { // FIXME should I switch to using the camera correction buffer in Transform.slf and leave this out? Transform result; _view.mult(result, _view, _correction.correction); diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 4161242a24..7758ddaf49 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -461,11 +461,6 @@ void GLVariableAllocationSupport::updateMemoryPressure() { if (newState != _memoryPressureState) { _memoryPressureState = newState; -#if THREADED_TEXTURE_BUFFERING - if (MemoryPressureState::Transfer == _memoryPressureState) { - TransferJob::startBufferingThread(); - } -#endif // Clear the existing queue _transferQueue = WorkQueue(); _promoteQueue = WorkQueue(); diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 15c0dfce49..c432e19368 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -390,6 +390,13 @@ void Batch::resetStages() { ADD_COMMAND(resetStages); } +void Batch::disableContextViewCorrection() { + ADD_COMMAND(disableContextViewCorrection); +} + +void Batch::restoreContextViewCorrection() { + ADD_COMMAND(restoreContextViewCorrection); +} void Batch::disableContextStereo() { ADD_COMMAND(disableContextStereo); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 27c9402131..77d22258b2 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -217,6 +217,9 @@ public: // Reset the stage caches and states void resetStages(); + void disableContextViewCorrection(); + void restoreContextViewCorrection(); + void disableContextStereo(); void restoreContextStereo(); @@ -304,6 +307,9 @@ public: COMMAND_resetStages, + COMMAND_disableContextViewCorrection, + COMMAND_restoreContextViewCorrection, + COMMAND_disableContextStereo, COMMAND_restoreContextStereo, diff --git a/libraries/model-networking/src/model-networking/MeshFace.cpp b/libraries/model-networking/src/model-networking/MeshFace.cpp deleted file mode 100644 index 8092d36aa3..0000000000 --- a/libraries/model-networking/src/model-networking/MeshFace.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// MeshFace.cpp -// libraries/model/src/model/ -// -// Created by Seth Alves on 2017-3-23 -// Copyright 2017 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 - -#include "MeshFace.h" - - -QScriptValue meshFaceToScriptValue(QScriptEngine* engine, const MeshFace &meshFace) { - QScriptValue obj = engine->newObject(); - obj.setProperty("vertices", qVectorIntToScriptValue(engine, meshFace.vertexIndices)); - return obj; -} - -void meshFaceFromScriptValue(const QScriptValue &object, MeshFace& meshFaceResult) { - qVectorIntFromScriptValue(object.property("vertices"), meshFaceResult.vertexIndices); -} - -QScriptValue qVectorMeshFaceToScriptValue(QScriptEngine* engine, const QVector& vector) { - QScriptValue array = engine->newArray(); - for (int i = 0; i < vector.size(); i++) { - array.setProperty(i, meshFaceToScriptValue(engine, vector.at(i))); - } - return array; -} - -void qVectorMeshFaceFromScriptValue(const QScriptValue& array, QVector& result) { - int length = array.property("length").toInteger(); - result.clear(); - - for (int i = 0; i < length; i++) { - MeshFace meshFace = MeshFace(); - meshFaceFromScriptValue(array.property(i), meshFace); - result << meshFace; - } -} diff --git a/libraries/model-networking/src/model-networking/MeshFace.h b/libraries/model-networking/src/model-networking/MeshFace.h deleted file mode 100644 index 3b81b372c3..0000000000 --- a/libraries/model-networking/src/model-networking/MeshFace.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// MeshFace.h -// libraries/model/src/model/ -// -// Created by Seth Alves on 2017-3-23 -// Copyright 2017 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_MeshFace_h -#define hifi_MeshFace_h - -#include -#include -#include - -#include - -using MeshPointer = std::shared_ptr; - -class MeshFace { - -public: - MeshFace() {} - ~MeshFace() {} - - QVector vertexIndices; - // TODO -- material... -}; - -Q_DECLARE_METATYPE(MeshFace) -Q_DECLARE_METATYPE(QVector) - -QScriptValue meshFaceToScriptValue(QScriptEngine* engine, const MeshFace &meshFace); -void meshFaceFromScriptValue(const QScriptValue &object, MeshFace& meshFaceResult); -QScriptValue qVectorMeshFaceToScriptValue(QScriptEngine* engine, const QVector& vector); -void qVectorMeshFaceFromScriptValue(const QScriptValue& array, QVector& result); - - - -#endif // hifi_MeshFace_h diff --git a/libraries/model-networking/src/model-networking/MeshProxy.cpp b/libraries/model-networking/src/model-networking/MeshProxy.cpp deleted file mode 100644 index 1b6fa43c82..0000000000 --- a/libraries/model-networking/src/model-networking/MeshProxy.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// -// MeshProxy.cpp -// libraries/model/src/model/ -// -// Created by Seth Alves on 2017-3-22. -// Copyright 2017 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 "MeshProxy.h" - - -QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in) { - return engine->newQObject(in, QScriptEngine::QtOwnership, - QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects); -} - -void meshFromScriptValue(const QScriptValue& value, MeshProxy* &out) { - out = qobject_cast(value.toQObject()); -} - -QScriptValue meshesToScriptValue(QScriptEngine* engine, const MeshProxyList &in) { - // QScriptValueList result; - QScriptValue result = engine->newArray(); - int i = 0; - foreach (MeshProxy* const meshProxy, in) { - result.setProperty(i++, meshToScriptValue(engine, meshProxy)); - } - return result; -} - -void meshesFromScriptValue(const QScriptValue& value, MeshProxyList &out) { - QScriptValueIterator itr(value); - - qDebug() << "in meshesFromScriptValue, value.length =" << value.property("length").toInt32(); - - while(itr.hasNext()) { - itr.next(); - MeshProxy* meshProxy = qscriptvalue_cast(itr.value()); - if (meshProxy) { - out.append(meshProxy); - } else { - qDebug() << "null meshProxy"; - } - } -} diff --git a/libraries/model-networking/src/model-networking/MeshProxy.h b/libraries/model-networking/src/model-networking/MeshProxy.h deleted file mode 100644 index c5b25b7895..0000000000 --- a/libraries/model-networking/src/model-networking/MeshProxy.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// MeshProxy.h -// libraries/model/src/model/ -// -// Created by Seth Alves on 2017-1-27. -// Copyright 2017 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_MeshProxy_h -#define hifi_MeshProxy_h - -#include -#include -#include - -#include - -using MeshPointer = std::shared_ptr; - -class MeshProxy : public QObject { - Q_OBJECT - -public: - MeshProxy(MeshPointer mesh) : _mesh(mesh) {} - ~MeshProxy() {} - - MeshPointer getMeshPointer() const { return _mesh; } - - Q_INVOKABLE int getNumVertices() const { return (int)_mesh->getNumVertices(); } - Q_INVOKABLE glm::vec3 getPos3(int index) const { return _mesh->getPos3(index); } - - -protected: - MeshPointer _mesh; -}; - -Q_DECLARE_METATYPE(MeshProxy*); - -class MeshProxyList : public QList {}; // typedef and using fight with the Qt macros/templates, do this instead -Q_DECLARE_METATYPE(MeshProxyList); - - -QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in); -void meshFromScriptValue(const QScriptValue& value, MeshProxy* &out); - -QScriptValue meshesToScriptValue(QScriptEngine* engine, const MeshProxyList &in); -void meshesFromScriptValue(const QScriptValue& value, MeshProxyList &out); - -#endif // hifi_MeshProxy_h diff --git a/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp b/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp new file mode 100644 index 0000000000..b44ea1ff56 --- /dev/null +++ b/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp @@ -0,0 +1,27 @@ +// +// SimpleMeshProxy.cpp +// libraries/model-networking/src/model-networking/ +// +// Created by Seth Alves on 2017-3-22. +// Copyright 2017 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 "SimpleMeshProxy.h" + +#include + +MeshPointer SimpleMeshProxy::getMeshPointer() const { + return _mesh; +} + +int SimpleMeshProxy::getNumVertices() const { + return (int)_mesh->getNumVertices(); +} + +glm::vec3 SimpleMeshProxy::getPos3(int index) const { + return _mesh->getPos3(index); +} + diff --git a/libraries/model-networking/src/model-networking/SimpleMeshProxy.h b/libraries/model-networking/src/model-networking/SimpleMeshProxy.h new file mode 100644 index 0000000000..24c3fca27e --- /dev/null +++ b/libraries/model-networking/src/model-networking/SimpleMeshProxy.h @@ -0,0 +1,36 @@ +// +// SimpleMeshProxy.h +// libraries/model-networking/src/model-networking/ +// +// Created by Seth Alves on 2017-1-27. +// Copyright 2017 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_SimpleMeshProxy_h +#define hifi_SimpleMeshProxy_h + +#include +#include +#include + +#include + +class SimpleMeshProxy : public MeshProxy { +public: + SimpleMeshProxy(const MeshPointer& mesh) : _mesh(mesh) { } + + MeshPointer getMeshPointer() const override; + + int getNumVertices() const override; + + glm::vec3 getPos3(int index) const override; + + +protected: + const MeshPointer _mesh; +}; + +#endif // hifi_SimpleMeshProxy_h diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index ed1715219a..5c8f59f20f 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -384,7 +384,7 @@ void NetworkTexture::makeRequest() { // Add a fragment to the base url so we can identify the section of the ktx being requested when debugging // The actual requested url is _activeUrl and will not contain the fragment _url.setFragment("head"); - _ktxHeaderRequest = ResourceManager::createResourceRequest(this, _activeUrl); + _ktxHeaderRequest = DependencyManager::get()->createResourceRequest(this, _activeUrl); if (!_ktxHeaderRequest) { qCDebug(networking).noquote() << "Failed to get request for" << _url.toDisplayString(); @@ -454,7 +454,7 @@ void NetworkTexture::startMipRangeRequest(uint16_t low, uint16_t high) { bool isHighMipRequest = low == NULL_MIP_LEVEL && high == NULL_MIP_LEVEL; - _ktxMipRequest = ResourceManager::createResourceRequest(this, _activeUrl); + _ktxMipRequest = DependencyManager::get()->createResourceRequest(this, _activeUrl); if (!_ktxMipRequest) { qCWarning(networking).noquote() << "Failed to get request for" << _url.toDisplayString(); diff --git a/libraries/model/src/model/Forward.h b/libraries/model/src/model/Forward.h new file mode 100644 index 0000000000..90f55fa64f --- /dev/null +++ b/libraries/model/src/model/Forward.h @@ -0,0 +1,19 @@ +// +// Forward.h +// libraries/model/src/model +// +// Created by Bradley Austin Davis on 2017/06/21 +// Copyright 2013-2017 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_model_Forward_h +#define hifi_model_Forward_h + +namespace model { + class Mesh; + using MeshPointer = std::shared_ptr; +} + +#endif diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index 3faa9981dc..e97660da4c 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -31,7 +31,7 @@ MessageID AssetClient::_currentID = 0; -AssetClient::AssetClient() { +AssetClient::AssetClient(const QString& cacheDir) : _cacheDir(cacheDir) { setCustomDeleter([](Dependency* dependency){ static_cast(dependency)->deleteLater(); }); @@ -55,14 +55,15 @@ void AssetClient::init() { // Setup disk cache if not already auto& networkAccessManager = NetworkAccessManager::getInstance(); if (!networkAccessManager.cache()) { - QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - cachePath = !cachePath.isEmpty() ? cachePath : "interfaceCache"; - + if (_cacheDir.isEmpty()) { + QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + _cacheDir = !cachePath.isEmpty() ? cachePath : "interfaceCache"; + } QNetworkDiskCache* cache = new QNetworkDiskCache(); cache->setMaximumCacheSize(MAXIMUM_CACHE_SIZE); - cache->setCacheDirectory(cachePath); + cache->setCacheDirectory(_cacheDir); networkAccessManager.setCache(cache); - qInfo() << "ResourceManager disk cache setup at" << cachePath + qInfo() << "ResourceManager disk cache setup at" << _cacheDir << "(size:" << MAXIMUM_CACHE_SIZE / BYTES_PER_GIGABYTES << "GB)"; } } diff --git a/libraries/networking/src/AssetClient.h b/libraries/networking/src/AssetClient.h index cab4a4f5b0..2bc694f367 100644 --- a/libraries/networking/src/AssetClient.h +++ b/libraries/networking/src/AssetClient.h @@ -49,7 +49,7 @@ using ProgressCallback = std::function class AssetClient : public QObject, public Dependency { Q_OBJECT public: - AssetClient(); + AssetClient(const QString& cacheDir=""); Q_INVOKABLE GetMappingRequest* createGetMappingRequest(const AssetPath& path); Q_INVOKABLE GetAllMappingsRequest* createGetAllMappingsRequest(); @@ -109,6 +109,8 @@ private: std::unordered_map> _pendingInfoRequests; std::unordered_map> _pendingUploads; + QString _cacheDir; + friend class AssetRequest; friend class AssetUpload; friend class MappingRequest; diff --git a/libraries/networking/src/AtpReply.cpp b/libraries/networking/src/AtpReply.cpp index 4440995ee0..6417478005 100644 --- a/libraries/networking/src/AtpReply.cpp +++ b/libraries/networking/src/AtpReply.cpp @@ -13,7 +13,7 @@ #include "AtpReply.h" AtpReply::AtpReply(const QUrl& url, QObject* parent) : - _resourceRequest(ResourceManager::createResourceRequest(parent, url)) { + _resourceRequest(DependencyManager::get()->createResourceRequest(parent, url)) { setOperation(QNetworkAccessManager::GetOperation); connect(_resourceRequest, &AssetResourceRequest::progress, this, &AtpReply::downloadProgress); diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 88ea68780b..f07514cd85 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -672,7 +672,7 @@ void Resource::makeRequest() { PROFILE_ASYNC_BEGIN(resource, "Resource:" + getType(), QString::number(_requestID), { { "url", _url.toString() }, { "activeURL", _activeUrl.toString() } }); - _request = ResourceManager::createResourceRequest(this, _activeUrl); + _request = DependencyManager::get()->createResourceRequest(this, _activeUrl); if (!_request) { qCDebug(networking).noquote() << "Failed to get request for" << _url.toDisplayString(); diff --git a/libraries/networking/src/ResourceManager.cpp b/libraries/networking/src/ResourceManager.cpp index e2c1cf2431..e9fe2f1ec1 100644 --- a/libraries/networking/src/ResourceManager.cpp +++ b/libraries/networking/src/ResourceManager.cpp @@ -24,10 +24,16 @@ #include "NetworkAccessManager.h" #include "NetworkLogging.h" -QThread ResourceManager::_thread; -ResourceManager::PrefixMap ResourceManager::_prefixMap; -QMutex ResourceManager::_prefixMapLock; +ResourceManager::ResourceManager() { + _thread.setObjectName("Resource Manager Thread"); + + auto assetClient = DependencyManager::set(_cacheDir); + assetClient->moveToThread(&_thread); + QObject::connect(&_thread, &QThread::started, assetClient.data(), &AssetClient::init); + + _thread.start(); +} void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) { QMutexLocker locker(&_prefixMapLock); @@ -75,16 +81,6 @@ QUrl ResourceManager::normalizeURL(const QUrl& originalUrl) { return url; } -void ResourceManager::init() { - _thread.setObjectName("Resource Manager Thread"); - - auto assetClient = DependencyManager::set(); - assetClient->moveToThread(&_thread); - QObject::connect(&_thread, &QThread::started, assetClient.data(), &AssetClient::init); - - _thread.start(); -} - void ResourceManager::cleanup() { // cleanup the AssetClient thread DependencyManager::destroy(); @@ -164,3 +160,7 @@ bool ResourceManager::resourceExists(const QUrl& url) { return false; } +void ResourceManager::setCacheDir(const QString& cacheDir) { + // TODO: check for existence? + _cacheDir = cacheDir; +} diff --git a/libraries/networking/src/ResourceManager.h b/libraries/networking/src/ResourceManager.h index 41da892701..4e7cd3d92d 100644 --- a/libraries/networking/src/ResourceManager.h +++ b/libraries/networking/src/ResourceManager.h @@ -14,7 +14,11 @@ #include +#include #include +#include + +#include #include "ResourceRequest.h" @@ -24,29 +28,38 @@ const QString URL_SCHEME_HTTPS = "https"; const QString URL_SCHEME_FTP = "ftp"; const QString URL_SCHEME_ATP = "atp"; -class ResourceManager { +class ResourceManager: public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + public: + ResourceManager(); - static void setUrlPrefixOverride(const QString& prefix, const QString& replacement); - static QString normalizeURL(const QString& urlString); - static QUrl normalizeURL(const QUrl& url); + void setUrlPrefixOverride(const QString& prefix, const QString& replacement); + QString normalizeURL(const QString& urlString); + QUrl normalizeURL(const QUrl& url); - static ResourceRequest* createResourceRequest(QObject* parent, const QUrl& url); + ResourceRequest* createResourceRequest(QObject* parent, const QUrl& url); - static void init(); - static void cleanup(); + void init(); + void cleanup(); // Blocking call to check if a resource exists. This function uses a QEventLoop internally // to return to the calling thread so that events can still be processed. - static bool resourceExists(const QUrl& url); + bool resourceExists(const QUrl& url); + + // adjust where we persist the cache + void setCacheDir(const QString& cacheDir); private: - static QThread _thread; + QThread _thread; using PrefixMap = std::map; - static PrefixMap _prefixMap; - static QMutex _prefixMapLock; + PrefixMap _prefixMap; + QMutex _prefixMapLock; + + QString _cacheDir; }; #endif diff --git a/libraries/networking/src/ResourceScriptingInterface.cpp b/libraries/networking/src/ResourceScriptingInterface.cpp index 38be49049c..3227d44de1 100644 --- a/libraries/networking/src/ResourceScriptingInterface.cpp +++ b/libraries/networking/src/ResourceScriptingInterface.cpp @@ -11,5 +11,5 @@ #include "ResourceManager.h" void ResourceScriptingInterface::overrideUrlPrefix(const QString& prefix, const QString& replacement) { - ResourceManager::setUrlPrefixOverride(prefix, replacement); + DependencyManager::get()->setUrlPrefixOverride(prefix, replacement); } diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index ad15d04db1..240697d890 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -69,7 +69,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::AvatarData: case PacketType::BulkAvatarData: case PacketType::KillAvatar: - return static_cast(AvatarMixerPacketVersion::AvatarIdentitySequenceFront); + return static_cast(AvatarMixerPacketVersion::IsReplicatedInAvatarIdentity); case PacketType::MessagesData: return static_cast(MessageDataVersion::TextOrBinaryData); case PacketType::ICEServerHeartbeat: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 2944c1ce93..6c42193e11 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -247,7 +247,8 @@ enum class AvatarMixerPacketVersion : PacketVersion { IdentityPacketsIncludeUpdateTime, AvatarIdentitySequenceId, MannequinDefaultAvatar, - AvatarIdentitySequenceFront + AvatarIdentitySequenceFront, + IsReplicatedInAvatarIdentity }; enum class DomainConnectRequestVersion : PacketVersion { diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 180f25f106..2e93f3515f 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -1668,7 +1668,8 @@ bool Octree::readJSONFromGzippedFile(QString qFileName) { } bool Octree::readFromURL(const QString& urlString) { - auto request = std::unique_ptr(ResourceManager::createResourceRequest(this, urlString)); + auto request = + std::unique_ptr(DependencyManager::get()->createResourceRequest(this, urlString)); if (!request) { return false; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index e90d3e3a0f..18ac905ef1 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -23,10 +23,6 @@ #include "InputPlugin.h" #include "PluginLogging.h" -DisplayPluginProvider PluginManager::_displayPluginProvider = []()->DisplayPluginList { return {}; }; -InputPluginProvider PluginManager::_inputPluginProvider = []()->InputPluginList { return {}; }; -CodecPluginProvider PluginManager::_codecPluginProvider = []()->CodecPluginList { return {}; }; -InputPluginSettingsPersister PluginManager::_inputSettingsPersister = [](const InputPluginList& list) {}; void PluginManager::setDisplayPluginProvider(const DisplayPluginProvider& provider) { _displayPluginProvider = provider; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index cb011392a4..08fe4fde20 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -33,16 +33,15 @@ public: void shutdown(); // Application that have statically linked plugins can expose them to the plugin manager with these function - static void setDisplayPluginProvider(const DisplayPluginProvider& provider); - static void setInputPluginProvider(const InputPluginProvider& provider); - static void setCodecPluginProvider(const CodecPluginProvider& provider); - static void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister); + void setDisplayPluginProvider(const DisplayPluginProvider& provider); + void setInputPluginProvider(const InputPluginProvider& provider); + void setCodecPluginProvider(const CodecPluginProvider& provider); + void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister); private: - static DisplayPluginProvider _displayPluginProvider; - static InputPluginProvider _inputPluginProvider; - static CodecPluginProvider _codecPluginProvider; - static InputPluginSettingsPersister _inputSettingsPersister; - + DisplayPluginProvider _displayPluginProvider { []()->DisplayPluginList { return {}; } }; + InputPluginProvider _inputPluginProvider { []()->InputPluginList { return {}; } }; + CodecPluginProvider _codecPluginProvider { []()->CodecPluginList { return {}; } }; + InputPluginSettingsPersister _inputSettingsPersister { [](const InputPluginList& list) {} }; PluginContainer* _container { nullptr }; }; diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index e4ce3c691a..c38e562672 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -103,7 +103,7 @@ bool Procedural::parseVersion(const QJsonValue& version) { } bool Procedural::parseShader(const QUrl& shaderPath) { - auto shaderUrl = ResourceManager::normalizeURL(shaderPath); + auto shaderUrl = DependencyManager::get()->normalizeURL(shaderPath); if (!shaderUrl.isValid()) { if (!shaderUrl.isEmpty()) { diff --git a/libraries/render-utils/src/DeferredFrameTransform.cpp b/libraries/render-utils/src/DeferredFrameTransform.cpp index b1166437db..baf523312c 100644 --- a/libraries/render-utils/src/DeferredFrameTransform.cpp +++ b/libraries/render-utils/src/DeferredFrameTransform.cpp @@ -39,7 +39,7 @@ void DeferredFrameTransform::update(RenderArgs* args) { args->getViewFrustum().evalProjectionMatrix(frameTransformBuffer.projectionMono); // Running in stero ? - bool isStereo = args->_context->isStereo(); + bool isStereo = args->isStereo(); if (!isStereo) { frameTransformBuffer.projection[0] = frameTransformBuffer.projectionMono; frameTransformBuffer.stereoInfo = glm::vec4(0.0f, (float)args->_viewport.z, 0.0f, 0.0f); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 73f0e37d6c..67452c5d33 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -867,10 +867,6 @@ bool Model::getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& transl return _rig.getRelativeDefaultJointTranslation(jointIndex, translationOut); } -bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { - return _rig.getJointCombinedRotation(jointIndex, rotation, _rotation); -} - QStringList Model::getJointNames() const { if (QThread::currentThread() != thread()) { QStringList result; diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index adee4d57b1..3eb796b763 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -177,7 +177,6 @@ public: int getJointStateCount() const { return (int)_rig.getJointStateCount(); } bool getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const; bool getJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) const; - bool getJointCombinedRotation(int jointIndex, glm::quat& rotation) const; /// \param jointIndex index of joint in model structure /// \param rotation[out] rotation of joint in model-frame diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index b49a066bf7..20c999019b 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -406,7 +406,7 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer batch.setFramebuffer(blitFbo); if (renderArgs->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { - if (renderArgs->_context->isStereo()) { + if (renderArgs->isStereo()) { gpu::Vec4i srcRectLeft; srcRectLeft.z = width / 2; srcRectLeft.w = height; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 1941766353..c4eea7ce7f 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -459,7 +459,7 @@ void SurfaceGeometryPass::run(const render::RenderContextPointer& renderContext, auto diffuseVPipeline = _diffusePass.getBlurVPipeline(); auto diffuseHPipeline = _diffusePass.getBlurHPipeline(); - _diffusePass.getParameters()->setWidthHeight(curvatureViewport.z, curvatureViewport.w, args->_context->isStereo()); + _diffusePass.getParameters()->setWidthHeight(curvatureViewport.z, curvatureViewport.w, args->isStereo()); glm::ivec2 textureSize(curvatureTexture->getDimensions()); _diffusePass.getParameters()->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, curvatureViewport)); _diffusePass.getParameters()->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]); diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index a75488ce7a..c2e03d4f46 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -99,6 +99,8 @@ namespace render { void pushViewFrustum(const ViewFrustum& viewFrustum) { _viewFrustums.push(viewFrustum); } void popViewFrustum() { _viewFrustums.pop(); } + bool isStereo() const { return _displayMode != MONO; } + std::shared_ptr _context; std::shared_ptr _blitFramebuffer; std::shared_ptr _pipeline; diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp index 0a6b3d16fc..73a8e0a0dd 100644 --- a/libraries/render/src/render/BlurTask.cpp +++ b/libraries/render/src/render/BlurTask.cpp @@ -217,7 +217,7 @@ void BlurGaussian::run(const RenderContextPointer& renderContext, const gpu::Fra auto blurVPipeline = getBlurVPipeline(); auto blurHPipeline = getBlurHPipeline(); - _parameters->setWidthHeight(args->_viewport.z, args->_viewport.w, args->_context->isStereo()); + _parameters->setWidthHeight(args->_viewport.z, args->_viewport.w, args->isStereo()); glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions()); _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, args->_viewport)); @@ -330,7 +330,7 @@ void BlurGaussianDepthAware::run(const RenderContextPointer& renderContext, cons auto sourceViewport = args->_viewport; - _parameters->setWidthHeight(sourceViewport.z, sourceViewport.w, args->_context->isStereo()); + _parameters->setWidthHeight(sourceViewport.z, sourceViewport.w, args->isStereo()); glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions()); _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, sourceViewport)); _parameters->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]); diff --git a/libraries/script-engine/src/FileScriptingInterface.cpp b/libraries/script-engine/src/FileScriptingInterface.cpp index 2f5cc2bc88..30d0a3a201 100644 --- a/libraries/script-engine/src/FileScriptingInterface.cpp +++ b/libraries/script-engine/src/FileScriptingInterface.cpp @@ -85,7 +85,7 @@ QString FileScriptingInterface::convertUrlToPath(QUrl url) { // this function is not in use void FileScriptingInterface::downloadZip(QString path, const QString link) { QUrl url = QUrl(link); - auto request = ResourceManager::createResourceRequest(nullptr, url); + auto request = DependencyManager::get()->createResourceRequest(nullptr, url); connect(request, &ResourceRequest::finished, this, [this, path]{ unzipFile(path, ""); // so intellisense isn't mad }); diff --git a/libraries/script-engine/src/ModelScriptingInterface.cpp b/libraries/script-engine/src/ModelScriptingInterface.cpp index f56312568e..762d9ffb29 100644 --- a/libraries/script-engine/src/ModelScriptingInterface.cpp +++ b/libraries/script-engine/src/ModelScriptingInterface.cpp @@ -9,17 +9,17 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "ModelScriptingInterface.h" #include #include #include -#include +#include #include "ScriptEngine.h" #include "ScriptEngineLogging.h" -#include "ModelScriptingInterface.h" #include "OBJWriter.h" ModelScriptingInterface::ModelScriptingInterface(QObject* parent) : QObject(parent) { - _modelScriptEngine = qobject_cast(parent); + _modelScriptEngine = qobject_cast(parent); qScriptRegisterSequenceMetaType>(_modelScriptEngine); qScriptRegisterMetaType(_modelScriptEngine, meshFaceToScriptValue, meshFaceFromScriptValue); @@ -118,7 +118,7 @@ QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) { (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); - MeshProxy* resultProxy = new MeshProxy(result); + MeshProxy* resultProxy = new SimpleMeshProxy(result); return meshToScriptValue(_modelScriptEngine, resultProxy); } @@ -134,7 +134,7 @@ QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshPro model::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); }, [&](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); }, [&](uint32_t index){ return index; }); - MeshProxy* resultProxy = new MeshProxy(result); + MeshProxy* resultProxy = new SimpleMeshProxy(result); return meshToScriptValue(_modelScriptEngine, resultProxy); } @@ -188,6 +188,6 @@ QScriptValue ModelScriptingInterface::newMesh(const QVector& vertices - MeshProxy* meshProxy = new MeshProxy(mesh); + MeshProxy* meshProxy = new SimpleMeshProxy(mesh); return meshToScriptValue(_modelScriptEngine, meshProxy); } diff --git a/libraries/script-engine/src/ModelScriptingInterface.h b/libraries/script-engine/src/ModelScriptingInterface.h index d899f532d8..ba23623acf 100644 --- a/libraries/script-engine/src/ModelScriptingInterface.h +++ b/libraries/script-engine/src/ModelScriptingInterface.h @@ -9,19 +9,13 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - #ifndef hifi_ModelScriptingInterface_h #define hifi_ModelScriptingInterface_h #include -#include -#include -#include -#include -#include -using MeshPointer = std::shared_ptr; -class ScriptEngine; +#include +class QScriptEngine; class ModelScriptingInterface : public QObject { Q_OBJECT @@ -37,7 +31,7 @@ public: const QVector& faces); private: - ScriptEngine* _modelScriptEngine { nullptr }; + QScriptEngine* _modelScriptEngine { nullptr }; }; #endif // hifi_ModelScriptingInterface_h diff --git a/libraries/script-engine/src/RecordingScriptingInterface.cpp b/libraries/script-engine/src/RecordingScriptingInterface.cpp index 98838441d2..7583f562e6 100644 --- a/libraries/script-engine/src/RecordingScriptingInterface.cpp +++ b/libraries/script-engine/src/RecordingScriptingInterface.cpp @@ -8,9 +8,17 @@ #include "RecordingScriptingInterface.h" +#include #include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include @@ -18,13 +26,6 @@ #include #include - -#include -#include -#include -#include -#include - #include "ScriptEngineLogging.h" using namespace recording; @@ -188,6 +189,14 @@ void RecordingScriptingInterface::stopRecording() { _lastClip->seek(0); } +QString RecordingScriptingInterface::getDefaultRecordingSaveDirectory() { + QString directory = PathUtils::getAppLocalDataPath() + "Avatar Recordings/"; + if (!QDir(directory).exists()) { + QDir().mkdir(directory); + } + return directory; +} + void RecordingScriptingInterface::saveRecording(const QString& filename) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "saveRecording", Qt::BlockingQueuedConnection, diff --git a/libraries/script-engine/src/RecordingScriptingInterface.h b/libraries/script-engine/src/RecordingScriptingInterface.h index a9fdf1deb4..c4220958a2 100644 --- a/libraries/script-engine/src/RecordingScriptingInterface.h +++ b/libraries/script-engine/src/RecordingScriptingInterface.h @@ -65,6 +65,7 @@ public slots: float recorderElapsed() const; + QString getDefaultRecordingSaveDirectory(); void saveRecording(const QString& filename); bool saveRecordingToAsset(QScriptValue getClipAtpUrl); void loadLastRecording(); diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index 601ca6bc95..dba2db0458 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -57,7 +57,7 @@ void ScriptCache::clearATPScriptsFromCache() { } void ScriptCache::deleteScript(const QUrl& unnormalizedURL) { - QUrl url = ResourceManager::normalizeURL(unnormalizedURL); + QUrl url = DependencyManager::get()->normalizeURL(unnormalizedURL); Lock lock(_containerLock); if (_scriptCache.contains(url)) { qCDebug(scriptengine) << "Delete script from cache:" << url.toString(); @@ -70,7 +70,7 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable qCDebug(scriptengine) << "ScriptCache::getScriptContents() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif QUrl unnormalizedURL(scriptOrURL); - QUrl url = ResourceManager::normalizeURL(unnormalizedURL); + QUrl url = DependencyManager::get()->normalizeURL(unnormalizedURL); // attempt to determine if this is a URL to a script, or if this is actually a script itself (which is valid in the // entityScript use case) @@ -109,7 +109,7 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable #ifdef THREAD_DEBUGGING qCDebug(scriptengine) << "about to call: ResourceManager::createResourceRequest(this, url); on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif - auto request = ResourceManager::createResourceRequest(nullptr, url); + auto request = DependencyManager::get()->createResourceRequest(nullptr, url); Q_ASSERT(request); request->setCacheEnabled(!forceDownload); connect(request, &ResourceRequest::finished, this, [=]{ scriptContentAvailable(maxRetries); }); @@ -166,7 +166,7 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { qCDebug(scriptengine) << QString("Retrying script request [%1 / %2]: %3") .arg(attempt).arg(maxRetries).arg(url.toString()); - auto request = ResourceManager::createResourceRequest(nullptr, url); + auto request = DependencyManager::get()->createResourceRequest(nullptr, url); Q_ASSERT(request); // We've already made a request, so the cache must be disabled or it wasn't there, so enabling diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index d9b41bb55d..11bb044d72 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1067,24 +1067,21 @@ void ScriptEngine::run() { // on shutdown and stop... so we want to loop and sleep until we've spent our time in // purgatory, constantly checking to see if our script was asked to end bool processedEvents = false; - while (!_isFinished && clock::now() < sleepUntil) { - - { - PROFILE_RANGE(script, "processEvents-sleep"); - QCoreApplication::processEvents(); // before we sleep again, give events a chance to process + if (!_isFinished) { + PROFILE_RANGE(script, "processEvents-sleep"); + std::chrono::milliseconds sleepFor = + std::chrono::duration_cast(sleepUntil - clock::now()); + if (sleepFor > std::chrono::milliseconds(0)) { + QEventLoop loop; + QTimer timer; + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.start(sleepFor.count()); + loop.exec(); + } else { + QCoreApplication::processEvents(); } processedEvents = true; - - // If after processing events, we're past due, exit asap - if (clock::now() >= sleepUntil) { - break; - } - - // We only want to sleep a small amount so that any pending events (like timers or invokeMethod events) - // will be able to process quickly. - static const int SMALL_SLEEP_AMOUNT = 100; - auto smallSleepUntil = clock::now() + static_cast(SMALL_SLEEP_AMOUNT); - std::this_thread::sleep_until(smallSleepUntil); } PROFILE_RANGE(script, "ScriptMainLoop"); @@ -1309,6 +1306,7 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int // make sure the timer stops when the script does connect(this, &ScriptEngine::scriptEnding, newTimer, &QTimer::stop); + CallbackData timerData = { function, currentEntityIdentifier, currentSandboxURL }; _timerFunctionMap.insert(newTimer, timerData); @@ -1392,6 +1390,15 @@ void ScriptEngine::print(const QString& message) { emit printedMessage(message, getFilename()); } + +void ScriptEngine::beginProfileRange(const QString& label) const { + PROFILE_SYNC_BEGIN(script, label.toStdString().c_str(), label.toStdString().c_str()); +} + +void ScriptEngine::endProfileRange(const QString& label) const { + PROFILE_SYNC_END(script, label.toStdString().c_str(), label.toStdString().c_str()); +} + // Script.require.resolve -- like resolvePath, but performs more validation and throws exceptions on invalid module identifiers (for consistency with Node.js) QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& relativeTo) { if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { @@ -1755,7 +1762,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac QList urls; for (QString includeFile : includeFiles) { - QString file = ResourceManager::normalizeURL(includeFile); + QString file = DependencyManager::get()->normalizeURL(includeFile); QUrl thisURL; bool isStandardLibrary = false; if (file.startsWith("/~/")) { diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 9da8603814..7c473a305b 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -43,6 +43,7 @@ #include "Vec3.h" #include "ConsoleScriptingInterface.h" #include "SettingHandle.h" +#include "Profile.h" class QScriptEngineDebugger; @@ -182,6 +183,8 @@ public: Q_INVOKABLE void print(const QString& message); Q_INVOKABLE QUrl resolvePath(const QString& path) const; Q_INVOKABLE QUrl resourcesPath() const; + Q_INVOKABLE void beginProfileRange(const QString& label) const; + Q_INVOKABLE void endProfileRange(const QString& label) const; // Entity Script Related methods Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) { diff --git a/libraries/shared/src/AudioHelpers.h b/libraries/shared/src/AudioHelpers.h index b43764ef5d..1dcc11af0c 100644 --- a/libraries/shared/src/AudioHelpers.h +++ b/libraries/shared/src/AudioHelpers.h @@ -14,6 +14,8 @@ #include +#include + const int IEEE754_MANT_BITS = 23; const int IEEE754_EXPN_BIAS = 127; @@ -66,6 +68,48 @@ static inline float fastExp2f(float x) { return x * xi.f; } +// +// on x86 architecture, assume that SSE2 is present +// +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__) + +#include +// inline sqrtss, without requiring /fp:fast +static inline float fastSqrtf(float x) { + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(x))); +} + +#else + +static inline float fastSqrtf(float x) { + return sqrtf(x); +} + +#endif + +// +// for -1 <= x <= 1, returns acos(x) +// otherwise, returns NaN +// +// abs |error| < 7e-5, smooth +// +static inline float fastAcosf(float x) { + + union { float f; int32_t i; } xi = { x }; + + int32_t sign = xi.i & 0x80000000; + xi.i ^= sign; // fabs(x) + + // compute sqrt(1-x) in parallel + float r = fastSqrtf(1.0f - xi.f); + + // polynomial for acos(x)/sqrt(1-x) over x=[0,1] + xi.f = ((-0.0198439236f * xi.f + 0.0762021306f) * xi.f + -0.212940971f) * xi.f + 1.57079633f; + + xi.f *= r; + return (sign ? PI - xi.f : xi.f); +} + // // Quantize a non-negative gain value to the nearest 0.5dB, and pack to a byte. // diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index ef92552d1f..3386ea2c22 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -17,6 +17,7 @@ #include #include #include +#include // Bring the most commonly used GLM types into the default namespace using glm::ivec2; diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index 9bf9d7bdcf..1fe9e2f83d 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -34,7 +34,18 @@ QString PathUtils::getAppDataPath() { return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/"; } -QString PathUtils::getAppLocalDataPath() { +QString PathUtils::getAppLocalDataPath(const QString& overridePath /* = "" */) { + static QString overriddenPath = ""; + // set the overridden path if one was passed in + if (!overridePath.isEmpty()) { + overriddenPath = overridePath; + } + // return overridden path if set + if (!overriddenPath.isEmpty()) { + return overriddenPath; + } + + // otherwise return standard path return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/"; } diff --git a/libraries/shared/src/PathUtils.h b/libraries/shared/src/PathUtils.h index 14eb81dd9a..42dd09c8b0 100644 --- a/libraries/shared/src/PathUtils.h +++ b/libraries/shared/src/PathUtils.h @@ -28,7 +28,7 @@ public: static const QString& resourcesPath(); static QString getAppDataPath(); - static QString getAppLocalDataPath(); + static QString getAppLocalDataPath(const QString& overridePath = ""); static QString getAppDataFilePath(const QString& filename); static QString getAppLocalDataFilePath(const QString& filename); diff --git a/libraries/shared/src/Profile.h b/libraries/shared/src/Profile.h index ee09298deb..5de4e8f41a 100644 --- a/libraries/shared/src/Profile.h +++ b/libraries/shared/src/Profile.h @@ -46,6 +46,20 @@ private: const QLoggingCategory& _category; }; + +inline void syncBegin(const QLoggingCategory& category, const QString& name, const QString& id, const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap()) { + if (category.isDebugEnabled()) { + tracing::traceEvent(category, name, tracing::DurationBegin, id, args, extra); + } +} + + +inline void syncEnd(const QLoggingCategory& category, const QString& name, const QString& id, const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap()) { + if (category.isDebugEnabled()) { + tracing::traceEvent(category, name, tracing::DurationEnd, id, args, extra); + } +} + inline void asyncBegin(const QLoggingCategory& category, const QString& name, const QString& id, const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap()) { if (category.isDebugEnabled()) { tracing::traceEvent(category, name, tracing::AsyncNestableStart, id, args, extra); @@ -80,6 +94,8 @@ inline void metadata(const QString& metadataType, const QVariantMap& args) { #define PROFILE_RANGE_EX(category, name, argbColor, payload, ...) Duration profileRangeThis(trace_##category(), name, argbColor, (uint64_t)payload, ##__VA_ARGS__); #define PROFILE_RANGE_BEGIN(category, rangeId, name, argbColor) rangeId = Duration::beginRange(trace_##category(), name, argbColor) #define PROFILE_RANGE_END(category, rangeId) Duration::endRange(trace_##category(), rangeId) +#define PROFILE_SYNC_BEGIN(category, name, id, ...) syncBegin(trace_##category(), name, id, ##__VA_ARGS__); +#define PROFILE_SYNC_END(category, name, id, ...) syncEnd(trace_##category(), name, id, ##__VA_ARGS__); #define PROFILE_ASYNC_BEGIN(category, name, id, ...) asyncBegin(trace_##category(), name, id, ##__VA_ARGS__); #define PROFILE_ASYNC_END(category, name, id, ...) asyncEnd(trace_##category(), name, id, ##__VA_ARGS__); #define PROFILE_COUNTER_IF_CHANGED(category, name, type, value) { static type lastValue = 0; type newValue = value; if (newValue != lastValue) { counter(trace_##category(), name, { { name, newValue }}); lastValue = newValue; } } diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 70067b93f3..b30637c83f 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -9,6 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "RegisteredMetaTypes.h" + +#include + #include #include #include @@ -17,10 +21,9 @@ #include #include #include -#include -#include - -#include "RegisteredMetaTypes.h" +#include +#include +#include int vec4MetaTypeId = qRegisterMetaType(); int vec3MetaTypeId = qRegisterMetaType(); @@ -34,6 +37,8 @@ int pickRayMetaTypeId = qRegisterMetaType(); int collisionMetaTypeId = qRegisterMetaType(); int qMapURLStringMetaTypeId = qRegisterMetaType>(); int socketErrorMetaTypeId = qRegisterMetaType(); +int voidLambdaType = qRegisterMetaType>(); +int variantLambdaType = qRegisterMetaType>(); void registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, mat4toScriptValue, mat4FromScriptValue); @@ -796,3 +801,101 @@ void qSizeFFromScriptValue(const QScriptValue& object, QSizeF& qSizeF) { qSizeF.setWidth(object.property("width").toVariant().toFloat()); qSizeF.setHeight(object.property("height").toVariant().toFloat()); } + +AnimationDetails::AnimationDetails() : + role(), url(), fps(0.0f), priority(0.0f), loop(false), hold(false), + startAutomatically(false), firstFrame(0.0f), lastFrame(0.0f), running(false), currentFrame(0.0f) { +} + +AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, + bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame) : + role(role), url(url), fps(fps), priority(priority), loop(loop), hold(hold), + startAutomatically(startAutomatically), firstFrame(firstFrame), lastFrame(lastFrame), + running(running), currentFrame(currentFrame) { +} + + +QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& details) { + QScriptValue obj = engine->newObject(); + obj.setProperty("role", details.role); + obj.setProperty("url", details.url.toString()); + obj.setProperty("fps", details.fps); + obj.setProperty("priority", details.priority); + obj.setProperty("loop", details.loop); + obj.setProperty("hold", details.hold); + obj.setProperty("startAutomatically", details.startAutomatically); + obj.setProperty("firstFrame", details.firstFrame); + obj.setProperty("lastFrame", details.lastFrame); + obj.setProperty("running", details.running); + obj.setProperty("currentFrame", details.currentFrame); + return obj; +} + +void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& details) { + // nothing for now... +} + +QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in) { + return engine->newQObject(in, QScriptEngine::QtOwnership, + QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects); +} + +void meshFromScriptValue(const QScriptValue& value, MeshProxy* &out) { + out = qobject_cast(value.toQObject()); +} + +QScriptValue meshesToScriptValue(QScriptEngine* engine, const MeshProxyList &in) { + // QScriptValueList result; + QScriptValue result = engine->newArray(); + int i = 0; + foreach(MeshProxy* const meshProxy, in) { + result.setProperty(i++, meshToScriptValue(engine, meshProxy)); + } + return result; +} + +void meshesFromScriptValue(const QScriptValue& value, MeshProxyList &out) { + QScriptValueIterator itr(value); + + qDebug() << "in meshesFromScriptValue, value.length =" << value.property("length").toInt32(); + + while (itr.hasNext()) { + itr.next(); + MeshProxy* meshProxy = qscriptvalue_cast(itr.value()); + if (meshProxy) { + out.append(meshProxy); + } else { + qDebug() << "null meshProxy"; + } + } +} + + +QScriptValue meshFaceToScriptValue(QScriptEngine* engine, const MeshFace &meshFace) { + QScriptValue obj = engine->newObject(); + obj.setProperty("vertices", qVectorIntToScriptValue(engine, meshFace.vertexIndices)); + return obj; +} + +void meshFaceFromScriptValue(const QScriptValue &object, MeshFace& meshFaceResult) { + qVectorIntFromScriptValue(object.property("vertices"), meshFaceResult.vertexIndices); +} + +QScriptValue qVectorMeshFaceToScriptValue(QScriptEngine* engine, const QVector& vector) { + QScriptValue array = engine->newArray(); + for (int i = 0; i < vector.size(); i++) { + array.setProperty(i, meshFaceToScriptValue(engine, vector.at(i))); + } + return array; +} + +void qVectorMeshFaceFromScriptValue(const QScriptValue& array, QVector& result) { + int length = array.property("length").toInteger(); + result.clear(); + + for (int i = 0; i < length; i++) { + MeshFace meshFace = MeshFace(); + meshFaceFromScriptValue(array.property(i), meshFace); + result << meshFace; + } +} diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 8a15f62eed..123c769a96 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -33,6 +34,8 @@ Q_DECLARE_METATYPE(xColor) Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(AACube) +Q_DECLARE_METATYPE(std::function); +Q_DECLARE_METATYPE(std::function); void registerMetaTypes(QScriptEngine* engine); @@ -167,4 +170,73 @@ void quuidFromScriptValue(const QScriptValue& object, QUuid& uuid); QScriptValue qSizeFToScriptValue(QScriptEngine* engine, const QSizeF& qSizeF); void qSizeFFromScriptValue(const QScriptValue& object, QSizeF& qSizeF); +class AnimationDetails { +public: + AnimationDetails(); + AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, + bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame); + + QString role; + QUrl url; + float fps; + float priority; + bool loop; + bool hold; + bool startAutomatically; + float firstFrame; + float lastFrame; + bool running; + float currentFrame; +}; +Q_DECLARE_METATYPE(AnimationDetails); +QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event); +void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& event); + +namespace model { + class Mesh; +} + +using MeshPointer = std::shared_ptr; + + +class MeshProxy : public QObject { + Q_OBJECT + +public: + virtual MeshPointer getMeshPointer() const = 0; + Q_INVOKABLE virtual int getNumVertices() const = 0; + Q_INVOKABLE virtual glm::vec3 getPos3(int index) const = 0; +}; + +Q_DECLARE_METATYPE(MeshProxy*); + +class MeshProxyList : public QList {}; // typedef and using fight with the Qt macros/templates, do this instead +Q_DECLARE_METATYPE(MeshProxyList); + + +QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in); +void meshFromScriptValue(const QScriptValue& value, MeshProxy* &out); + +QScriptValue meshesToScriptValue(QScriptEngine* engine, const MeshProxyList &in); +void meshesFromScriptValue(const QScriptValue& value, MeshProxyList &out); + +class MeshFace { + +public: + MeshFace() {} + ~MeshFace() {} + + QVector vertexIndices; + // TODO -- material... +}; + +Q_DECLARE_METATYPE(MeshFace) +Q_DECLARE_METATYPE(QVector) + +QScriptValue meshFaceToScriptValue(QScriptEngine* engine, const MeshFace &meshFace); +void meshFaceFromScriptValue(const QScriptValue &object, MeshFace& meshFaceResult); +QScriptValue qVectorMeshFaceToScriptValue(QScriptEngine* engine, const QVector& vector); +void qVectorMeshFaceFromScriptValue(const QScriptValue& array, QVector& result); + + #endif // hifi_RegisteredMetaTypes_h diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index a68d27e620..58b8aead45 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -1076,3 +1076,24 @@ void setMaxCores(uint8_t maxCores) { SetProcessAffinityMask(process, newProcessAffinity); #endif } + +#ifdef Q_OS_WIN +VOID CALLBACK parentDiedCallback(PVOID lpParameter, BOOLEAN timerOrWaitFired) { + if (!timerOrWaitFired && qApp) { + qDebug() << "Parent process died, quitting"; + qApp->quit(); + } +} + +void watchParentProcess(int parentPID) { + DWORD processID = parentPID; + HANDLE procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID); + + HANDLE newHandle; + RegisterWaitForSingleObject(&newHandle, procHandle, parentDiedCallback, NULL, INFINITE, WT_EXECUTEONLYONCE); +} +#else +void watchParentProcess(int parentPID) { + qWarning() << "Parent PID option not implemented on this plateform"; +} +#endif // Q_OS_WIN \ No newline at end of file diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 0f30842f47..681418a263 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -235,4 +235,7 @@ const QString& getInterfaceSharedMemoryName(); void setMaxCores(uint8_t maxCores); +const QString PARENT_PID_OPTION = "parent-pid"; +void watchParentProcess(int parentPID); + #endif // hifi_SharedUtil_h diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/shared/src/shared/types/AnimationLoop.cpp similarity index 95% rename from libraries/animation/src/AnimationLoop.cpp rename to libraries/shared/src/shared/types/AnimationLoop.cpp index 3d7bca863f..f77bd8bb2a 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/shared/src/shared/types/AnimationLoop.cpp @@ -9,11 +9,13 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - -#include "AnimationCache.h" #include "AnimationLoop.h" +#include "../../NumericalConstants.h" +#include "../../SharedUtil.h" +#include "../../GLMHelpers.h" +#include "../../RegisteredMetaTypes.h" + const float AnimationLoop::MAXIMUM_POSSIBLE_FRAME = 100000.0f; AnimationLoop::AnimationLoop() : @@ -62,7 +64,7 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati { } -void AnimationLoop::simulateAtTime(quint64 now) { +void AnimationLoop::simulateAtTime(uint64_t now) { float deltaTime = (float)(now - _lastSimulated) / (float)USECS_PER_SECOND; _lastSimulated = now; simulate(deltaTime); diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/shared/src/shared/types/AnimationLoop.h similarity index 93% rename from libraries/animation/src/AnimationLoop.h rename to libraries/shared/src/shared/types/AnimationLoop.h index 6adfbf35e2..33434209e7 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/shared/src/shared/types/AnimationLoop.h @@ -14,6 +14,9 @@ class AnimationDetails; +#include +#include + class AnimationLoop { public: static const float MAXIMUM_POSSIBLE_FRAME; @@ -58,7 +61,7 @@ public: void stop() { setRunning(false); } void simulate(float deltaTime); /// call this with deltaTime if you as the caller are managing the delta time between calls - void simulateAtTime(quint64 now); /// call this with "now" if you want the animationLoop to handle delta times + void simulateAtTime(uint64_t now); /// call this with "now" if you want the animationLoop to handle delta times private: float _fps; @@ -71,7 +74,7 @@ private: float _currentFrame; float _maxFrameIndexHint; bool _resetOnRunning; - quint64 _lastSimulated; + uint64_t _lastSimulated; }; #endif // hifi_AnimationLoop_h diff --git a/libraries/trackers/src/trackers/DeviceTracker.cpp b/libraries/trackers/src/trackers/DeviceTracker.cpp deleted file mode 100644 index 93aeb607bc..0000000000 --- a/libraries/trackers/src/trackers/DeviceTracker.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 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 "DeviceTracker.h" - -DeviceTracker::SingletonData::~SingletonData() { - // Destroy all the device registered - //TODO C++11 for (auto device = _devicesVector.begin(); device != _devicesVector.end(); device++) { - for (Vector::iterator device = _devicesVector.begin(); device != _devicesVector.end(); device++) { - delete (*device); - } -} - -int DeviceTracker::getNumDevices() { - return (int)Singleton::get()->_devicesMap.size(); -} - -DeviceTracker::ID DeviceTracker::getDeviceID(const Name& name) { - //TODO C++11 auto deviceIt = Singleton::get()->_devicesMap.find(name); - Map::iterator deviceIt = Singleton::get()->_devicesMap.find(name); - if (deviceIt != Singleton::get()->_devicesMap.end()) { - return (*deviceIt).second; - } else { - return INVALID_DEVICE; - } -} - -DeviceTracker* DeviceTracker::getDevice(const Name& name) { - return getDevice(getDeviceID(name)); -} - -DeviceTracker* DeviceTracker::getDevice(DeviceTracker::ID deviceID) { - if ((deviceID >= 0) && (deviceID < (int)(Singleton::get()->_devicesVector.size()))) { - return Singleton::get()->_devicesVector[ deviceID ]; - } else { - return NULL; - } -} - -DeviceTracker::ID DeviceTracker::registerDevice(const Name& name, DeviceTracker* device) { - // Check that the device exists, if not exit - if (!device) { - return INVALID_DEVICE; - } - - // Look if the name is not already used - ID deviceID = getDeviceID(name); - if (deviceID >= 0) { - return INVALID_DEVICE_NAME; - } - - // Good to register the device - deviceID = (ID)Singleton::get()->_devicesVector.size(); - Singleton::get()->_devicesMap.insert(Map::value_type(name, deviceID)); - Singleton::get()->_devicesVector.push_back(device); - device->assignIDAndName(deviceID, name); - - return deviceID; -} - -void DeviceTracker::destroyDevice(const Name& name) { - DeviceTracker::ID deviceID = getDeviceID(name); - if (deviceID != INVALID_DEVICE) { - delete Singleton::get()->_devicesVector[getDeviceID(name)]; - Singleton::get()->_devicesVector[getDeviceID(name)] = nullptr; - } -} - -void DeviceTracker::updateAll() { - //TODO C++11 for (auto deviceIt = Singleton::get()->_devicesVector.begin(); deviceIt != Singleton::get()->_devicesVector.end(); deviceIt++) { - for (Vector::iterator deviceIt = Singleton::get()->_devicesVector.begin(); deviceIt != Singleton::get()->_devicesVector.end(); deviceIt++) { - if ((*deviceIt)) - (*deviceIt)->update(); - } -} - -// Core features of the Device Tracker -DeviceTracker::DeviceTracker() : - _ID(INVALID_DEVICE), - _name("Unkown") -{ -} - -DeviceTracker::~DeviceTracker() { -} - -void DeviceTracker::update() { -} diff --git a/libraries/trackers/src/trackers/DeviceTracker.h b/libraries/trackers/src/trackers/DeviceTracker.h deleted file mode 100644 index 8a7f509cb3..0000000000 --- a/libraries/trackers/src/trackers/DeviceTracker.h +++ /dev/null @@ -1,115 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 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_DeviceTracker_h -#define hifi_DeviceTracker_h - -#include -#include -#include - -// Singleton template class -template < typename T > -class TemplateSingleton { -public: - - static T* get() { - if ( !_singleton._one ) { - _singleton._one = new T(); - } - return _singleton._one; - } - - TemplateSingleton() : - _one(0) - { - } - ~TemplateSingleton() { - if ( _one ) { - delete _one; - _one = 0; - } - } -private: - static TemplateSingleton< T > _singleton; - T* _one; -}; -template -TemplateSingleton TemplateSingleton::_singleton; - -/// Base class for device trackers. -class DeviceTracker { -public: - - // THe ID and Name types used to manage the pool of devices - typedef std::string Name; - typedef int ID; - static const ID INVALID_DEVICE = -1; - static const ID INVALID_DEVICE_NAME = -2; - - // Singleton interface to register and query the devices currently connected - static int getNumDevices(); - static ID getDeviceID(const Name& name); - static DeviceTracker* getDevice(ID deviceID); - static DeviceTracker* getDevice(const Name& name); - - /// Update all the devices calling for their update() function - /// This should be called every frame by the main loop to update all the devices that pull their state - static void updateAll(); - - /// Register a device tracker to the factory - /// Right after creating a new DeviceTracker, it should be registered - /// This is why, it's recommended to use a factory static call in the specialized class - /// to create a new input device - /// - /// \param name The Name under wich registering the device - /// \param parent The DeviceTracker - /// - /// \return The Index of the newly registered device. - /// Valid if everything went well. - /// INVALID_DEVICE if the device is not valid (NULL) - /// INVALID_DEVICE_NAME if the name is already taken - static ID registerDevice(const Name& name, DeviceTracker* tracker); - - static void destroyDevice(const Name& name); - - // DeviceTracker interface - - virtual void update(); - - /// Get the ID assigned to the Device when registered after creation, or INVALID_DEVICE if it hasn't been registered which should not happen. - ID getID() const { return _ID; } - - /// Get the name assigned to the Device when registered after creation, or "Unknown" if it hasn't been registered which should not happen. - const Name& getName() const { return _name; } - - typedef std::map< Name, ID > Map; - static const Map& getDevices() { return Singleton::get()->_devicesMap; } - -protected: - DeviceTracker(); - virtual ~DeviceTracker(); - -private: - ID _ID; - Name _name; - - // this call is used by the singleton when the device tracker is currently beeing registered and beeing assigned an ID - void assignIDAndName( const ID id, const Name& name ) { _ID = id; _name = name; } - - typedef std::vector< DeviceTracker* > Vector; - struct SingletonData { - Map _devicesMap; - Vector _devicesVector; - - ~SingletonData(); - }; - typedef TemplateSingleton< SingletonData > Singleton; -}; - -#endif // hifi_DeviceTracker_h diff --git a/libraries/trackers/src/trackers/MotionTracker.cpp b/libraries/trackers/src/trackers/MotionTracker.cpp deleted file mode 100644 index c6012c0422..0000000000 --- a/libraries/trackers/src/trackers/MotionTracker.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 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 "MotionTracker.h" - -// glm::mult(mat43, mat43) just the composition of the 2 matrices assuming they are in fact mat44 with the last raw = { 0, 0, 0, 1 } -namespace glm { - mat4x3 mult(const mat4& lhs, const mat4x3& rhs) { - vec3 lrx(lhs[0].x, lhs[1].x, lhs[2].x); - vec3 lry(lhs[0].y, lhs[1].y, lhs[2].y); - vec3 lrz(lhs[0].z, lhs[1].z, lhs[2].z); - return mat4x3( - dot(lrx, rhs[0]), - dot(lry, rhs[0]), - dot(lrz, rhs[0]), - - dot(lrx, rhs[1]), - dot(lry, rhs[1]), - dot(lrz, rhs[1]), - - dot(lrx, rhs[2]), - dot(lry, rhs[2]), - dot(lrz, rhs[2]), - - dot(lrx, rhs[3]) + lhs[3].x, - dot(lry, rhs[3]) + lhs[3].y, - dot(lrz, rhs[3]) + lhs[3].z - ); - } - mat4x3 mult(const mat4x3& lhs, const mat4x3& rhs) { - vec3 lrx(lhs[0].x, lhs[1].x, lhs[2].x); - vec3 lry(lhs[0].y, lhs[1].y, lhs[2].y); - vec3 lrz(lhs[0].z, lhs[1].z, lhs[2].z); - return mat4x3( - dot(lrx, rhs[0]), - dot(lry, rhs[0]), - dot(lrz, rhs[0]), - - dot(lrx, rhs[1]), - dot(lry, rhs[1]), - dot(lrz, rhs[1]), - - dot(lrx, rhs[2]), - dot(lry, rhs[2]), - dot(lrz, rhs[2]), - - dot(lrx, rhs[3]) + lhs[3].x, - dot(lry, rhs[3]) + lhs[3].y, - dot(lrz, rhs[3]) + lhs[3].z - ); - } -} - -// MotionTracker -MotionTracker::MotionTracker() : - DeviceTracker() -{ - _jointsArray.resize(1); - _jointsMap.insert(JointTracker::Map::value_type(Semantic("Root"), 0)); -} - -MotionTracker::~MotionTracker() -{ -} - -bool MotionTracker::isConnected() const { - return false; -} - -MotionTracker::Index MotionTracker::addJoint(const Semantic& semantic, Index parent) { - // Check the parent - if (int(parent) < 0) - return INVALID_PARENT; - - // Check that the semantic is not already in use - Index foundIndex = findJointIndex(semantic); - if (foundIndex >= 0) { - return INVALID_SEMANTIC; - } - - - // All good then allocate the joint - Index newIndex = (Index)_jointsArray.size(); - _jointsArray.push_back(JointTracker(semantic, parent)); - _jointsMap.insert(JointTracker::Map::value_type(semantic, newIndex)); - - return newIndex; -} - -MotionTracker::Index MotionTracker::findJointIndex(const Semantic& semantic) const { - // TODO C++11 auto jointIt = _jointsMap.find(semantic); - JointTracker::Map::const_iterator jointIt = _jointsMap.find(semantic); - if (jointIt != _jointsMap.end()) { - return (*jointIt).second; - } - - return INVALID_SEMANTIC; -} - -void MotionTracker::updateAllAbsTransform() { - _jointsArray[0].updateAbsFromLocTransform(0); - - // Because we know the hierarchy is stored from root down the branches let's just traverse and update - for (Index i = 1; i < (Index)(_jointsArray.size()); i++) { - JointTracker* joint = _jointsArray.data() + i; - joint->updateAbsFromLocTransform(_jointsArray.data() + joint->getParent()); - } -} - - -// MotionTracker::JointTracker -MotionTracker::JointTracker::JointTracker() : - _locFrame(), - _absFrame(), - _semantic(""), - _parent(INVALID_PARENT), - _lastUpdate(1) // Joint inactive -{ -} - -MotionTracker::JointTracker::JointTracker(const Semantic& semantic, Index parent) : - _semantic(semantic), - _parent(parent), - _lastUpdate(1) // Joint inactive -{ -} - -MotionTracker::JointTracker::JointTracker(const JointTracker& tracker) : - _locFrame(tracker._locFrame), - _absFrame(tracker._absFrame), - _semantic(tracker._semantic), - _parent(tracker._parent), - _lastUpdate(tracker._lastUpdate) -{ -} - -void MotionTracker::JointTracker::updateAbsFromLocTransform(const JointTracker* parentJoint) { - if (parentJoint) { - editAbsFrame()._transform = (parentJoint->getAbsFrame()._transform * getLocFrame()._transform); - } else { - editAbsFrame()._transform = getLocFrame()._transform; - } -} - -void MotionTracker::JointTracker::updateLocFromAbsTransform(const JointTracker* parentJoint) { - if (parentJoint) { - glm::mat4 ip = glm::inverse(parentJoint->getAbsFrame()._transform); - editLocFrame()._transform = (ip * getAbsFrame()._transform); - } else { - editLocFrame()._transform = getAbsFrame()._transform; - } -} - -//-------------------------------------------------------------------------------------- -// MotionTracker::Frame -//-------------------------------------------------------------------------------------- - -MotionTracker::Frame::Frame() : - _transform() -{ -} - -void MotionTracker::Frame::setRotation(const glm::quat& rotation) { - glm::mat3x3 rot = glm::mat3_cast(rotation); - _transform[0] = glm::vec4(rot[0], 0.0f); - _transform[1] = glm::vec4(rot[1], 0.0f); - _transform[2] = glm::vec4(rot[2], 0.0f); -} - -void MotionTracker::Frame::getRotation(glm::quat& rotation) const { - rotation = glm::quat_cast(_transform); -} - -void MotionTracker::Frame::setTranslation(const glm::vec3& translation) { - _transform[3] = glm::vec4(translation, 1.0f); -} - -void MotionTracker::Frame::getTranslation(glm::vec3& translation) const { - translation = extractTranslation(_transform); -} - diff --git a/libraries/trackers/src/trackers/MotionTracker.h b/libraries/trackers/src/trackers/MotionTracker.h deleted file mode 100644 index 26c8dcea2c..0000000000 --- a/libraries/trackers/src/trackers/MotionTracker.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 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_MotionTracker_h -#define hifi_MotionTracker_h - -#include "DeviceTracker.h" - -#include - -/// Base class for device trackers. -class MotionTracker : public DeviceTracker { -public: - - class Frame { - public: - Frame(); - - glm::mat4 _transform; - - void setRotation(const glm::quat& rotation); - void getRotation(glm::quat& rotatio) const; - - void setTranslation(const glm::vec3& translation); - void getTranslation(glm::vec3& translation) const; - }; - - // Semantic and Index types to retreive the JointTrackers of this MotionTracker - typedef std::string Semantic; - typedef int32_t Index; - static const Index INVALID_SEMANTIC = -1; - static const Index INVALID_PARENT = -2; - - class JointTracker { - public: - typedef std::vector< JointTracker > Vector; - typedef std::map< Semantic, Index > Map; - - JointTracker(); - JointTracker(const JointTracker& tracker); - JointTracker(const Semantic& semantic, Index parent); - - const Frame& getLocFrame() const { return _locFrame; } - Frame& editLocFrame() { return _locFrame; } - void setLocFrame(const Frame& frame) { editLocFrame() = frame; } - - const Frame& getAbsFrame() const { return _absFrame; } - Frame& editAbsFrame() { return _absFrame; } - void setAbsFrame(const Frame& frame) { editAbsFrame() = frame; } - - const Semantic& getSemantic() const { return _semantic; } - const Index& getParent() const { return _parent; } - - bool isActive() const { return (_lastUpdate <= 0); } - void tickNewFrame() { _lastUpdate++; } - void activeFrame() { _lastUpdate = 0; } - - /// Update the loc/abs transform for this joint from the current abs/loc value and the specified parent joint abs frame - void updateLocFromAbsTransform(const JointTracker* parentJoint); - void updateAbsFromLocTransform(const JointTracker* parentJoint); - - protected: - Frame _locFrame; - Frame _absFrame; - Semantic _semantic; - Index _parent; - int _lastUpdate; - }; - - virtual bool isConnected() const; - - Index numJointTrackers() const { return (Index)_jointsArray.size(); } - - /// Access a Joint from it's index. - /// Index 0 is always the "Root". - /// if the index is Invalid then returns NULL. - const JointTracker* getJointTracker(Index index) const { return ((index > 0) && (index < (Index)(_jointsArray.size())) ? _jointsArray.data() + index : NULL); } - JointTracker* editJointTracker(Index index) { return ((index > 0) && (index < (Index)(_jointsArray.size())) ? _jointsArray.data() + index : NULL); } - - /// From a semantic, find the Index of the Joint. - /// \return the index of the mapped Joint or INVALID_SEMANTIC if the semantic is not knowned. - Index findJointIndex(const Semantic& semantic) const; - -protected: - MotionTracker(); - virtual ~MotionTracker(); - - JointTracker::Vector _jointsArray; - JointTracker::Map _jointsMap; - - /// Adding joint is only done from the specialized Motion Tracker, hence this function is protected. - /// The hierarchy of joints must be created from the top down to the branches. - /// The "Root" node is at index 0 and exists at creation of the Motion Tracker. - /// - /// \param semantic A joint is defined by it's semantic, the unique name mapping to it - /// \param parent The parent's index, the parent must be valid and correspond to a Joint that has been previously created - /// - /// \return The Index of the newly created Joint. - /// Valid if everything went well. - /// INVALID_SEMANTIC if the semantic is already in use - /// INVALID_PARENT if the parent is not valid - Index addJoint(const Semantic& semantic, Index parent); - - /// Update the absolute transform stack traversing the hierarchy from the root down the branches - /// This is a generic way to update all the Joint's absFrame by combining the locFrame going down the hierarchy branch. - void updateAllAbsTransform(); -}; - - - -#endif // hifi_MotionTracker_h diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index f0006cb399..648bdad1bf 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -886,12 +886,6 @@ QQmlContext* OffscreenQmlSurface::getSurfaceContext() { return _qmlContext; } -Q_DECLARE_METATYPE(std::function); -auto VoidLambdaType = qRegisterMetaType>(); -Q_DECLARE_METATYPE(std::function); -auto VariantLambdaType = qRegisterMetaType>(); - - void OffscreenQmlSurface::executeOnUiThread(std::function function, bool blocking ) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "executeOnUiThread", blocking ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 8b3dc342e2..1e426dd8f0 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -623,7 +623,8 @@ TabletButtonProxy* TabletProxy::addButton(const QVariant& properties) { auto toolbarProxy = DependencyManager::get()->getSystemToolbarProxy(); if (toolbarProxy) { // copy properties from tablet button proxy to toolbar button proxy. - toolbarProxy->addButton(tabletButtonProxy->getProperties()); + auto toolbarButtonProxy = toolbarProxy->addButton(tabletButtonProxy->getProperties()); + tabletButtonProxy->setToolbarButtonProxy(toolbarButtonProxy); } } return tabletButtonProxy.data(); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 82ca2a7d38..06cf929368 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -30,6 +30,8 @@ if (NOT SERVER_ONLY AND NOT ANDROID) add_subdirectory(${DIR}) set(DIR "steamClient") add_subdirectory(${DIR}) + set(DIR "hifiLeapMotion") + add_subdirectory(${DIR}) endif() # server-side plugins diff --git a/plugins/hifiLeapMotion/CMakeLists.txt b/plugins/hifiLeapMotion/CMakeLists.txt new file mode 100644 index 0000000000..14f9bbaa17 --- /dev/null +++ b/plugins/hifiLeapMotion/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Created by David Rowe on 15 Jun 2017. +# Copyright 2017 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 +# + +find_package(LEAPMOTION) +if (LEAPMOTION_FOUND) + set(TARGET_NAME hifiLeapMotion) + setup_hifi_plugin(Script Qml Widgets) + link_hifi_libraries(shared controllers ui plugins input-plugins) + target_leapmotion() +endif() diff --git a/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp b/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp new file mode 100644 index 0000000000..174dd02426 --- /dev/null +++ b/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp @@ -0,0 +1,493 @@ +// +// LeapMotionPlugin.cpp +// +// Created by David Rowe on 15 Jun 2017. +// Copyright 2017 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 "LeapMotionPlugin.h" + +#include + +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(inputplugins) +Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins") + +const char* LeapMotionPlugin::NAME = "Leap Motion"; +const char* LeapMotionPlugin::LEAPMOTION_ID_STRING = "Leap Motion"; + +const bool DEFAULT_ENABLED = false; +const char* SENSOR_ON_DESKTOP = "Desktop"; +const char* SENSOR_ON_HMD = "HMD"; +const char* DEFAULT_SENSOR_LOCATION = SENSOR_ON_DESKTOP; + +enum LeapMotionJointIndex { + LeftHand = 0, + LeftHandThumb1, + LeftHandThumb2, + LeftHandThumb3, + LeftHandThumb4, + LeftHandIndex1, + LeftHandIndex2, + LeftHandIndex3, + LeftHandIndex4, + LeftHandMiddle1, + LeftHandMiddle2, + LeftHandMiddle3, + LeftHandMiddle4, + LeftHandRing1, + LeftHandRing2, + LeftHandRing3, + LeftHandRing4, + LeftHandPinky1, + LeftHandPinky2, + LeftHandPinky3, + LeftHandPinky4, + RightHand, + RightHandThumb1, + RightHandThumb2, + RightHandThumb3, + RightHandThumb4, + RightHandIndex1, + RightHandIndex2, + RightHandIndex3, + RightHandIndex4, + RightHandMiddle1, + RightHandMiddle2, + RightHandMiddle3, + RightHandMiddle4, + RightHandRing1, + RightHandRing2, + RightHandRing3, + RightHandRing4, + RightHandPinky1, + RightHandPinky2, + RightHandPinky3, + RightHandPinky4, + + Size +}; + +static controller::StandardPoseChannel LeapMotionJointIndexToPoseIndexMap[LeapMotionJointIndex::Size] = { + controller::LEFT_HAND, + controller::LEFT_HAND_THUMB1, + controller::LEFT_HAND_THUMB2, + controller::LEFT_HAND_THUMB3, + controller::LEFT_HAND_THUMB4, + controller::LEFT_HAND_INDEX1, + controller::LEFT_HAND_INDEX2, + controller::LEFT_HAND_INDEX3, + controller::LEFT_HAND_INDEX4, + controller::LEFT_HAND_MIDDLE1, + controller::LEFT_HAND_MIDDLE2, + controller::LEFT_HAND_MIDDLE3, + controller::LEFT_HAND_MIDDLE4, + controller::LEFT_HAND_RING1, + controller::LEFT_HAND_RING2, + controller::LEFT_HAND_RING3, + controller::LEFT_HAND_RING4, + controller::LEFT_HAND_PINKY1, + controller::LEFT_HAND_PINKY2, + controller::LEFT_HAND_PINKY3, + controller::LEFT_HAND_PINKY4, + controller::RIGHT_HAND, + controller::RIGHT_HAND_THUMB1, + controller::RIGHT_HAND_THUMB2, + controller::RIGHT_HAND_THUMB3, + controller::RIGHT_HAND_THUMB4, + controller::RIGHT_HAND_INDEX1, + controller::RIGHT_HAND_INDEX2, + controller::RIGHT_HAND_INDEX3, + controller::RIGHT_HAND_INDEX4, + controller::RIGHT_HAND_MIDDLE1, + controller::RIGHT_HAND_MIDDLE2, + controller::RIGHT_HAND_MIDDLE3, + controller::RIGHT_HAND_MIDDLE4, + controller::RIGHT_HAND_RING1, + controller::RIGHT_HAND_RING2, + controller::RIGHT_HAND_RING3, + controller::RIGHT_HAND_RING4, + controller::RIGHT_HAND_PINKY1, + controller::RIGHT_HAND_PINKY2, + controller::RIGHT_HAND_PINKY3, + controller::RIGHT_HAND_PINKY4 +}; + +#define UNKNOWN_JOINT (controller::StandardPoseChannel)0 + +static controller::StandardPoseChannel LeapMotionJointIndexToPoseIndex(LeapMotionJointIndex i) { + assert(i >= 0 && i < LeapMotionJointIndex::Size); + if (i >= 0 && i < LeapMotionJointIndex::Size) { + return LeapMotionJointIndexToPoseIndexMap[i]; + } else { + return UNKNOWN_JOINT; + } +} + +QStringList controllerJointNames = { + "Hips", + "RightUpLeg", + "RightLeg", + "RightFoot", + "LeftUpLeg", + "LeftLeg", + "LeftFoot", + "Spine", + "Spine1", + "Spine2", + "Spine3", + "Neck", + "Head", + "RightShoulder", + "RightArm", + "RightForeArm", + "RightHand", + "RightHandThumb1", + "RightHandThumb2", + "RightHandThumb3", + "RightHandThumb4", + "RightHandIndex1", + "RightHandIndex2", + "RightHandIndex3", + "RightHandIndex4", + "RightHandMiddle1", + "RightHandMiddle2", + "RightHandMiddle3", + "RightHandMiddle4", + "RightHandRing1", + "RightHandRing2", + "RightHandRing3", + "RightHandRing4", + "RightHandPinky1", + "RightHandPinky2", + "RightHandPinky3", + "RightHandPinky4", + "LeftShoulder", + "LeftArm", + "LeftForeArm", + "LeftHand", + "LeftHandThumb1", + "LeftHandThumb2", + "LeftHandThumb3", + "LeftHandThumb4", + "LeftHandIndex1", + "LeftHandIndex2", + "LeftHandIndex3", + "LeftHandIndex4", + "LeftHandMiddle1", + "LeftHandMiddle2", + "LeftHandMiddle3", + "LeftHandMiddle4", + "LeftHandRing1", + "LeftHandRing2", + "LeftHandRing3", + "LeftHandRing4", + "LeftHandPinky1", + "LeftHandPinky2", + "LeftHandPinky3", + "LeftHandPinky4" +}; + +static const char* getControllerJointName(controller::StandardPoseChannel i) { + if (i >= 0 && i < controller::NUM_STANDARD_POSES) { + return qPrintable(controllerJointNames[i]); + } + return "unknown"; +} + + +void LeapMotionPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { + if (!_enabled) { + return; + } + + const auto frame = _controller.frame(); + const auto frameID = frame.id(); + if (_lastFrameID >= frameID) { + // Leap Motion not connected or duplicate frame. + return; + } + + if (!_hasLeapMotionBeenConnected) { + emit deviceConnected(getName()); + _hasLeapMotionBeenConnected = true; + } + + processFrame(frame); // Updates _joints. + + auto joints = _joints; + + auto userInputMapper = DependencyManager::get(); + userInputMapper->withLock([&, this]() { + _inputDevice->update(deltaTime, inputCalibrationData, joints, _prevJoints); + }); + + _prevJoints = joints; + + _lastFrameID = frameID; +} + +controller::Input::NamedVector LeapMotionPlugin::InputDevice::getAvailableInputs() const { + static controller::Input::NamedVector availableInputs; + if (availableInputs.size() == 0) { + for (int i = 0; i < LeapMotionJointIndex::Size; i++) { + auto channel = LeapMotionJointIndexToPoseIndex(static_cast(i)); + availableInputs.push_back(makePair(channel, getControllerJointName(channel))); + } + }; + return availableInputs; +} + +QString LeapMotionPlugin::InputDevice::getDefaultMappingConfig() const { + static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/leapmotion.json"; + return MAPPING_JSON; +} + +void LeapMotionPlugin::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, + const std::vector& joints, + const std::vector& prevJoints) { + + glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; + glm::quat controllerToAvatarRotation = glmExtractRotation(controllerToAvatar); + + glm::vec3 hmdSensorPosition; // HMD + glm::quat hmdSensorOrientation; // HMD + glm::vec3 leapMotionOffset; // Desktop + if (_isLeapOnHMD) { + hmdSensorPosition = extractTranslation(inputCalibrationData.hmdSensorMat); + hmdSensorOrientation = extractRotation(inputCalibrationData.hmdSensorMat); + } else { + // Desktop "zero" position is some distance above the Leap Motion sensor and half the avatar's shoulder-to-hand length + // in front of avatar. + float halfShouldToHandLength = fabsf(extractTranslation(inputCalibrationData.defaultLeftHand).x + - extractTranslation(inputCalibrationData.defaultLeftArm).x) / 2.0f; + leapMotionOffset = glm::vec3(0.0f, _desktopHeightOffset, halfShouldToHandLength); + } + + for (size_t i = 0; i < joints.size(); i++) { + int poseIndex = LeapMotionJointIndexToPoseIndex((LeapMotionJointIndex)i); + + if (joints[i].position == Vectors::ZERO) { + _poseStateMap[poseIndex] = controller::Pose(); + continue; + } + + glm::vec3 pos; + glm::quat rot; + if (_isLeapOnHMD) { + auto jointPosition = joints[i].position; + const glm::vec3 HMD_EYE_TO_LEAP_OFFSET = glm::vec3(0.0f, 0.0f, -0.09f); // Eyes to surface of Leap Motion. + jointPosition = glm::vec3(-jointPosition.x, -jointPosition.z, -jointPosition.y) + HMD_EYE_TO_LEAP_OFFSET; + jointPosition = hmdSensorPosition + hmdSensorOrientation * jointPosition; + pos = transformPoint(controllerToAvatar, jointPosition); + + glm::quat jointOrientation = joints[i].orientation; + jointOrientation = glm::quat(jointOrientation.w, -jointOrientation.x, -jointOrientation.z, -jointOrientation.y); + rot = controllerToAvatarRotation * hmdSensorOrientation * jointOrientation; + } else { + pos = controllerToAvatarRotation * (joints[i].position - leapMotionOffset); + const glm::quat ZERO_HAND_ORIENTATION = glm::quat(glm::vec3(PI_OVER_TWO, PI, 0.0f)); + rot = controllerToAvatarRotation * joints[i].orientation * ZERO_HAND_ORIENTATION; + } + + glm::vec3 linearVelocity, angularVelocity; + if (i < prevJoints.size()) { + linearVelocity = (pos - (prevJoints[i].position * METERS_PER_CENTIMETER)) / deltaTime; // m/s + // quat log imaginary part points along the axis of rotation, with length of one half the angle of rotation. + glm::quat d = glm::log(rot * glm::inverse(prevJoints[i].orientation)); + angularVelocity = glm::vec3(d.x, d.y, d.z) / (0.5f * deltaTime); // radians/s + } + + _poseStateMap[poseIndex] = controller::Pose(pos, rot, linearVelocity, angularVelocity); + } +} + +void LeapMotionPlugin::init() { + loadSettings(); + + auto preferences = DependencyManager::get(); + static const QString LEAPMOTION_PLUGIN { "Leap Motion" }; + { + auto getter = [this]()->bool { return _enabled; }; + auto setter = [this](bool value) { + _enabled = value; + saveSettings(); + if (!_enabled) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->withLock([&, this]() { + _inputDevice->clearState(); + }); + } + }; + auto preference = new CheckPreference(LEAPMOTION_PLUGIN, "Enabled", getter, setter); + preferences->addPreference(preference); + } + { + auto getter = [this]()->QString { return _sensorLocation; }; + auto setter = [this](QString value) { + _sensorLocation = value; + saveSettings(); + applySensorLocation(); + }; + auto preference = new ComboBoxPreference(LEAPMOTION_PLUGIN, "Sensor location", getter, setter); + QStringList list = { SENSOR_ON_DESKTOP, SENSOR_ON_HMD }; + preference->setItems(list); + preferences->addPreference(preference); + } + { + auto getter = [this]()->float { return _desktopHeightOffset; }; + auto setter = [this](float value) { + _desktopHeightOffset = value; + saveSettings(); + applyDesktopHeightOffset(); + }; + auto preference = new SpinnerPreference(LEAPMOTION_PLUGIN, "Desktop height for horizontal forearms", getter, setter); + float MIN_VALUE = 0.0f; + float MAX_VALUE = 1.0f; + float DECIMALS = 2.0f; + float STEP = 0.01f; + preference->setMin(MIN_VALUE); + preference->setMax(MAX_VALUE); + preference->setDecimals(DECIMALS); + preference->setStep(STEP); + preferences->addPreference(preference); + } +} + +bool LeapMotionPlugin::activate() { + InputPlugin::activate(); + + // Nothing required to be done to start up Leap Motion library. + + _joints.resize(LeapMotionJointIndex::Size, { glm::vec3(), glm::quat() }); + + auto userInputMapper = DependencyManager::get(); + userInputMapper->registerDevice(_inputDevice); + + return true; +} + +void LeapMotionPlugin::deactivate() { + if (_inputDevice->_deviceID != controller::Input::INVALID_DEVICE) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->removeDevice(_inputDevice->_deviceID); + } + + InputPlugin::deactivate(); +} + +const char* SETTINGS_ENABLED_KEY = "enabled"; +const char* SETTINGS_SENSOR_LOCATION_KEY = "sensorLocation"; +const char* SETTINGS_DESKTOP_HEIGHT_OFFSET_KEY = "desktopHeightOffset"; + +void LeapMotionPlugin::saveSettings() const { + Settings settings; + QString idString = getID(); + settings.beginGroup(idString); + { + settings.setValue(QString(SETTINGS_ENABLED_KEY), _enabled); + settings.setValue(QString(SETTINGS_SENSOR_LOCATION_KEY), _sensorLocation); + settings.setValue(QString(SETTINGS_DESKTOP_HEIGHT_OFFSET_KEY), _desktopHeightOffset); + } + settings.endGroup(); +} + +void LeapMotionPlugin::loadSettings() { + Settings settings; + QString idString = getID(); + settings.beginGroup(idString); + { + _enabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool(); + _sensorLocation = settings.value(SETTINGS_SENSOR_LOCATION_KEY, QVariant(DEFAULT_SENSOR_LOCATION)).toString(); + _desktopHeightOffset = + settings.value(SETTINGS_DESKTOP_HEIGHT_OFFSET_KEY, QVariant(DEFAULT_DESKTOP_HEIGHT_OFFSET)).toFloat(); + applySensorLocation(); + applyDesktopHeightOffset(); + } + settings.endGroup(); +} + +void LeapMotionPlugin::InputDevice::clearState() { + for (size_t i = 0; i < LeapMotionJointIndex::Size; i++) { + int poseIndex = LeapMotionJointIndexToPoseIndex((LeapMotionJointIndex)i); + _poseStateMap[poseIndex] = controller::Pose(); + } +} + +void LeapMotionPlugin::applySensorLocation() { + bool isLeapOnHMD = _sensorLocation == SENSOR_ON_HMD; + _controller.setPolicyFlags(isLeapOnHMD ? Leap::Controller::POLICY_OPTIMIZE_HMD : Leap::Controller::POLICY_DEFAULT); + _inputDevice->setIsLeapOnHMD(isLeapOnHMD); +} + +void LeapMotionPlugin::applyDesktopHeightOffset() { + _inputDevice->setDektopHeightOffset(_desktopHeightOffset); +} + +const float LEFT_SIDE_SIGN = -1.0f; +const float RIGHT_SIDE_SIGN = 1.0f; + +glm::quat LeapBasisToQuat(float sideSign, const Leap::Matrix& basis) { + glm::vec3 xAxis = sideSign * glm::vec3(basis.xBasis.x, basis.xBasis.y, basis.xBasis.z); + glm::vec3 yAxis = glm::vec3(basis.yBasis.x, basis.yBasis.y, basis.yBasis.z); + glm::vec3 zAxis = glm::vec3(basis.zBasis.x, basis.zBasis.y, basis.zBasis.z); + glm::quat orientation = (glm::quat_cast(glm::mat3(xAxis, yAxis, zAxis))); + return orientation; +} + +glm::vec3 LeapVectorToVec3(const Leap::Vector& vec) { + return glm::vec3(vec.x * METERS_PER_MILLIMETER, vec.y * METERS_PER_MILLIMETER, vec.z * METERS_PER_MILLIMETER); +} + +void LeapMotionPlugin::processFrame(const Leap::Frame& frame) { + // Default to uncontrolled. + for (int i = 0; i < _joints.size(); i++) { + _joints[i].position = glm::vec3(); + } + + auto hands = frame.hands(); + const int MAX_NUMBER_OF_HANDS = 2; + for (int i = 0; i < hands.count() && i < MAX_NUMBER_OF_HANDS; i++) { + auto hand = hands[i]; + + int sideSign = hand.isLeft() ? LEFT_SIDE_SIGN : RIGHT_SIDE_SIGN; + int jointIndex = hand.isLeft() ? LeapMotionJointIndex::LeftHand : LeapMotionJointIndex::RightHand; + + // Hand. + _joints[jointIndex].position = LeapVectorToVec3(hand.wristPosition()); + _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, hand.basis()); + + // Fingers. + // Leap Motion SDK guarantees full set of fingers and finger joints so can straightforwardly process them all. + Leap::FingerList fingers = hand.fingers(); + for (int j = Leap::Finger::Type::TYPE_THUMB; j <= Leap::Finger::Type::TYPE_PINKY; j++) { + Leap::Finger finger; + finger = fingers[j]; + Leap::Bone bone; + bone = finger.bone(Leap::Bone::Type::TYPE_PROXIMAL); + jointIndex++; + _joints[jointIndex].position = LeapVectorToVec3(bone.prevJoint()); + _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); + bone = finger.bone(Leap::Bone::Type::TYPE_INTERMEDIATE); + jointIndex++; + _joints[jointIndex].position = LeapVectorToVec3(bone.prevJoint()); + _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); + bone = finger.bone(Leap::Bone::Type::TYPE_DISTAL); + jointIndex++; + _joints[jointIndex].position = LeapVectorToVec3(bone.prevJoint()); + _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); + jointIndex++; + _joints[jointIndex].position = LeapVectorToVec3(bone.nextJoint()); + _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); + } + } +} + diff --git a/plugins/hifiLeapMotion/src/LeapMotionPlugin.h b/plugins/hifiLeapMotion/src/LeapMotionPlugin.h new file mode 100644 index 0000000000..391d569567 --- /dev/null +++ b/plugins/hifiLeapMotion/src/LeapMotionPlugin.h @@ -0,0 +1,99 @@ +// +// LeapMotionPlugin.h +// +// Created by David Rowe on 15 Jun 2017. +// Copyright 2017 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_LeapMotionPlugin_h +#define hifi_LeapMotionPlugin_h + +#include +#include + +// LeapMotion SDK +#include + +class LeapMotionPlugin : public InputPlugin { + Q_OBJECT + +public: + // InputPlugin methods + virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } + virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; + + bool isHandController() const override { return true; } + + // Plugin methods + virtual const QString getName() const override { return NAME; } + const QString getID() const override { return LEAPMOTION_ID_STRING; } + + virtual void init() override; + + virtual bool activate() override; + virtual void deactivate() override; + + virtual void saveSettings() const override; + virtual void loadSettings() override; + +protected: + static const char* NAME; + static const char* LEAPMOTION_ID_STRING; + const float DEFAULT_DESKTOP_HEIGHT_OFFSET = 0.2f; + + bool _enabled { false }; + QString _sensorLocation; + float _desktopHeightOffset { DEFAULT_DESKTOP_HEIGHT_OFFSET }; + + struct LeapMotionJoint { + glm::vec3 position; + glm::quat orientation; + }; + + std::vector _joints; + std::vector _prevJoints; + + class InputDevice : public controller::InputDevice { + public: + friend class LeapMotionPlugin; + + InputDevice() : controller::InputDevice("LeapMotion") {} + + // Device functions + virtual controller::Input::NamedVector getAvailableInputs() const override; + virtual QString getDefaultMappingConfig() const override; + virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override {}; + virtual void focusOutEvent() override {}; + + void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, + const std::vector& joints, + const std::vector& prevJoints); + + void clearState(); + + void setDektopHeightOffset(float desktopHeightOffset) { _desktopHeightOffset = desktopHeightOffset; }; + void setIsLeapOnHMD(bool isLeapOnHMD) { _isLeapOnHMD = isLeapOnHMD; }; + + private: + float _desktopHeightOffset { 0.0f }; + bool _isLeapOnHMD { false }; + }; + + std::shared_ptr _inputDevice { std::make_shared() }; + +private: + void applySensorLocation(); + void applyDesktopHeightOffset(); + + void processFrame(const Leap::Frame& frame); + + Leap::Controller _controller; + + bool _hasLeapMotionBeenConnected { false }; + int64_t _lastFrameID { -1 }; +}; + +#endif // hifi_LeapMotionPlugin_h diff --git a/plugins/hifiLeapMotion/src/LeapMotionProvider.cpp b/plugins/hifiLeapMotion/src/LeapMotionProvider.cpp new file mode 100644 index 0000000000..62517439c3 --- /dev/null +++ b/plugins/hifiLeapMotion/src/LeapMotionProvider.cpp @@ -0,0 +1,51 @@ +// +// LeapMotionProvider.cpp +// +// Created by David Rowe on 15 Jun 2017. +// Copyright 2017 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 + +#include +#include +#include + +#include +#include + +#include "LeapMotionPlugin.h" + +class LeapMotionProvider : public QObject, public InputProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json") + Q_INTERFACES(InputProvider) + +public: + LeapMotionProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~LeapMotionProvider() {} + + virtual InputPluginList getInputPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + InputPluginPointer plugin(new LeapMotionPlugin()); + if (plugin->isSupported()) { + _inputPlugins.push_back(plugin); + } + }); + return _inputPlugins; + } + + virtual void destroyInputPlugins() override { + _inputPlugins.clear(); + } + +private: + InputPluginList _inputPlugins; +}; + +#include "LeapMotionProvider.moc" diff --git a/plugins/hifiLeapMotion/src/plugin.json b/plugins/hifiLeapMotion/src/plugin.json new file mode 100644 index 0000000000..2e867d96e4 --- /dev/null +++ b/plugins/hifiLeapMotion/src/plugin.json @@ -0,0 +1 @@ +{"name":"Leap Motion"} diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index d914cdcfad..648373ccc2 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -959,15 +959,33 @@ void ViveControllerManager::InputDevice::calibrateFeet(glm::mat4& defaultToRefer controller::Pose& secondFootPose = secondFoot.second; if (determineLimbOrdering(firstFootPose, secondFootPose, headXAxis, headPosition)) { - _jointToPuckMap[controller::LEFT_FOOT] = firstFoot.first; - _pucksOffset[firstFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultLeftFoot, firstFootPose); - _jointToPuckMap[controller::RIGHT_FOOT] = secondFoot.first; - _pucksOffset[secondFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultRightFoot, secondFootPose); + calibrateFoot(defaultToReferenceMat, inputCalibration, firstFoot, true); + calibrateFoot(defaultToReferenceMat, inputCalibration, secondFoot, false); } else { - _jointToPuckMap[controller::LEFT_FOOT] = secondFoot.first; - _pucksOffset[secondFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultLeftFoot, secondFootPose); - _jointToPuckMap[controller::RIGHT_FOOT] = firstFoot.first; - _pucksOffset[firstFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultRightFoot, firstFootPose); + calibrateFoot(defaultToReferenceMat, inputCalibration, secondFoot, true); + calibrateFoot(defaultToReferenceMat, inputCalibration, firstFoot, false); + } +} + +void ViveControllerManager::InputDevice::calibrateFoot(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, PuckPosePair& footPair, bool isLeftFoot){ + controller::Pose footPose = footPair.second; + glm::mat4 puckPoseAvatarMat = createMatFromQuatAndPos(footPose.getRotation(), footPose.getTranslation()); + glm::mat4 defaultFoot = isLeftFoot ? inputCalibration.defaultLeftFoot : inputCalibration.defaultRightFoot; + glm::mat4 footOffset = computeOffset(defaultToReferenceMat, defaultFoot, footPose); + + glm::quat rotationOffset = glmExtractRotation(footOffset); + glm::vec3 translationOffset = extractTranslation(footOffset); + glm::vec3 avatarXAxisInPuckFrame = glm::normalize(transformVectorFast(glm::inverse(puckPoseAvatarMat), glm::vec3(-1.0f, 0.0f, 0.0f))); + float distance = glm::dot(translationOffset, avatarXAxisInPuckFrame); + glm::vec3 finalTranslation = translationOffset - (distance * avatarXAxisInPuckFrame); + glm::mat4 finalOffset = createMatFromQuatAndPos(rotationOffset, finalTranslation); + + if (isLeftFoot) { + _jointToPuckMap[controller::LEFT_FOOT] = footPair.first; + _pucksOffset[footPair.first] = finalOffset; + } else { + _jointToPuckMap[controller::RIGHT_FOOT] = footPair.first; + _pucksOffset[footPair.first] = finalOffset; } } diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 67a9ff46fd..0b0406bb60 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -98,6 +98,7 @@ private: void calibrateLeftHand(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, PuckPosePair& handPair); void calibrateRightHand(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, PuckPosePair& handPair); void calibrateFeet(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); + void calibrateFoot(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, PuckPosePair& footPair, bool isLeftFoot); void calibrateHips(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); void calibrateChest(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); void calibrateShoulders(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, diff --git a/scripts/developer/EZrecord.js b/scripts/developer/EZrecord.js new file mode 100644 index 0000000000..7fdebada79 --- /dev/null +++ b/scripts/developer/EZrecord.js @@ -0,0 +1,275 @@ +"use strict"; + +// +// EZrecord.js +// +// Created by David Rowe on 24 Jun 2017. +// Copyright 2017 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 +// + +(function () { + + var APP_NAME = "EZRECORD", + APP_ICON_INACTIVE = "icons/tablet-icons/avatar-record-i.svg", + APP_ICON_ACTIVE = "icons/tablet-icons/avatar-record-a.svg", + SHORTCUT_KEY = "r", // Alt modifier is assumed. + tablet, + button, + + RecordingIndicator, + Recorder; + + function log(message) { + print(APP_NAME + ": " + message); + } + + function logDetails() { + return { + current_domain: location.placename + }; + } + + RecordingIndicator = (function () { + // Displays "recording" overlay. + + var hmdOverlay, + HMD_FONT_SIZE = 0.08, + desktopOverlay, + DESKTOP_FONT_SIZE = 24; + + function show() { + // Create both overlays in case user switches desktop/HMD mode. + var screenSize = Controller.getViewportDimensions(), + recordingText = "REC", // Unicode circle \u25cf doesn't render in HMD. + CAMERA_JOINT_INDEX = -7; + + if (HMD.active) { + // 3D overlay attached to avatar. + hmdOverlay = Overlays.addOverlay("text3d", { + text: recordingText, + dimensions: { x: 3 * HMD_FONT_SIZE, y: HMD_FONT_SIZE }, + parentID: MyAvatar.sessionUUID, + parentJointIndex: CAMERA_JOINT_INDEX, + localPosition: { x: 0.95, y: 0.95, z: -2.0 }, + color: { red: 255, green: 0, blue: 0 }, + alpha: 0.9, + lineHeight: HMD_FONT_SIZE, + backgroundAlpha: 0, + ignoreRayIntersection: true, + isFacingAvatar: true, + drawInFront: true, + visible: true + }); + } else { + // 2D overlay on desktop. + desktopOverlay = Overlays.addOverlay("text", { + text: recordingText, + width: 3 * DESKTOP_FONT_SIZE, + height: DESKTOP_FONT_SIZE, + x: screenSize.x - 4 * DESKTOP_FONT_SIZE, + y: DESKTOP_FONT_SIZE, + font: { size: DESKTOP_FONT_SIZE }, + color: { red: 255, green: 8, blue: 8 }, + alpha: 1.0, + backgroundAlpha: 0, + visible: true + }); + } + } + + function hide() { + if (desktopOverlay) { + Overlays.deleteOverlay(desktopOverlay); + } + if (hmdOverlay) { + Overlays.deleteOverlay(hmdOverlay); + } + } + + return { + show: show, + hide: hide + }; + }()); + + Recorder = (function () { + var IDLE = 0, + COUNTING_DOWN = 1, + RECORDING = 2, + recordingState = IDLE, + + countdownTimer, + countdownSeconds, + COUNTDOWN_SECONDS = 3, + + tickSound, + startRecordingSound, + finishRecordingSound, + TICK_SOUND = "../system/assets/sounds/countdown-tick.wav", + START_RECORDING_SOUND = "../system/assets/sounds/start-recording.wav", + FINISH_RECORDING_SOUND = "../system/assets/sounds/finish-recording.wav", + START_RECORDING_SOUND_DURATION = 1200, + SOUND_VOLUME = 0.2; + + function playSound(sound) { + Audio.playSound(sound, { + position: MyAvatar.position, + localOnly: true, + volume: SOUND_VOLUME + }); + } + + function isRecording() { + return recordingState === COUNTING_DOWN || recordingState === RECORDING; + } + + function startRecording() { + if (recordingState !== IDLE) { + return; + } + + log("Start countdown"); + countdownSeconds = COUNTDOWN_SECONDS; + playSound(tickSound); + countdownTimer = Script.setInterval(function () { + countdownSeconds -= 1; + if (countdownSeconds <= 0) { + Script.clearInterval(countdownTimer); + playSound(startRecordingSound); + log("Start recording"); + Script.setTimeout(function () { + // Delay start so that start beep is not included in recorded sound. + Recording.startRecording(); + RecordingIndicator.show(); + }, START_RECORDING_SOUND_DURATION); + recordingState = RECORDING; + } else { + playSound(tickSound); + } + }, 1000); + + recordingState = COUNTING_DOWN; + } + + function cancelRecording() { + log("Cancel recording"); + if (recordingState === COUNTING_DOWN) { + Script.clearInterval(countdownTimer); + } else { + Recording.stopRecording(); + RecordingIndicator.hide(); + } + recordingState = IDLE; + } + + function finishRecording() { + playSound(finishRecordingSound); + Recording.stopRecording(); + RecordingIndicator.hide(); + var filename = (new Date()).toISOString(); // yyyy-mm-ddThh:mm:ss.sssZ + filename = filename.replace(/[\-:]|\.\d*Z$/g, "").replace("T", "-") + ".hfr"; // yyyymmmdd-hhmmss.hfr + filename = Recording.getDefaultRecordingSaveDirectory() + filename; + log("Finish recording: " + filename); + Recording.saveRecording(filename); + recordingState = IDLE; + UserActivityLogger.logAction("ezrecord_finish_recording", logDetails()); + } + + function stopRecording() { + if (recordingState === COUNTING_DOWN) { + cancelRecording(); + } else if (recordingState === RECORDING) { + finishRecording(); + } + } + + function setUp() { + tickSound = SoundCache.getSound(Script.resolvePath(TICK_SOUND)); + startRecordingSound = SoundCache.getSound(Script.resolvePath(START_RECORDING_SOUND)); + finishRecordingSound = SoundCache.getSound(Script.resolvePath(FINISH_RECORDING_SOUND)); + } + + function tearDown() { + if (recordingState !== IDLE) { + cancelRecording(); + } + } + + return { + isRecording: isRecording, + startRecording: startRecording, + stopRecording: stopRecording, + setUp: setUp, + tearDown: tearDown + }; + }()); + + function toggleRecording() { + if (Recorder.isRecording()) { + Recorder.stopRecording(); + } else { + Recorder.startRecording(); + } + button.editProperties({ isActive: Recorder.isRecording() }); + } + + function onKeyPressEvent(event) { + if (event.isAlt && event.text === SHORTCUT_KEY && !event.isControl && !event.isMeta && !event.isAutoRepeat) { + toggleRecording(); + } + } + + function onButtonClicked() { + toggleRecording(); + } + + function setUp() { + tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + if (!tablet) { + return; + } + + Recorder.setUp(); + + // Tablet/toolbar button. + button = tablet.addButton({ + icon: APP_ICON_INACTIVE, + activeIcon: APP_ICON_ACTIVE, + text: APP_NAME, + isActive: false + }); + if (button) { + button.clicked.connect(onButtonClicked); + } + + Controller.keyPressEvent.connect(onKeyPressEvent); + + UserActivityLogger.logAction("ezrecord_run_script", logDetails()); + } + + function tearDown() { + + Controller.keyPressEvent.disconnect(onKeyPressEvent); + + Recorder.tearDown(); + + if (!tablet) { + return; + } + + if (button) { + button.clicked.disconnect(onButtonClicked); + tablet.removeButton(button); + button = null; + } + + tablet = null; + + } + + setUp(); + Script.scriptEnding.connect(tearDown); +}()); diff --git a/scripts/developer/tests/puck-attach.js b/scripts/developer/tests/puck-attach.js new file mode 100644 index 0000000000..2d0a2e6d02 --- /dev/null +++ b/scripts/developer/tests/puck-attach.js @@ -0,0 +1,174 @@ +// +// Created by Anthony J. Thibault on 2017/06/20 +// Copyright 2017 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 +// +// When this script is running, a new app button, named "PUCKTACH", will be added to the toolbar/tablet. +// Click this app to bring up the puck attachment panel. This panel contains the following fields. +// +// * Tracked Object - A drop down list of all the available pucks found. If no pucks are found this list will only have a single NONE entry. +// Closing and re-opening the app will refresh this list. +// * Model URL - A model url of the model you wish to be attached to the specified puck. +// * Position X, Y, Z - used to apply an offset between the puck and the attached model. +// * Rot X, Y, Z - used to apply euler angle offsets, in degrees, between the puck and the attached model. +// * Create Attachment - when this button is pressed a new Entity will be created at the specified puck's location. +// If a puck atttachment already exists, it will be destroyed before the new entity is created. +// * Destroy Attachmetn - destroies the entity attached to the puck. +// + +/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ +/* global Xform */ +Script.include("/~/system/libraries/Xform.js"); + +(function() { // BEGIN LOCAL_SCOPE + +var TABLET_BUTTON_NAME = "PUCKTACH"; +var HTML_URL = "https://s3.amazonaws.com/hifi-public/tony/html/puck-attach.html"; + +var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); +var tabletButton = tablet.addButton({ + text: TABLET_BUTTON_NAME, + icon: "https://s3.amazonaws.com/hifi-public/tony/icons/puck-i.svg", + activeIcon: "https://s3.amazonaws.com/hifi-public/tony/icons/puck-a.svg" +}); + +tabletButton.clicked.connect(function () { + if (shown) { + tablet.gotoHomeScreen(); + } else { + tablet.gotoWebScreen(HTML_URL); + } +}); + +var shown = false; +var attachedEntity; +var attachedObj; + +function onScreenChanged(type, url) { + if (type === "Web" && url === HTML_URL) { + tabletButton.editProperties({isActive: true}); + if (!shown) { + // hook up to event bridge + tablet.webEventReceived.connect(onWebEventReceived); + + Script.setTimeout(function () { + // send available tracked objects to the html running in the tablet. + var availableTrackedObjects = getAvailableTrackedObjects(); + tablet.emitScriptEvent(JSON.stringify(availableTrackedObjects)); + + // print("PUCK-ATTACH: availableTrackedObjects = " + JSON.stringify(availableTrackedObjects)); + }, 1000); // wait 1 sec before sending.. + } + shown = true; + } else { + tabletButton.editProperties({isActive: false}); + if (shown) { + // disconnect from event bridge + tablet.webEventReceived.disconnect(onWebEventReceived); + } + shown = false; + } +} + +tablet.screenChanged.connect(onScreenChanged); + +function indexToTrackedObjectName(index) { + return "TrackedObject" + pad(index, 2); +} + +function getAvailableTrackedObjects() { + var available = []; + var NUM_TRACKED_OBJECTS = 16; + var i; + for (i = 0; i < NUM_TRACKED_OBJECTS; i++) { + var key = indexToTrackedObjectName(i); + var pose = Controller.getPoseValue(Controller.Hardware.Vive[key]); + if (pose && pose.valid) { + available.push(i); + } + } + return available; +} + +function attach(obj) { + attachedEntity = Entities.addEntity({ + type: "Model", + name: "puck-attach-entity", + modelURL: obj.modelurl + }); + attachedObj = obj; + var localPos = {x: Number(obj.posx), y: Number(obj.posy), z: Number(obj.posz)}; + var localRot = Quat.fromVec3Degrees({x: Number(obj.rotx), y: Number(obj.roty), z: Number(obj.rotz)}); + attachedObj.localXform = new Xform(localRot, localPos); + var key = indexToTrackedObjectName(Number(attachedObj.puckno)); + attachedObj.key = key; + + // print("PUCK-ATTACH: attachedObj = " + JSON.stringify(attachedObj)); + + Script.update.connect(update); + update(); +} + +function remove() { + if (attachedEntity) { + Script.update.disconnect(update); + Entities.deleteEntity(attachedEntity); + attachedEntity = undefined; + } + attachedObj = undefined; +} + +function pad(num, size) { + var tempString = "000000000" + num; + return tempString.substr(tempString.length - size); +} + +function update() { + if (attachedEntity && attachedObj && Controller.Hardware.Vive) { + var pose = Controller.getPoseValue(Controller.Hardware.Vive[attachedObj.key]); + var avatarXform = new Xform(MyAvatar.orientation, MyAvatar.position); + var puckXform = new Xform(pose.rotation, pose.translation); + var finalXform = Xform.mul(avatarXform, Xform.mul(puckXform, attachedObj.localXform)); + if (pose && pose.valid) { + Entities.editEntity(attachedEntity, { + position: finalXform.pos, + rotation: finalXform.rot + }); + } else { + if (pose) { + print("PUCK-ATTACH: WARNING: invalid pose for " + attachedObj.key); + } else { + print("PUCK-ATTACH: WARNING: could not find key " + attachedObj.key); + } + } + } +} + +function onWebEventReceived(msg) { + var obj = {}; + try { + obj = JSON.parse(msg); + } catch (err) { + return; + } + if (obj.cmd === "attach") { + remove(); + attach(obj); + } else if (obj.cmd === "detach") { + remove(); + } +} + +Script.scriptEnding.connect(function () { + remove(); + tablet.removeButton(tabletButton); + if (shown) { + tablet.webEventReceived.disconnect(onWebEventReceived); + tablet.gotoHomeScreen(); + } + tablet.screenChanged.disconnect(onScreenChanged); +}); + +}()); // END LOCAL_SCOPE diff --git a/scripts/developer/utilities/tools/reverbTest.js b/scripts/developer/utilities/tools/reverbTest.js index a7a6bad9d7..8d83140ecd 100644 --- a/scripts/developer/utilities/tools/reverbTest.js +++ b/scripts/developer/utilities/tools/reverbTest.js @@ -35,8 +35,8 @@ var audioOptions = new AudioEffectOptions({ wetDryMix: 50, }); -AudioDevice.setReverbOptions(audioOptions); -AudioDevice.setReverb(true); +Audio.setReverbOptions(audioOptions); +Audio.setReverb(true); print("Reverb is ON."); var panel = new Panel(10, 160); @@ -66,7 +66,7 @@ var parameters = [ ] function setter(name) { - return function(value) { audioOptions[name] = value; AudioDevice.setReverbOptions(audioOptions); } + return function(value) { audioOptions[name] = value; Audio.setReverbOptions(audioOptions); } } function getter(name) { @@ -89,7 +89,7 @@ Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseRelease function scriptEnding() { panel.destroy(); - AudioDevice.setReverb(false); + Audio.setReverb(false); print("Reverb is OFF."); } Script.scriptEnding.connect(scriptEnding); diff --git a/scripts/system/assets/sounds/countdown-tick.wav b/scripts/system/assets/sounds/countdown-tick.wav new file mode 100644 index 0000000000..015e1f642e Binary files /dev/null and b/scripts/system/assets/sounds/countdown-tick.wav differ diff --git a/scripts/system/assets/sounds/finish-recording.wav b/scripts/system/assets/sounds/finish-recording.wav new file mode 100644 index 0000000000..f224049f97 Binary files /dev/null and b/scripts/system/assets/sounds/finish-recording.wav differ diff --git a/scripts/system/assets/sounds/start-recording.wav b/scripts/system/assets/sounds/start-recording.wav new file mode 100644 index 0000000000..71c69f3372 Binary files /dev/null and b/scripts/system/assets/sounds/start-recording.wav differ diff --git a/scripts/system/audio.js b/scripts/system/audio.js index cb9589ae9e..0a3471fa81 100644 --- a/scripts/system/audio.js +++ b/scripts/system/audio.js @@ -15,6 +15,7 @@ var TABLET_BUTTON_NAME = "AUDIO"; var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png"; +var AUDIO_QML_SOURCE = "../audio/Audio.qml"; var MUTE_ICONS = { icon: "icons/tablet-icons/mic-mute-i.svg", @@ -34,7 +35,6 @@ function onMuteToggled() { } } -var shouldActivateButton = false; var onAudioScreen = false; function onClicked() { @@ -44,18 +44,14 @@ function onClicked() { } else { var entity = HMD.tabletID; Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); - shouldActivateButton = true; - shouldActivateButton = true; - tablet.loadQMLSource("../audio/Audio.qml"); - onAudioScreen = true; + tablet.loadQMLSource(AUDIO_QML_SOURCE); } } function onScreenChanged(type, url) { + onAudioScreen = (type === "QML" && url === AUDIO_QML_SOURCE); // for toolbar mode: change button to active when window is first openend, false otherwise. - button.editProperties({isActive: shouldActivateButton}); - shouldActivateButton = false; - onAudioScreen = false; + button.editProperties({isActive: onAudioScreen}); } var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); diff --git a/scripts/system/controllers/leapHands.js b/scripts/system/controllers/leapHands.js deleted file mode 100644 index 1be0b1e5f6..0000000000 --- a/scripts/system/controllers/leapHands.js +++ /dev/null @@ -1,527 +0,0 @@ -// -// leapHands.js -// examples -// -// Created by David Rowe on 8 Sep 2014. -// Copyright 2014 High Fidelity, Inc. -// -// This is an example script that uses the Leap Motion to make the avatar's hands replicate the user's hand actions. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -var leftTriggerValue = 0; -var rightTriggerValue = 0; - -var LEAP_TRIGGER_START_ANGLE = 15.0; -var LEAP_TRIGGER_END_ANGLE = 40.0; - -function getLeapMotionLeftTrigger() { - //print("left trigger = " + leftTriggerValue); - return leftTriggerValue; -} -function getLeapMotionRightTrigger() { - //print("right trigger = " + rightTriggerValue); - return rightTriggerValue; -} - -var leapHands = (function () { - - var isOnHMD, - LEAP_ON_HMD_MENU_ITEM = "Leap Motion on HMD", - LEAP_OFFSET = 0.019, // Thickness of Leap Motion plus HMD clip - HMD_OFFSET = 0.070, // Eyeballs to front surface of Oculus DK2 TODO: Confirm and make depend on device and eye relief - hasHandAndWristJoints, - handToWristOffset = [], // For avatars without a wrist joint we control an estimate of a proper hand joint position - HAND_OFFSET = 0.4, // Relative distance of wrist to hand versus wrist to index finger knuckle - handAnimationStateHandlers, - handAnimationStateFunctions, - handAnimationStateProperties, - hands, - wrists, - NUM_HANDS = 2, // 0 = left; 1 = right - fingers, - NUM_FINGERS = 5, // 0 = thumb; ...; 4 = pinky - THUMB = 0, - MIDDLE_FINGER = 2, - NUM_FINGER_JOINTS = 3, // 0 = metacarpal(hand)-proximal(finger) joint; ...; 2 = intermediate-distal joint - MAX_HAND_INACTIVE_COUNT = 20, - calibrationStatus, - UNCALIBRATED = 0, - CALIBRATING = 1, - CALIBRATED = 2, - CALIBRATION_TIME = 1000, // milliseconds - avatarScale, - avatarFaceModelURL, - avatarSkeletonModelURL, - settingsTimer, - HMD_CAMERA_TO_AVATAR_ROTATION = [ - Quat.angleAxis(180.0, { x: 0, y: 0, z: 1 }), - Quat.angleAxis(-180.0, { x: 0, y: 0, z: 1 }) - ], - DESKTOP_CAMERA_TO_AVATAR_ROTATION = - Quat.multiply(Quat.angleAxis(180.0, { x: 0, y: 1, z: 0 }), Quat.angleAxis(90.0, { x: 0, y: 0, z: 1 })), - LEAP_THUMB_ROOT_ADJUST = [Quat.fromPitchYawRollDegrees(0, 0, 20), Quat.fromPitchYawRollDegrees(0, 0, -20)]; - - function printSkeletonJointNames() { - var jointNames, - i; - - print(MyAvatar.skeletonModelURL); - - print("Skeleton joint names ..."); - jointNames = MyAvatar.getJointNames(); - for (i = 0; i < jointNames.length; i += 1) { - print(i + ": " + jointNames[i]); - } - print("... skeleton joint names"); - } - - function animateLeftHand() { - var ROTATION_AND_POSITION = 0; - - return { - leftHandType: ROTATION_AND_POSITION, - leftHandPosition: hands[0].position, - leftHandRotation: hands[0].rotation - }; - } - - function animateRightHand() { - var ROTATION_AND_POSITION = 0; - - return { - rightHandType: ROTATION_AND_POSITION, - rightHandPosition: hands[1].position, - rightHandRotation: hands[1].rotation - }; - } - - function finishCalibration() { - var avatarPosition, - handPosition, - middleFingerPosition, - leapHandHeight, - h; - - if (!isOnHMD) { - if (hands[0].controller.isActive() && hands[1].controller.isActive()) { - leapHandHeight = (hands[0].controller.getAbsTranslation().y + hands[1].controller.getAbsTranslation().y) / 2.0; - } else { - calibrationStatus = UNCALIBRATED; - return; - } - } - - avatarPosition = MyAvatar.position; - - for (h = 0; h < NUM_HANDS; h += 1) { - handPosition = MyAvatar.getJointPosition(hands[h].jointName); - if (!hasHandAndWristJoints) { - middleFingerPosition = MyAvatar.getJointPosition(fingers[h][MIDDLE_FINGER][0].jointName); - handToWristOffset[h] = Vec3.multiply(Vec3.subtract(handPosition, middleFingerPosition), 1.0 - HAND_OFFSET); - } - - if (isOnHMD) { - // Offset of Leap Motion origin from physical eye position - hands[h].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET }; - } else { - hands[h].zeroPosition = { - x: handPosition.x - avatarPosition.x, - y: handPosition.y - avatarPosition.y, - z: avatarPosition.z - handPosition.z - }; - hands[h].zeroPosition = Vec3.multiplyQbyV(MyAvatar.orientation, hands[h].zeroPosition); - hands[h].zeroPosition.y = hands[h].zeroPosition.y - leapHandHeight; - } - } - - MyAvatar.clearJointData("LeftHand"); - MyAvatar.clearJointData("LeftForeArm"); - MyAvatar.clearJointData("RightHand"); - MyAvatar.clearJointData("RightForeArm"); - - calibrationStatus = CALIBRATED; - print("Leap Motion: Calibrated"); - } - - function calibrate() { - var jointNames, - i; - - calibrationStatus = CALIBRATING; - - avatarScale = MyAvatar.scale; - avatarFaceModelURL = MyAvatar.faceModelURL; - avatarSkeletonModelURL = MyAvatar.skeletonModelURL; - - // Does this skeleton have both wrist and hand joints? - hasHandAndWristJoints = false; - jointNames = MyAvatar.getJointNames(); - for (i = 0; i < jointNames.length; i += 1) { - hasHandAndWristJoints = hasHandAndWristJoints || jointNames[i].toLowerCase() === "leftwrist"; - } - - // Set avatar arms vertical, forearms horizontal, as "zero" position for calibration - MyAvatar.setJointRotation("LeftForeArm", Quat.fromPitchYawRollDegrees(0.0, 0.0, 90.0)); - MyAvatar.setJointRotation("LeftHand", Quat.fromPitchYawRollDegrees(0.0, 90.0, 0.0)); - MyAvatar.setJointRotation("RightForeArm", Quat.fromPitchYawRollDegrees(0.0, 0.0, -90.0)); - MyAvatar.setJointRotation("RightHand", Quat.fromPitchYawRollDegrees(0.0, -90.0, 0.0)); - - // Wait for arms to assume their positions before calculating - Script.setTimeout(finishCalibration, CALIBRATION_TIME); - } - - function checkCalibration() { - - if (calibrationStatus === CALIBRATED) { - return true; - } - - if (calibrationStatus !== CALIBRATING) { - calibrate(); - } - - return false; - } - - function setIsOnHMD() { - isOnHMD = Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM); - print("Leap Motion: " + (isOnHMD ? "Is on HMD" : "Is on desk")); - } - - function checkSettings() { - if (calibrationStatus > UNCALIBRATED && (MyAvatar.scale !== avatarScale - || MyAvatar.faceModelURL !== avatarFaceModelURL - || MyAvatar.skeletonModelURL !== avatarSkeletonModelURL - || Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM) !== isOnHMD)) { - print("Leap Motion: Recalibrate..."); - calibrationStatus = UNCALIBRATED; - - setIsOnHMD(); - } - } - - function setUp() { - - wrists = [ - { - jointName: "LeftWrist", - controller: Controller.createInputController("Spatial", "joint_L_wrist") - }, - { - jointName: "RightWrist", - controller: Controller.createInputController("Spatial", "joint_R_wrist") - } - ]; - - hands = [ - { - jointName: "LeftHand", - controller: Controller.createInputController("Spatial", "joint_L_hand"), - inactiveCount: 0 - }, - { - jointName: "RightHand", - controller: Controller.createInputController("Spatial", "joint_R_hand"), - inactiveCount: 0 - } - ]; - - // The Leap controller's first joint is the hand-metacarpal joint but this joint's data is not used because it's too - // dependent on the model skeleton exactly matching the Leap skeleton; using just the second and subsequent joints - // seems to work better over all. - fingers = [{}, {}]; - fingers[0] = [ - [ - { jointName: "LeftHandThumb1", controller: Controller.createInputController("Spatial", "joint_L_thumb2") }, - { jointName: "LeftHandThumb2", controller: Controller.createInputController("Spatial", "joint_L_thumb3") }, - { jointName: "LeftHandThumb3", controller: Controller.createInputController("Spatial", "joint_L_thumb4") } - ], - [ - { jointName: "LeftHandIndex1", controller: Controller.createInputController("Spatial", "joint_L_index2") }, - { jointName: "LeftHandIndex2", controller: Controller.createInputController("Spatial", "joint_L_index3") }, - { jointName: "LeftHandIndex3", controller: Controller.createInputController("Spatial", "joint_L_index4") } - ], - [ - { jointName: "LeftHandMiddle1", controller: Controller.createInputController("Spatial", "joint_L_middle2") }, - { jointName: "LeftHandMiddle2", controller: Controller.createInputController("Spatial", "joint_L_middle3") }, - { jointName: "LeftHandMiddle3", controller: Controller.createInputController("Spatial", "joint_L_middle4") } - ], - [ - { jointName: "LeftHandRing1", controller: Controller.createInputController("Spatial", "joint_L_ring2") }, - { jointName: "LeftHandRing2", controller: Controller.createInputController("Spatial", "joint_L_ring3") }, - { jointName: "LeftHandRing3", controller: Controller.createInputController("Spatial", "joint_L_ring4") } - ], - [ - { jointName: "LeftHandPinky1", controller: Controller.createInputController("Spatial", "joint_L_pinky2") }, - { jointName: "LeftHandPinky2", controller: Controller.createInputController("Spatial", "joint_L_pinky3") }, - { jointName: "LeftHandPinky3", controller: Controller.createInputController("Spatial", "joint_L_pinky4") } - ] - ]; - fingers[1] = [ - [ - { jointName: "RightHandThumb1", controller: Controller.createInputController("Spatial", "joint_R_thumb2") }, - { jointName: "RightHandThumb2", controller: Controller.createInputController("Spatial", "joint_R_thumb3") }, - { jointName: "RightHandThumb3", controller: Controller.createInputController("Spatial", "joint_R_thumb4") } - ], - [ - { jointName: "RightHandIndex1", controller: Controller.createInputController("Spatial", "joint_R_index2") }, - { jointName: "RightHandIndex2", controller: Controller.createInputController("Spatial", "joint_R_index3") }, - { jointName: "RightHandIndex3", controller: Controller.createInputController("Spatial", "joint_R_index4") } - ], - [ - { jointName: "RightHandMiddle1", controller: Controller.createInputController("Spatial", "joint_R_middle2") }, - { jointName: "RightHandMiddle2", controller: Controller.createInputController("Spatial", "joint_R_middle3") }, - { jointName: "RightHandMiddle3", controller: Controller.createInputController("Spatial", "joint_R_middle4") } - ], - [ - { jointName: "RightHandRing1", controller: Controller.createInputController("Spatial", "joint_R_ring2") }, - { jointName: "RightHandRing2", controller: Controller.createInputController("Spatial", "joint_R_ring3") }, - { jointName: "RightHandRing3", controller: Controller.createInputController("Spatial", "joint_R_ring4") } - ], - [ - { jointName: "RightHandPinky1", controller: Controller.createInputController("Spatial", "joint_R_pinky2") }, - { jointName: "RightHandPinky2", controller: Controller.createInputController("Spatial", "joint_R_pinky3") }, - { jointName: "RightHandPinky3", controller: Controller.createInputController("Spatial", "joint_R_pinky4") } - ] - ]; - - handAnimationStateHandlers = [null, null]; - handAnimationStateFunctions = [animateLeftHand, animateRightHand]; - handAnimationStateProperties = [ - ["leftHandType", "leftHandPosition", "leftHandRotation"], - ["rightHandType", "rightHandPosition", "rightHandPosition"] - ]; - - setIsOnHMD(); - - settingsTimer = Script.setInterval(checkSettings, 2000); - - calibrationStatus = UNCALIBRATED; - - { - var mapping = Controller.newMapping("LeapmotionTrigger"); - mapping.from(getLeapMotionLeftTrigger).to(Controller.Standard.LT); - mapping.from(getLeapMotionRightTrigger).to(Controller.Standard.RT); - mapping.enable(); - } - } - - function moveHands() { - var h, - i, - j, - side, - handOffset, - wristOffset, - handRotation, - locRotation, - cameraOrientation, - inverseAvatarOrientation; - - for (h = 0; h < NUM_HANDS; h += 1) { - side = h === 0 ? -1.0 : 1.0; - - if (hands[h].controller.isActive()) { - - // Calibrate if necessary. - if (!checkCalibration()) { - return; - } - - // Hand animation handlers ... - if (handAnimationStateHandlers[h] === null) { - handAnimationStateHandlers[h] = MyAvatar.addAnimationStateHandler(handAnimationStateFunctions[h], - handAnimationStateProperties[h]); - } - - // Hand position ... - handOffset = hands[h].controller.getAbsTranslation(); - handRotation = hands[h].controller.getAbsRotation(); - - if (isOnHMD) { - - // Adjust to control wrist position if "hand" joint is at wrist ... - if (!hasHandAndWristJoints) { - wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]); - handOffset = Vec3.sum(handOffset, wristOffset); - } - - // Hand offset in camera coordinates ... - handOffset = { - x: -handOffset.x, - y: -handOffset.z, - z: -handOffset.y - hands[h].zeroPosition.z - }; - - // Hand offset in world coordinates ... - cameraOrientation = Camera.getOrientation(); - handOffset = Vec3.sum(Camera.getPosition(), Vec3.multiplyQbyV(cameraOrientation, handOffset)); - - // Hand offset in avatar coordinates ... - inverseAvatarOrientation = Quat.inverse(MyAvatar.orientation); - handOffset = Vec3.subtract(handOffset, MyAvatar.position); - handOffset = Vec3.multiplyQbyV(inverseAvatarOrientation, handOffset); - handOffset.z = -handOffset.z; - handOffset.x = -handOffset.x; - - - // Hand rotation in camera coordinates ... - handRotation = { - x: -handRotation.y, - y: -handRotation.z, - z: -handRotation.x, - w: handRotation.w - }; - - // Hand rotation in avatar coordinates ... - handRotation = Quat.multiply(HMD_CAMERA_TO_AVATAR_ROTATION[h], handRotation); - cameraOrientation = { - x: cameraOrientation.z, - y: cameraOrientation.y, - z: cameraOrientation.x, - w: cameraOrientation.w - }; - cameraOrientation = Quat.multiply(cameraOrientation, Quat.inverse(MyAvatar.orientation)); - handRotation = Quat.multiply(handRotation, cameraOrientation); // Works!!! - - } else { - - // Adjust to control wrist position if "hand" joint is at wrist ... - if (!hasHandAndWristJoints) { - wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]); - handOffset = Vec3.sum(handOffset, wristOffset); - } - - // Hand offset in camera coordinates ... - handOffset = { - x: -handOffset.x, - y: hands[h].zeroPosition.y + handOffset.y, - z: hands[h].zeroPosition.z - handOffset.z - }; - - // Hand rotation in camera coordinates ... - handRotation = { - x: handRotation.z, - y: handRotation.y, - z: handRotation.x, - w: handRotation.w - }; - - // Hand rotation in avatar coordinates ... - handRotation = Quat.multiply(DESKTOP_CAMERA_TO_AVATAR_ROTATION, handRotation); - } - - // Set hand position and orientation for animation state handler ... - hands[h].position = handOffset; - hands[h].rotation = handRotation; - - // Set finger joints ... - var summed = 0; - var closeAngle = 0; - for (i = 0; i < NUM_FINGERS; i += 1) { - for (j = 0; j < NUM_FINGER_JOINTS; j += 1) { - if (fingers[h][i][j].controller !== null) { - locRotation = fingers[h][i][j].controller.getLocRotation(); - var eulers = Quat.safeEulerAngles(locRotation); - closeAngle += eulers.x; - - summed++; - - if (i === THUMB) { - locRotation = { - x: side * locRotation.y, - y: side * -locRotation.z, - z: side * -locRotation.x, - w: locRotation.w - }; - if (j === 0) { - // Adjust avatar thumb root joint rotation to make avatar hands look better - locRotation = Quat.multiply(LEAP_THUMB_ROOT_ADJUST[h], locRotation); - } - } else { - locRotation = { - x: -locRotation.x, - y: -locRotation.z, - z: -locRotation.y, - w: locRotation.w - }; - } - MyAvatar.setJointRotation(fingers[h][i][j].jointName, locRotation); - } - } - } - - hands[h].inactiveCount = 0; - if (summed > 0) { - closeAngle /= summed; - } - - var triggerValue = (-closeAngle - LEAP_TRIGGER_START_ANGLE) / (LEAP_TRIGGER_END_ANGLE - LEAP_TRIGGER_START_ANGLE); - triggerValue = Math.max(0.0, Math.min(triggerValue, 1.0)); - - if (h == 0) { - leftTriggerValue = triggerValue; - } else { - rightTriggerValue = triggerValue; - - } - - } else { - - if (hands[h].inactiveCount < MAX_HAND_INACTIVE_COUNT) { - - hands[h].inactiveCount += 1; - - if (hands[h].inactiveCount === MAX_HAND_INACTIVE_COUNT) { - if (handAnimationStateHandlers[h] !== null) { - MyAvatar.removeAnimationStateHandler(handAnimationStateHandlers[h]); - handAnimationStateHandlers[h] = null; - leftTriggerValue = 0.0; - rightTriggerValue = 0.0; - } - } - } - } - } - } - - function tearDown() { - var h, - i, - j; - - Script.clearInterval(settingsTimer); - - for (h = 0; h < NUM_HANDS; h += 1) { - Controller.releaseInputController(hands[h].controller); - Controller.releaseInputController(wrists[h].controller); - if (handAnimationStateHandlers[h] !== null) { - MyAvatar.removeAnimationStateHandler(handAnimationStateHandlers[h]); - } - for (i = 0; i < NUM_FINGERS; i += 1) { - for (j = 0; j < NUM_FINGER_JOINTS; j += 1) { - if (fingers[h][i][j].controller !== null) { - Controller.releaseInputController(fingers[h][i][j].controller); - } - } - } - } - } - - return { - printSkeletonJointNames: printSkeletonJointNames, - setUp : setUp, - moveHands : moveHands, - tearDown : tearDown - }; -}()); - - -//leapHands.printSkeletonJointNames(); - -leapHands.setUp(); -Script.update.connect(leapHands.moveHands); -Script.scriptEnding.connect(leapHands.tearDown); diff --git a/scripts/system/help.js b/scripts/system/help.js index a335b2ef9c..1265a5597b 100644 --- a/scripts/system/help.js +++ b/scripts/system/help.js @@ -40,7 +40,8 @@ } function onScreenChanged(type, url) { - onHelpScreen = false; + onHelpScreen = type === "Web" && url.startsWith("../../../html/tabletHelp.html"); + button.editProperties({ isActive: onHelpScreen }); } button.clicked.connect(onClicked); diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 4d26bcadb6..3be8143830 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -52,17 +52,11 @@ function onMessageBoxClosed(id, button) { Window.messageBoxClosed.connect(onMessageBoxClosed); -var shouldActivateButton = false; var onMarketplaceScreen = false; function showMarketplace() { UserActivityLogger.openedMarketplace(); - - shouldActivateButton = true; - tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL); - onMarketplaceScreen = true; - tablet.webEventReceived.connect(function (message) { if (message === GOTO_DIRECTORY) { @@ -122,7 +116,6 @@ function onClick() { if (onMarketplaceScreen) { // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); - onMarketplaceScreen = false; } else { var entity = HMD.tabletID; Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})}); @@ -131,10 +124,9 @@ function onClick() { } function onScreenChanged(type, url) { + onMarketplaceScreen = type === "Web" && url === MARKETPLACE_URL_INITIAL // for toolbar mode: change button to active when window is first openend, false otherwise. - marketplaceButton.editProperties({isActive: shouldActivateButton}); - shouldActivateButton = false; - onMarketplaceScreen = false; + marketplaceButton.editProperties({isActive: onMarketplaceScreen}); } marketplaceButton.clicked.connect(onClick); diff --git a/scripts/system/menu.js b/scripts/system/menu.js index 4ad5958144..c7a44d3e48 100644 --- a/scripts/system/menu.js +++ b/scripts/system/menu.js @@ -21,7 +21,6 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet- sortOrder: 3 }); - var shouldActivateButton = false; var onMenuScreen = false; function onClicked() { @@ -31,17 +30,13 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet- } else { var entity = HMD.tabletID; Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})}); - shouldActivateButton = true; tablet.gotoMenuScreen(); - onMenuScreen = true; } } function onScreenChanged(type, url) { - // for toolbar mode: change button to active when window is first openend, false otherwise. - button.editProperties({isActive: shouldActivateButton}); - shouldActivateButton = false; - onMenuScreen = false; + onMenuScreen = type === "Menu"; + button.editProperties({isActive: onMenuScreen}); } button.clicked.connect(onClicked); diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 0500c13f9b..2c81622668 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -40,7 +40,7 @@ var HOVER_TEXTURES = { var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6}; var SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29}; var HOVER_COLOR = {red: 0xD0, green: 0xD0, blue: 0xD0}; // almost white for now - +var PAL_QML_SOURCE = "../Pal.qml"; var conserveResources = true; Script.include("/~/system/libraries/controllers.js"); @@ -479,7 +479,8 @@ function populateNearbyUserList(selectData, oldAudioData) { admin: false, personalMute: !!id && Users.getPersonalMuteStatus(id), // expects proper boolean, not null ignore: !!id && Users.getIgnoreStatus(id), // ditto - isPresent: true + isPresent: true, + isReplicated: avatar.isReplicated }; if (id) { addAvatarNode(id); // No overlay for ourselves @@ -726,17 +727,14 @@ function tabletVisibilityChanged() { } var onPalScreen = false; -var shouldActivateButton = false; function onTabletButtonClicked() { if (onPalScreen) { // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); } else { - shouldActivateButton = true; - tablet.loadQMLSource("../Pal.qml"); + tablet.loadQMLSource(PAL_QML_SOURCE); tablet.tabletShownChanged.connect(tabletVisibilityChanged); - onPalScreen = true; Users.requestsDomainListData = true; populateNearbyUserList(); isWired = true; @@ -764,14 +762,13 @@ function wireEventBridge(on) { } function onTabletScreenChanged(type, url) { - wireEventBridge(shouldActivateButton); + onPalScreen = (type === "QML" && url === PAL_QML_SOURCE); + wireEventBridge(onPalScreen); // for toolbar mode: change button to active when window is first openend, false otherwise. - button.editProperties({isActive: shouldActivateButton}); - shouldActivateButton = false; - onPalScreen = false; + button.editProperties({isActive: onPalScreen}); // disable sphere overlays when not on pal screen. - if (type !== "QML" || url !== "../Pal.qml") { + if (!onPalScreen) { off(); } } diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 6321c17ded..37618253ee 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -377,18 +377,14 @@ function fillImageDataFromPrevious() { var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html"); var isInSnapshotReview = false; -var shouldActivateButton = false; function onButtonClicked() { if (isInSnapshotReview){ // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); } else { - shouldActivateButton = true; fillImageDataFromPrevious(); tablet.gotoWebScreen(SNAPSHOT_REVIEW_URL); - tablet.webEventReceived.connect(onMessage); HMD.openTablet(); - isInSnapshotReview = true; } } @@ -507,8 +503,9 @@ function takeSnapshot() { Window.takeSnapshot(false, includeAnimated, 1.91); }, SNAPSHOT_DELAY); }, FINISH_SOUND_DELAY); + UserActivityLogger.logAction("snaphshot_taken", { location: location.href }); } - + function isDomainOpen(id, callback) { print("Checking open status of domain with ID:", id); var status = false; @@ -662,11 +659,15 @@ function maybeDeleteSnapshotStories() { storyIDsToMaybeDelete = []; } function onTabletScreenChanged(type, url) { - button.editProperties({ isActive: shouldActivateButton }); - shouldActivateButton = false; - if (isInSnapshotReview) { - tablet.webEventReceived.disconnect(onMessage); - isInSnapshotReview = false; + var wasInSnapshotReview = isInSnapshotReview; + isInSnapshotReview = (type === "Web" && url === SNAPSHOT_REVIEW_URL); + button.editProperties({ isActive: isInSnapshotReview }); + if (isInSnapshotReview !== wasInSnapshotReview) { + if (isInSnapshotReview) { + tablet.webEventReceived.connect(onMessage); + } else { + tablet.webEventReceived.disconnect(onMessage); + } } } function onUsernameChanged() { diff --git a/scripts/tutorials/halfDuplex.js b/scripts/tutorials/halfDuplex.js index e1ed132233..d4a993ae06 100644 --- a/scripts/tutorials/halfDuplex.js +++ b/scripts/tutorials/halfDuplex.js @@ -20,7 +20,7 @@ var averageLoudness = 0.0; var AVERAGING_TIME = 0.9; var LOUDNESS_THRESHOLD = 100; -var HYSTERESIS_GAP = 1.41; // 3db gap +var HYSTERESIS_GAP = 1.41; // 3dB gap var MICROPHONE_DISPLAY_NAME = "Microphone"; var debug = false; @@ -54,17 +54,13 @@ Script.update.connect(function () { print("Muted!"); } isMuted = true; - if (!AudioDevice.getMuted()) { - AudioDevice.toggleMute(); - } + Audio.muted = true; } else if (isMuted && (averageLoudness < LOUDNESS_THRESHOLD)) { if (debug) { print("UnMuted!"); } isMuted = false; - if (AudioDevice.getMuted()) { - AudioDevice.toggleMute(); - } + Audio.muted = false; } }); diff --git a/server-console/src/main.js b/server-console/src/main.js index 95fb0d81b2..efa04a8512 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -334,6 +334,7 @@ function startInterface(url) { // create a new Interface instance - Interface makes sure only one is running at a time var pInterface = new Process('interface', interfacePath, argArray); + pInterface.detached = true; pInterface.start(); } @@ -892,10 +893,19 @@ function onContentLoaded() { deleteOldFiles(logPath, DELETE_LOG_FILES_OLDER_THAN_X_SECONDS, LOG_FILE_REGEX); if (dsPath && acPath) { - domainServer = new Process('domain-server', dsPath, ["--get-temp-name"], logPath); - acMonitor = new ACMonitorProcess('ac-monitor', acPath, ['-n7', - '--log-directory', logPath, - '--http-status-port', httpStatusPort], httpStatusPort, logPath); + var dsArguments = ['--get-temp-name', + '--parent-pid', process.pid]; + domainServer = new Process('domain-server', dsPath, dsArguments, logPath); + domainServer.restartOnCrash = true; + + var acArguments = ['-n7', + '--log-directory', logPath, + '--http-status-port', httpStatusPort, + '--parent-pid', process.pid]; + acMonitor = new ACMonitorProcess('ac-monitor', acPath, acArguments, + httpStatusPort, logPath); + acMonitor.restartOnCrash = true; + homeServer = new ProcessGroup('home', [domainServer, acMonitor]); logWindow = new LogWindow(acMonitor, domainServer); diff --git a/server-console/src/modules/hf-process.js b/server-console/src/modules/hf-process.js index 20b8966148..767befec7b 100644 --- a/server-console/src/modules/hf-process.js +++ b/server-console/src/modules/hf-process.js @@ -113,6 +113,10 @@ function Process(name, command, commandArgs, logDirectory) { this.logDirectory = logDirectory; this.logStdout = null; this.logStderr = null; + this.detached = false; + this.restartOnCrash = false; + this.restartCount = 0; + this.firstRestartTimestamp = Date.now(); this.state = ProcessStates.STOPPED; }; @@ -165,9 +169,10 @@ Process.prototype = extend(Process.prototype, { try { this.child = childProcess.spawn(this.command, this.commandArgs, { - detached: false, + detached: this.detached, stdio: ['ignore', logStdout, logStderr] }); + log.debug("Spawned " + this.command + " with pid " + this.child.pid); } catch (e) { log.debug("Got error starting child process for " + this.name, e); this.child = null; @@ -266,7 +271,30 @@ Process.prototype = extend(Process.prototype, { clearTimeout(this.stoppingTimeoutID); this.stoppingTimeoutID = null; } + // Grab current state before updating it. + var unexpectedShutdown = this.state != ProcessStates.STOPPING; this.updateState(ProcessStates.STOPPED); + + if (unexpectedShutdown && this.restartOnCrash) { + var MAX_RESTARTS = 10; + var MAX_RESTARTS_PERIOD = 10; // 10 min + var MSEC_PER_MIN = 1000 * 60; + var now = Date.now(); + var timeDiff = (now - this.firstRestartTimestamp) / MSEC_PER_MIN; + if (timeDiff > MAX_RESTARTS_PERIOD) { + this.firstRestartTimestamp = now; + this.restartCount = 0; + } + + if (this.restartCount < 10) { + this.restartCount++; + + log.warn("Child stopped unexpectedly, restarting."); + this.start(); + } else { + log.warn("Child stopped unexpectedly too many times, not restarting."); + } + } } }); diff --git a/tests/controllers/CMakeLists.txt b/tests/controllers/CMakeLists.txt index 3aac4db0a8..3221070837 100644 --- a/tests/controllers/CMakeLists.txt +++ b/tests/controllers/CMakeLists.txt @@ -5,6 +5,8 @@ set(TARGET_NAME controllers-test) setup_hifi_project(Script Qml) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") +setup_memory_debugger() + # link in the shared libraries link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers) @@ -16,4 +18,4 @@ if (WIN32) target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) endif() -package_libraries_for_deployment() \ No newline at end of file +package_libraries_for_deployment() diff --git a/tests/entities/CMakeLists.txt b/tests/entities/CMakeLists.txt index 448ea83956..080ae7cdd9 100644 --- a/tests/entities/CMakeLists.txt +++ b/tests/entities/CMakeLists.txt @@ -3,7 +3,7 @@ set(TARGET_NAME "entities-test") # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Network Script) - +setup_memory_debugger() set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries diff --git a/tests/gpu-test/CMakeLists.txt b/tests/gpu-test/CMakeLists.txt index c37e36b53b..d73d7a111d 100644 --- a/tests/gpu-test/CMakeLists.txt +++ b/tests/gpu-test/CMakeLists.txt @@ -2,6 +2,7 @@ set(TARGET_NAME gpu-test) AUTOSCRIBE_SHADER_LIB(gpu model render-utils) # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Quick Gui OpenGL Script Widgets) +setup_memory_debugger() set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") link_hifi_libraries(networking gl gpu gpu-gl procedural shared fbx model model-networking animation script-engine render render-utils octree image ktx) package_libraries_for_deployment() diff --git a/tests/qt59/CMakeLists.txt b/tests/qt59/CMakeLists.txt index 32cc125ecf..e0e8138a1e 100644 --- a/tests/qt59/CMakeLists.txt +++ b/tests/qt59/CMakeLists.txt @@ -1,10 +1,12 @@ set(TARGET_NAME qt59) - + if (WIN32) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049 /ignore:4217") endif() +setup_memory_debugger() + # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Gui) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") diff --git a/tests/recording/CMakeLists.txt b/tests/recording/CMakeLists.txt index 4e881fcbd9..b5b1e6a54e 100644 --- a/tests/recording/CMakeLists.txt +++ b/tests/recording/CMakeLists.txt @@ -2,6 +2,7 @@ set(TARGET_NAME recording-test) # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Test) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") +setup_memory_debugger() link_hifi_libraries(shared recording) package_libraries_for_deployment() diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index a8e4ab286c..b6989a57b7 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -5,6 +5,8 @@ if (WIN32) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049 /ignore:4217") endif() +setup_memory_debugger() + # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 52592cd202..9c4e3ae870 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -519,7 +520,7 @@ public: _entitySimulation = simpleSimulation; } - ResourceManager::init(); + DependencyManager::set(); setFlags(Qt::MSWindowsOwnDC | Qt::Window | Qt::Dialog | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint); _size = QSize(800, 600); @@ -574,7 +575,7 @@ public: DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - ResourceManager::cleanup(); + DependencyManager::get()->cleanup(); // remove the NodeList from the DependencyManager DependencyManager::destroy(); } @@ -997,7 +998,7 @@ private: QFileInfo atpPathInfo(atpPath); if (atpPathInfo.exists()) { QString atpUrl = QUrl::fromLocalFile(atpPath).toString(); - ResourceManager::setUrlPrefixOverride("atp:/", atpUrl + "/"); + DependencyManager::get()->setUrlPrefixOverride("atp:/", atpUrl + "/"); } _octree->clear(); _octree->getTree()->readFromURL(fileName); diff --git a/tests/render-texture-load/CMakeLists.txt b/tests/render-texture-load/CMakeLists.txt index 1f0c0a069a..30030914ab 100644 --- a/tests/render-texture-load/CMakeLists.txt +++ b/tests/render-texture-load/CMakeLists.txt @@ -5,6 +5,8 @@ if (WIN32) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049 /ignore:4217") endif() +setup_memory_debugger() + # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") diff --git a/tests/render-texture-load/src/main.cpp b/tests/render-texture-load/src/main.cpp index f426cd8024..67b80d9ba8 100644 --- a/tests/render-texture-load/src/main.cpp +++ b/tests/render-texture-load/src/main.cpp @@ -329,7 +329,7 @@ public: installEventFilter(this); QThreadPool::globalInstance()->setMaxThreadCount(2); QThread::currentThread()->setPriority(QThread::HighestPriority); - ResourceManager::init(); + DependencyManager::set(); setFlags(Qt::MSWindowsOwnDC | Qt::Window | Qt::Dialog | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint); _size = QSize(800, 600); _renderThread._size = _size; @@ -369,7 +369,7 @@ public: DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - ResourceManager::cleanup(); + DependencyManager::get()->cleanup(); } protected: diff --git a/tests/render-utils/CMakeLists.txt b/tests/render-utils/CMakeLists.txt index 5ec6a28b5c..4944ad2cbc 100644 --- a/tests/render-utils/CMakeLists.txt +++ b/tests/render-utils/CMakeLists.txt @@ -5,6 +5,8 @@ set(TARGET_NAME render-utils-test) setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") +setup_memory_debugger() + # link in the shared libraries link_hifi_libraries(render-utils gl gpu gpu-gl shared) target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/tests/shaders/CMakeLists.txt b/tests/shaders/CMakeLists.txt index 5b38f473e8..bab1e0dcdc 100644 --- a/tests/shaders/CMakeLists.txt +++ b/tests/shaders/CMakeLists.txt @@ -5,6 +5,8 @@ set(TARGET_NAME shaders-test) setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") +setup_memory_debugger() + # link in the shared libraries link_hifi_libraries(shared octree gl gpu gpu-gl model render fbx networking entities script-engine physics diff --git a/tools/ac-client/CMakeLists.txt b/tools/ac-client/CMakeLists.txt index 9e623b02e9..24eeadba9c 100644 --- a/tools/ac-client/CMakeLists.txt +++ b/tools/ac-client/CMakeLists.txt @@ -1,3 +1,4 @@ set(TARGET_NAME ac-client) setup_hifi_project(Core Widgets) +setup_memory_debugger() link_hifi_libraries(shared networking) diff --git a/tools/atp-get/CMakeLists.txt b/tools/atp-get/CMakeLists.txt index b1646dc023..75f92b787d 100644 --- a/tools/atp-get/CMakeLists.txt +++ b/tools/atp-get/CMakeLists.txt @@ -1,3 +1,4 @@ set(TARGET_NAME atp-get) setup_hifi_project(Core Widgets) +setup_memory_debugger() link_hifi_libraries(shared networking) diff --git a/tools/avatar-json-to-dot.js b/tools/avatar-json-to-dot.js new file mode 100644 index 0000000000..fcd75a99c1 --- /dev/null +++ b/tools/avatar-json-to-dot.js @@ -0,0 +1,27 @@ +// usage: +// node avatar-json-to-dot.js /path/to/avatar-animaton.json > out.dot +// +// Then if you have graphviz installed you can run the following command to generate a png. +// dot -Tpng out.dot > out.png + +var fs = require('fs'); +var filename = process.argv[2]; + +function dumpNodes(node) { + node.children.forEach(function (child) { + console.log(' ' + node.id + ' -> ' + child.id + ';'); + dumpNodes(child); + }); +} + +fs.readFile(filename, 'utf8', function (err, data) { + if (err) { + console.log('error opening ' + filename + ', err = ' + err); + } else { + var graph = JSON.parse(data); + console.log('digraph graphname {'); + console.log(' rankdir = "LR";'); + dumpNodes(graph.root); + console.log('}'); + } +}); diff --git a/tools/ice-client/CMakeLists.txt b/tools/ice-client/CMakeLists.txt index a80145974c..ae42d79f7e 100644 --- a/tools/ice-client/CMakeLists.txt +++ b/tools/ice-client/CMakeLists.txt @@ -1,3 +1,4 @@ set(TARGET_NAME ice-client) setup_hifi_project(Core Widgets) +setup_memory_debugger() link_hifi_libraries(shared networking) diff --git a/tools/skeleton-dump/CMakeLists.txt b/tools/skeleton-dump/CMakeLists.txt index 04d450d9c2..bb2fe24f51 100644 --- a/tools/skeleton-dump/CMakeLists.txt +++ b/tools/skeleton-dump/CMakeLists.txt @@ -1,4 +1,5 @@ set(TARGET_NAME skeleton-dump) setup_hifi_project(Core Widgets) +setup_memory_debugger() link_hifi_libraries(shared fbx model gpu gl animation) diff --git a/tools/vhacd-util/CMakeLists.txt b/tools/vhacd-util/CMakeLists.txt index 810d13ffd7..c28aa9efa4 100644 --- a/tools/vhacd-util/CMakeLists.txt +++ b/tools/vhacd-util/CMakeLists.txt @@ -8,6 +8,8 @@ find_package(VHACD REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${VHACD_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${VHACD_LIBRARIES}) +setup_memory_debugger() + if (UNIX AND NOT APPLE) include(FindOpenMP) if(OPENMP_FOUND) diff --git a/unpublishedScripts/marketplace/doppleganger-attachments/app-doppleganger-attachments.js b/unpublishedScripts/marketplace/doppleganger-attachments/app-doppleganger-attachments.js new file mode 100644 index 0000000000..4617cf47b6 --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-attachments/app-doppleganger-attachments.js @@ -0,0 +1,134 @@ +// doppleganger-app.js +// +// Created by Timothy Dedischew on 04/21/2017. +// Copyright 2017 High Fidelity, Inc. +// +// This Client script creates an instance of a Doppleganger that can be toggled on/off via tablet button. +// (for more info see doppleganger.js) +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var require = Script.require; + +var WANT_DEBUG = false; + +var DopplegangerClass = require('./doppleganger.js'), + DopplegangerAttachments = require('./doppleganger-attachments.js'), + modelHelper = require('./model-helper.js').modelHelper; + +var tablet = Tablet.getTablet('com.highfidelity.interface.tablet.system'), + button = tablet.addButton({ + icon: Script.resolvePath('./doppleganger-i.svg'), + activeIcon: Script.resolvePath('./doppleganger-a.svg'), + text: 'MIRROR' + }); + +Script.scriptEnding.connect(function() { + tablet.removeButton(button); + button = null; +}); + +var doppleganger = new DopplegangerClass({ + avatar: MyAvatar, + mirrored: false, + autoUpdate: true, + type: 'overlay' +}); + +// add support for displaying regular (non-soft) attachments on the doppleganger +{ + var RECHECK_ATTACHMENT_MS = 1000; + var dopplegangerAttachments = new DopplegangerAttachments(doppleganger), + attachmentInterval = null, + lastHash = dopplegangerAttachments.getAttachmentsHash(); + + // monitor for attachment changes, but only when the doppleganger is active + doppleganger.activeChanged.connect(function(active, reason) { + if (attachmentInterval) { + Script.clearInterval(attachmentInterval); + } + if (active) { + attachmentInterval = Script.setInterval(checkAttachmentsHash, RECHECK_ATTACHMENT_MS); + } else { + attachmentInterval = null; + } + }); + function checkAttachmentsHash() { + var currentHash = dopplegangerAttachments.getAttachmentsHash(); + if (currentHash !== lastHash) { + lastHash = currentHash; + debugPrint('app-doppleganger | detect attachment change'); + dopplegangerAttachments.refreshAttachments(); + } + } +} + +// hide the doppleganger if this client script is unloaded +Script.scriptEnding.connect(doppleganger, 'stop'); + +// hide the doppleganger if the user switches domains (which might place them arbitrarily far away in world space) +function onDomainChanged() { + if (doppleganger.active) { + doppleganger.stop('domain_changed'); + } +} +Window.domainChanged.connect(onDomainChanged); +Window.domainConnectionRefused.connect(onDomainChanged); +Script.scriptEnding.connect(function() { + Window.domainChanged.disconnect(onDomainChanged); + Window.domainConnectionRefused.disconnect(onDomainChanged); +}); + +// toggle on/off via tablet button +button.clicked.connect(doppleganger, 'toggle'); + +// highlight tablet button based on current doppleganger state +doppleganger.activeChanged.connect(function(active, reason) { + if (button) { + button.editProperties({ isActive: active }); + debugPrint('doppleganger.activeChanged', active, reason); + } +}); + +// alert the user if there was an error applying their skeletonModelURL +doppleganger.modelLoaded.connect(function(error, result) { + if (doppleganger.active && error) { + Window.alert('doppleganger | ' + error + '\n' + doppleganger.skeletonModelURL); + } +}); + +// ---------------------------------------------------------------------------- + +// add debug indicators, but only if the user has configured the settings value +if (Settings.getValue('debug.doppleganger', false)) { + WANT_DEBUG = true; + DopplegangerClass.addDebugControls(doppleganger); +} + +function debugPrint() { + if (WANT_DEBUG) { + print('app-doppleganger | ' + [].slice.call(arguments).join(' ')); + } +} +// ---------------------------------------------------------------------------- + +UserActivityLogger.logAction('doppleganger_app_load'); +doppleganger.activeChanged.connect(function(active, reason) { + if (active) { + UserActivityLogger.logAction('doppleganger_enable'); + } else { + if (reason === 'stop') { + // user intentionally toggled the doppleganger + UserActivityLogger.logAction('doppleganger_disable'); + } else { + debugPrint('doppleganger stopped:', reason); + UserActivityLogger.logAction('doppleganger_autodisable', { reason: reason }); + } + } +}); +dopplegangerAttachments.attachmentsUpdated.connect(function(attachments) { + UserActivityLogger.logAction('doppleganger_attachments', { count: attachments.length }); +}); + diff --git a/interface/resources/icons/tablet-icons/doppleganger-a.svg b/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-a.svg similarity index 100% rename from interface/resources/icons/tablet-icons/doppleganger-a.svg rename to unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-a.svg diff --git a/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-attachments.js b/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-attachments.js new file mode 100644 index 0000000000..a3b3873c2d --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-attachments.js @@ -0,0 +1,238 @@ +"use strict"; +/* eslint-env commonjs */ +/* eslint-disable comma-dangle */ + +module.exports = DopplegangerAttachments; + +DopplegangerAttachments.version = '0.0.0'; +DopplegangerAttachments.WANT_DEBUG = false; + +var _modelHelper = require('./model-helper.js'), + modelHelper = _modelHelper.modelHelper, + ModelReadyWatcher = _modelHelper.ModelReadyWatcher, + utils = require('./utils.js'); + +function log() { + print('doppleganger-attachments | ' + [].slice.call(arguments).join(' ')); +} + +function debugPrint() { + DopplegangerAttachments.WANT_DEBUG && log.apply(this, arguments); +} + +function DopplegangerAttachments(doppleganger, options) { + utils.assign(this, { + _options: options, + doppleganger: doppleganger, + attachments: undefined, + manualJointSync: true, + attachmentsUpdated: utils.signal(function attachmentsUpdated(currentAttachments, previousAttachments){}), + }); + this._initialize(); + debugPrint('DopplegangerAttachments...', JSON.stringify(options)); +} +DopplegangerAttachments.prototype = { + // "hash" the current attachments (so that changes can be detected) + getAttachmentsHash: function() { + return JSON.stringify(this.doppleganger.avatar.getAttachmentsVariant()); + }, + // create a pure Object copy of the current native attachments variant + _cloneAttachmentsVariant: function() { + return JSON.parse(JSON.stringify(this.doppleganger.avatar.getAttachmentsVariant())); + }, + // fetch and resolve attachments to include jointIndex and other relevant $metadata + _getResolvedAttachments: function() { + var attachments = this._cloneAttachmentsVariant(), + objectID = this.doppleganger.objectID; + function toString() { + return '[attachment #' + this.$index + ' ' + this.$path + ' @ ' + this.jointName + '{' + this.$jointIndex + '}]'; + } + return attachments.map(function(attachment, i) { + var jointIndex = modelHelper.getJointIndex(objectID, attachment.jointName), + path = (attachment.modelUrl+'').split(/[?#]/)[0].split('/').slice(-3).join('/'); + return Object.defineProperties(attachment, { + $hash: { value: JSON.stringify(attachment) }, + $index: { value: i }, + $jointIndex: { value: jointIndex }, + $path: { value: path }, + toString: { value: toString }, + }); + }); + }, + // compare before / after attachment sets to determine which ones need to be (re)created + refreshAttachments: function() { + var before = this.attachments || [], + beforeIndex = before.reduce(function(out, att, index) { + out[att.$hash] = index; return out; + }, {}); + var after = this._getResolvedAttachments(), + afterIndex = after.reduce(function(out, att, index) { + out[att.$hash] = index; return out; + }, {}); + + Object.keys(beforeIndex).concat(Object.keys(afterIndex)).forEach(function(hash) { + if (hash in beforeIndex && hash in afterIndex) { + // print('reusing previous attachment', hash); + after[afterIndex[hash]] = before[beforeIndex[hash]]; + } else if (!(hash in afterIndex)) { + var attachment = before[beforeIndex[hash]]; + attachment.properties && attachment.properties.objectID && + modelHelper.deleteObject(attachment.properties.objectID); + delete attachment.properties; + } + }); + this.attachments = after; + this._createAttachmentObjects(); + this.attachmentsUpdated(after, before); + }, + _createAttachmentObjects: function() { + try { + var attachments = this.attachments, + parentID = this.doppleganger.objectID, + jointNames = this.doppleganger.jointNames, + properties = modelHelper.getProperties(this.doppleganger.objectID); + + debugPrint('DopplegangerAttachments..._createAttachmentObjects', JSON.stringify({ + type: properties.type, + attachments: attachments.length, + parentID: parentID, + jointNames: jointNames.join(' | '), + },0,2)); + return attachments.map(utils.bind(this, function(attachment, i) { + var type = modelHelper.type(attachment.properties && attachment.properties.objectID); + if (type === 'overlay') { + debugPrint('skipping already-provisioned attachment object', type, attachment.properties && attachment.properties.name); + return attachment; + } + var jointIndex = attachment.$jointIndex, // jointNames.indexOf(attachment.jointName), + scale = this.doppleganger.avatar.scale * (attachment.scale||1.0); + + attachment.properties = utils.assign({ + name: attachment.toString(), + type: properties.type, + modelURL: attachment.modelUrl, + scale: scale, + dimensions: modelHelper.type(parentID) === 'entity' ? + Vec3.multiply(attachment.scale||1.0, Vec3.ONE) : undefined, + visible: false, + collisionless: true, + dynamic: false, + shapeType: 'none', + lifetime: 60, + grabbable: true, + }, !this.manualJointSync && { + parentID: parentID, + parentJointIndex: jointIndex, + }); + var objectID = attachment.properties.objectID = modelHelper.addObject(attachment.properties); + attachment._resource = ModelCache.prefetch(attachment.properties.modelURL); + attachment._modelReadier = new ModelReadyWatcher( { + resource: attachment._resource, + objectID: objectID, + }); + this.doppleganger.activeChanged.connect(attachment._modelReadier, '_stop'); + + attachment._modelReadier.modelReady.connect(this, function(err, result) { + if (err) { + log('>>>>> modelReady ERROR <<<<<: ' + err, attachment.modelUrl); + modelHelper.deleteObject(objectID); + return objectID = null; + } + debugPrint('attachment model ('+modelHelper.type(result.objectID)+') is ready; # joints ==', + result.jointNames && result.jointNames.length, result.naturalDimensions, result.objectID); + var properties = modelHelper.getProperties(result.objectID), + naturalDimensions = attachment.properties.naturalDimensions = properties.naturalDimensions; + modelHelper.editObject(result.objectID, { + dimensions: naturalDimensions ? Vec3.multiply(attachment.scale, naturalDimensions) : undefined, + }); + this.onJointsUpdated(parentID); // trigger once to initialize position/rotation + // give time for model overlay to "settle", then make it visible + Script.setTimeout(utils.bind(this, function() { + modelHelper.editObject(result.objectID, { + visible: true, + }); + attachment._loaded = true; + }), 100); + }); + return attachment; + })); + } catch (e) { + log('_createAttachmentObjects ERROR:', e.stack || e, e.fileName, e.lineNumber); + } + }, + + _removeAttachmentObjects: function() { + if (this.attachments) { + this.attachments.forEach(function(attachment) { + if (attachment.properties) { + if (attachment.properties.objectID) { + modelHelper.deleteObject(attachment.properties.objectID); + } + delete attachment.properties.objectID; + } + }); + delete this.attachments; + } + }, + + onJointsUpdated: function onJointsUpdated(objectID) { + var jointOrientations = modelHelper.getJointOrientations(objectID), + jointPositions = modelHelper.getJointPositions(objectID), + parentID = objectID, + avatarScale = this.doppleganger.scale, + manualJointSync = this.manualJointSync; + + if (!this.attachments) { + this.refreshAttachments(); + } + var updatedObjects = this.attachments.reduce(function(updates, attachment, i) { + if (!attachment.properties || !attachment._loaded) { + return updates; + } + var objectID = attachment.properties.objectID, + jointIndex = attachment.$jointIndex, + jointOrientation = jointOrientations[jointIndex], + jointPosition = jointPositions[jointIndex]; + + var translation = Vec3.multiply(avatarScale, attachment.translation), + rotation = Quat.fromVec3Degrees(attachment.rotation), + localPosition = Vec3.multiplyQbyV(jointOrientation, translation), + localRotation = rotation; + + updates[objectID] = manualJointSync ? { + visible: true, + position: Vec3.sum(jointPosition, localPosition), + rotation: Quat.multiply(jointOrientation, localRotation), + scale: avatarScale * attachment.scale, + } : { + visible: true, + parentID: parentID, + parentJointIndex: jointIndex, + localRotation: localRotation, + localPosition: localPosition, + scale: attachment.scale, + }; + onJointsUpdated[objectID] = updates[objectID]; + return updates; + }, {}); + modelHelper.editObjects(updatedObjects); + }, + + _initialize: function() { + var doppleganger = this.doppleganger; + if ('$attachmentControls' in doppleganger) { + throw new Error('only one set of debug controls can be added per doppleganger'); + } + doppleganger.$attachmentControls = this; + doppleganger.activeChanged.connect(this, function(active) { + if (active) { + doppleganger.jointsUpdated.connect(this, 'onJointsUpdated'); + } else { + doppleganger.jointsUpdated.disconnect(this, 'onJointsUpdated'); + this._removeAttachmentObjects(); + } + }); + + Script.scriptEnding.connect(this, '_removeAttachmentObjects'); + }, +}; diff --git a/interface/resources/icons/tablet-icons/doppleganger-i.svg b/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-i.svg similarity index 100% rename from interface/resources/icons/tablet-icons/doppleganger-i.svg rename to unpublishedScripts/marketplace/doppleganger-attachments/doppleganger-i.svg diff --git a/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger.js b/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger.js new file mode 100644 index 0000000000..bebd36df45 --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-attachments/doppleganger.js @@ -0,0 +1,515 @@ +"use strict"; + +// doppleganger.js +// +// Created by Timothy Dedischew on 04/21/2017. +// Copyright 2017 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 +// + +/* eslint-env commonjs */ +// @module doppleganger +// +// This module contains the `Doppleganger` class implementation for creating an inspectable replica of +// an Avatar (as a model directly in front of and facing them). Joint positions and rotations are copied +// over in an update thread, so that the model automatically mirrors the Avatar's joint movements. +// An Avatar can then for example walk around "themselves" and examine from the back, etc. +// +// This should be helpful for inspecting your own look and debugging avatars, etc. +// +// The doppleganger is created as an overlay so that others do not see it -- and this also allows for the +// highest possible update rate when keeping joint data in sync. + +module.exports = Doppleganger; + +var _modelHelper = require('./model-helper.js'), + modelHelper = _modelHelper.modelHelper, + ModelReadyWatcher = _modelHelper.ModelReadyWatcher; + +// @property {bool} - toggle verbose debug logging on/off +Doppleganger.WANT_DEBUG = false; + +// @property {bool} - when set true, Script.update will be used instead of setInterval for syncing joint data +Doppleganger.USE_SCRIPT_UPDATE = false; + +// @property {int} - the frame rate to target when using setInterval for joint updates +Doppleganger.TARGET_FPS = 60; + +// @class Doppleganger - Creates a new instance of a Doppleganger. +// @param {Avatar} [options.avatar=MyAvatar] - Avatar used to retrieve position and joint data. +// @param {bool} [options.mirrored=true] - Apply "symmetric mirroring" of Left/Right joints. +// @param {bool} [options.autoUpdate=true] - Automatically sync joint data. +function Doppleganger(options) { + this.options = options = options || {}; + this.avatar = options.avatar || MyAvatar; + this.mirrored = 'mirrored' in options ? options.mirrored : true; + this.autoUpdate = 'autoUpdate' in options ? options.autoUpdate : true; + + // @public + this.active = false; // whether doppleganger is currently being displayed/updated + this.objectID = null; // current doppleganger's Overlay or Entity id + this.frame = 0; // current joint update frame + + // @signal - emitted when .active state changes + this.activeChanged = signal(function(active, reason) {}); + // @signal - emitted once model is either loaded or errors out + this.modelLoaded = signal(function(error, result){}); + // @signal - emitted each time the model's joint data has been synchronized + this.jointsUpdated = signal(function(objectID){}); +} + +Doppleganger.prototype = { + // @public @method - toggles doppleganger on/off + toggle: function() { + if (this.active) { + debugPrint('toggling off'); + this.stop(); + } else { + debugPrint('toggling on'); + this.start(); + } + return this.active; + }, + + // @public @method - synchronize the joint data between Avatar / doppleganger + update: function() { + this.frame++; + try { + if (!this.objectID) { + throw new Error('!this.objectID'); + } + + if (this.avatar.skeletonModelURL !== this.skeletonModelURL) { + return this.stop('avatar_changed'); + } + + var rotations = this.avatar.getJointRotations(); + var translations = this.avatar.getJointTranslations(); + var size = rotations.length; + + // note: this mismatch can happen when the avatar's model is actively changing + if (size !== translations.length || + (this.jointStateCount && size !== this.jointStateCount)) { + debugPrint('mismatched joint counts (avatar model likely changed)', size, translations.length, this.jointStateCount); + this.stop('avatar_changed_joints'); + return; + } + this.jointStateCount = size; + + if (this.mirrored) { + var mirroredIndexes = this.mirroredIndexes; + var outRotations = new Array(size); + var outTranslations = new Array(size); + for (var i=0; i < size; i++) { + var index = mirroredIndexes[i]; + if (index < 0 || index === false) { + index = i; + } + var rot = rotations[index]; + var trans = translations[index]; + trans.x *= -1; + rot.y *= -1; + rot.z *= -1; + outRotations[i] = rot; + outTranslations[i] = trans; + } + rotations = outRotations; + translations = outTranslations; + } + modelHelper.editObject(this.objectID, { + jointRotations: rotations, + jointTranslations: translations + }); + this.jointsUpdated(this.objectID); + } catch (e) { + log('.update error: '+ e, index, e.stack); + this.stop('update_error'); + throw e; + } + }, + + // @public @method - show the doppleganger (and start the update thread, if options.autoUpdate was specified). + // @param {vec3} [options.position=(in front of avatar)] - starting position + // @param {quat} [options.orientation=avatar.orientation] - starting orientation + start: function(options) { + options = assign(this.options, options); + if (this.objectID) { + log('start() called but object model already exists', this.objectID); + return; + } + var avatar = this.avatar; + if (!avatar.jointNames.length) { + return this.stop('joints_unavailable'); + } + + this.frame = 0; + var localPosition = Vec3.multiply(2, Quat.getForward(avatar.orientation)); + this.position = options.position || Vec3.sum(avatar.position, localPosition); + this.orientation = options.orientation || avatar.orientation; + this.skeletonModelURL = avatar.skeletonModelURL; + this.scale = avatar.scale || 1.0; + this.jointStateCount = 0; + this.jointNames = avatar.jointNames; + this.type = options.type || 'overlay'; + this.mirroredNames = modelHelper.deriveMirroredJointNames(this.jointNames); + this.mirroredIndexes = this.mirroredNames.map(function(name) { + return name ? avatar.getJointIndex(name) : false; + }); + + this.objectID = modelHelper.addObject({ + type: this.type === 'overlay' ? 'model' : 'Model', + modelURL: this.skeletonModelURL, + position: this.position, + rotation: this.orientation, + scale: this.scale + }); + Script.scriptEnding.connect(this, function() { + modelHelper.deleteObject(this.objectID); + }); + debugPrint('doppleganger created; objectID =', this.objectID); + + // trigger clean up (and stop updates) if the object gets deleted + this.onObjectDeleted = function(uuid) { + if (uuid === this.objectID) { + log('onObjectDeleted', uuid); + this.stop('object_deleted'); + } + }; + modelHelper.objectDeleted.connect(this, 'onObjectDeleted'); + + if ('onLoadComplete' in avatar) { + // stop the current doppleganger if Avatar loads a different model URL + this.onLoadComplete = function() { + if (avatar.skeletonModelURL !== this.skeletonModelURL) { + this.stop('avatar_changed_load'); + } + }; + avatar.onLoadComplete.connect(this, 'onLoadComplete'); + } + + this.onModelLoaded = function(error, result) { + if (error) { + return this.stop(error); + } + debugPrint('model ('+modelHelper.type(this.objectID)+')' + ' is ready; # joints == ' + result.jointNames.length); + var naturalDimensions = modelHelper.getProperties(this.objectID, ['naturalDimensions']).naturalDimensions; + debugPrint('naturalDimensions:', JSON.stringify(naturalDimensions)); + var props = { visible: true }; + if (naturalDimensions) { + props.dimensions = Vec3.multiply(this.scale, naturalDimensions); + } + debugPrint('scaledDimensions:', this.scale, JSON.stringify(props.dimensions)); + modelHelper.editObject(this.objectID, props); + if (!options.position) { + this.syncVerticalPosition(); + } + if (this.autoUpdate) { + this._createUpdateThread(); + } + }; + + this._resource = ModelCache.prefetch(this.skeletonModelURL); + this._modelReadier = new ModelReadyWatcher({ + resource: this._resource, + objectID: this.objectID + }); + this._modelReadier.modelReady.connect(this, 'onModelLoaded'); + this.activeChanged(this.active = true, 'start'); + }, + + // @public @method - hide the doppleganger + // @param {String} [reason=stop] - the reason stop was called + stop: function(reason) { + reason = reason || 'stop'; + if (this.onUpdate) { + Script.update.disconnect(this, 'onUpdate'); + delete this.onUpdate; + } + if (this._interval) { + Script.clearInterval(this._interval); + this._interval = undefined; + } + if (this.onObjectDeleted) { + modelHelper.objectDeleted.disconnect(this, 'onObjectDeleted'); + delete this.onObjectDeleted; + } + if (this.onLoadComplete) { + this.avatar.onLoadComplete.disconnect(this, 'onLoadComplete'); + delete this.onLoadComplete; + } + if (this.onModelLoaded) { + this._modelReadier && this._modelReadier.modelReady.disconnect(this, 'onModelLoaded'); + this._modelReadier = this.onModelLoaded = undefined; + } + if (this.objectID) { + modelHelper.deleteObject(this.objectID); + this.objectID = undefined; + } + if (this.active) { + this.activeChanged(this.active = false, reason); + } else if (reason) { + debugPrint('already stopped so not triggering another activeChanged; latest reason was:', reason); + } + }, + // @public @method - Reposition the doppleganger so it sees "eye to eye" with the Avatar. + // @param {String} [byJointName=Hips] - the reference joint used to align the Doppleganger and Avatar + syncVerticalPosition: function(byJointName) { + byJointName = byJointName || 'Hips'; + var positions = modelHelper.getJointPositions(this.objectID), + properties = modelHelper.getProperties(this.objectID), + dopplePosition = properties.position, + doppleJointIndex = modelHelper.getJointIndex(this.objectID, byJointName),// names.indexOf(byJointName), + doppleJointPosition = positions[doppleJointIndex]; + + debugPrint('........... doppleJointPosition', JSON.stringify({ + byJointName: byJointName, + dopplePosition: dopplePosition, + doppleJointIndex: doppleJointIndex, + doppleJointPosition: doppleJointPosition, + properties: properties.type, + positions: positions[0] + },0,2)); + var avatarPosition = this.avatar.position, + avatarJointIndex = this.avatar.getJointIndex(byJointName), + avatarJointPosition = this.avatar.getJointPosition(avatarJointIndex); + + var offset = (avatarJointPosition.y - doppleJointPosition.y); + debugPrint('adjusting for offset', offset); + if (properties.type === 'model') { + dopplePosition.y = avatarPosition.y + offset; + } else { + dopplePosition.y = avatarPosition.y - offset; + } + + this.position = dopplePosition; + modelHelper.editObject(this.objectID, { position: this.position }); + }, + + // @private @method - creates the update thread to synchronize joint data + _createUpdateThread: function() { + if (Doppleganger.USE_SCRIPT_UPDATE) { + debugPrint('creating Script.update thread'); + this.onUpdate = this.update; + Script.update.connect(this, 'onUpdate'); + } else { + debugPrint('creating Script.setInterval thread @ ~', Doppleganger.TARGET_FPS +'fps'); + var timeout = 1000 / Doppleganger.TARGET_FPS; + this._interval = Script.setInterval(bind(this, 'update'), timeout); + } + } + +}; + +// @function - bind a function to a `this` context +// @param {Object} - the `this` context +// @param {Function|String} - function or method name +function bind(thiz, method) { + method = thiz[method] || method; + return function() { + return method.apply(thiz, arguments); + }; +} + +// @function - Qt signal polyfill +function signal(template) { + var callbacks = []; + return Object.defineProperties(function() { + var args = [].slice.call(arguments); + callbacks.forEach(function(obj) { + obj.handler.apply(obj.scope, args); + }); + }, { + connect: { value: function(scope, handler) { + var callback = {scope: scope, handler: scope[handler] || handler || scope}; + if (!callback.handler || !callback.handler.apply) { + throw new Error('invalid arguments to connect:' + [template, scope, handler]); + } + callbacks.push({scope: scope, handler: scope[handler] || handler || scope}); + }}, + disconnect: { value: function(scope, handler) { + var match = {scope: scope, handler: scope[handler] || handler || scope}; + callbacks = callbacks.filter(function(obj) { + return !(obj.scope === match.scope && obj.handler === match.handler); + }); + }} + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill +/* eslint-disable */ +function assign(target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; +} +/* eslint-enable */ +// //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill + +// @function - debug logging +function log() { + print('doppleganger | ' + [].slice.call(arguments).join(' ')); +} + +function debugPrint() { + Doppleganger.WANT_DEBUG && log.apply(this, arguments); +} + +// -- ADVANCED DEBUGGING -- +// @function - Add debug joint indicators / extra debugging info. +// @param {Doppleganger} - existing Doppleganger instance to add controls to +// +// @note: +// * rightclick toggles mirror mode on/off +// * shift-rightclick toggles the debug indicators on/off +// * clicking on an indicator displays the joint name and mirrored joint name in the debug log. +// +// Example use: +// var doppleganger = new Doppleganger(); +// Doppleganger.addDebugControls(doppleganger); +Doppleganger.addDebugControls = function(doppleganger) { + DebugControls.COLOR_DEFAULT = { red: 255, blue: 255, green: 255 }; + DebugControls.COLOR_SELECTED = { red: 0, blue: 255, green: 0 }; + + function DebugControls() { + this.enableIndicators = true; + this.selectedJointName = null; + this.debugOverlayIDs = undefined; + this.jointSelected = signal(function(result) {}); + } + DebugControls.prototype = { + start: function() { + if (!this.onMousePressEvent) { + this.onMousePressEvent = this._onMousePressEvent; + Controller.mousePressEvent.connect(this, 'onMousePressEvent'); + } + }, + + stop: function() { + this.removeIndicators(); + if (this.onMousePressEvent) { + Controller.mousePressEvent.disconnect(this, 'onMousePressEvent'); + delete this.onMousePressEvent; + } + }, + + createIndicators: function(jointNames) { + this.jointNames = jointNames; + return jointNames.map(function(name, i) { + return Overlays.addOverlay('shape', { + shape: 'Icosahedron', + scale: 0.1, + solid: false, + alpha: 0.5 + }); + }); + }, + + removeIndicators: function() { + if (this.debugOverlayIDs) { + this.debugOverlayIDs.forEach(Overlays.deleteOverlay); + this.debugOverlayIDs = undefined; + } + }, + + onJointsUpdated: function(overlayID) { + if (!this.enableIndicators) { + return; + } + var jointNames = Overlays.getProperty(overlayID, 'jointNames'), + jointOrientations = Overlays.getProperty(overlayID, 'jointOrientations'), + jointPositions = Overlays.getProperty(overlayID, 'jointPositions'), + selectedIndex = jointNames.indexOf(this.selectedJointName); + + if (!this.debugOverlayIDs) { + this.debugOverlayIDs = this.createIndicators(jointNames); + } + + // batch all updates into a single call (using the editOverlays({ id: {props...}, ... }) API) + var updatedOverlays = this.debugOverlayIDs.reduce(function(updates, id, i) { + updates[id] = { + position: jointPositions[i], + rotation: jointOrientations[i], + color: i === selectedIndex ? DebugControls.COLOR_SELECTED : DebugControls.COLOR_DEFAULT, + solid: i === selectedIndex + }; + return updates; + }, {}); + Overlays.editOverlays(updatedOverlays); + }, + + _onMousePressEvent: function(evt) { + if (!evt.isLeftButton || !this.enableIndicators || !this.debugOverlayIDs) { + return; + } + var ray = Camera.computePickRay(evt.x, evt.y), + hit = Overlays.findRayIntersection(ray, true, this.debugOverlayIDs); + + hit.jointIndex = this.debugOverlayIDs.indexOf(hit.overlayID); + hit.jointName = this.jointNames[hit.jointIndex]; + this.jointSelected(hit); + } + }; + + if ('$debugControls' in doppleganger) { + throw new Error('only one set of debug controls can be added per doppleganger'); + } + var debugControls = new DebugControls(); + doppleganger.$debugControls = debugControls; + + function onMousePressEvent(evt) { + if (evt.isRightButton) { + if (evt.isShifted) { + debugControls.enableIndicators = !debugControls.enableIndicators; + if (!debugControls.enableIndicators) { + debugControls.removeIndicators(); + } + } else { + doppleganger.mirrored = !doppleganger.mirrored; + } + } + } + + doppleganger.activeChanged.connect(function(active) { + if (active) { + debugControls.start(); + doppleganger.jointsUpdated.connect(debugControls, 'onJointsUpdated'); + Controller.mousePressEvent.connect(onMousePressEvent); + } else { + Controller.mousePressEvent.disconnect(onMousePressEvent); + doppleganger.jointsUpdated.disconnect(debugControls, 'onJointsUpdated'); + debugControls.stop(); + } + }); + + debugControls.jointSelected.connect(function(hit) { + debugControls.selectedJointName = hit.jointName; + if (hit.jointIndex < 0) { + return; + } + hit.mirroredJointName = modelHelper.deriveMirroredJointNames([hit.jointName])[0]; + log('selected joint:', JSON.stringify(hit, 0, 2)); + }); + + Script.scriptEnding.connect(debugControls, 'removeIndicators'); + + return doppleganger; +}; diff --git a/unpublishedScripts/marketplace/doppleganger-attachments/model-helper.js b/unpublishedScripts/marketplace/doppleganger-attachments/model-helper.js new file mode 100644 index 0000000000..2dda2c12ec --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-attachments/model-helper.js @@ -0,0 +1,325 @@ +// model-helper.js +// +// Created by Timothy Dedischew on 06/01/2017. +// Copyright 2017 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 +// + +/* eslint-env commonjs */ +// @module model-helper +// +// This module provides ModelReadyWatcher (a helper class for knowing when a model becomes usable inworld) and +// also initial plumbing helpers to eliminate unnecessary API differences when working with Model Overlays and +// Model Entities at a high-level from scripting. + +var utils = require('./utils.js'), + assert = utils.assert; + +module.exports = { + version: '0.0.0', + ModelReadyWatcher: ModelReadyWatcher +}; + +var _objectDeleted = utils.signal(function objectDeleted(objectID){}); +// proxy for _objectDeleted that only binds deletion tracking if script actually connects to the unified signal +var objectDeleted = utils.assign(function objectDeleted(objectID){}, { + connect: function() { + Overlays.overlayDeleted.connect(_objectDeleted); + // Entities.deletingEntity.connect(objectDeleted); + Script.scriptEnding.connect(function() { + Overlays.overlayDeleted.disconnect(_objectDeleted); + // Entities.deletingEntity.disconnect(objectDeleted); + }); + // hereafter _objectDeleted.connect will be used instead + this.connect = utils.bind(_objectDeleted, 'connect'); + return this.connect.apply(this, arguments); + }, + disconnect: utils.bind(_objectDeleted, 'disconnect') +}); + +var modelHelper = module.exports.modelHelper = { + // Entity <-> Overlay property translations + _entityFromOverlay: { + modelURL: function url() { + return this.url; + }, + dimensions: function dimensions() { + return Vec3.multiply(this.scale, this.naturalDimensions); + } + }, + _overlayFromEntity: { + url: function modelURL() { + return this.modelURL; + }, + scale: function scale() { + return this.dimensions && this.naturalDimensions && { + x: this.dimensions.x / this.naturalDimensions.x, + y: this.dimensions.y / this.naturalDimensions.y, + z: this.dimensions.z / this.naturalDimensions.z + }; + } + }, + objectDeleted: objectDeleted, + type: function(objectID) { + // TODO: support Model Entities (by detecting type from objectID, which is already possible) + return !Uuid.isNull(objectID) ? 'overlay' : null; + }, + addObject: function(properties) { + var type = 'overlay'; // this.resolveType(properties) + switch (type) { + case 'overlay': return Overlays.addOverlay(properties.type, this.toOverlayProps(properties)); + } + return false; + }, + editObject: function(objectID, properties) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.editOverlay(objectID, this.toOverlayProps(properties)); + } + return false; + }, + deleteObject: function(objectID) { + return this.type(objectID) === 'overlay' && Overlays.deleteOverlay(objectID); + }, + getProperty: function(objectID, propertyName) { + return this.type(objectID) === 'overlay' && Overlays.getProperty(objectID, propertyName); + }, + getProperties: function(objectID, filter) { + switch (this.type(objectID)) { + case 'overlay': + filter = Array.isArray(filter) ? filter : [ + 'position', 'rotation', 'localPosition', 'localRotation', 'parentID', + 'parentJointIndex', 'scale', 'name', 'visible', 'type', 'url', + 'dimensions', 'naturalDimensions', 'grabbable' + ]; + var properties = filter.reduce(function(out, propertyName) { + out[propertyName] = Overlays.getProperty(objectID, propertyName); + return out; + }, {}); + return this.toEntityProps(properties); + } + return null; + }, + // adapt Entity conventions to Overlay (eg: { modelURL: ... } -> { url: ... }) + toOverlayProps: function(properties) { + var result = {}; + for (var from in this._overlayFromEntity) { + var adapter = this._overlayFromEntity[from]; + result[from] = adapter.call(properties, from, adapter.name); + } + return utils.assign(result, properties); + }, + // adapt Overlay conventions to Entity (eg: { url: ... } -> { modelURL: ... }) + toEntityProps: function(properties) { + var result = {}; + for (var from in this._entityToOverlay) { + var adapter = this._entityToOverlay[from]; + result[from] = adapter.call(properties, from, adapter.name); + } + return utils.assign(result, properties); + }, + editObjects: function(updatedObjects) { + var objectIDs = Object.keys(updatedObjects), + type = this.type(objectIDs[0]); + switch (type) { + case 'overlay': + var translated = {}; + for (var objectID in updatedObjects) { + translated[objectID] = this.toOverlayProps(updatedObjects[objectID]); + } + return Overlays.editOverlays(translated); + } + return false; + }, + getJointIndex: function(objectID, name) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointNames').indexOf(name); + } + return -1; + }, + getJointNames: function(objectID) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointNames'); + } + return []; + }, + // @function - derives mirrored joint names from a list of regular joint names + // @param {Array} - list of joint names to mirror + // @return {Array} - list of mirrored joint names (note: entries for non-mirrored joints will be `undefined`) + deriveMirroredJointNames: function(jointNames) { + return jointNames.map(function(name, i) { + if (/Left/.test(name)) { + return name.replace('Left', 'Right'); + } + if (/Right/.test(name)) { + return name.replace('Right', 'Left'); + } + return undefined; + }); + }, + getJointPosition: function(objectID, index) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointPositions')[index]; + } + return Vec3.ZERO; + }, + getJointPositions: function(objectID) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointPositions'); + } + return []; + }, + getJointOrientation: function(objectID, index) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointOrientations')[index]; + } + return Quat.normalize({}); + }, + getJointOrientations: function(objectID) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointOrientations'); + } + }, + getJointTranslation: function(objectID, index) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointTranslations')[index]; + } + return Vec3.ZERO; + }, + getJointTranslations: function(objectID) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointTranslations'); + } + return []; + }, + getJointRotation: function(objectID, index) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointRotations')[index]; + } + return Quat.normalize({}); + }, + getJointRotations: function(objectID) { + switch (this.type(objectID)) { + case 'overlay': return Overlays.getProperty(objectID, 'jointRotations'); + } + return []; + } +}; // modelHelper + + +// @property {PreconditionFunction} - indicates when the model's jointNames have become available +ModelReadyWatcher.JOINTS = function(state) { + return Array.isArray(state.jointNames); +}; +// @property {PreconditionFunction} - indicates when a model's naturalDimensions have become available +ModelReadyWatcher.DIMENSIONS = function(state) { + return Vec3.length(state.naturalDimensions) > 0; +}; +// @property {PreconditionFunction} - indicates when both a model's naturalDimensions and jointNames have become available +ModelReadyWatcher.JOINTS_AND_DIMENSIONS = function(state) { + // eslint-disable-next-line new-cap + return ModelReadyWatcher.JOINTS(state) && ModelReadyWatcher.DIMENSIONS(state); +}; +// @property {int} - interval used for continually rechecking model readiness, until ready or a timeout occurs +ModelReadyWatcher.RECHECK_MS = 50; +// @property {int} - default wait time before considering a model unready-able. +ModelReadyWatcher.DEFAULT_TIMEOUT_SECS = 10; + +// @private @class - waits for model to become usable inworld and tracks errors/timeouts +// @param [Object} options -- key/value config options: +// @param {ModelResource} options.resource - a ModelCache prefetched resource to observe for determining load state +// @param {Uuid} options.objectID - an inworld object to observe for determining readiness states +// @param {Function} [options.precondition=ModelReadyWatcher.JOINTS] - the precondition used to determine if the model is usable +// @param {int} [options.maxWaitSeconds=10] - max seconds to wait for the model to become usable, after which a timeout error is emitted +// @return {ModelReadyWatcher} +function ModelReadyWatcher(options) { + options = utils.assign({ + precondition: ModelReadyWatcher.JOINTS, + maxWaitSeconds: ModelReadyWatcher.DEFAULT_TIMEOUT_SECS + }, options); + + assert(!Uuid.isNull(options.objectID), 'Error: invalid options.objectID'); + assert(options.resource && 'state' in options.resource, 'Error: invalid options.resource'); + assert(typeof options.precondition === 'function', 'Error: invalid options.precondition'); + + utils.assign(this, { + resource: options.resource, + objectID: options.objectID, + precondition: options.precondition, + + // @signal - emitted when the model becomes ready, or with the error that prevented it + modelReady: utils.signal(function modelReady(error, result){}), + + // @public + ready: false, // tracks readiness state + jointNames: null, // populated with detected jointNames + naturalDimensions: null, // populated with detected naturalDimensions + + _startTime: new Date, + _watchdogTimer: Script.setTimeout(utils.bind(this, function() { + this._watchdogTimer = null; + }), options.maxWaitSeconds * 1000), + _interval: Script.setInterval(utils.bind(this, '_waitUntilReady'), ModelReadyWatcher.RECHECK_MS) + }); + + this.modelReady.connect(this, function(error, result) { + this.ready = !error && result; + }); +} + +ModelReadyWatcher.prototype = { + contructor: ModelReadyWatcher, + // @public method -- cancels monitoring and (if model was not yet ready) emits an error + cancel: function() { + return this._stop() && !this.ready && this.modelReady('cancelled', null); + }, + // stop pending timers + _stop: function() { + var stopped = 0; + if (this._watchdogTimer) { + Script.clearTimeout(this._watchdogTimer); + this._watchdogTimer = null; + stopped++; + } + if (this._interval) { + Script.clearInterval(this._interval); + this._interval = null; + stopped++; + } + return stopped; + }, + // the monitoring thread func + _waitUntilReady: function() { + var error = null, result = null; + if (!this._watchdogTimer) { + error = this.precondition.name || 'timeout'; + } else if (this.resource.state === Resource.State.FAILED) { + error = 'prefetch_failed'; + } else if (this.resource.state === Resource.State.FINISHED) { + // in theory there will always be at least one "joint name" that represents the main submesh + var names = modelHelper.getJointNames(this.objectID); + if (Array.isArray(names) && names.length) { + this.jointNames = names; + } + var props = modelHelper.getProperties(this.objectID, ['naturalDimensions']); + if (props && props.naturalDimensions && Vec3.length(props.naturalDimensions)) { + this.naturalDimensions = props.naturalDimensions; + } + var state = { + resource: this.resource, + objectID: this.objectID, + waitTime: (new Date - this._startTime) / 1000, + jointNames: this.jointNames, + naturalDimensions: this.naturalDimensions + }; + if (this.precondition(state)) { + result = state; + } + } + if (error || result !== null) { + this._stop(); + this.modelReady(error, result); + } + } +}; // ModelReadyWatcher.prototype diff --git a/unpublishedScripts/marketplace/doppleganger-attachments/utils.js b/unpublishedScripts/marketplace/doppleganger-attachments/utils.js new file mode 100644 index 0000000000..76c6e1ef7f --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-attachments/utils.js @@ -0,0 +1,99 @@ +/* eslint-env commonjs */ + +module.exports = { + bind: bind, + signal: signal, + assign: assign, + assert: assert +}; + +// @function - bind a function to a `this` context +// @param {Object} - the `this` context +// @param {Function|String} - function or method name +// @param {value} varargs... - optional curry-right arguments (passed to method after any explicit arguments) +function bind(thiz, method, varargs) { + method = thiz[method] || method; + varargs = [].slice.call(arguments, 2); + return function() { + var args = [].slice.call(arguments).concat(varargs); + return method.apply(thiz, args); + }; +} + +// @function - Qt signal polyfill +function signal(template) { + var callbacks = []; + return Object.defineProperties(function() { + var args = [].slice.call(arguments); + callbacks.forEach(function(obj) { + obj.handler.apply(obj.scope, args); + }); + }, { + connect: { value: function(scope, handler) { + var callback = {scope: scope, handler: scope[handler] || handler || scope}; + if (!callback.handler || !callback.handler.apply) { + throw new Error('invalid arguments to connect:' + [template, scope, handler]); + } + callbacks.push({scope: scope, handler: scope[handler] || handler || scope}); + }}, + disconnect: { value: function(scope, handler) { + var match = {scope: scope, handler: scope[handler] || handler || scope}; + callbacks = callbacks.filter(function(obj) { + return !(obj.scope === match.scope && obj.handler === match.handler); + }); + }} + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill +/* eslint-disable */ +function assign(target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; +} +/* eslint-enable */ +// //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill + +// examples: +// assert(function assertion() { return (conditions === true) }, 'assertion failed!') +// var neededValue = assert(idString, 'idString not specified!'); +// assert(false, 'unexpected state'); +function assert(truthy, message) { + message = message || 'Assertion Failed:'; + + if (typeof truthy === 'function' && truthy.name === 'assertion') { + // extract function body to display with the assertion message + var assertion = (truthy+'').replace(/[\r\n]/g, ' ') + .replace(/^[^{]+\{|\}$|^\s*|\s*$/g, '').trim() + .replace(/^return /,'').replace(/\s[\r\n\t\s]+/g, ' '); + message += ' ' + JSON.stringify(assertion); + try { + truthy = truthy(); + } catch (e) { + message += '(exception: ' + e +')'; + } + } + if (!truthy) { + message += ' ('+truthy+')'; + throw new Error(message); + } + return truthy; +} diff --git a/scripts/system/app-doppleganger.js b/unpublishedScripts/marketplace/doppleganger-mirror/app-doppleganger.js similarity index 95% rename from scripts/system/app-doppleganger.js rename to unpublishedScripts/marketplace/doppleganger-mirror/app-doppleganger.js index d7f85e5767..f4c7bf99c0 100644 --- a/scripts/system/app-doppleganger.js +++ b/unpublishedScripts/marketplace/doppleganger-mirror/app-doppleganger.js @@ -14,8 +14,8 @@ var DopplegangerClass = Script.require('./doppleganger.js'); var tablet = Tablet.getTablet('com.highfidelity.interface.tablet.system'), button = tablet.addButton({ - icon: "icons/tablet-icons/doppleganger-i.svg", - activeIcon: "icons/tablet-icons/doppleganger-a.svg", + icon: Script.resolvePath('./doppleganger-i.svg'), + activeIcon: Script.resolvePath('./doppleganger-a.svg'), text: 'MIRROR' }); diff --git a/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger-a.svg b/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger-a.svg new file mode 100644 index 0000000000..100986647e --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger-a.svg @@ -0,0 +1,94 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger-i.svg b/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger-i.svg new file mode 100644 index 0000000000..0c55e0e0c7 --- /dev/null +++ b/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger-i.svg @@ -0,0 +1,94 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/scripts/system/doppleganger.js b/unpublishedScripts/marketplace/doppleganger-mirror/doppleganger.js similarity index 100% rename from scripts/system/doppleganger.js rename to unpublishedScripts/marketplace/doppleganger-mirror/doppleganger.js diff --git a/unpublishedScripts/marketplace/xylophone/A4.wav b/unpublishedScripts/marketplace/xylophone/A4.wav new file mode 100644 index 0000000000..8e3f4e370c Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/A4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/B4.wav b/unpublishedScripts/marketplace/xylophone/B4.wav new file mode 100644 index 0000000000..49a6ad0873 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/B4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/C4.wav b/unpublishedScripts/marketplace/xylophone/C4.wav new file mode 100644 index 0000000000..dc6724de6d Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/C4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/C5.wav b/unpublishedScripts/marketplace/xylophone/C5.wav new file mode 100644 index 0000000000..815a7909df Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/C5.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/D4.wav b/unpublishedScripts/marketplace/xylophone/D4.wav new file mode 100644 index 0000000000..0c0a7a66f2 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/D4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/E4.wav b/unpublishedScripts/marketplace/xylophone/E4.wav new file mode 100644 index 0000000000..dc84268702 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/E4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/F4.wav b/unpublishedScripts/marketplace/xylophone/F4.wav new file mode 100644 index 0000000000..353adc1c6a Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/F4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/G4.wav b/unpublishedScripts/marketplace/xylophone/G4.wav new file mode 100644 index 0000000000..7bb88e690f Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/G4.wav differ diff --git a/unpublishedScripts/marketplace/xylophone/Mallet3-2bpc_phys.obj b/unpublishedScripts/marketplace/xylophone/Mallet3-2bpc_phys.obj new file mode 100644 index 0000000000..d23d2a9d4f --- /dev/null +++ b/unpublishedScripts/marketplace/xylophone/Mallet3-2bpc_phys.obj @@ -0,0 +1,1060 @@ +# This file uses centimeters as units for non-parametric coordinates. + +g default +v -1.006609 1.535144 -8.257065 +v -1.006609 -1.971825 -8.257065 +v 2.334219 -0.218341 -8.257065 +v -1.123304 0.882099 -2.057893 +v -1.123305 -1.703815 -2.057893 +v 1.753316 -0.218341 -2.057893 +v 0.005766 -0.218341 -8.257065 +v -0.265666 -0.218341 -2.057893 +vt 0.375000 0.312500 +vt 0.458333 0.312500 +vt 0.458333 0.688440 +vt 0.375000 0.688440 +vt 0.541667 0.312500 +vt 0.541667 0.688440 +vt 0.625000 0.312500 +vt 0.625000 0.688440 +vt 0.421875 0.291566 +vt 0.421875 0.020934 +vt 0.500000 0.150000 +vt 0.656250 0.156250 +vt 0.421875 0.979066 +vt 0.421875 0.708434 +vt 0.500000 0.837500 +vt 0.656250 0.843750 +vn -0.999823 0.000000 -0.018821 +vn -0.999823 0.000000 -0.018821 +vn -0.999823 0.000000 -0.018821 +vn -0.999823 0.000000 -0.018821 +vn 0.461543 -0.885970 0.045121 +vn 0.461543 -0.885970 0.045121 +vn 0.461543 -0.885970 0.045121 +vn 0.461543 -0.885970 0.045121 +vn 0.416112 0.906525 0.071161 +vn 0.416112 0.906525 0.071161 +vn 0.416112 0.906525 0.071161 +vn 0.416112 0.906525 0.071161 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +s off +g polySurface3 phys +f 1/1/1 2/2/2 5/3/3 4/4/4 +f 2/2/5 3/5/6 6/6/7 5/3/8 +f 3/5/9 1/7/10 4/8/11 6/6/12 +s 1 +f 2/9/13 1/10/14 7/11/15 +f 3/12/16 2/9/13 7/11/15 +f 1/10/14 3/12/16 7/11/15 +s 2 +f 4/13/17 5/14/18 8/15/19 +f 5/14/18 6/16/20 8/15/19 +f 6/16/20 4/13/17 8/15/19 +g default +v 0.648287 -0.670052 21.955959 +v 0.374289 -0.944046 21.955959 +v 0.000000 -1.044334 21.955959 +v -0.374289 -0.944046 21.955959 +v -0.648287 -0.670052 21.955959 +v -0.748577 -0.295761 21.955959 +v -0.648287 0.078529 21.955959 +v -0.374289 0.352524 21.955959 +v 0.000000 0.452820 21.955959 +v 0.374289 0.352524 21.955959 +v 0.648287 0.078529 21.955959 +v 0.748577 -0.295761 21.955959 +v 1.252394 -1.018829 21.667019 +v 0.723070 -1.548157 21.667019 +v 0.000000 -1.741898 21.667019 +v -0.723070 -1.548157 21.667019 +v -1.252394 -1.018829 21.667019 +v -1.446140 -0.295761 21.667019 +v -1.252394 0.427307 21.667019 +v -0.723070 0.956635 21.667019 +v 0.000000 1.150383 21.667019 +v 0.723070 0.956635 21.667019 +v 1.252394 0.427307 21.667019 +v 1.446140 -0.295761 21.667019 +v 1.771153 -1.318336 21.207382 +v 1.022575 -2.066917 21.207382 +v 0.000000 -2.340912 21.207382 +v -1.022575 -2.066917 21.207382 +v -1.771153 -1.318336 21.207382 +v -2.045151 -0.295761 21.207382 +v -1.771153 0.726814 21.207382 +v -1.022575 1.475388 21.207382 +v 0.000000 1.749390 21.207382 +v 1.022575 1.475388 21.207382 +v 1.771153 0.726814 21.207382 +v 2.045151 -0.295761 21.207382 +v 2.169210 -1.548157 20.608372 +v 1.252394 -2.464973 20.608372 +v 0.000000 -2.800545 20.608372 +v -1.252394 -2.464973 20.608372 +v -2.169210 -1.548157 20.608372 +v -2.504788 -0.295761 20.608372 +v -2.169210 0.956635 20.608372 +v -1.252394 1.873451 20.608372 +v 0.000000 2.209030 20.608372 +v 1.252394 1.873451 20.608372 +v 2.169210 0.956635 20.608372 +v 2.504788 -0.295761 20.608372 +v 2.419440 -1.692627 19.910809 +v 1.396864 -2.715202 19.910809 +v 0.000000 -3.089485 19.910809 +v -1.396864 -2.715202 19.910809 +v -2.419440 -1.692627 19.910809 +v -2.793728 -0.295761 19.910809 +v -2.419440 1.101105 19.910809 +v -1.396864 2.123680 19.910809 +v 0.000000 2.497971 19.910809 +v 1.396864 2.123680 19.910809 +v 2.419440 1.101105 19.910809 +v 2.793728 -0.295761 19.910809 +v 2.504788 -1.741905 19.162231 +v 1.446140 -2.800552 19.162231 +v 0.000000 -3.188042 19.162231 +v -1.446140 -2.800552 19.162231 +v -2.504788 -1.741905 19.162231 +v -2.892280 -0.295761 19.162231 +v -2.504788 1.150375 19.162231 +v -1.446140 2.209023 19.162230 +v 0.000000 2.596519 19.162231 +v 1.446140 2.209023 19.162230 +v 2.504788 1.150375 19.162231 +v 2.892280 -0.295761 19.162231 +v 2.419440 -1.692627 18.413654 +v 1.396864 -2.715202 18.413654 +v 0.000000 -3.089485 18.413654 +v -1.396864 -2.715202 18.413654 +v -2.419440 -1.692627 18.413654 +v -2.793728 -0.295761 18.413654 +v -2.419440 1.101105 18.413654 +v -1.396864 2.123680 18.413654 +v 0.000000 2.497971 18.413654 +v 1.396864 2.123680 18.413654 +v 2.419440 1.101105 18.413654 +v 2.793728 -0.295761 18.413654 +v 2.169210 -1.548157 17.716091 +v 1.252394 -2.464973 17.716091 +v 0.000000 -2.800545 17.716091 +v -1.252394 -2.464973 17.716091 +v -2.169210 -1.548157 17.716091 +v -2.504788 -0.295761 17.716091 +v -2.169210 0.956635 17.716091 +v -1.252394 1.873451 17.716091 +v 0.000000 2.209030 17.716091 +v 1.252394 1.873451 17.716091 +v 2.169210 0.956635 17.716091 +v 2.504788 -0.295761 17.716091 +v 1.771153 -1.318336 17.117081 +v 1.022575 -2.066917 17.117081 +v 0.000000 -2.340912 17.117081 +v -1.022575 -2.066917 17.117081 +v -1.771153 -1.318336 17.117081 +v -2.045151 -0.295761 17.117081 +v -1.771153 0.726814 17.117081 +v -1.022575 1.475388 17.117081 +v 0.000000 1.749390 17.117081 +v 1.022575 1.475388 17.117081 +v 1.771153 0.726814 17.117081 +v 2.045151 -0.295761 17.117081 +v 1.252394 -1.018829 16.657444 +v 0.723070 -1.548157 16.657444 +v 0.000000 -1.741898 16.657444 +v -0.723070 -1.548157 16.657444 +v -1.252394 -1.018829 16.657444 +v -1.446140 -0.295761 16.657444 +v -1.252394 0.427307 16.657444 +v -0.723070 0.956635 16.657444 +v 0.000000 1.150383 16.657444 +v 0.723070 0.956635 16.657444 +v 1.252394 0.427307 16.657444 +v 1.446140 -0.295761 16.657444 +v 0.648287 -0.670052 16.368504 +v 0.374289 -0.944046 16.368504 +v 0.000000 -1.044334 16.368504 +v -0.374289 -0.944046 16.368504 +v -0.648287 -0.670052 16.368504 +v -0.748577 -0.295761 16.368504 +v -0.648287 0.078529 16.368504 +v -0.374289 0.352524 16.368504 +v 0.000000 0.452820 16.368504 +v 0.374289 0.352524 16.368504 +v 0.648287 0.078529 16.368504 +v 0.748577 -0.295761 16.368504 +v 0.000000 -0.295761 22.054512 +v 0.000000 -0.295761 16.269951 +vt 0.000000 0.083333 +vt 0.083333 0.083333 +vt 0.083333 0.166667 +vt 0.000000 0.166667 +vt 0.166667 0.083333 +vt 0.166667 0.166667 +vt 0.250000 0.083333 +vt 0.250000 0.166667 +vt 0.333333 0.083333 +vt 0.333333 0.166667 +vt 0.416667 0.083333 +vt 0.416667 0.166667 +vt 0.500000 0.083333 +vt 0.500000 0.166667 +vt 0.583333 0.083333 +vt 0.583333 0.166667 +vt 0.666667 0.083333 +vt 0.666667 0.166667 +vt 0.750000 0.083333 +vt 0.750000 0.166667 +vt 0.833333 0.083333 +vt 0.833333 0.166667 +vt 0.916667 0.083333 +vt 0.916667 0.166667 +vt 1.000000 0.083333 +vt 1.000000 0.166667 +vt 0.083333 0.250000 +vt 0.000000 0.250000 +vt 0.166667 0.250000 +vt 0.250000 0.250000 +vt 0.333333 0.250000 +vt 0.416667 0.250000 +vt 0.500000 0.250000 +vt 0.583333 0.250000 +vt 0.666667 0.250000 +vt 0.750000 0.250000 +vt 0.833333 0.250000 +vt 0.916667 0.250000 +vt 1.000000 0.250000 +vt 0.083333 0.333333 +vt 0.000000 0.333333 +vt 0.166667 0.333333 +vt 0.250000 0.333333 +vt 0.333333 0.333333 +vt 0.416667 0.333333 +vt 0.500000 0.333333 +vt 0.583333 0.333333 +vt 0.666667 0.333333 +vt 0.750000 0.333333 +vt 0.833333 0.333333 +vt 0.916667 0.333333 +vt 1.000000 0.333333 +vt 0.083333 0.416667 +vt 0.000000 0.416667 +vt 0.166667 0.416667 +vt 0.250000 0.416667 +vt 0.333333 0.416667 +vt 0.416667 0.416667 +vt 0.500000 0.416667 +vt 0.583333 0.416667 +vt 0.666667 0.416667 +vt 0.750000 0.416667 +vt 0.833333 0.416667 +vt 0.916667 0.416667 +vt 1.000000 0.416667 +vt 0.083333 0.500000 +vt 0.000000 0.500000 +vt 0.166667 0.500000 +vt 0.250000 0.500000 +vt 0.333333 0.500000 +vt 0.416667 0.500000 +vt 0.500000 0.500000 +vt 0.583333 0.500000 +vt 0.666667 0.500000 +vt 0.750000 0.500000 +vt 0.833333 0.500000 +vt 0.916667 0.500000 +vt 1.000000 0.500000 +vt 0.083333 0.583333 +vt 0.000000 0.583333 +vt 0.166667 0.583333 +vt 0.250000 0.583333 +vt 0.333333 0.583333 +vt 0.416667 0.583333 +vt 0.500000 0.583333 +vt 0.583333 0.583333 +vt 0.666667 0.583333 +vt 0.750000 0.583333 +vt 0.833333 0.583333 +vt 0.916667 0.583333 +vt 1.000000 0.583333 +vt 0.083333 0.666667 +vt 0.000000 0.666667 +vt 0.166667 0.666667 +vt 0.250000 0.666667 +vt 0.333333 0.666667 +vt 0.416667 0.666667 +vt 0.500000 0.666667 +vt 0.583333 0.666667 +vt 0.666667 0.666667 +vt 0.750000 0.666667 +vt 0.833333 0.666667 +vt 0.916667 0.666667 +vt 1.000000 0.666667 +vt 0.083333 0.750000 +vt 0.000000 0.750000 +vt 0.166667 0.750000 +vt 0.250000 0.750000 +vt 0.333333 0.750000 +vt 0.416667 0.750000 +vt 0.500000 0.750000 +vt 0.583333 0.750000 +vt 0.666667 0.750000 +vt 0.750000 0.750000 +vt 0.833333 0.750000 +vt 0.916667 0.750000 +vt 1.000000 0.750000 +vt 0.083333 0.833333 +vt 0.000000 0.833333 +vt 0.166667 0.833333 +vt 0.250000 0.833333 +vt 0.333333 0.833333 +vt 0.416667 0.833333 +vt 0.500000 0.833333 +vt 0.583333 0.833333 +vt 0.666667 0.833333 +vt 0.750000 0.833333 +vt 0.833333 0.833333 +vt 0.916667 0.833333 +vt 1.000000 0.833333 +vt 0.083333 0.916667 +vt 0.000000 0.916667 +vt 0.166667 0.916667 +vt 0.250000 0.916667 +vt 0.333333 0.916667 +vt 0.416667 0.916667 +vt 0.500000 0.916667 +vt 0.583333 0.916667 +vt 0.666667 0.916667 +vt 0.750000 0.916667 +vt 0.833333 0.916667 +vt 0.916667 0.916667 +vt 1.000000 0.916667 +vt 0.041667 0.000000 +vt 0.125000 0.000000 +vt 0.208333 0.000000 +vt 0.291667 0.000000 +vt 0.375000 0.000000 +vt 0.458333 0.000000 +vt 0.541667 0.000000 +vt 0.625000 0.000000 +vt 0.708333 0.000000 +vt 0.791667 0.000000 +vt 0.875000 0.000000 +vt 0.958333 0.000000 +vt 0.041667 1.000000 +vt 0.125000 1.000000 +vt 0.208333 1.000000 +vt 0.291667 1.000000 +vt 0.375000 1.000000 +vt 0.458333 1.000000 +vt 0.541667 1.000000 +vt 0.625000 1.000000 +vt 0.708333 1.000000 +vt 0.791667 1.000000 +vt 0.875000 1.000000 +vt 0.958333 1.000000 +vn 0.289762 -0.167294 0.942365 +vn 0.167292 -0.289761 0.942365 +vn 0.270243 -0.468077 0.841352 +vn 0.468076 -0.270243 0.841352 +vn 0.167292 -0.289761 0.942365 +vn -0.000001 -0.334591 0.942364 +vn -0.000001 -0.540489 0.841351 +vn 0.270243 -0.468077 0.841352 +vn -0.000001 -0.334591 0.942364 +vn -0.167292 -0.289761 0.942365 +vn -0.270244 -0.468076 0.841352 +vn -0.000001 -0.540489 0.841351 +vn -0.167292 -0.289761 0.942365 +vn -0.289758 -0.167292 0.942366 +vn -0.468075 -0.270243 0.841353 +vn -0.270244 -0.468076 0.841352 +vn -0.289758 -0.167292 0.942366 +vn -0.334585 -0.000000 0.942366 +vn -0.540484 0.000000 0.841354 +vn -0.468075 -0.270243 0.841353 +vn -0.334585 -0.000000 0.942366 +vn -0.289758 0.167293 0.942366 +vn -0.468076 0.270244 0.841352 +vn -0.540484 0.000000 0.841354 +vn -0.289758 0.167293 0.942366 +vn -0.167293 0.289759 0.942366 +vn -0.270245 0.468078 0.841350 +vn -0.468076 0.270244 0.841352 +vn -0.167293 0.289759 0.942366 +vn 0.000002 0.334587 0.942365 +vn 0.000001 0.540490 0.841350 +vn -0.270245 0.468078 0.841350 +vn 0.000002 0.334587 0.942365 +vn 0.167293 0.289758 0.942366 +vn 0.270244 0.468077 0.841351 +vn 0.000001 0.540490 0.841350 +vn 0.167293 0.289758 0.942366 +vn 0.289761 0.167292 0.942365 +vn 0.468076 0.270243 0.841353 +vn 0.270244 0.468077 0.841351 +vn 0.289761 0.167292 0.942365 +vn 0.334591 0.000000 0.942364 +vn 0.540487 -0.000000 0.841352 +vn 0.468076 0.270243 0.841353 +vn 0.334591 0.000000 0.942364 +vn 0.289762 -0.167294 0.942365 +vn 0.468076 -0.270243 0.841352 +vn 0.540487 -0.000000 0.841352 +vn 0.468076 -0.270243 0.841352 +vn 0.270243 -0.468077 0.841352 +vn 0.364804 -0.631861 0.683864 +vn 0.631861 -0.364805 0.683863 +vn 0.270243 -0.468077 0.841352 +vn -0.000001 -0.540489 0.841351 +vn -0.000000 -0.729611 0.683863 +vn 0.364804 -0.631861 0.683864 +vn -0.000001 -0.540489 0.841351 +vn -0.270244 -0.468076 0.841352 +vn -0.364804 -0.631862 0.683863 +vn -0.000000 -0.729611 0.683863 +vn -0.270244 -0.468076 0.841352 +vn -0.468075 -0.270243 0.841353 +vn -0.631860 -0.364805 0.683864 +vn -0.364804 -0.631862 0.683863 +vn -0.468075 -0.270243 0.841353 +vn -0.540484 0.000000 0.841354 +vn -0.729609 0.000000 0.683864 +vn -0.631860 -0.364805 0.683864 +vn -0.540484 0.000000 0.841354 +vn -0.468076 0.270244 0.841352 +vn -0.631861 0.364806 0.683863 +vn -0.729609 0.000000 0.683864 +vn -0.468076 0.270244 0.841352 +vn -0.270245 0.468078 0.841350 +vn -0.364806 0.631861 0.683863 +vn -0.631861 0.364806 0.683863 +vn -0.270245 0.468078 0.841350 +vn 0.000001 0.540490 0.841350 +vn 0.000000 0.729610 0.683863 +vn -0.364806 0.631861 0.683863 +vn 0.000001 0.540490 0.841350 +vn 0.270244 0.468077 0.841351 +vn 0.364806 0.631861 0.683863 +vn 0.000000 0.729610 0.683863 +vn 0.270244 0.468077 0.841351 +vn 0.468076 0.270243 0.841353 +vn 0.631861 0.364805 0.683864 +vn 0.364806 0.631861 0.683863 +vn 0.468076 0.270243 0.841353 +vn 0.540487 -0.000000 0.841352 +vn 0.729610 -0.000000 0.683864 +vn 0.631861 0.364805 0.683864 +vn 0.540487 -0.000000 0.841352 +vn 0.468076 -0.270243 0.841352 +vn 0.631861 -0.364805 0.683863 +vn 0.729610 -0.000000 0.683864 +vn 0.631861 -0.364805 0.683863 +vn 0.364804 -0.631861 0.683864 +vn 0.438133 -0.758871 0.481823 +vn 0.758872 -0.438134 0.481822 +vn 0.364804 -0.631861 0.683864 +vn -0.000000 -0.729611 0.683863 +vn -0.000000 -0.876269 0.481822 +vn 0.438133 -0.758871 0.481823 +vn -0.000000 -0.729611 0.683863 +vn -0.364804 -0.631862 0.683863 +vn -0.438133 -0.758872 0.481822 +vn -0.000000 -0.876269 0.481822 +vn -0.364804 -0.631862 0.683863 +vn -0.631860 -0.364805 0.683864 +vn -0.758871 -0.438134 0.481823 +vn -0.438133 -0.758872 0.481822 +vn -0.631860 -0.364805 0.683864 +vn -0.729609 0.000000 0.683864 +vn -0.876269 0.000000 0.481823 +vn -0.758871 -0.438134 0.481823 +vn -0.729609 0.000000 0.683864 +vn -0.631861 0.364806 0.683863 +vn -0.758871 0.438134 0.481822 +vn -0.876269 0.000000 0.481823 +vn -0.631861 0.364806 0.683863 +vn -0.364806 0.631861 0.683863 +vn -0.438134 0.758869 0.481827 +vn -0.758871 0.438134 0.481822 +vn -0.364806 0.631861 0.683863 +vn 0.000000 0.729610 0.683863 +vn 0.000000 0.876264 0.481831 +vn -0.438134 0.758869 0.481827 +vn 0.000000 0.729610 0.683863 +vn 0.364806 0.631861 0.683863 +vn 0.438134 0.758870 0.481825 +vn 0.000000 0.876264 0.481831 +vn 0.364806 0.631861 0.683863 +vn 0.631861 0.364805 0.683864 +vn 0.758871 0.438135 0.481822 +vn 0.438134 0.758870 0.481825 +vn 0.631861 0.364805 0.683864 +vn 0.729610 -0.000000 0.683864 +vn 0.876269 -0.000000 0.481823 +vn 0.758871 0.438135 0.481822 +vn 0.729610 -0.000000 0.683864 +vn 0.631861 -0.364805 0.683863 +vn 0.758872 -0.438134 0.481822 +vn 0.876269 -0.000000 0.481823 +vn 0.758872 -0.438134 0.481822 +vn 0.438133 -0.758871 0.481823 +vn 0.484271 -0.838784 0.248842 +vn 0.838785 -0.484272 0.248839 +vn 0.438133 -0.758871 0.481823 +vn -0.000000 -0.876269 0.481822 +vn -0.000000 -0.968544 0.248843 +vn 0.484271 -0.838784 0.248842 +vn -0.000000 -0.876269 0.481822 +vn -0.438133 -0.758872 0.481822 +vn -0.484271 -0.838785 0.248842 +vn -0.000000 -0.968544 0.248843 +vn -0.438133 -0.758872 0.481822 +vn -0.758871 -0.438134 0.481823 +vn -0.838785 -0.484272 0.248839 +vn -0.484271 -0.838785 0.248842 +vn -0.758871 -0.438134 0.481823 +vn -0.876269 0.000000 0.481823 +vn -0.968545 -0.000000 0.248837 +vn -0.838785 -0.484272 0.248839 +vn -0.876269 0.000000 0.481823 +vn -0.758871 0.438134 0.481822 +vn -0.838785 0.484274 0.248836 +vn -0.968545 -0.000000 0.248837 +vn -0.758871 0.438134 0.481822 +vn -0.438134 0.758869 0.481827 +vn -0.484273 0.838785 0.248837 +vn -0.838785 0.484274 0.248836 +vn -0.438134 0.758869 0.481827 +vn 0.000000 0.876264 0.481831 +vn -0.000000 0.968546 0.248836 +vn -0.484273 0.838785 0.248837 +vn 0.000000 0.876264 0.481831 +vn 0.438134 0.758870 0.481825 +vn 0.484274 0.838785 0.248834 +vn -0.000000 0.968546 0.248836 +vn 0.438134 0.758870 0.481825 +vn 0.758871 0.438135 0.481822 +vn 0.838785 0.484274 0.248834 +vn 0.484274 0.838785 0.248834 +vn 0.758871 0.438135 0.481822 +vn 0.876269 -0.000000 0.481823 +vn 0.968546 -0.000000 0.248836 +vn 0.838785 0.484274 0.248834 +vn 0.876269 -0.000000 0.481823 +vn 0.758872 -0.438134 0.481822 +vn 0.838785 -0.484272 0.248839 +vn 0.968546 -0.000000 0.248836 +vn 0.838785 -0.484272 0.248839 +vn 0.484271 -0.838784 0.248842 +vn 0.499998 -0.866026 0.000000 +vn 0.866026 -0.500000 0.000000 +vn 0.484271 -0.838784 0.248842 +vn -0.000000 -0.968544 0.248843 +vn 0.000000 -1.000000 0.000002 +vn 0.499998 -0.866026 0.000000 +vn -0.000000 -0.968544 0.248843 +vn -0.484271 -0.838785 0.248842 +vn -0.499998 -0.866027 0.000002 +vn 0.000000 -1.000000 0.000002 +vn -0.484271 -0.838785 0.248842 +vn -0.838785 -0.484272 0.248839 +vn -0.866025 -0.500000 0.000000 +vn -0.499998 -0.866027 0.000002 +vn -0.838785 -0.484272 0.248839 +vn -0.968545 -0.000000 0.248837 +vn -1.000000 -0.000000 0.000000 +vn -0.866025 -0.500000 0.000000 +vn -0.968545 -0.000000 0.248837 +vn -0.838785 0.484274 0.248836 +vn -0.866026 0.500000 0.000002 +vn -1.000000 -0.000000 0.000000 +vn -0.838785 0.484274 0.248836 +vn -0.484273 0.838785 0.248837 +vn -0.500001 0.866025 0.000002 +vn -0.866026 0.500000 0.000002 +vn -0.484273 0.838785 0.248837 +vn -0.000000 0.968546 0.248836 +vn -0.000000 1.000000 0.000000 +vn -0.500001 0.866025 0.000002 +vn -0.000000 0.968546 0.248836 +vn 0.484274 0.838785 0.248834 +vn 0.500001 0.866025 -0.000000 +vn -0.000000 1.000000 0.000000 +vn 0.484274 0.838785 0.248834 +vn 0.838785 0.484274 0.248834 +vn 0.866026 0.499999 0.000000 +vn 0.500001 0.866025 -0.000000 +vn 0.838785 0.484274 0.248834 +vn 0.968546 -0.000000 0.248836 +vn 1.000000 -0.000000 0.000000 +vn 0.866026 0.499999 0.000000 +vn 0.968546 -0.000000 0.248836 +vn 0.838785 -0.484272 0.248839 +vn 0.866026 -0.500000 0.000000 +vn 1.000000 -0.000000 0.000000 +vn 0.866026 -0.500000 0.000000 +vn 0.499998 -0.866026 0.000000 +vn 0.484270 -0.838785 -0.248842 +vn 0.838785 -0.484272 -0.248838 +vn 0.499998 -0.866026 0.000000 +vn 0.000000 -1.000000 0.000002 +vn 0.000000 -0.968544 -0.248843 +vn 0.484270 -0.838785 -0.248842 +vn 0.000000 -1.000000 0.000002 +vn -0.499998 -0.866027 0.000002 +vn -0.484271 -0.838785 -0.248841 +vn 0.000000 -0.968544 -0.248843 +vn -0.499998 -0.866027 0.000002 +vn -0.866025 -0.500000 0.000000 +vn -0.838785 -0.484272 -0.248838 +vn -0.484271 -0.838785 -0.248841 +vn -0.866025 -0.500000 0.000000 +vn -1.000000 -0.000000 0.000000 +vn -0.968545 0.000000 -0.248837 +vn -0.838785 -0.484272 -0.248838 +vn -1.000000 -0.000000 0.000000 +vn -0.866026 0.500000 0.000002 +vn -0.838785 0.484274 -0.248834 +vn -0.968545 0.000000 -0.248837 +vn -0.866026 0.500000 0.000002 +vn -0.500001 0.866025 0.000002 +vn -0.484273 0.838785 -0.248835 +vn -0.838785 0.484274 -0.248834 +vn -0.500001 0.866025 0.000002 +vn -0.000000 1.000000 0.000000 +vn 0.000000 0.968545 -0.248837 +vn -0.484273 0.838785 -0.248835 +vn -0.000000 1.000000 0.000000 +vn 0.500001 0.866025 -0.000000 +vn 0.484273 0.838785 -0.248834 +vn 0.000000 0.968545 -0.248837 +vn 0.500001 0.866025 -0.000000 +vn 0.866026 0.499999 0.000000 +vn 0.838785 0.484273 -0.248834 +vn 0.484273 0.838785 -0.248834 +vn 0.866026 0.499999 0.000000 +vn 1.000000 -0.000000 0.000000 +vn 0.968546 0.000000 -0.248836 +vn 0.838785 0.484273 -0.248834 +vn 1.000000 -0.000000 0.000000 +vn 0.866026 -0.500000 0.000000 +vn 0.838785 -0.484272 -0.248838 +vn 0.968546 0.000000 -0.248836 +vn 0.838785 -0.484272 -0.248838 +vn 0.484270 -0.838785 -0.248842 +vn 0.438133 -0.758872 -0.481823 +vn 0.758871 -0.438134 -0.481823 +vn 0.484270 -0.838785 -0.248842 +vn 0.000000 -0.968544 -0.248843 +vn -0.000000 -0.876268 -0.481824 +vn 0.438133 -0.758872 -0.481823 +vn 0.000000 -0.968544 -0.248843 +vn -0.484271 -0.838785 -0.248841 +vn -0.438134 -0.758872 -0.481822 +vn -0.000000 -0.876268 -0.481824 +vn -0.484271 -0.838785 -0.248841 +vn -0.838785 -0.484272 -0.248838 +vn -0.758872 -0.438135 -0.481821 +vn -0.438134 -0.758872 -0.481822 +vn -0.838785 -0.484272 -0.248838 +vn -0.968545 0.000000 -0.248837 +vn -0.876268 0.000000 -0.481824 +vn -0.758872 -0.438135 -0.481821 +vn -0.968545 0.000000 -0.248837 +vn -0.838785 0.484274 -0.248834 +vn -0.758871 0.438134 -0.481823 +vn -0.876268 0.000000 -0.481824 +vn -0.838785 0.484274 -0.248834 +vn -0.484273 0.838785 -0.248835 +vn -0.438133 0.758869 -0.481827 +vn -0.758871 0.438134 -0.481823 +vn -0.484273 0.838785 -0.248835 +vn 0.000000 0.968545 -0.248837 +vn 0.000000 0.876264 -0.481831 +vn -0.438133 0.758869 -0.481827 +vn 0.000000 0.968545 -0.248837 +vn 0.484273 0.838785 -0.248834 +vn 0.438134 0.758870 -0.481825 +vn 0.000000 0.876264 -0.481831 +vn 0.484273 0.838785 -0.248834 +vn 0.838785 0.484273 -0.248834 +vn 0.758871 0.438135 -0.481822 +vn 0.438134 0.758870 -0.481825 +vn 0.838785 0.484273 -0.248834 +vn 0.968546 0.000000 -0.248836 +vn 0.876268 0.000000 -0.481824 +vn 0.758871 0.438135 -0.481822 +vn 0.968546 0.000000 -0.248836 +vn 0.838785 -0.484272 -0.248838 +vn 0.758871 -0.438134 -0.481823 +vn 0.876268 0.000000 -0.481824 +vn 0.758871 -0.438134 -0.481823 +vn 0.438133 -0.758872 -0.481823 +vn 0.364804 -0.631862 -0.683863 +vn 0.631861 -0.364805 -0.683863 +vn 0.438133 -0.758872 -0.481823 +vn -0.000000 -0.876268 -0.481824 +vn 0.000000 -0.729611 -0.683863 +vn 0.364804 -0.631862 -0.683863 +vn -0.000000 -0.876268 -0.481824 +vn -0.438134 -0.758872 -0.481822 +vn -0.364804 -0.631862 -0.683863 +vn 0.000000 -0.729611 -0.683863 +vn -0.438134 -0.758872 -0.481822 +vn -0.758872 -0.438135 -0.481821 +vn -0.631861 -0.364804 -0.683863 +vn -0.364804 -0.631862 -0.683863 +vn -0.758872 -0.438135 -0.481821 +vn -0.876268 0.000000 -0.481824 +vn -0.729609 -0.000000 -0.683864 +vn -0.631861 -0.364804 -0.683863 +vn -0.876268 0.000000 -0.481824 +vn -0.758871 0.438134 -0.481823 +vn -0.631861 0.364805 -0.683863 +vn -0.729609 -0.000000 -0.683864 +vn -0.758871 0.438134 -0.481823 +vn -0.438133 0.758869 -0.481827 +vn -0.364806 0.631861 -0.683863 +vn -0.631861 0.364805 -0.683863 +vn -0.438133 0.758869 -0.481827 +vn 0.000000 0.876264 -0.481831 +vn -0.000000 0.729610 -0.683863 +vn -0.364806 0.631861 -0.683863 +vn 0.000000 0.876264 -0.481831 +vn 0.438134 0.758870 -0.481825 +vn 0.364806 0.631862 -0.683862 +vn -0.000000 0.729610 -0.683863 +vn 0.438134 0.758870 -0.481825 +vn 0.758871 0.438135 -0.481822 +vn 0.631861 0.364805 -0.683863 +vn 0.364806 0.631862 -0.683862 +vn 0.758871 0.438135 -0.481822 +vn 0.876268 0.000000 -0.481824 +vn 0.729609 -0.000000 -0.683865 +vn 0.631861 0.364805 -0.683863 +vn 0.876268 0.000000 -0.481824 +vn 0.758871 -0.438134 -0.481823 +vn 0.631861 -0.364805 -0.683863 +vn 0.729609 -0.000000 -0.683865 +vn 0.631861 -0.364805 -0.683863 +vn 0.364804 -0.631862 -0.683863 +vn 0.270244 -0.468078 -0.841351 +vn 0.468077 -0.270244 -0.841352 +vn 0.364804 -0.631862 -0.683863 +vn 0.000000 -0.729611 -0.683863 +vn 0.000000 -0.540489 -0.841351 +vn 0.270244 -0.468078 -0.841351 +vn 0.000000 -0.729611 -0.683863 +vn -0.364804 -0.631862 -0.683863 +vn -0.270243 -0.468076 -0.841352 +vn 0.000000 -0.540489 -0.841351 +vn -0.364804 -0.631862 -0.683863 +vn -0.631861 -0.364804 -0.683863 +vn -0.468076 -0.270243 -0.841352 +vn -0.270243 -0.468076 -0.841352 +vn -0.631861 -0.364804 -0.683863 +vn -0.729609 -0.000000 -0.683864 +vn -0.540487 0.000000 -0.841352 +vn -0.468076 -0.270243 -0.841352 +vn -0.729609 -0.000000 -0.683864 +vn -0.631861 0.364805 -0.683863 +vn -0.468078 0.270244 -0.841351 +vn -0.540487 0.000000 -0.841352 +vn -0.631861 0.364805 -0.683863 +vn -0.364806 0.631861 -0.683863 +vn -0.270246 0.468078 -0.841350 +vn -0.468078 0.270244 -0.841351 +vn -0.364806 0.631861 -0.683863 +vn -0.000000 0.729610 -0.683863 +vn 0.000000 0.540490 -0.841350 +vn -0.270246 0.468078 -0.841350 +vn -0.000000 0.729610 -0.683863 +vn 0.364806 0.631862 -0.683862 +vn 0.270246 0.468078 -0.841350 +vn 0.000000 0.540490 -0.841350 +vn 0.364806 0.631862 -0.683862 +vn 0.631861 0.364805 -0.683863 +vn 0.468076 0.270244 -0.841352 +vn 0.270246 0.468078 -0.841350 +vn 0.631861 0.364805 -0.683863 +vn 0.729609 -0.000000 -0.683865 +vn 0.540485 -0.000000 -0.841354 +vn 0.468076 0.270244 -0.841352 +vn 0.729609 -0.000000 -0.683865 +vn 0.631861 -0.364805 -0.683863 +vn 0.468077 -0.270244 -0.841352 +vn 0.540485 -0.000000 -0.841354 +vn 0.468077 -0.270244 -0.841352 +vn 0.270244 -0.468078 -0.841351 +vn 0.167292 -0.289761 -0.942365 +vn 0.289759 -0.167293 -0.942366 +vn 0.270244 -0.468078 -0.841351 +vn 0.000000 -0.540489 -0.841351 +vn 0.000000 -0.334590 -0.942364 +vn 0.167292 -0.289761 -0.942365 +vn 0.000000 -0.540489 -0.841351 +vn -0.270243 -0.468076 -0.841352 +vn -0.167291 -0.289761 -0.942365 +vn 0.000000 -0.334590 -0.942364 +vn -0.270243 -0.468076 -0.841352 +vn -0.468076 -0.270243 -0.841352 +vn -0.289760 -0.167293 -0.942365 +vn -0.167291 -0.289761 -0.942365 +vn -0.468076 -0.270243 -0.841352 +vn -0.540487 0.000000 -0.841352 +vn -0.334588 0.000000 -0.942364 +vn -0.289760 -0.167293 -0.942365 +vn -0.540487 0.000000 -0.841352 +vn -0.468078 0.270244 -0.841351 +vn -0.289761 0.167293 -0.942365 +vn -0.334588 0.000000 -0.942364 +vn -0.468078 0.270244 -0.841351 +vn -0.270246 0.468078 -0.841350 +vn -0.167294 0.289759 -0.942365 +vn -0.289761 0.167293 -0.942365 +vn -0.270246 0.468078 -0.841350 +vn 0.000000 0.540490 -0.841350 +vn 0.000000 0.334587 -0.942365 +vn -0.167294 0.289759 -0.942365 +vn 0.000000 0.540490 -0.841350 +vn 0.270246 0.468078 -0.841350 +vn 0.167293 0.289759 -0.942365 +vn 0.000000 0.334587 -0.942365 +vn 0.270246 0.468078 -0.841350 +vn 0.468076 0.270244 -0.841352 +vn 0.289759 0.167293 -0.942365 +vn 0.167293 0.289759 -0.942365 +vn 0.468076 0.270244 -0.841352 +vn 0.540485 -0.000000 -0.841354 +vn 0.334585 0.000000 -0.942365 +vn 0.289759 0.167293 -0.942365 +vn 0.540485 -0.000000 -0.841354 +vn 0.468077 -0.270244 -0.841352 +vn 0.289759 -0.167293 -0.942366 +vn 0.334585 0.000000 -0.942365 +vn 0.167292 -0.289761 0.942365 +vn 0.289762 -0.167294 0.942365 +vn -0.000000 0.000000 1.000000 +vn -0.000001 -0.334591 0.942364 +vn 0.167292 -0.289761 0.942365 +vn -0.000000 0.000000 1.000000 +vn -0.167292 -0.289761 0.942365 +vn -0.000001 -0.334591 0.942364 +vn -0.000000 0.000000 1.000000 +vn -0.289758 -0.167292 0.942366 +vn -0.167292 -0.289761 0.942365 +vn -0.000000 0.000000 1.000000 +vn -0.334585 -0.000000 0.942366 +vn -0.289758 -0.167292 0.942366 +vn -0.000000 0.000000 1.000000 +vn -0.289758 0.167293 0.942366 +vn -0.334585 -0.000000 0.942366 +vn -0.000000 0.000000 1.000000 +vn -0.167293 0.289759 0.942366 +vn -0.289758 0.167293 0.942366 +vn -0.000000 0.000000 1.000000 +vn 0.000002 0.334587 0.942365 +vn -0.167293 0.289759 0.942366 +vn -0.000000 0.000000 1.000000 +vn 0.167293 0.289758 0.942366 +vn 0.000002 0.334587 0.942365 +vn -0.000000 0.000000 1.000000 +vn 0.289761 0.167292 0.942365 +vn 0.167293 0.289758 0.942366 +vn -0.000000 0.000000 1.000000 +vn 0.334591 0.000000 0.942364 +vn 0.289761 0.167292 0.942365 +vn -0.000000 0.000000 1.000000 +vn 0.289762 -0.167294 0.942365 +vn 0.334591 0.000000 0.942364 +vn -0.000000 0.000000 1.000000 +vn 0.289759 -0.167293 -0.942366 +vn 0.167292 -0.289761 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn 0.167292 -0.289761 -0.942365 +vn 0.000000 -0.334590 -0.942364 +vn 0.000001 0.000000 -1.000000 +vn 0.000000 -0.334590 -0.942364 +vn -0.167291 -0.289761 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn -0.167291 -0.289761 -0.942365 +vn -0.289760 -0.167293 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn -0.289760 -0.167293 -0.942365 +vn -0.334588 0.000000 -0.942364 +vn 0.000001 0.000000 -1.000000 +vn -0.334588 0.000000 -0.942364 +vn -0.289761 0.167293 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn -0.289761 0.167293 -0.942365 +vn -0.167294 0.289759 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn -0.167294 0.289759 -0.942365 +vn 0.000000 0.334587 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn 0.000000 0.334587 -0.942365 +vn 0.167293 0.289759 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn 0.167293 0.289759 -0.942365 +vn 0.289759 0.167293 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn 0.289759 0.167293 -0.942365 +vn 0.334585 0.000000 -0.942365 +vn 0.000001 0.000000 -1.000000 +vn 0.334585 0.000000 -0.942365 +vn 0.289759 -0.167293 -0.942366 +vn 0.000001 0.000000 -1.000000 +s off +g phys polySurface4 +f 9/17/21 10/18/22 22/19/23 21/20/24 +f 10/18/25 11/21/26 23/22/27 22/19/28 +f 11/21/29 12/23/30 24/24/31 23/22/32 +f 12/23/33 13/25/34 25/26/35 24/24/36 +f 13/25/37 14/27/38 26/28/39 25/26/40 +f 14/27/41 15/29/42 27/30/43 26/28/44 +f 15/29/45 16/31/46 28/32/47 27/30/48 +f 16/31/49 17/33/50 29/34/51 28/32/52 +f 17/33/53 18/35/54 30/36/55 29/34/56 +f 18/35/57 19/37/58 31/38/59 30/36/60 +f 19/37/61 20/39/62 32/40/63 31/38/64 +f 20/39/65 9/41/66 21/42/67 32/40/68 +f 21/20/69 22/19/70 34/43/71 33/44/72 +f 22/19/73 23/22/74 35/45/75 34/43/76 +f 23/22/77 24/24/78 36/46/79 35/45/80 +f 24/24/81 25/26/82 37/47/83 36/46/84 +f 25/26/85 26/28/86 38/48/87 37/47/88 +f 26/28/89 27/30/90 39/49/91 38/48/92 +f 27/30/93 28/32/94 40/50/95 39/49/96 +f 28/32/97 29/34/98 41/51/99 40/50/100 +f 29/34/101 30/36/102 42/52/103 41/51/104 +f 30/36/105 31/38/106 43/53/107 42/52/108 +f 31/38/109 32/40/110 44/54/111 43/53/112 +f 32/40/113 21/42/114 33/55/115 44/54/116 +f 33/44/117 34/43/118 46/56/119 45/57/120 +f 34/43/121 35/45/122 47/58/123 46/56/124 +f 35/45/125 36/46/126 48/59/127 47/58/128 +f 36/46/129 37/47/130 49/60/131 48/59/132 +f 37/47/133 38/48/134 50/61/135 49/60/136 +f 38/48/137 39/49/138 51/62/139 50/61/140 +f 39/49/141 40/50/142 52/63/143 51/62/144 +f 40/50/145 41/51/146 53/64/147 52/63/148 +f 41/51/149 42/52/150 54/65/151 53/64/152 +f 42/52/153 43/53/154 55/66/155 54/65/156 +f 43/53/157 44/54/158 56/67/159 55/66/160 +f 44/54/161 33/55/162 45/68/163 56/67/164 +f 45/57/165 46/56/166 58/69/167 57/70/168 +f 46/56/169 47/58/170 59/71/171 58/69/172 +f 47/58/173 48/59/174 60/72/175 59/71/176 +f 48/59/177 49/60/178 61/73/179 60/72/180 +f 49/60/181 50/61/182 62/74/183 61/73/184 +f 50/61/185 51/62/186 63/75/187 62/74/188 +f 51/62/189 52/63/190 64/76/191 63/75/192 +f 52/63/193 53/64/194 65/77/195 64/76/196 +f 53/64/197 54/65/198 66/78/199 65/77/200 +f 54/65/201 55/66/202 67/79/203 66/78/204 +f 55/66/205 56/67/206 68/80/207 67/79/208 +f 56/67/209 45/68/210 57/81/211 68/80/212 +f 57/70/213 58/69/214 70/82/215 69/83/216 +f 58/69/217 59/71/218 71/84/219 70/82/220 +f 59/71/221 60/72/222 72/85/223 71/84/224 +f 60/72/225 61/73/226 73/86/227 72/85/228 +f 61/73/229 62/74/230 74/87/231 73/86/232 +f 62/74/233 63/75/234 75/88/235 74/87/236 +f 63/75/237 64/76/238 76/89/239 75/88/240 +f 64/76/241 65/77/242 77/90/243 76/89/244 +f 65/77/245 66/78/246 78/91/247 77/90/248 +f 66/78/249 67/79/250 79/92/251 78/91/252 +f 67/79/253 68/80/254 80/93/255 79/92/256 +f 68/80/257 57/81/258 69/94/259 80/93/260 +f 69/83/261 70/82/262 82/95/263 81/96/264 +f 70/82/265 71/84/266 83/97/267 82/95/268 +f 71/84/269 72/85/270 84/98/271 83/97/272 +f 72/85/273 73/86/274 85/99/275 84/98/276 +f 73/86/277 74/87/278 86/100/279 85/99/280 +f 74/87/281 75/88/282 87/101/283 86/100/284 +f 75/88/285 76/89/286 88/102/287 87/101/288 +f 76/89/289 77/90/290 89/103/291 88/102/292 +f 77/90/293 78/91/294 90/104/295 89/103/296 +f 78/91/297 79/92/298 91/105/299 90/104/300 +f 79/92/301 80/93/302 92/106/303 91/105/304 +f 80/93/305 69/94/306 81/107/307 92/106/308 +f 81/96/309 82/95/310 94/108/311 93/109/312 +f 82/95/313 83/97/314 95/110/315 94/108/316 +f 83/97/317 84/98/318 96/111/319 95/110/320 +f 84/98/321 85/99/322 97/112/323 96/111/324 +f 85/99/325 86/100/326 98/113/327 97/112/328 +f 86/100/329 87/101/330 99/114/331 98/113/332 +f 87/101/333 88/102/334 100/115/335 99/114/336 +f 88/102/337 89/103/338 101/116/339 100/115/340 +f 89/103/341 90/104/342 102/117/343 101/116/344 +f 90/104/345 91/105/346 103/118/347 102/117/348 +f 91/105/349 92/106/350 104/119/351 103/118/352 +f 92/106/353 81/107/354 93/120/355 104/119/356 +f 93/109/357 94/108/358 106/121/359 105/122/360 +f 94/108/361 95/110/362 107/123/363 106/121/364 +f 95/110/365 96/111/366 108/124/367 107/123/368 +f 96/111/369 97/112/370 109/125/371 108/124/372 +f 97/112/373 98/113/374 110/126/375 109/125/376 +f 98/113/377 99/114/378 111/127/379 110/126/380 +f 99/114/381 100/115/382 112/128/383 111/127/384 +f 100/115/385 101/116/386 113/129/387 112/128/388 +f 101/116/389 102/117/390 114/130/391 113/129/392 +f 102/117/393 103/118/394 115/131/395 114/130/396 +f 103/118/397 104/119/398 116/132/399 115/131/400 +f 104/119/401 93/120/402 105/133/403 116/132/404 +f 105/122/405 106/121/406 118/134/407 117/135/408 +f 106/121/409 107/123/410 119/136/411 118/134/412 +f 107/123/413 108/124/414 120/137/415 119/136/416 +f 108/124/417 109/125/418 121/138/419 120/137/420 +f 109/125/421 110/126/422 122/139/423 121/138/424 +f 110/126/425 111/127/426 123/140/427 122/139/428 +f 111/127/429 112/128/430 124/141/431 123/140/432 +f 112/128/433 113/129/434 125/142/435 124/141/436 +f 113/129/437 114/130/438 126/143/439 125/142/440 +f 114/130/441 115/131/442 127/144/443 126/143/444 +f 115/131/445 116/132/446 128/145/447 127/144/448 +f 116/132/449 105/133/450 117/146/451 128/145/452 +f 117/135/453 118/134/454 130/147/455 129/148/456 +f 118/134/457 119/136/458 131/149/459 130/147/460 +f 119/136/461 120/137/462 132/150/463 131/149/464 +f 120/137/465 121/138/466 133/151/467 132/150/468 +f 121/138/469 122/139/470 134/152/471 133/151/472 +f 122/139/473 123/140/474 135/153/475 134/152/476 +f 123/140/477 124/141/478 136/154/479 135/153/480 +f 124/141/481 125/142/482 137/155/483 136/154/484 +f 125/142/485 126/143/486 138/156/487 137/155/488 +f 126/143/489 127/144/490 139/157/491 138/156/492 +f 127/144/493 128/145/494 140/158/495 139/157/496 +f 128/145/497 117/146/498 129/159/499 140/158/500 +f 10/18/501 9/17/502 141/160/503 +f 11/21/504 10/18/505 141/161/506 +f 12/23/507 11/21/508 141/162/509 +f 13/25/510 12/23/511 141/163/512 +f 14/27/513 13/25/514 141/164/515 +f 15/29/516 14/27/517 141/165/518 +f 16/31/519 15/29/520 141/166/521 +f 17/33/522 16/31/523 141/167/524 +f 18/35/525 17/33/526 141/168/527 +f 19/37/528 18/35/529 141/169/530 +f 20/39/531 19/37/532 141/170/533 +f 9/41/534 20/39/535 141/171/536 +f 129/148/537 130/147/538 142/172/539 +f 130/147/540 131/149/541 142/173/542 +f 131/149/543 132/150/544 142/174/545 +f 132/150/546 133/151/547 142/175/548 +f 133/151/549 134/152/550 142/176/551 +f 134/152/552 135/153/553 142/177/554 +f 135/153/555 136/154/556 142/178/557 +f 136/154/558 137/155/559 142/179/560 +f 137/155/561 138/156/562 142/180/563 +f 138/156/564 139/157/565 142/181/566 +f 139/157/567 140/158/568 142/182/569 +f 140/158/570 129/159/571 142/183/572 diff --git a/unpublishedScripts/marketplace/xylophone/Mallet3-2pc.fbx b/unpublishedScripts/marketplace/xylophone/Mallet3-2pc.fbx new file mode 100644 index 0000000000..559646d230 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/Mallet3-2pc.fbx differ diff --git a/unpublishedScripts/marketplace/xylophone/pUtils.js b/unpublishedScripts/marketplace/xylophone/pUtils.js new file mode 100644 index 0000000000..2cafbc1f50 --- /dev/null +++ b/unpublishedScripts/marketplace/xylophone/pUtils.js @@ -0,0 +1,34 @@ +// +// pUtils.js +// +// Created by Patrick Gosch on 03/28/2017 +// Copyright 2017 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 +// + +getEntityTextures = function(id) { + var results = null; + var properties = Entities.getEntityProperties(id, "textures"); + if (properties.textures) { + try { + results = JSON.parse(properties.textures); + } catch (err) { + logDebug(err); + logDebug(properties.textures); + } + } + return results ? results : {}; +}; + +setEntityTextures = function(id, textureList) { + var json = JSON.stringify(textureList); + Entities.editEntity(id, {textures: json}); +}; + +editEntityTextures = function(id, textureName, textureURL) { + var textureList = getEntityTextures(id); + textureList[textureName] = textureURL; + setEntityTextures(id, textureList); +}; diff --git a/unpublishedScripts/marketplace/xylophone/xyloKey_2_a_e.fbx b/unpublishedScripts/marketplace/xylophone/xyloKey_2_a_e.fbx new file mode 100644 index 0000000000..405abb433b Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xyloKey_2_a_e.fbx differ diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave.fbx b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave.fbx new file mode 100644 index 0000000000..bb9ef84d42 --- /dev/null +++ b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave.fbx @@ -0,0 +1,1031 @@ +; FBX 7.5.0 project file +; Copyright (C) 1997-2015 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7500 + CreationTimeStamp: { + Version: 1000 + Year: 2017 + Month: 3 + Day: 6 + Hour: 10 + Minute: 48 + Second: 41 + Millisecond: 261 + } + Creator: "FBX SDK/FBX Plugins version 2017.0.1" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "F:\Dropbox\Dropbox\_High Fidelity\xylophone\xylophoneFrameWithWave.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "F:\Dropbox\Dropbox\_High Fidelity\xylophone\xylophoneFrameWithWave.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "Autodesk" + P: "Original|ApplicationName", "KString", "", "", "Maya" + P: "Original|ApplicationVersion", "KString", "", "", "2017" + P: "Original|DateTime_GMT", "DateTime", "", "", "06/03/2017 18:48:41.259" + P: "Original|FileName", "KString", "", "", "F:\Dropbox\Dropbox\_High Fidelity\xylophone\xylophoneFrameWithWave.fbx" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "Autodesk" + P: "LastSaved|ApplicationName", "KString", "", "", "Maya" + P: "LastSaved|ApplicationVersion", "KString", "", "", "2017" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "06/03/2017 18:48:41.259" + P: "Original|ApplicationActiveProject", "KString", "", "", "F:\Dropbox\Dropbox\_High Fidelity\xylophone" + P: "Original|ApplicationNativeFile", "KString", "", "", "F:\Dropbox\Dropbox\_High Fidelity\xylophone\xylophoneFrameWithWave.mb" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",11 + P: "TimeProtocol", "enum", "", "",2 + P: "SnapOnFrameMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",1924423250 + P: "TimeSpanStop", "KTime", "Time", "",384884650000 + P: "CustomFrameRate", "double", "Number", "",-1 + P: "TimeMarker", "Compound", "", "" + P: "CurrentTimeMarker", "int", "Integer", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 1980820224, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "Take 001" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 30 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "AnimationStack" { + Count: 1 + PropertyTemplate: "FbxAnimStack" { + Properties70: { + P: "Description", "KString", "", "", "" + P: "LocalStart", "KTime", "Time", "",0 + P: "LocalStop", "KTime", "Time", "",0 + P: "ReferenceStart", "KTime", "Time", "",0 + P: "ReferenceStop", "KTime", "Time", "",0 + } + } + } + ObjectType: "AnimationLayer" { + Count: 1 + PropertyTemplate: "FbxAnimLayer" { + Properties70: { + P: "Weight", "Number", "", "A",100 + P: "Mute", "bool", "", "",0 + P: "Solo", "bool", "", "",0 + P: "Lock", "bool", "", "",0 + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BlendMode", "enum", "", "",0 + P: "RotationAccumulationMode", "enum", "", "",0 + P: "ScaleAccumulationMode", "enum", "", "",0 + P: "BlendModeBypass", "ULongLong", "", "",0 + } + } + } + ObjectType: "NodeAttribute" { + Count: 5 + PropertyTemplate: "FbxNull" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "Size", "double", "Number", "",100 + P: "Look", "enum", "", "",1 + } + } + } + ObjectType: "Model" { + Count: 6 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Geometry" { + Count: 1 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 1 + PropertyTemplate: "FbxSurfaceMaterial" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Unknown" + P: "MultiLayer", "bool", "", "",0 + } + } + } + ObjectType: "Implementation" { + Count: 1 + PropertyTemplate: "FbxImplementation" { + Properties70: { + P: "ShaderLanguage", "KString", "", "", "MentalRaySL" + P: "ShaderLanguageVersion", "KString", "", "", "" + P: "RenderAPI", "KString", "", "", "MentalRay" + P: "RenderAPIVersion", "KString", "", "", "" + P: "RootBindingName", "KString", "", "", "" + P: "Constants", "Compound", "", "" + } + } + } + ObjectType: "BindingTable" { + Count: 1 + PropertyTemplate: "FbxBindingTable" { + Properties70: { + P: "TargetName", "KString", "", "", "" + P: "TargetType", "KString", "", "", "" + P: "CodeAbsoluteURL", "KString", "XRefUrl", "", "" + P: "CodeRelativeURL", "KString", "XRefUrl", "", "" + P: "CodeTAG", "KString", "", "", "shader" + P: "DescAbsoluteURL", "KString", "XRefUrl", "", "" + P: "DescRelativeURL", "KString", "XRefUrl", "", "" + P: "DescTAG", "KString", "", "", "shader" + } + } + } + ObjectType: "Texture" { + Count: 8 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Video" { + Count: 4 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "Path", "KString", "XRefUrl", "", "" + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "InterlaceMode", "enum", "", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + NodeAttribute: 1611246784, "NodeAttribute::", "Null" { + Properties70: { + P: "Look", "enum", "", "",0 + } + TypeFlags: "Null" + } + NodeAttribute: 1611245728, "NodeAttribute::", "Null" { + Properties70: { + P: "Look", "enum", "", "",0 + } + TypeFlags: "Null" + } + NodeAttribute: 1611246608, "NodeAttribute::", "Null" { + Properties70: { + P: "Look", "enum", "", "",0 + } + TypeFlags: "Null" + } + NodeAttribute: 1611246256, "NodeAttribute::", "Null" { + Properties70: { + P: "Look", "enum", "", "",0 + } + TypeFlags: "Null" + } + NodeAttribute: 1611247136, "NodeAttribute::", "Null" { + Properties70: { + P: "Look", "enum", "", "",0 + } + TypeFlags: "Null" + } + Geometry: 1983184160, "Geometry::", "Mesh" { + Vertices: *3117 { + a: -101.134796142578,80.4016571044922,-41.9429893493652,-93.2760238647461,80.4016571044922,-34.0842208862305,-84.7931442260742,80.4016571044922,-26.308177947998,-75.6639556884766,80.4016571044922,-19.3006763458252,-65.958625793457,80.4016647338867,-13.1157073974609,-55.7510528564453,80.4016571044922,-7.80038452148438,-45.1189613342285,80.4016647338867,-3.39517498016357,-34.143310546875,80.4016571044922,0.0663824081420898,-22.9076843261719,80.4016647338867,2.5579195022583,-11.497615814209,80.4016647338867,4.06047391891479,-4.2708282114827e-015,80.4016571044922,4.56259965896606,11.4976043701172,80.4016647338867,4.06047391891479,22.9076728820801,80.4016647338867,2.55792045593262,34.1433029174805,80.4016571044922,0.0663833618164063,45.1189575195313,80.4016571044922,-3.39517116546631,55.7510375976563,80.4016571044922,-7.80037879943848,65.958625793457,80.4016647338867,-13.1157073974609,75.663948059082,80.4016571044922,-19.3006649017334,84.7931289672852,80.4016571044922,-26.3081703186035,93.2760238647461,80.4016571044922,-34.0842208862305,-94.3248672485352,80.4016571044922,-33.558349609375,-85.7758941650391,80.4016571044922,-25.7204284667969,-76.5680999755859,80.4016571044922,-18.6525764465332,-66.7711563110352,80.4016571044922,-12.4092292785645,-56.4582214355469,80.4016571044922,-7.03904724121094,-45.7067222595215,80.4016647338867,-2.5843620300293,-34.598316192627,80.4016571044922,0.919064521789551,-23.2183227539063,80.4016571044922,3.44261598587036,-11.6552543640137,80.4016647338867,4.96531867980957,-1.27318719478353e-006,80.4016647338867,5.47432899475098,11.6552352905273,80.4016647338867,4.96532011032104,23.218318939209,80.4016571044922,3.44261646270752,34.5983009338379,80.4016647338867,0.919069290161133,45.7067070007324,80.4016571044922,-2.58435535430908,56.4582099914551,80.4016571044922,-7.03904151916504,66.7711715698242,80.4016647338867,-12.4092407226563,76.5680694580078,80.4016571044922,-18.6525630950928,85.7758636474609,80.4016571044922,-25.7204093933105,94.2930908203125,80.4016571044922,-33.5279312133789, +-108.993537902832,66.775390625,-49.8017349243164,-110.662445068359,66.3969421386719,-51.4706420898438,-108.993537902832,69.2256240844727,-49.8017349243164,-107.324630737305,66.3969345092773,-48.1328277587891,-108.373474121094,66.3969268798828,-47.6069564819336,-110.042373657227,69.2256164550781,-49.2758636474609,-111.711296081543,66.3969421386719,-50.9447708129883,-110.042373657227,66.775390625,-49.2758636474609,-101.134796142578,63.8953247070313,-41.942985534668,-102.8037109375,64.2737884521484,-43.6119003295898,-101.134796142578,65.5349426269531,-41.942985534668,-99.4658813476563,64.2737884521484,-40.2740783691406,-100.514114379883,64.2709197998047,-39.7478942871094,-102.183639526367,65.5349426269531,-41.417121887207,-103.852119445801,64.2735900878906,-43.0856018066406,-102.183364868164,63.8944778442383,-41.4169235229492,-93.2502746582031,66.7794799804688,-34.0965347290039,-94.9441452026367,66.3973083496094,-35.7523422241211,-93.2760238647461,69.2256164550781,-34.0842208862305,-91.5082473754883,66.4115905761719,-32.4637451171875,-92.5253219604492,66.4146881103516,-31.9074630737305,-94.2947998046875,69.2256164550781,-33.5295562744141,-95.9614105224609,66.4003753662109,-35.1959609985352,-94.2673950195313,66.7811737060547,-33.5402221679688,-84.7451095581055,63.8937377929688,-26.3395690917969,-86.5636444091797,64.2603149414063,-27.93115234375,-84.7931442260742,65.5349426269531,-26.3081817626953,-82.8368988037109,64.280876159668,-24.8065795898438,-83.8190383911133,64.2743682861328,-24.2183609008789,-85.7758941650391,65.5349426269531,-25.7204284667969,-87.5458526611328,64.2569732666016,-27.3429107666016,-85.7275848388672,63.8910369873047,-25.7515563964844,-75.6172790527344,66.7636337280273,-19.3372459411621,-77.6282424926758,66.386589050293,-20.8084487915039,-75.6639556884766,69.2256240844727,-19.3006744384766,-73.5194854736328,66.3652114868164,-17.9340476989746,-74.4234085083008,66.3727569580078,-17.2858238220215,-76.5680847167969,69.2256164550781,-18.6525688171387,-78.5321960449219,66.393440246582,-20.160213470459,-76.5213241577148,66.7675933837891,-18.6890602111816, +-65.914306640625,63.9208984375,-13.1578102111816,-68.1123962402344,64.3090362548828,-14.4882507324219,-65.958625793457,65.5349426269531,-13.1157073974609,-63.6341857910156,64.330451965332,-11.9053153991699,-64.4464797973633,64.3219451904297,-11.1987190246582,-66.7711410522461,65.5349426269531,-12.4092292785645,-68.9247131347656,64.3013000488281,-13.7816429138184,-66.7267532348633,63.9164009094238,-12.4512405395508,-55.7104187011719,66.7360992431641,-7.84817886352539,-58.0856781005859,66.3365783691406,-9.01607894897461,-55.7510528564453,69.2256164550781,-7.80038452148438,-53.2602767944336,66.3160858154297,-6.76837921142578,-53.9671859741211,66.3255996704102,-6.00693130493164,-56.4582176208496,69.2256164550781,-7.03904342651367,-58.7926025390625,66.3452911376953,-8.25461196899414,-56.4174880981445,66.7411651611328,-7.08674621582031,-45.0835609436035,63.9475708007813,-3.44853591918945,-47.6201858520508,64.3582611083984,-4.43151092529297,-45.1189613342285,65.5349502563477,-3.39517593383789,-42.4819679260254,64.3767395019531,-2.56350326538086,-43.0694389343262,64.3662338256836,-1.75260162353516,-45.7067108154297,65.5349426269531,-2.58435821533203,-48.2076873779297,64.3485336303711,-3.62059020996094,-45.6712112426758,63.9419059753418,-2.63762283325195,-34.1147918701172,66.711784362793,0.00797653198242188,-36.7901611328125,66.2906723022461,-0.768394470214844,-34.143310546875,69.2256164550781,0.0663833618164063,-31.3872623443604,66.2753829956055,0.677543640136719,-31.8420143127441,66.2867889404297,1.5302848815918,-34.5983200073242,69.2256164550781,0.919063568115234,-37.2449264526367,66.3013763427734,0.0843658447265625,-34.569694519043,66.7180023193359,0.860752105712891,-22.8876056671143,63.9678497314453,2.49544525146484,-25.6718997955322,64.3980102539063,1.9449462890625,-22.9076843261719,65.5349426269531,2.55791854858398,-20.0667133331299,64.4089508056641,2.93203735351563,-20.3771553039551,64.3968734741211,3.8167610168457,-23.2183265686035,65.5349426269531,3.4426155090332,-25.9823532104492,64.3864288330078,2.82968521118164, +-23.198169708252,63.9611740112305,3.38022232055664,-11.487232208252,66.6971435546875,3.99534225463867,-14.3440227508545,66.2600021362305,3.68563842773438,-11.497615814209,69.2256240844727,4.06047439575195,-8.61154460906982,66.254280090332,4.18651580810547,-8.76906967163086,66.2667922973633,5.09136581420898,-11.655252456665,69.2256240844727,4.96531867980957,-14.5015478134155,66.272216796875,4.59049987792969,-11.6448211669922,66.7041244506836,4.90026092529297,-2.64522583393045e-007,63.9755401611328,4.49654388427734,-2.88798141479492,64.4170455932617,4.43647384643555,-4.3665691925438e-015,65.5349426269531,4.56259918212891,2.88798046112061,64.4170455932617,4.43647384643555,2.88798141479492,64.4045104980469,5.34820556640625,1.09400730252673e-006,65.5349426269531,5.47432708740234,-2.88797998428345,64.4045104980469,5.34820556640625,1.01989189715823e-006,63.9684524536133,5.40834426879883,11.4872207641602,66.6971435546875,3.99534225463867,8.61153507232666,66.254280090332,4.18651580810547,11.4976043701172,69.2256240844727,4.06047439575195,14.3440113067627,66.2600021362305,3.68564224243164,14.501537322998,66.272216796875,4.59049987792969,11.655237197876,69.2256240844727,4.9653205871582,8.76905536651611,66.2667770385742,5.09136581420898,11.6448078155518,66.7041244506836,4.90026473999023,22.8875980377197,63.9678497314453,2.49544906616211,20.0667057037354,64.4089508056641,2.93204116821289,22.9076728820801,65.5349426269531,2.55792236328125,25.6718902587891,64.3980102539063,1.9449462890625,25.982349395752,64.3864288330078,2.82968521118164,23.218318939209,65.5349426269531,3.4426155090332,20.3771438598633,64.3968658447266,3.8167610168457,23.1981620788574,63.9611778259277,3.38022613525391,34.1147804260254,66.711784362793,0.0079803466796875,31.3872566223145,66.275390625,0.677547454833984,34.1433029174805,69.2256164550781,0.0663833618164063,36.7901458740234,66.2906646728516,-0.768394470214844,37.2449111938477,66.301383972168,0.0843696594238281,34.5983047485352,69.2256164550781,0.9190673828125,31.8419990539551,66.2867965698242,1.53028869628906, +34.5696792602539,66.7180023193359,0.860755920410156,45.0835494995117,63.9475708007813,-3.44853210449219,42.4819526672363,64.3767471313477,-2.56350326538086,45.1189575195313,65.5349426269531,-3.39517211914063,47.6201782226563,64.3582611083984,-4.4315071105957,48.2076721191406,64.3485260009766,-3.62058639526367,45.7067070007324,65.5349502563477,-2.58435440063477,43.0694351196289,64.3662338256836,-1.75259780883789,45.671199798584,63.9419021606445,-2.63761901855469,55.7104034423828,66.7360992431641,-7.84817504882813,53.2602653503418,66.3160858154297,-6.76837539672852,55.7510375976563,69.2256240844727,-7.80037689208984,58.0856590270996,66.3365859985352,-9.01607131958008,58.7925987243652,66.3452987670898,-8.25461196899414,56.4582138061523,69.2256240844727,-7.03904342651367,53.9671859741211,66.3255920410156,-6.00693130493164,56.41748046875,66.7411727905273,-7.08673858642578,65.914306640625,63.9208984375,-13.1578102111816,63.6341857910156,64.3304443359375,-11.9053153991699,65.958625793457,65.5349426269531,-13.1157073974609,68.1123962402344,64.3090515136719,-14.4882507324219,68.9246978759766,64.3013000488281,-13.7816314697266,66.771125793457,65.5349426269531,-12.4092178344727,64.4464645385742,64.3219451904297,-11.1987075805664,66.7267379760742,63.9163970947266,-12.451229095459,75.6172637939453,66.7636337280273,-19.3372459411621,73.5194702148438,66.3652038574219,-17.9340438842773,75.663948059082,69.2256164550781,-19.300666809082,77.6282348632813,66.386589050293,-20.8084411621094,78.5321807861328,66.3934326171875,-20.1602020263672,76.5680694580078,69.2256240844727,-18.6525535583496,74.4233932495117,66.3727569580078,-17.2858123779297,76.5213088989258,66.7675933837891,-18.6890411376953,84.7450942993164,63.893741607666,-26.3395614624023,82.8368835449219,64.280876159668,-24.8065643310547,84.7931289672852,65.5349426269531,-26.3081741333008,86.5636291503906,64.2603149414063,-27.9311447143555,87.5460586547852,64.2542266845703,-27.3433609008789,85.7758636474609,65.5349426269531,-25.7203979492188,83.8194808959961,64.2741928100586,-24.2186889648438, +85.7277374267578,63.8902359008789,-25.7517395019531,93.2495880126953,66.7794799804688,-34.0958938598633,91.5069046020508,66.4110107421875,-32.462516784668,93.2760238647461,69.2256164550781,-34.0842208862305,94.9428863525391,66.3978881835938,-35.7510833740234,95.9909210205078,66.3982696533203,-35.2243957519531,94.3231811523438,69.2256240844727,-33.5567245483398,92.5550994873047,66.4166717529297,-31.9357757568359,94.2980804443359,66.7811431884766,-33.5695877075195,101.134765625,63.8953247070313,-41.9429702758789,99.4658660888672,64.2737884521484,-40.2740707397461,101.134765625,65.5349426269531,-41.9429702758789,102.803680419922,64.2737884521484,-43.6118774414063,103.852531433105,64.2737884521484,-43.0860137939453,102.183624267578,65.5349426269531,-41.4170989990234,100.514709472656,64.2737884521484,-39.7481918334961,102.183624267578,63.8953285217285,-41.4170989990234,108.993530273438,66.775390625,-49.8017349243164,107.324630737305,66.3969421386719,-48.1328201293945,108.993530273438,69.2256240844727,-49.8017349243164,110.662445068359,66.3969421386719,-51.4706420898438,111.711288452148,66.3969421386719,-50.9447708129883,110.042366027832,69.2256164550781,-49.2758636474609,108.373466491699,66.3969421386719,-47.6069564819336,110.042366027832,66.775390625,-49.2758636474609,100.759162902832,80.4016571044922,-41.5673751831055,101.526153564453,80.4016571044922,-40.7597465515137,101.134765625,79.9412155151367,-41.9429702758789,102.183624267578,79.5957336425781,-41.4170989990234,108.993530273438,70.3071975708008,-49.8017349243164,113.127655029297,65.2392120361328,-53.9358596801758,113.719665527344,65.4537506103516,-52.9531478881836,110.042366027832,69.9617309570313,-49.2758636474609,110.812942504883,69.0171051025391,-50.0464248657227,110.102928161621,68.9471893310547,-50.9111328125,-101.177276611328,80.4016571044922,-41.985466003418,-101.277847290039,80.4016571044922,-41.8712692260742,-101.914657592773,80.4016571044922,-41.1481285095215,-108.993537902832,69.9640274047852,-49.8017349243164,-110.042373657227,69.5481109619141,-49.2758636474609, +-112.208450317383,65.6708984375,-53.0166473388672,-112.776893615723,65.8964996337891,-52.0103759765625,-102.183639526367,80.0424575805664,-41.417121887207,-110.345245361328,69.1436614990234,-49.578727722168,-109.687026977539,69.0379638671875,-50.4952163696289,-83.0836486816406,4.99999904632568,-27.2701225280762,-73.4974212646484,4.99999475479126,-20.0309410095215,-63.2841377258301,4.99999570846558,-13.7071371078491,-52.5309410095215,5.00000095367432,-8.35268497467041,-41.3295707702637,5.00000381469727,-4.01324415206909,-29.7755908966064,5.00000238418579,-0.725861072540283,-17.9675750732422,4.99999952316284,1.48143672943115,-6.00626611709595,4.99999618530273,2.58982419967651,6.00628566741943,4.99999618530273,2.58980798721313,17.9675941467285,4.99999952316284,1.48143815994263,29.7756099700928,5.00000238418579,-0.725861549377441,41.32958984375,5.00000381469727,-4.01325416564941,52.5309600830078,5.00000095367432,-8.35269165039063,63.2841529846191,4.99999570846558,-13.7071447372437,73.4974365234375,4.99999570846558,-20.0309410095215,83.0836563110352,5,-27.2701263427734,-83.0836486816406,1.9073486328125e-006,-27.2701148986816,-73.4974212646484,1.66893005371094e-006,-20.030933380127,-63.2841300964355,1.19209289550781e-006,-13.7071447372437,-52.530933380127,1.19209289550781e-006,-8.35269260406494,-41.3295707702637,1.19209289550781e-006,-4.01324415206909,-29.7755908966064,2.38418579101563e-007,-0.725861072540283,-17.9675750732422,2.38418579101563e-007,1.48143672943115,-6.00626611709595,-3.814697265625e-006,2.58982419967651,6.00628566741943,-3.814697265625e-006,2.58980798721313,17.9675941467285,2.38418579101563e-007,1.48143815994263,29.7756099700928,2.38418579101563e-007,-0.725861549377441,41.32958984375,1.19209289550781e-006,-4.01325416564941,52.5309600830078,2.14576721191406e-006,-8.35269165039063,63.2841529846191,2.14576721191406e-006,-13.7071447372437,73.4974365234375,1.66893005371094e-006,-20.0309410095215,83.0836563110352,1.9073486328125e-006,-27.2701263427734,-94.4441452026367,78.323600769043,-32.8871726989746,-94.6315307617188,78.5938415527344,-32.6924247741699, +-85.4963531494141,78.5938110351563,-24.3646087646484,-85.3235931396484,78.3236770629883,-24.5726528167725,-75.6317443847656,78.5938110351563,-16.9152030944824,-75.4789199829102,78.3236770629883,-17.1382999420166,-65.1218719482422,78.5938110351563,-10.407769203186,-64.9902801513672,78.3236770629883,-10.6440143585205,-54.0564117431641,78.5938110351563,-4.89782238006592,-53.9471817016602,78.3236770629883,-5.14520645141602,-42.5297584533691,78.5938110351563,-0.432375907897949,-42.4438209533691,78.3236770629883,-0.688781976699829,-30.6402568817139,78.5938110351563,2.95048189163208,-30.5783443450928,78.3236770629883,2.68723702430725,-18.4893436431885,78.5938110351563,5.22187328338623,-18.4519824981689,78.3236770629883,4.95404529571533,-6.18068504333496,78.5938110351563,6.36244869232178,-6.16819620132446,78.3236770629883,6.09231615066528,6.18070507049561,78.5938110351563,6.36244773864746,6.16821622848511,78.3236770629883,6.09231519699097,18.4893627166748,78.5938110351563,5.2218713760376,18.4520015716553,78.3236770629883,4.9540433883667,30.6402759552002,78.5938110351563,2.95047760009766,30.5783634185791,78.3236770629883,2.68723273277283,42.5297775268555,78.5938110351563,-0.432382106781006,42.4438400268555,78.3236770629883,-0.688788175582886,54.0564308166504,78.5938110351563,-4.89783048629761,53.9472007751465,78.3236770629883,-5.14521408081055,65.1218872070313,78.5938110351563,-10.4077768325806,64.9902954101563,78.3236770629883,-10.644021987915,75.6317596435547,78.5938110351563,-16.9152126312256,75.4789352416992,78.3236770629883,-17.1383094787598,85.4963607788086,78.5938110351563,-24.364616394043,85.323600769043,78.3236770629883,-24.572660446167,94.6315383911133,78.5938415527344,-32.6924362182617,94.4441528320313,78.323600769043,-32.8871841430664,-94.6315307617188,83.0534973144531,-32.6924247741699,-94.4441528320313,83.3234939575195,-32.8872032165527,-85.4963531494141,83.0535430908203,-24.3646087646484,-85.3235931396484,83.3236770629883,-24.5726528167725,-75.6317443847656,83.0535430908203,-16.9152030944824,-75.4789199829102,83.3236770629883,-17.1382999420166, +-65.1218719482422,83.0535430908203,-10.407769203186,-64.9902801513672,83.3236770629883,-10.6440143585205,-54.0564117431641,83.0535430908203,-4.89782238006592,-53.9471817016602,83.3236770629883,-5.14520645141602,-42.5297584533691,83.0535430908203,-0.432375907897949,-42.4438209533691,83.3236770629883,-0.688781976699829,-30.6402568817139,83.0535430908203,2.95048189163208,-30.5783443450928,83.3236770629883,2.68723702430725,-18.4893436431885,83.0535430908203,5.22187328338623,-18.4519824981689,83.3236770629883,4.95404529571533,-6.18068504333496,83.0535430908203,6.36244869232178,-6.16819620132446,83.3236770629883,6.09231615066528,6.18070507049561,83.0535430908203,6.36244773864746,6.16821622848511,83.3236770629883,6.09231519699097,18.4893627166748,83.0535430908203,5.2218713760376,18.4520015716553,83.3236770629883,4.9540433883667,30.6402759552002,83.0535430908203,2.95047760009766,30.5783634185791,83.3236770629883,2.68723273277283,42.5297775268555,83.0535430908203,-0.432382106781006,42.4438400268555,83.3236770629883,-0.688788175582886,54.0564308166504,83.0535430908203,-4.89783048629761,53.9472007751465,83.3236770629883,-5.14521408081055,65.1218872070313,83.0535430908203,-10.4077768325806,64.9902954101563,83.3236770629883,-10.644021987915,75.6317596435547,83.0535430908203,-16.9152126312256,75.4789352416992,83.3236770629883,-17.1383094787598,85.4963607788086,83.0535430908203,-24.364616394043,85.323600769043,83.3236770629883,-24.572660446167,94.4441604614258,83.3234939575195,-32.8872146606445,94.6315383911133,83.0534973144531,-32.6924362182617,-92.1468734741211,83.3236618041992,-35.1668243408203,-83.2564086914063,83.3236770629883,-27.0620708465576,-83.0836486816406,83.0535430908203,-27.2701148986816,-73.6502456665039,83.3236770629883,-19.8078365325928,-73.4974212646484,83.0535430908203,-20.030933380127,-63.4157257080078,83.3236770629883,-13.4708909988403,-63.2841377258301,83.0535430908203,-13.7071380615234,-52.6401710510254,83.3236770629883,-8.10530376434326,-52.5309410095215,83.0535430908203,-8.35268592834473,-41.4155082702637,83.3236770629883,-3.75684428215027, +-41.3295707702637,83.0535430908203,-4.01324701309204,-29.8375034332275,83.3236770629883,-0.462619930505753,-29.7755908966064,83.0535430908203,-0.725862979888916,-18.0049362182617,83.3236770629883,1.74927043914795,-17.9675750732422,83.0535430908203,1.48144245147705,-6.01875495910645,83.3236770629883,2.85995674133301,-6.00626611709595,83.0535430908203,2.58982419967651,6.01877450942993,83.3236770629883,2.85995578765869,6.00628566741943,83.0535430908203,2.5898232460022,18.004955291748,83.3236770629883,1.74926805496216,17.9675941467285,83.0535430908203,1.48144006729126,29.8375225067139,83.3236770629883,-0.462624222040176,29.7756099700928,83.0535430908203,-0.72586727142334,41.41552734375,83.3236770629883,-3.75685048103333,41.32958984375,83.0535430908203,-4.0132532119751,52.6401901245117,83.3236770629883,-8.10531139373779,52.5309600830078,83.0535430908203,-8.35269355773926,63.4157409667969,83.3236770629883,-13.4708986282349,63.2841529846191,83.0535430908203,-13.707145690918,73.650260925293,83.3236770629883,-19.8078441619873,73.4974365234375,83.0535430908203,-20.0309410095215,83.2564163208008,83.3236770629883,-27.0620822906494,83.0836563110352,83.0535430908203,-27.2701263427734,92.1468887329102,83.3236618041992,-35.1668395996094,-91.9624938964844,78.5937728881836,-35.3643684387207,-92.1468353271484,78.3236770629883,-35.1668281555176,-83.0836486816406,78.5938110351563,-27.2701148986816,-83.2564086914063,78.3236770629883,-27.0620708465576,-73.4974212646484,78.5938110351563,-20.030933380127,-73.6502456665039,78.3236770629883,-19.8078365325928,-63.2841377258301,78.5938110351563,-13.7071380615234,-63.4157257080078,78.3236770629883,-13.4708909988403,-52.5309410095215,78.5938110351563,-8.35268592834473,-52.6401710510254,78.3236770629883,-8.10530376434326,-41.3295707702637,78.5938110351563,-4.01324701309204,-41.4155082702637,78.3236770629883,-3.75684428215027,-29.7755908966064,78.5938110351563,-0.725862979888916,-29.8375034332275,78.3236770629883,-0.462619930505753,-17.9675750732422,78.5938110351563,1.48144245147705,-18.0049362182617,78.3236770629883,1.74927043914795, +-6.00626611709595,78.5938110351563,2.58982419967651,-6.01875495910645,78.3236770629883,2.85995674133301,6.00628566741943,78.5938110351563,2.5898232460022,6.01877450942993,78.3236770629883,2.85995578765869,17.9675941467285,78.5938110351563,1.48144006729126,18.004955291748,78.3236770629883,1.74926805496216,29.7756099700928,78.5938110351563,-0.72586727142334,29.8375225067139,78.3236770629883,-0.462624222040176,41.32958984375,78.5938110351563,-4.0132532119751,41.41552734375,78.3236770629883,-3.75685048103333,52.5309600830078,78.5938110351563,-8.35269355773926,52.6401901245117,78.3236770629883,-8.10531139373779,63.2841529846191,78.5938110351563,-13.707145690918,63.4157409667969,78.3236770629883,-13.4708986282349,73.4974365234375,78.5938110351563,-20.0309410095215,73.650260925293,78.3236770629883,-19.8078441619873,83.0836563110352,78.5938110351563,-27.2701263427734,83.2564163208008,78.3236770629883,-27.0620822906494,92.1468505859375,78.3236770629883,-35.1668395996094,91.9625091552734,78.5937728881836,-35.3643760681152,-94.4441528320313,0.000185161959961988,-32.8872032165527,-94.6315307617188,0.270181238651276,-32.6924247741699,-85.4963531494141,0.270133376121521,-24.3646087646484,-85.3235931396484,7.15255737304688e-007,-24.5726528167725,-75.6317443847656,0.270134806632996,-16.9152030944824,-75.4789199829102,2.14576721191406e-006,-17.1382999420166,-65.1218719482422,0.270135283470154,-10.4077682495117,-64.9902801513672,2.62260437011719e-006,-10.6440143585205,-54.0564117431641,0.270132899284363,-4.89782238006592,-53.9471817016602,1.19209289550781e-006,-5.14520835876465,-42.5297584533691,0.270130038261414,-0.432374000549316,-42.4438209533691,-2.62260437011719e-006,-0.688780546188354,-30.6402568817139,0.270129084587097,2.95048570632935,-30.5783443450928,1.66893005371094e-006,2.6872398853302,-18.4893436431885,0.270128130912781,5.22187423706055,-18.4519824981689,1.19209289550781e-006,4.95405578613281,-6.18068504333496,0.270128607749939,6.36244106292725,-6.16819620132446,-4.05311584472656e-006,6.09231042861938,6.18070507049561,0.270128607749939,6.3624382019043, +6.16821622848511,-4.05311584472656e-006,6.09230947494507,18.4893627166748,0.270128130912781,5.22186088562012,18.4520015716553,1.19209289550781e-006,4.95404243469238,30.6402759552002,0.270129084587097,2.95048713684082,30.5783634185791,1.66893005371094e-006,2.68724322319031,42.5297775268555,0.270130038261414,-0.43237829208374,42.4438400268555,-2.62260437011719e-006,-0.688786745071411,54.0564308166504,0.270132899284363,-4.89783096313477,53.9472007751465,1.19209289550781e-006,-5.14521408081055,65.1218872070313,0.270135283470154,-10.4077749252319,64.9902954101563,2.62260437011719e-006,-10.6440238952637,75.6317596435547,0.270134806632996,-16.9152126312256,75.4789352416992,2.14576721191406e-006,-17.1383094787598,85.4963607788086,0.270133376121521,-24.364616394043,85.323600769043,7.15255737304688e-007,-24.572660446167,94.6315383911133,0.270181208848953,-32.6924362182617,94.4441604614258,0.000185148528544232,-32.8872146606445,-94.6315307617188,4.72983837127686,-32.6924247741699,-94.4441452026367,5.00008010864258,-32.8871726989746,-85.4963531494141,4.72986698150635,-24.3646087646484,-85.3235931396484,5,-24.5726528167725,-75.6317443847656,4.72986555099487,-16.9152030944824,-75.4789199829102,5.00000095367432,-17.1382999420166,-65.1218719482422,4.72986459732056,-10.4077682495117,-64.9902801513672,5,-10.6440143585205,-54.0564117431641,4.72986698150635,-4.89782238006592,-53.9471817016602,5.00000047683716,-5.14520835876465,-42.5297584533691,4.72987079620361,-0.432374000549316,-42.4438209533691,4.99999952316284,-0.688780546188354,-30.6402568817139,4.72986268997192,2.95048570632935,-30.5783443450928,4.99999904632568,2.6872398853302,-18.4893436431885,4.72986173629761,5.22187423706055,-18.4519824981689,5.00000047683716,4.95405578613281,-6.18068504333496,4.7298641204834,6.36244106292725,-6.16819620132446,4.99999618530273,6.09231042861938,6.18070507049561,4.7298641204834,6.3624382019043,6.16821622848511,4.99999618530273,6.09230947494507,18.4893627166748,4.72986173629761,5.22186088562012,18.4520015716553,5.00000047683716,4.95404243469238, +30.6402759552002,4.72986268997192,2.95048713684082,30.5783634185791,4.99999904632568,2.68724322319031,42.5297775268555,4.72987079620361,-0.43237829208374,42.4438400268555,4.99999952316284,-0.688786745071411,54.0564308166504,4.72986698150635,-4.89783096313477,53.9472007751465,5.00000047683716,-5.14521408081055,65.1218872070313,4.72986459732056,-10.4077749252319,64.9902954101563,5,-10.6440238952637,75.6317596435547,4.72986555099487,-16.9152126312256,75.4789352416992,5.00000095367432,-17.1383094787598,85.4963607788086,4.72986698150635,-24.364616394043,85.323600769043,5,-24.572660446167,94.4441528320313,5.00008010864258,-32.8871841430664,94.6315383911133,4.72983837127686,-32.6924362182617,98.6819000244141,82.8489685058594,-36.8038597106934,98.5104904174805,83.118278503418,-37.0146865844727,98.6067047119141,78.5076522827148,-36.7290077209473,98.3990783691406,78.2377243041992,-36.903450012207,96.1720581054688,78.2377243041992,-39.1304817199707,95.9976196289063,78.5076522827148,-39.3381080627441,96.283203125,83.118278503418,-39.2419815063477,102.768844604492,81.8451538085938,-40.9448509216309,102.632362365723,82.1059417724609,-41.1906814575195,102.242713928223,77.6812515258789,-40.4191970825195,101.997947692871,77.4196395874023,-40.5565223693848,99.8251419067383,77.4196395874023,-42.7293434143066,99.6878128051758,77.6812515258789,-42.9741134643555,100.213500976563,81.8453369140625,-43.5002861022949,100.459167480469,82.1059417724609,-43.3638954162598,106.692047119141,79.4483261108398,-44.9149208068848,106.600936889648,79.6815795898438,-45.2061080932617,105.456016540527,75.7077484130859,-43.6793022155762,105.163986206055,75.474967956543,-43.7693672180176,103.037986755371,75.474967956543,-45.8953704833984,102.947929382324,75.7077484130859,-46.1874046325684,104.183609008789,79.448486328125,-47.423511505127,104.474594116211,79.6815795898438,-47.332462310791,110.188659667969,75.3871994018555,-48.4510765075684,110.137733459473,75.5740966796875,-48.7823677062988,108.269172668457,72.3770904541016,-46.5318298339844,107.93701171875,72.1915893554688,-46.5817413330078, +105.850364685059,72.1915893554688,-48.668399810791,105.800453186035,72.3770904541016,-49.000560760498,107.719757080078,75.3872909545898,-50.9201240539551,108.050880432129,75.5740966796875,-50.8692283630371,113.060264587402,69.7372741699219,-51.3546676635742,113.035797119141,69.8725051879883,-51.7123184204102,110.683090209961,67.5686340332031,-48.9775848388672,110.325202941895,67.4341430664063,-49.0017509460449,108.270378112793,67.4341430664063,-51.0565872192383,108.246208190918,67.5686264038086,-51.4144744873047,110.623336791992,69.7373123168945,-53.7917098999023,110.980880737305,69.8725051879883,-53.7672424316406,115.232009887695,62.752025604248,-53.5506629943848,115.22200012207,62.8410568237305,-53.9227294921875,112.614677429199,61.3385581970215,-50.9333610534668,112.242645263672,61.24951171875,-50.9433670043945,110.211990356445,61.24951171875,-52.9740257263184,110.201988220215,61.3385581970215,-53.346061706543,112.819313049316,62.7520446777344,-55.9634284973145,113.19132232666,62.8410606384277,-55.9534187316895,116.6875,54.7475624084473,-55.0225448608398,116.684608459473,54.7977142333984,-55.4017028808594,113.960990905762,53.9592514038086,-52.2960395812988,113.581871032715,53.9088668823242,-52.2989540100098,111.567581176758,53.908863067627,-54.3132553100586,111.564666748047,53.9592475891113,-54.6923713684082,114.291175842285,54.7475662231445,-57.4188995361328,114.670310974121,54.7977142333984,-57.4160079956055,117.418212890625,46.0975914001465,-55.7616539001465,117.418212890625,46.1137619018555,-56.1436882019043,114.650894165039,45.8449211120605,-52.9943313598633,114.26887512207,45.8286399841309,-52.9943313598633,112.262962341309,45.8286361694336,-55.0002593994141,112.262962341309,45.8449172973633,-55.3822860717773,115.030281066895,46.097599029541,-58.1496086120605,115.412300109863,46.11376953125,-58.1496086120605,117.41822052002,37.2260780334473,-55.7616577148438,117.41822052002,37.2099075317383,-56.143684387207,114.650894165039,37.4787521362305,-52.9943237304688,114.26887512207,37.4950332641602,-52.9943237304688, +112.262954711914,37.4950294494629,-55.0002632141113,112.262954711914,37.4787483215332,-55.3822822570801,115.0302734375,37.2260818481445,-58.1496047973633,115.412307739258,37.2099113464355,-58.1496047973633,116.6875,28.5761108398438,-55.0225563049316,116.684616088867,28.5259609222412,-55.401683807373,113.960968017578,29.364429473877,-52.2960205078125,113.581878662109,29.4148101806641,-52.2989387512207,111.567565917969,29.4148063659668,-54.3132629394531,111.564651489258,29.3644275665283,-54.6923522949219,114.291168212891,28.5761203765869,-57.418888092041,114.670318603516,28.5259666442871,-57.4159965515137,115.232032775879,20.5716323852539,-53.5506858825684,115.222023010254,20.4826164245605,-53.9226951599121,112.614639282227,21.9851341247559,-50.9333267211914,112.242668151855,22.0741653442383,-50.9433326721191,110.211952209473,22.074161529541,-52.9740524291992,110.201950073242,21.9851303100586,-53.3460273742676,112.819290161133,20.5716514587402,-55.9634056091309,113.191352844238,20.4826202392578,-55.9533958435059,113.060317993164,13.5863590240479,-51.3547096252441,113.035850524902,13.4511699676514,-51.7122611999512,110.683029174805,15.7550888061523,-48.9775276184082,110.325256347656,15.8895311355591,-49.0016899108887,108.270317077637,15.8895273208618,-51.0566444396973,108.246154785156,15.7550849914551,-51.4144134521484,110.62328338623,13.5864009857178,-53.7916641235352,110.980934143066,13.451171875,-53.7671928405762,110.18872833252,7.93638515472412,-48.4511451721191,110.137832641602,7.7495813369751,-48.7822723388672,108.269088745117,10.9466991424561,-46.5317420959473,107.937126159668,11.1320915222168,-46.5816230773926,105.850242614746,11.1320905685425,-48.6685104370117,105.800361633301,10.9466953277588,-49.0004730224609,107.719696044922,7.93647766113281,-50.9200592041016,108.050987243652,7.74958181381226,-50.8691368103027,106.692108154297,3.87519121170044,-44.9149932861328,106.601058959961,3.64210057258606,-45.205982208252,105.455932617188,7.61613893508911,-43.6792144775391,105.164154052734,7.8487114906311,-43.7691993713379, +103.037811279297,7.84870958328247,-45.8955345153809,102.947830200195,7.61613750457764,-46.187313079834,104.183547973633,3.87534999847412,-47.4234466552734,104.474731445313,3.64209961891174,-47.3323364257813,102.768890380859,1.47834777832031,-40.944896697998,102.632499694824,1.21774280071259,-41.1905555725098,102.24267578125,5.64266109466553,-40.4191474914551,101.998123168945,5.90404605865479,-40.5563545227051,99.8249664306641,5.90404319763184,-42.7295112609863,99.6877593994141,5.64265871047974,-42.974063873291,100.213470458984,1.47852873802185,-43.5002555847168,100.45930480957,1.21773934364319,-43.36376953125,98.6819076538086,0.47459077835083,-36.8038711547852,98.5105743408203,0.205408349633217,-37.0145950317383,98.6067047119141,4.81617784500122,-36.7290000915527,98.3991851806641,5.08596038818359,-36.9033470153809,96.1719512939453,5.08596038818359,-39.1305847167969,95.9976043701172,4.81617975234985,-39.3381004333496,96.0724716186523,0.474717617034912,-39.4133033752441,96.2832946777344,0.205409303307533,-39.2418937683105,91.7614135742188,5,-35.1809463500977,92.1520843505859,5,-35.1718978881836,91.9610443115234,4.72987031936646,-35.3629341125488,91.9610443115234,0.270131468772888,-35.3629341125488,92.1520919799805,7.15255737304688e-007,-35.1718826293945,91.7614135742188,-2.86102294921875e-006,-35.1809463500977,-98.5104751586914,83.1182708740234,-37.0146789550781,-98.681884765625,82.8489608764648,-36.8038520812988,-96.2831802368164,83.1182708740234,-39.2419776916504,-95.9975967407227,78.5076446533203,-39.3381004333496,-96.1720352172852,78.2377166748047,-39.1304740905762,-98.3990631103516,78.2377166748047,-36.9034423828125,-98.606689453125,78.5076446533203,-36.7290000915527,-102.632354736328,82.1059341430664,-41.1906814575195,-102.768836975098,81.8451461791992,-40.9448509216309,-100.459136962891,82.1059341430664,-43.363899230957,-100.213478088379,81.845329284668,-43.5002861022949,-99.6877822875977,77.6812438964844,-42.9741096496582,-99.8251113891602,77.4196319580078,-42.7293395996094,-101.997924804688,77.4196319580078,-40.5565223693848, +-102.242691040039,77.6812438964844,-40.4191970825195,-106.600921630859,79.6815719604492,-45.206111907959,-106.692031860352,79.4483184814453,-44.914924621582,-104.474555969238,79.6815719604492,-47.3324661254883,-104.183570861816,79.4484786987305,-47.4235153198242,-102.947891235352,75.7077407836914,-46.1874084472656,-103.037948608398,75.4749603271484,-45.8953742980957,-105.163955688477,75.4749603271484,-43.7693672180176,-105.455986022949,75.7077407836914,-43.6793060302734,-110.137710571289,75.5740966796875,-48.7823715209961,-110.188629150391,75.3871994018555,-48.4510803222656,-108.050842285156,75.574089050293,-50.8692359924316,-107.719718933105,75.3872833251953,-50.9201316833496,-105.800415039063,72.377082824707,-49.0005645751953,-105.850326538086,72.1915817260742,-48.6684036254883,-107.936973571777,72.1915740966797,-46.5817413330078,-108.269134521484,72.3770751953125,-46.5318298339844,-113.035766601563,69.8725051879883,-51.7123222351074,-113.060241699219,69.7372741699219,-51.3546714782715,-110.980834960938,69.8724975585938,-53.7672538757324,-110.623291015625,69.7373046875,-53.7917213439941,-108.246162414551,67.5686187744141,-51.414478302002,-108.270332336426,67.4341354370117,-51.0565910339355,-110.325157165527,67.4341354370117,-49.0017547607422,-110.683044433594,67.5686187744141,-48.9775886535645,-115.221977233887,62.8410606384277,-53.9227333068848,-115.231986999512,62.7520294189453,-53.550666809082,-113.191268920898,62.8410568237305,-55.9534339904785,-112.819259643555,62.7520408630371,-55.9634399414063,-110.201934814453,61.3385467529297,-53.346061706543,-110.211936950684,61.2495002746582,-52.9740257263184,-112.242607116699,61.2495002746582,-50.9433708190918,-112.614639282227,61.3385467529297,-50.9333648681641,-116.684585571289,54.7977142333984,-55.4017066955566,-116.687469482422,54.7475624084473,-55.0225486755371,-114.670257568359,54.7977104187012,-57.4160194396973,-114.291122436523,54.74755859375,-57.4189109802246,-111.564613342285,53.9592437744141,-54.6923713684082,-111.567527770996,53.9088592529297,-54.3132553100586, +-113.581825256348,53.9088592529297,-52.298957824707,-113.960945129395,53.9592437744141,-52.2960433959961,-117.418190002441,46.11376953125,-56.1436996459961,-117.418190002441,46.097599029541,-55.7616653442383,-115.412254333496,46.11376953125,-58.1496238708496,-115.030235290527,46.097599029541,-58.1496238708496,-112.262908935547,45.8449172973633,-55.3822898864746,-112.262908935547,45.8286361694336,-55.0002632141113,-114.268836975098,45.8286323547363,-52.9943389892578,-114.650856018066,45.844913482666,-52.9943389892578,-117.418197631836,37.2099113464355,-56.1436958312988,-117.418197631836,37.2260818481445,-55.7616691589355,-115.412261962891,37.2099113464355,-58.1496200561523,-115.030227661133,37.2260818481445,-58.1496200561523,-112.262908935547,37.4787483215332,-55.3822860717773,-112.262908935547,37.4950294494629,-55.0002670288086,-114.268829345703,37.4950294494629,-52.9943351745605,-114.650848388672,37.4787483215332,-52.9943351745605,-116.684593200684,28.5259666442871,-55.4016952514648,-116.687484741211,28.5761165618896,-55.0225677490234,-114.670272827148,28.5259685516357,-57.4160079956055,-114.291122436523,28.5761222839355,-57.4188995361328,-111.564598083496,29.3644275665283,-54.6923561096191,-111.567512512207,29.4148082733154,-54.3132705688477,-113.581840515137,29.4148063659668,-52.298942565918,-113.960929870605,29.3644275665283,-52.296028137207,-115.222007751465,20.4826183319092,-53.9227066040039,-115.23201751709,20.5716361999512,-53.5506973266602,-113.191307067871,20.4826221466064,-55.9534072875977,-112.819244384766,20.5716533660889,-55.9634170532227,-110.201904296875,21.9851322174072,-53.3460273742676,-110.211906433105,22.0741634368896,-52.9740524291992,-112.242630004883,22.0741634368896,-50.9433403015137,-112.614601135254,21.9851322174072,-50.9333343505859,-113.035835266113,13.4511709213257,-51.712272644043,-113.06029510498,13.5863609313965,-51.3547210693359,-110.980895996094,13.4511737823486,-53.767204284668,-110.623237609863,13.5864028930664,-53.791675567627,-108.246101379395,15.7550888061523,-51.4144172668457, +-108.270263671875,15.8895320892334,-51.0566482543945,-110.325218200684,15.8895330429077,-49.0016937255859,-110.682991027832,15.755090713501,-48.9775314331055,-110.137817382813,7.74958038330078,-48.7822761535645,-110.188705444336,7.93638467788696,-48.4511489868164,-108.050941467285,7.74958419799805,-50.8691444396973,-107.719650268555,7.9364800453186,-50.9200630187988,-105.800315856934,10.9467000961304,-49.0004730224609,-105.850196838379,11.1320953369141,-48.6685104370117,-107.937088012695,11.1320953369141,-46.5816230773926,-108.269050598145,10.946702003479,-46.5317420959473,-106.601051330566,3.64210081100464,-45.205982208252,-106.692100524902,3.87519216537476,-44.9149932861328,-104.47469329834,3.64210295677185,-47.3323364257813,-104.18350982666,3.87535333633423,-47.4234466552734,-102.947799682617,7.61614608764648,-46.187313079834,-103.037780761719,7.84871816635132,-45.8955345153809,-105.164123535156,7.84871673583984,-43.7691955566406,-105.455902099609,7.61614465713501,-43.6792106628418,-102.632484436035,1.21774196624756,-41.1905479431152,-102.76887512207,1.47834753990173,-40.9448890686035,-100.459274291992,1.21774077415466,-43.3637657165527,-100.213439941406,1.47853016853333,-43.5002479553223,-99.6877365112305,5.64266443252563,-42.9740600585938,-99.8249435424805,5.90404891967773,-42.7295074462891,-101.998092651367,5.90404891967773,-40.5563507080078,-102.242645263672,5.64266443252563,-40.4191436767578,-98.5105667114258,0.205408409237862,-37.0145874023438,-98.6819000244141,0.474591016769409,-36.8038635253906,-96.2832794189453,0.20541013777256,-39.241886138916,-96.0724487304688,0.474718600511551,-39.4132957458496,-95.9975891113281,4.81618356704712,-39.3380928039551,-96.1719360351563,5.08596420288086,-39.1305770874023,-98.399169921875,5.08596229553223,-36.9033393859863,-98.606689453125,4.81617975234985,-36.7289924621582,-91.7613983154297,-2.86102294921875e-006,-35.1809349060059,-92.1520767211914,7.15255737304688e-007,-35.1718711853027,-91.9610290527344,0.270131468772888,-35.362922668457,-91.9610290527344,4.72987031936646,-35.362922668457, +-92.1520690917969,5,-35.1718864440918,-91.7613983154297,5,-35.1809349060059,-89.6443176269531,4.72986793518066,-37.9042282104492,-89.4686431884766,4.99999952316284,-37.6959571838379,-89.4686431884766,-7.15255737304688e-007,-37.6959571838379,-89.6443176269531,0.270131468772888,-37.9042282104492,-75.9273986816406,5.00000190734863,-35.8880500793457,-75.754638671875,4.72986793518066,-36.0960960388184,-67.014030456543,4.72986268997192,-29.4954986572266,-67.1668548583984,4.99999523162842,-29.2724018096924,-75.7546157836914,0.270132839679718,-36.0960731506348,-75.927375793457,2.38418579101563e-007,-35.8880271911621,-67.166877746582,1.19209289550781e-006,-29.2724132537842,-67.0140533447266,0.27013236284256,-29.4955101013184,-57.7017059326172,4.72986316680908,-23.729549407959,-57.8332939147949,4.99999570846558,-23.4933013916016,-57.8332748413086,1.19209289550781e-006,-23.4932918548584,-57.7016868591309,0.270131945610046,-23.7295417785645,-47.8970718383789,4.72986841201782,-18.8474235534668,-48.0063018798828,5.00000095367432,-18.6000442504883,-48.0062866210938,1.19209289550781e-006,-18.6000385284424,-47.8970565795898,0.270132899284363,-18.8474178314209,-37.6837921142578,4.72986841201782,-14.8907814025879,-37.7697296142578,5,-14.634373664856,-37.7697296142578,2.38418579101563e-007,-14.634373664856,-37.6837921142578,0.270135760307312,-14.8907814025879,-27.1490173339844,4.7298698425293,-11.8933773040771,-27.2109298706055,4.99999952316284,-11.6301412582397,-27.2109184265137,2.14576721191406e-006,-11.6301393508911,-27.1490058898926,0.270133852958679,-11.8933753967285,-16.3826236724854,4.72986602783203,-9.8807954788208,-16.4199848175049,4.99999809265137,-9.61295604705811,-16.4199848175049,-1.66893005371094e-006,-9.61295604705811,-16.3826236724854,0.270132422447205,-9.8807954788208,-5.47642993927002,4.72986316680908,-8.87018013000488,-5.48891830444336,4.99999713897705,-8.60004711151123,-5.48892736434937,-3.57627868652344e-006,-8.60004711151123,-5.47643804550171,0.270129084587097,-8.87018013000488,5.47645711898804,4.72986316680908,-8.87017440795898, +5.48894596099854,4.99999713897705,-8.60004138946533,5.48894596099854,-3.57627868652344e-006,-8.60004138946533,5.47645711898804,0.270129084587097,-8.87017440795898,16.3826293945313,4.72986602783203,-9.88079261779785,16.4199905395508,4.99999809265137,-9.61296463012695,16.4200019836426,-1.66893005371094e-006,-9.61296463012695,16.382640838623,0.27013236284256,-9.88079261779785,27.1490230560303,4.7298698425293,-11.8933763504028,27.2109355926514,4.99999952316284,-11.6301441192627,27.2109260559082,2.14576721191406e-006,-11.6301422119141,27.1490135192871,0.270133852958679,-11.8933744430542,37.6837997436523,4.72986841201782,-14.8907861709595,37.7697372436523,5,-14.6343746185303,37.7697372436523,2.38418579101563e-007,-14.6343765258789,37.6837997436523,0.270135790109634,-14.8907880783081,47.8970909118652,4.72986841201782,-18.8474388122559,48.0063209533691,5.00000095367432,-18.6000480651855,48.0063171386719,1.19209289550781e-006,-18.6000442504883,47.897087097168,0.270132839679718,-18.8474349975586,57.7017211914063,4.72986316680908,-23.7295589447021,57.833309173584,4.99999570846558,-23.4933109283447,57.833324432373,1.19209289550781e-006,-23.4933204650879,57.7017364501953,0.270131945610046,-23.7295684814453,67.0140533447266,4.72986221313477,-29.4955139160156,67.166877746582,4.99999523162842,-29.2724170684814,67.1669082641602,1.19209289550781e-006,-29.2724323272705,67.0140838623047,0.27013224363327,-29.4955291748047,75.7546615600586,4.72986793518066,-36.0961227416992,75.9274215698242,5.00000190734863,-35.8880767822266,75.9274139404297,2.38418579101563e-007,-35.888069152832,75.7546539306641,0.27013286948204,-36.0961151123047,89.4686660766602,4.99999952316284,-37.695972442627,89.6443405151367,4.72986793518066,-37.904239654541,78.3127593994141,4.72986698150635,-38.4281349182129,78.4684677124023,4.99999952316284,-38.2045440673828,89.6443405151367,0.270131468772888,-37.904239654541,89.4686660766602,-7.15255737304688e-007,-37.695972442627,78.4684677124023,2.86102294921875e-006,-38.2045402526855,78.3127593994141,0.270130187273026,-38.4281311035156, +-78.4684448242188,4.99999952316284,-38.2045211791992,-78.3127365112305,4.72986698150635,-38.4281120300293,-78.3127365112305,0.270130276679993,-38.4281120300293,-78.4684448242188,2.86102294921875e-006,-38.2045211791992,-86.1482315063477,4.72986745834351,-40.144115447998,-86.0634536743164,4.99999904632568,-39.877613067627,-86.0634536743164,-2.38418579101563e-006,-39.877613067627,-86.1482315063477,0.270132660865784,-40.144115447998,-82.0005798339844,4.72986507415771,-40.3358726501465,-82.0604095458984,5.00000190734863,-40.062686920166,-82.0604095458984,-9.5367431640625e-007,-40.062686920166,-82.0005798339844,0.270135521888733,-40.3358726501465,82.000602722168,4.72986507415771,-40.3358917236328,82.060432434082,5.00000190734863,-40.0627059936523,82.060432434082,-9.5367431640625e-007,-40.0627021789551,82.000602722168,0.270135402679443,-40.3358879089355,86.1482543945313,4.72986745834351,-40.1441307067871,86.0634765625,4.99999904632568,-39.877628326416,86.0634765625,-2.38418579101563e-006,-39.877628326416,86.1482543945313,0.270132660865784,-40.1441307067871,-86.1897201538086,78.6237640380859,-38.8950538635254,-89.0711135864258,78.5386657714844,-43.663818359375,-80.6813583374023,78.6515045166016,-39.9868278503418,-81.7489166259766,78.5672149658203,-45.3726387023926,-74.9691314697266,78.6769180297852,-39.4104385375977,-74.385368347168,78.5933837890625,-44.8047027587891,-68.8010025024414,78.699951171875,-37.5123443603516,-67.152946472168,78.6172103881836,-42.6215476989746,-62.1925888061523,78.7206115722656,-34.5955505371094,-59.9889450073242,78.6386489868164,-39.4320182800293,-55.2234268188477,78.738899230957,-31.0213279724121,-52.7927894592285,78.6576843261719,-35.6922760009766,-47.9520111083984,78.7548217773438,-27.1502933502197,-45.506778717041,78.6742858886719,-31.763708114624,-40.4174461364746,78.7683563232422,-23.3064727783203,-38.1116790771484,78.6884078979492,-27.9482345581055,-32.651180267334,78.7794952392578,-19.7678527832031,-30.612434387207,78.7000579833984,-24.4975814819336,-24.6848545074463,78.7882232666016,-16.7653865814209, +-23.0276660919189,78.7091827392578,-21.6142272949219,-16.5554313659668,78.7945098876953,-14.4832572937012,-15.3818626403809,78.7157592773438,-19.4512329101563,-8.30865478515625,78.79833984375,-13.0575408935547,-7.69921398162842,78.7197647094727,-18.1134643554688,5.62667846679688e-005,78.7996673583984,-12.5727710723877,4.33921813964844e-005,78.7211608886719,-17.6610107421875,8.30876636505127,78.7983474731445,-13.0575523376465,7.69930076599121,78.7197647094727,-18.1134719848633,16.5555381774902,78.7945175170898,-14.4832792282104,15.3819484710693,78.7157669067383,-19.4512500762939,24.6849594116211,78.7882308959961,-16.7654190063477,23.0277481079102,78.7091827392578,-21.6142501831055,32.6512794494629,78.7795028686523,-19.7678909301758,30.6125106811523,78.700065612793,-24.4976100921631,40.417537689209,78.7683639526367,-23.3065166473389,38.1117553710938,78.6884231567383,-27.9482669830322,47.9520950317383,78.7548294067383,-27.1503391265869,45.5068435668945,78.6742935180664,-31.763744354248,55.223503112793,78.7389144897461,-31.0213756561279,52.7928504943848,78.6576995849609,-35.6923065185547,62.1926612854004,78.7206192016602,-34.5955924987793,59.9890060424805,78.6386642456055,-39.4320526123047,68.8010711669922,78.699951171875,-37.5123825073242,67.1529922485352,78.6172103881836,-42.6215782165527,74.9691848754883,78.6769256591797,-39.4104614257813,74.3853988647461,78.593391418457,-44.8047256469727,80.681396484375,78.6515045166016,-39.9868431091309,81.7489395141602,78.5672149658203,-45.3726654052734,86.1897506713867,78.6237640380859,-38.8950653076172,89.0711364746094,78.5386657714844,-43.6638374328613,83.5052795410156,78.6376342773438,-39.746654510498,85.5079727172852,78.5531158447266,-44.9173469543457,77.8048782348633,78.6648788452148,-39.8889770507813,78.0442886352539,78.5806732177734,-45.3531455993652,-83.505241394043,78.6376342773438,-39.746639251709,-85.5079574584961,78.553108215332,-44.9173164367676,-77.8048324584961,78.6648788452148,-39.8889579772949,-78.0442581176758,78.5806655883789,-45.3531188964844,-96.0659408569336,82.4715042114258,-39.4067611694336, +-96.3051452636719,82.7926864624023,-39.6429595947266,-96.2552871704102,83.0826416015625,-39.2646560668945,-95.7960052490234,82.8628234863281,-39.140983581543,-88.9592971801758,82.8310241699219,-43.4113693237305,-89.1214141845703,82.4394149780273,-43.744758605957,-92.2420654296875,83.0394058227539,-35.6400260925293,-91.6675415039063,83.0535430908203,-35.0953712463379,-91.9579315185547,82.665641784668,-35.3601036071777,-86.3481750488281,83.0048675537109,-39.2447814941406,-86.1863708496094,82.6312942504883,-38.8900871276855,-85.4578399658203,82.8163223266602,-44.6448745727539,-85.5412368774414,82.4246063232422,-45.0062370300293,-83.5786056518555,82.9887390136719,-40.1234016418457,-83.502799987793,82.6152954101563,-39.7413291931152,-81.7458190917969,82.8018112182617,-45.0963973999023,-81.7661437988281,82.4101028442383,-45.4651260375977,-78.0765914916992,82.7877502441406,-45.0784111022949,-78.0473098754883,82.3960876464844,-45.4468116760254,-80.6798706054688,82.5996398925781,-39.9813613891602,-80.6896591186523,82.9729766845703,-40.3687896728516,-77.7652053833008,82.9577102661133,-40.2693023681641,-77.80419921875,82.5841979980469,-39.883472442627,-74.456169128418,82.7745666503906,-44.5367088317871,-74.3743515014648,82.3829040527344,-44.8971061706543,-67.2528305053711,82.7497253417969,-42.3628196716309,-67.1238403320313,82.358154296875,-42.7089195251465,-74.9693222045898,82.5704193115234,-39.4050712585449,-74.8798370361328,82.9438171386719,-39.7822494506836,-68.6668548583984,82.9173355102539,-37.8703346252441,-68.8022842407227,82.5437088012695,-37.5073318481445,-60.1106643676758,82.7274780273438,-39.1824684143066,-59.9504623413086,82.3359451293945,-39.5146255493164,-62.0279884338379,82.8932571411133,-34.9401016235352,-62.1944351196289,82.5196075439453,-34.5908584594727,-52.9206848144531,82.7077331542969,-35.4450035095215,-52.7505645751953,82.3162384033203,-35.7719993591309,-55.0469627380371,82.8717727661133,-31.3598461151123,-55.2255172729492,82.4981231689453,-31.0168380737305,-45.6363525390625,82.6905288696289,-31.5163612365723, +-45.4650001525879,82.2990341186523,-31.8427257537842,-47.7754211425781,82.8529739379883,-27.488805770874,-47.9548416137695,82.4793243408203,-27.1462554931641,-38.2333526611328,82.6758728027344,-27.6959896087646,-38.0718269348145,82.2843780517578,-28.0274105072021,-40.2513771057129,82.8369293212891,-23.6503963470459,-40.4200592041016,82.4632720947266,-23.3023509979248,-30.7198219299316,82.6637954711914,-24.2381172180176,-30.5772476196289,82.2723007202148,-24.5782451629639,-32.5044784545898,82.8236923217773,-20.1206169128418,-32.6529808044434,82.4500503540039,-19.7633628845215,-23.114860534668,82.6543273925781,-21.346607208252,-22.9990940093994,82.2628326416016,-21.6969261169434,-24.5656700134277,82.8132934570313,-17.128547668457,-24.6863269805908,82.4396591186523,-16.7607917785645,-15.4435567855835,82.6475067138672,-19.1760902404785,-15.361644744873,82.2560119628906,-19.5359573364258,-16.4710693359375,82.8058013916016,-14.8562116622925,-16.5564785003662,82.4321670532227,-14.4785537719727,-7.73123073577881,82.6433563232422,-17.8329544067383,-7.68871688842773,82.2518615722656,-18.1996917724609,-8.26487064361572,82.8012390136719,-13.4375257492065,-8.30920600891113,82.4276123046875,-13.0527582168579,4.88245677843224e-005,82.6419219970703,-17.3785610198975,4.81299539387692e-005,82.2504272460938,-17.7477912902832,4.31912412750535e-005,82.7996597290039,-12.9553318023682,4.46349949925207e-005,82.426025390625,-12.5679578781128,7.7313289642334,82.6433563232422,-17.8329582214355,7.68881320953369,82.2518539428711,-18.1996994018555,8.26495552062988,82.8012390136719,-13.4375419616699,8.30929470062256,82.427604675293,-13.0527677536011,15.4436550140381,82.6475143432617,-19.176097869873,15.3617401123047,82.2560043334961,-19.5359725952148,16.4711513519287,82.8058090209961,-14.8562421798706,16.5565662384033,82.4321594238281,-14.4785709381104,23.1149597167969,82.6543273925781,-21.346622467041,22.9991893768311,82.262825012207,-21.696949005127,24.5657482147217,82.8133010864258,-17.128589630127,24.6864128112793,82.4396514892578,-16.760814666748, +30.7199192047119,82.6638031005859,-24.2381324768066,30.5773391723633,82.2722930908203,-24.5782699584961,32.5045547485352,82.8236999511719,-20.120662689209,32.6530685424805,82.4500350952148,-19.7633895874023,38.2334442138672,82.6758804321289,-27.6960124969482,38.0719146728516,82.2843704223633,-28.0274410247803,40.2514533996582,82.8369445800781,-23.6504306793213,40.4201393127441,82.4632873535156,-23.3023853302002,45.6364364624023,82.6905364990234,-31.5163955688477,45.4650840759277,82.2990417480469,-31.8427600860596,47.7754936218262,82.8529815673828,-27.488842010498,47.9549140930176,82.4793319702148,-27.1462917327881,52.9207649230957,82.7077484130859,-35.4450225830078,52.7506370544434,82.3162384033203,-35.7720260620117,55.0470275878906,82.8717803955078,-31.3598747253418,55.2255821228027,82.4981384277344,-31.0168762207031,60.110725402832,82.7274932861328,-39.1825332641602,59.9505386352539,82.3359985351563,-39.5146598815918,62.0280609130859,82.8932647705078,-34.9401092529297,62.1944923400879,82.5196533203125,-34.5908966064453,67.2528533935547,82.7497406005859,-42.3629302978516,67.1238861083984,82.3582611083984,-42.7089462280273,68.6669311523438,82.9173431396484,-37.8702926635742,68.8023300170898,82.5437927246094,-37.5073699951172,74.4561920166016,82.7745742797852,-44.5368804931641,74.3744049072266,82.3830795288086,-44.8971290588379,74.8798751831055,82.9438247680664,-39.7822723388672,74.969367980957,82.5704345703125,-39.4050941467285,78.0766220092773,82.7877502441406,-45.0785942077637,78.0473556518555,82.3962631225586,-45.4468307495117,77.765251159668,82.9577178955078,-40.2691917419434,77.8042297363281,82.5843276977539,-39.8834915161133,81.7458648681641,82.8018112182617,-45.096565246582,81.7661819458008,82.410270690918,-45.4651412963867,85.4579544067383,82.8163146972656,-44.6451568603516,85.5412826538086,82.4248886108398,-45.0062561035156,80.6799011230469,82.5995178222656,-39.9813804626465,80.6896896362305,82.9729766845703,-40.3689308166504,83.5785827636719,82.9887466430664,-40.1231880187988,83.5028228759766,82.6155319213867,-39.7413482666016, +95.796028137207,82.8628311157227,-39.1409873962402,96.2553100585938,83.082649230957,-39.2646598815918,96.3051681518555,82.7926940917969,-39.6429634094238,96.0659637451172,82.4715118408203,-39.4067687988281,88.9594345092773,82.8310241699219,-43.4115982055664,89.1195526123047,82.4396514892578,-43.745964050293,91.9579467773438,82.665641784668,-35.3601150512695,91.6675567626953,83.0535430908203,-35.0953826904297,92.2420806884766,83.0394058227539,-35.6400375366211,86.1880798339844,82.6315460205078,-38.8890686035156,86.3480987548828,83.0048751831055,-39.2445755004883 + } + PolygonVertexIndex: *4196 { + a: 0,233,-235,43,42,48,-54,1,0,234,235,-21,51,50,56,-62,2,1,20,-22,59,58,64,-70,3,2,21,-23,67,66,72,-78,4,3,22,-24,75,74,80,-86,5,4,23,-25,83,82,88,-94,6,5,24,-26,91,90,96,-102,7,6,25,-27,99,98,104,-110,8,7,26,-28,107,106,112,-118,9,8,27,-29,115,114,120,-126,10,9,28,-30,123,122,128,-134,11,10,29,-31,131,130,136,-142,12,11,30,-32,139,138,144,-150,13,12,31,-33,147,146,152,-158,14,13,32,-34,155,154,160,-166,15,14,33,-35,163,162,168,-174,16,15,34,-36,171,170,176,-182,17,16,35,-37,179,178,184,-190,18,17,36,-38,187,186,192,-198,19,18,37,-39,195,194,200,-206,203,202,208,-214,211,210,216,-222,219,218,228,-230,49,48,42,-42,53,52,44,-44,57,56,50,-50,61,60,52,-52,65,64,58,-58,69,68,60,-60,73,72,66,-66,77,76,68,-68,81,80,74,-74,85,84,76,-76,89,88,82,-82,93,92,84,-84,97,96,90,-90,101,100,92,-92,105,104,98,-98,109,108,100,-100,113,112,106,-106,117,116,108,-108,121,120,114,-114,125,124,116,-116,129,128,122,-122,133,132,124,-124,137,136,130,-130,141,140,132,-132,145,144,138,-138,149,148,140,-140,153,152,146,-146,157,156,148,-148,161,160,154,-154,165,164,156,-156,169,168,162,-162,173,172,164,-164,177,176,170,-170,181,180,172,-172,185,184,178,-178,189,188,180,-180,193,192,186,-186,197,196,188,-188,201,200,194,-194,205,204,196,-196,209,208,202,-202,204,212,226,224,-39,217,216,210,-210,212,220,230,-227,40,39,46,-46,39,42,43,-47,48,47,54,-54,47,50,51,-55,56,55,62,-62,55,58,59,-63,64,63,70,-70,63,66,67,-71,72,71,78,-78,71,74,75,-79,80,79,86,-86,79,82,83,-87,88,87,94,-94,87,90,91,-95,96,95,102,-102,95,98,99,-103,104,103,110,-110,103,106,107,-111,112,111,118,-118,111,114,115,-119,120,119,126,-126,119,122,123,-127,128,127,134,-134,127,130,131,-135,136,135,142,-142,135,138,139,-143,144,143,150,-150,143,146,147,-151,152,151,158,-158,151,154,155,-159,160,159,166,-166,159,162,163,-167,168,167,174,-174,167,170,171,-175,176,175,182,-182,175,178,179,-183,184,183,190,-190,183,186,187,-191,192,191,198,-198,191,194,195,-199,200,199,206,-206,199,202,203,-207,208,207,214,-214,207,210,211,-215,216,215,222,-222,215,218,219,-223,41,42,-40, +41,39,-41,44,45,-47,44,46,-44,49,50,-48,49,47,-49,52,53,-55,52,54,-52,57,58,-56,57,55,-57,60,61,-63,60,62,-60,65,66,-64,65,63,-65,68,69,-71,68,70,-68,73,74,-72,73,71,-73,76,77,-79,76,78,-76,81,82,-80,81,79,-81,84,85,-87,84,86,-84,89,90,-88,89,87,-89,92,93,-95,92,94,-92,97,98,-96,97,95,-97,100,101,-103,100,102,-100,105,106,-104,105,103,-105,108,109,-111,108,110,-108,113,114,-112,113,111,-113,116,117,-119,116,118,-116,121,122,-120,121,119,-121,124,125,-127,124,126,-124,129,130,-128,129,127,-129,132,133,-135,132,134,-132,137,138,-136,137,135,-137,140,141,-143,140,142,-140,145,146,-144,145,143,-145,148,149,-151,148,150,-148,153,154,-152,153,151,-153,156,157,-159,156,158,-156,161,162,-160,161,159,-161,164,165,-167,164,166,-164,169,170,-168,169,167,-169,172,173,-175,172,174,-172,177,178,-176,177,175,-177,180,181,-183,180,182,-180,185,186,-184,185,183,-185,188,189,-191,188,190,-188,193,194,-192,193,191,-193,196,197,-199,196,198,-196,201,202,-200,201,199,-201,204,205,-207,204,206,-204,209,210,-208,209,207,-209,212,213,-215,212,214,-212,217,218,-216,217,215,-217,220,221,-223,220,222,-220,196,204,38,-38,213,212,204,-204,221,220,212,-212,188,196,37,-37,180,188,36,-36,172,180,35,-35,164,172,34,-34,156,164,33,-33,148,156,32,-32,140,148,31,-31,132,140,30,-30,124,132,29,-29,116,124,28,-28,108,116,27,-27,100,108,26,-26,92,100,25,-25,84,92,24,-24,76,84,23,-23,68,76,22,-22,60,68,21,-21,52,60,20,235,-241,44,52,240,-238,41,242,-237,49,41,236,233,-1,57,49,0,-2,65,57,1,-3,73,65,2,-4,81,73,3,-5,89,81,4,-6,97,89,5,-7,105,97,6,-8,113,105,7,-9,121,113,8,-10,129,121,9,-11,137,129,10,-12,145,137,11,-13,153,145,12,-14,161,153,13,-15,169,161,14,-16,177,169,15,-17,185,177,16,-18,193,185,17,-19,201,193,18,-20,209,201,19,223,-226,217,209,225,-228,224,223,19,-39,232,228,218,-218,231,230,-221,229,231,220,-220,227,232,-218,239,238,40,-46,238,242,41,-41,241,239,45,-45,237,241,-45,275,276,628,-628,276,275,278,-278,277,278,280,-280,279,280,282,-282,281,282,284,-284,283,284,286,-286,285,286,288,-288,287,288,290,-290,289,290,292,-292,291,292,294,-294,293, +294,296,-296,295,296,298,-298,297,298,300,-300,299,300,302,-302,301,302,304,-304,303,304,306,-306,305,306,308,-308,307,308,310,-310,309,310,492,-492,311,312,622,-624,312,311,313,-315,314,313,315,-317,316,315,317,-319,318,317,319,-321,320,319,321,-323,322,321,323,-325,324,323,325,-327,326,325,327,-329,328,327,329,-331,330,329,331,-333,332,331,333,-335,334,333,335,-337,336,335,337,-339,338,337,339,-341,340,339,341,-343,342,341,343,-345,344,343,346,-346,345,346,489,-491,347,915,912,911,-625,349,348,350,-352,351,350,352,-354,353,352,354,-356,355,354,356,-358,357,356,358,-360,359,358,360,-362,361,360,362,-364,363,362,364,-366,365,364,366,-368,367,366,368,-370,369,368,370,-372,371,370,372,-374,373,372,374,-376,375,374,376,-378,377,376,378,-380,379,378,380,-1036,381,382,626,-626,382,381,383,-385,384,383,385,-387,386,385,387,-389,388,387,389,-391,390,389,391,-393,392,391,393,-395,394,393,395,-397,396,395,397,-399,398,397,399,-401,400,399,401,-403,402,401,403,-405,404,403,405,-407,406,405,407,-409,408,407,409,-411,410,409,411,-413,412,411,413,-415,414,413,416,-416,415,416,494,-494,417,418,742,-742,418,417,420,-420,419,420,422,-422,421,422,424,-424,423,424,426,-426,425,426,428,-428,427,428,430,-430,429,430,432,-432,431,432,434,-434,433,434,436,-436,435,436,438,-438,437,438,440,-440,439,440,442,-442,441,442,444,-444,443,444,446,-446,445,446,448,-448,447,448,450,-450,449,450,452,-452,451,452,609,-609,453,454,747,-749,454,453,455,-457,456,455,457,-459,458,457,459,-461,460,459,461,-463,462,461,463,-465,464,463,465,-467,466,465,467,-469,468,467,469,-471,470,469,471,-473,472,471,473,-475,474,473,475,-477,476,475,477,-479,478,477,479,-481,480,479,481,-483,482,481,483,-485,484,483,485,-487,486,485,488,-488,487,488,610,-612,490,489,496,-498,491,492,499,-499,493,494,501,-501,497,496,504,-506,498,499,507,-507,500,501,509,-509,502,503,511,-511,505,504,512,-514,506,507,515,-515,508,509,517,-517,510,511,519,-519,513,512,520,-522,514,515,523,-523,516,517,525,-525,518,519,527,-527,521,520,528,-530,522,523,531,-531,524,525,533,-533,526,527, +535,-535,529,528,536,-538,530,531,539,-539,532,533,541,-541,534,535,543,-543,537,536,544,-546,538,539,547,-547,540,541,549,-549,542,543,551,-551,545,544,552,-554,546,547,555,-555,548,549,557,-557,550,551,559,-559,553,552,560,-562,554,555,563,-563,556,557,565,-565,558,559,567,-567,561,560,568,-570,562,563,571,-571,564,565,573,-573,566,567,575,-575,569,568,576,-578,570,571,579,-579,572,573,581,-581,574,575,583,-583,577,576,584,-586,578,579,587,-587,580,581,589,-589,582,583,591,-591,585,584,592,-594,586,587,595,-595,588,589,597,-597,590,591,599,-599,593,592,600,-602,594,595,603,-603,596,597,605,-605,598,599,607,-607,601,600,608,-610,602,603,611,-611,604,605,613,-613,606,607,615,-615,612,613,618,-618,614,615,620,-620,616,618,824,-824,619,621,828,-828,623,622,629,-631,624,911,910,632,-632,625,626,634,-634,627,628,636,-636,630,629,637,-639,631,632,640,-640,633,634,642,-642,635,636,644,-644,638,637,645,-647,639,640,648,-648,641,642,650,-650,643,644,652,-652,646,645,653,-655,647,648,656,-656,649,650,658,-658,651,652,660,-660,654,653,661,-663,655,656,664,-664,657,658,666,-666,659,660,668,-668,662,661,669,-671,663,664,672,-672,665,666,674,-674,667,668,676,-676,670,669,677,-679,671,672,680,-680,673,674,682,-682,675,676,684,-684,678,677,685,-687,679,680,688,-688,681,682,690,-690,683,684,692,-692,686,685,693,-695,687,688,696,-696,689,690,698,-698,691,692,700,-700,694,693,701,-703,695,696,704,-704,697,698,706,-706,699,700,708,-708,702,701,709,-711,703,704,712,-712,705,706,714,-714,707,708,716,-716,710,709,717,-719,711,712,720,-720,713,714,722,-722,715,716,724,-724,718,717,725,-727,719,720,728,-728,721,722,730,-730,723,724,732,-732,726,725,733,-735,727,728,736,-736,729,730,738,-738,731,732,740,-740,734,733,741,-743,735,736,744,-744,737,738,746,-746,739,740,748,-748,743,744,751,-751,745,746,753,-753,749,751,758,-758,752,754,756,-756,755,756,836,-836,757,758,838,-838,759,760,832,-832,760,759,762,-762,761,762,768,-768,763,764,834,-834,764,763,766,-766,765,766,770,-770,767,768,772,-772,769,770,774,-774,771,772,776,-776,773,774,778,-778, +775,776,780,-780,777,778,782,-782,779,780,784,-784,781,782,786,-786,783,784,788,-788,785,786,790,-790,787,788,792,-792,789,790,794,-794,791,792,796,-796,793,794,798,-798,795,796,800,-800,797,798,802,-802,799,800,804,-804,801,802,806,-806,803,804,808,-808,805,806,810,-810,807,808,812,-812,809,810,814,-814,811,812,816,-816,813,814,818,-818,815,816,820,-820,817,818,822,-822,819,820,826,-826,821,822,830,-830,823,824,847,-849,825,826,844,-844,827,828,849,-851,829,830,846,-846,831,832,839,-841,833,834,841,-843,835,836,840,-840,837,838,842,-842,843,844,848,-848,845,846,850,-850,276,277,313,-312,277,279,315,-314,279,281,317,-316,281,283,319,-318,283,285,321,-320,285,287,323,-322,287,289,325,-324,289,291,327,-326,291,293,329,-328,293,295,331,-330,295,297,333,-332,297,299,335,-334,299,301,337,-336,301,303,339,-338,303,305,341,-340,305,307,343,-342,307,309,346,-344,312,314,348,-348,314,316,350,-349,316,318,352,-351,318,320,354,-353,320,322,356,-355,322,324,358,-357,324,326,360,-359,326,328,362,-361,328,330,364,-363,330,332,366,-365,332,334,368,-367,334,336,370,-369,336,338,372,-371,338,340,374,-373,340,342,376,-375,342,344,378,-377,344,345,380,-379,349,351,385,-384,351,353,387,-386,353,355,389,-388,355,357,391,-390,357,359,393,-392,359,361,395,-394,361,363,397,-396,363,365,399,-398,365,367,401,-400,367,369,403,-402,369,371,405,-404,371,373,407,-406,373,375,409,-408,375,377,411,-410,377,379,413,-412,379,1035,1034,416,-414,382,384,278,-276,384,386,280,-279,386,388,282,-281,388,390,284,-283,390,392,286,-285,392,394,288,-287,394,396,290,-289,396,398,292,-291,398,400,294,-293,400,402,296,-295,402,404,298,-297,404,406,300,-299,406,408,302,-301,408,410,304,-303,410,412,306,-305,412,414,308,-307,414,415,310,-309,418,419,455,-454,419,421,457,-456,421,423,459,-458,423,425,461,-460,425,427,463,-462,427,429,465,-464,429,431,467,-466,431,433,469,-468,433,435,471,-470,435,437,473,-472,437,439,475,-474,439,441,477,-476,441,443,479,-478,443,445,481,-480,445,447,483,-482,447,449,485,-484,449,451,488,-486,454,456,243,754,-754,456,458,244,-244, +458,460,245,-245,460,462,246,-246,462,464,247,-247,464,466,248,-248,466,468,249,-249,468,470,250,-250,470,472,251,-251,472,474,252,-252,474,476,253,-253,476,478,254,-254,478,480,255,-255,480,482,256,-256,482,484,257,-257,484,486,258,-258,486,487,617,616,-259,833,832,760,-764,760,761,766,-764,761,767,770,-767,767,771,774,-771,771,775,778,-775,775,779,782,-779,779,783,786,-783,783,787,790,-787,787,791,794,-791,791,795,798,-795,795,799,802,-799,799,803,806,-803,803,807,810,-807,807,811,814,-811,811,815,818,-815,815,819,822,-819,819,825,830,-823,259,260,422,-421,260,261,424,-423,261,262,426,-425,262,263,428,-427,263,264,430,-429,264,265,432,-431,265,266,434,-433,266,267,436,-435,267,268,438,-437,268,269,440,-439,269,270,442,-441,270,271,444,-443,271,272,446,-445,272,273,448,-447,273,274,450,-449,274,621,620,452,-451,608,610,488,-452,611,612,617,-488,613,614,619,-619,615,609,452,-621,346,309,491,-490,310,415,493,-493,380,345,490,-496,489,491,498,-497,492,493,500,-500,494,1031,1030,502,-502,495,490,497,-504,496,498,506,-505,499,500,508,-508,501,502,510,-510,503,497,505,-512,504,506,514,-513,507,508,516,-516,509,510,518,-518,511,505,513,-520,512,514,522,-521,515,516,524,-524,517,518,526,-526,519,513,521,-528,520,522,530,-529,523,524,532,-532,525,526,534,-534,527,521,529,-536,528,530,538,-537,531,532,540,-540,533,534,542,-542,535,529,537,-544,536,538,546,-545,539,540,548,-548,541,542,550,-550,543,537,545,-552,544,546,554,-553,547,548,556,-556,549,550,558,-558,551,545,553,-560,552,554,562,-561,555,556,564,-564,557,558,566,-566,559,553,561,-568,560,562,570,-569,563,564,572,-572,565,566,574,-574,567,561,569,-576,568,570,578,-577,571,572,580,-580,573,574,582,-582,575,569,577,-584,576,578,586,-585,579,580,588,-588,581,582,590,-590,583,577,585,-592,584,586,594,-593,587,588,596,-596,589,590,598,-598,591,585,593,-600,592,594,602,-601,595,596,604,-604,597,598,606,-606,599,593,601,-608,600,602,610,-609,603,604,612,-612,605,606,614,-614,607,601,609,-616,741,743,750,-418,744,745,752,-752,746,747,454,-754,748,742,418,-454,312,347,624, +-623,382,275,627,-627,276,311,623,-629,622,624,631,-630,626,627,635,-635,628,623,630,-637,629,631,639,-638,632,633,641,-641,634,635,643,-643,636,630,638,-645,637,639,647,-646,640,641,649,-649,642,643,651,-651,644,638,646,-653,645,647,655,-654,648,649,657,-657,650,651,659,-659,652,646,654,-661,653,655,663,-662,656,657,665,-665,658,659,667,-667,660,654,662,-669,661,663,671,-670,664,665,673,-673,666,667,675,-675,668,662,670,-677,669,671,679,-678,672,673,681,-681,674,675,683,-683,676,670,678,-685,677,679,687,-686,680,681,689,-689,682,683,691,-691,684,678,686,-693,685,687,695,-694,688,689,697,-697,690,691,699,-699,692,686,694,-701,693,695,703,-702,696,697,705,-705,698,699,707,-707,700,694,702,-709,701,703,711,-710,704,705,713,-713,706,707,715,-715,708,702,710,-717,709,711,719,-718,712,713,721,-721,714,715,723,-723,716,710,718,-725,717,719,727,-726,720,721,729,-729,722,723,731,-731,724,718,726,-733,725,727,735,-734,728,729,737,-737,730,731,739,-739,732,726,734,-741,733,735,743,-742,736,737,745,-745,738,739,747,-747,740,734,742,-749,758,751,752,-756,243,244,762,-760,260,259,764,-766,244,245,768,-763,261,260,765,-770,245,246,772,-769,262,261,769,-774,246,247,776,-773,263,262,773,-778,247,248,780,-777,264,263,777,-782,248,249,784,-781,265,264,781,-786,249,250,788,-785,266,265,785,-790,250,251,792,-789,267,266,789,-794,251,252,796,-793,268,267,793,-798,252,253,800,-797,269,268,797,-802,253,254,804,-801,270,269,801,-806,254,255,808,-805,271,270,805,-810,255,256,812,-809,272,271,809,-814,256,257,816,-813,273,272,813,-818,257,258,820,-817,274,273,817,-822,824,618,619,-828,755,835,838,-759,835,839,842,-839,839,832,833,-843,825,843,846,-831,843,847,850,-847,847,824,827,-851,840,836,756,754,243,759,-832,837,841,834,764,259,749,-758,848,844,826,820,258,616,-824,828,621,274,821,829,845,-850,750,749,259,420,-418,616,617,-619,619,620,-622,749,750,-752,752,753,-755,899,900,494,-417,381,625,852,-852,905,906,854,-854,907,908,856,-856,855,856,858,-858,857,858,860,-860,859,860,862,-862,861,862,864,-864,863,864,866,-866,865,866,868,-868,867, +868,870,-870,869,870,872,-872,871,872,874,-874,873,874,876,-876,875,876,878,-878,877,878,880,-880,879,880,882,-882,881,882,884,-884,883,884,886,-886,885,886,888,-888,887,888,890,-890,889,890,892,-892,891,892,894,-894,893,894,896,-896,903,904,898,-898,901,902,900,-900,897,898,902,-902,895,896,904,-904,851,852,906,-906,853,854,908,-908,910,909,625,633,-633,916,347,348,-350,917,916,349,383,-382,1030,1029,495,503,-503,1036,380,495,1029,-1029,909,912,913,-915,914,913,920,-922,915,917,919,-919,918,919,923,-923,921,920,924,-926,922,923,928,-930,925,924,926,-928,927,926,932,-934,929,928,931,-931,930,931,936,-938,933,932,934,-936,935,934,940,-942,937,936,939,-939,938,939,943,-943,941,940,944,-946,942,943,947,-947,945,944,948,-950,946,947,951,-951,949,948,952,-954,950,951,955,-955,953,952,956,-958,954,955,959,-959,957,956,960,-962,958,959,963,-963,961,960,964,-966,962,963,967,-967,965,964,968,-970,966,967,971,-971,969,968,972,-974,970,971,975,-975,973,972,976,-978,974,975,979,-979,977,976,980,-982,978,979,983,-983,981,980,984,-986,982,983,987,-987,985,984,988,-990,986,987,991,-991,989,988,992,-994,990,991,995,-995,993,992,996,-998,994,995,999,-999,997,996,1000,-1002,998,999,1003,-1003,1001,1000,1004,-1006,1002,1003,1007,-1007,1005,1004,1008,-1010,1006,1007,1011,-1011,1009,1008,1012,-1014,1010,1011,1015,-1015,1013,1012,1016,-1018,1014,1015,1019,-1019,1017,1016,1020,-1022,1018,1019,1024,-1026,1021,1020,1022,-1024,1023,1022,1032,-1034,1025,1024,1027,-1027,1026,1027,1037,-1039,1028,1031,1033,-1033,1034,1036,1038,-1038,1032,1038,1036,-1029,1037,899,416,-1035,900,1033,1031,-495,913,912,915,-919,919,917,381,-852,625,909,914,-853,920,922,929,-925,923,905,853,-929,906,921,925,-855,926,930,937,-933,931,907,855,-937,908,927,933,-857,932,937,938,-935,936,855,857,-940,856,933,935,-859,934,938,942,-941,939,857,859,-944,858,935,941,-861,940,942,946,-945,943,859,861,-948,860,941,945,-863,944,946,950,-949,947,861,863,-952,862,945,949,-865,948,950,954,-953,951,863,865,-956,864,949,953,-867,952,954,958,-957,955,865,867,-960,866,953,957,-869,956, +958,962,-961,959,867,869,-964,868,957,961,-871,960,962,966,-965,963,869,871,-968,870,961,965,-873,964,966,970,-969,967,871,873,-972,872,965,969,-875,968,970,974,-973,971,873,875,-976,874,969,973,-877,972,974,978,-977,975,875,877,-980,876,973,977,-879,976,978,982,-981,979,877,879,-984,878,977,981,-881,980,982,986,-985,983,879,881,-988,880,981,985,-883,984,986,990,-989,987,881,883,-992,882,985,989,-885,988,990,994,-993,991,883,885,-996,884,989,993,-887,992,994,998,-997,995,885,887,-1000,886,993,997,-889,996,998,1002,-1001,999,887,889,-1004,888,997,1001,-891,1000,1002,1006,-1005,1003,889,891,-1008,890,1001,1005,-893,1004,1006,1010,-1009,1007,891,893,-1012,892,1005,1009,-895,1008,1010,1014,-1013,1011,893,895,-1016,894,1009,1013,-897,1016,1018,1025,-1021,1019,903,897,-1025,904,1017,1021,-899,1022,1026,1038,-1033,1027,901,899,-1038,902,1023,1033,-901,1020,1025,1026,-1023,1024,897,901,-1028,898,1021,1023,-903,1012,1014,1018,-1017,1015,895,903,-1020,896,1013,1017,-905,913,918,922,-921,919,851,905,-924,852,914,921,-907,924,929,930,-927,928,853,907,-932,854,925,927,-909,909,910,911,-913,915,347,916,-918,1028,1029,1030,-1032,1034,1035,380,-1037 + } + Edges: *2108 { + a: 0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,18,19,20,21,22,23,24,26,27,28,29,30,31,32,34,35,36,37,38,39,40,42,43,44,45,46,47,48,50,51,52,53,54,55,56,58,59,60,61,62,63,64,66,67,68,69,70,71,72,74,75,76,77,78,79,80,82,83,84,85,86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,106,107,108,109,110,111,112,114,115,116,117,118,119,120,122,123,124,125,126,127,128,130,131,132,133,134,135,136,138,139,140,141,142,143,144,146,147,148,149,150,151,152,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,180,182,183,184,185,186,188,190,191,192,193,194,196,198,199,200,201,202,204,206,207,208,209,210,212,214,215,216,217,218,220,222,223,224,225,226,228,230,231,232,233,234,236,238,239,240,241,242,244,246,247,248,249,250,252,254,255,256,257,258,260,262,263,264,265,266,268,270,271,272,273,274,276,278,279,280,281,282,284,286,287,288,289,290,292,294,295,296,297,298,300,302,303,304,305,306,308,310,311,312,313,314,316,318,319,320,321,322,324,326,327,328,329,330,332,334,335,336,337,338,339,340,341,343,344,345,346,347,349,350,351,352,353,355,357,358,359,361,363,365,366,367,369,371,373,374,375,377,379,381,382,383,385,387,389,390,391,393,395,397,398,399,401,403,405,406,407,409,411,413,414,415,417,419,421,422,423,425,427,429,430,431,433,435,437,438,439,441,443,445,446,447,449,451,453,454,455,457,459,461,462,463,465,467,469,470,471,473,475,477,478,479,481,483,485,486,487,489,491,493,494,495,497,499,501,502,503,505,507,509,510,511,513,515,517,518,519,521,523,525,526,527,529,531,535,538,539,541,547,553,559,565,571,577,583,589,595,601,607,613,619,625,631,637,643,649,655,661,667,673,679,685,691,697,703,709,715,721,727,733,739,745,751,757,763,769,775,781,784,787,791,793,796,797,799,803,805,808,812,824,828,832,836,840,844,848,852,856,860,864,868,872,876,880,884,888,892,893,896,897,898,899,900,903,905,909,913,917,921,925,929,933,937,941,945,949,953,957,961,965,969,973,977,981,984,985,986,989,990,991,995,998,999,1001,1002,1006,1009,1010,1012,1013,1017,1020,1021,1024,1025,1026,1027,1029,1030, +1031,1033,1034,1035,1037,1038,1039,1041,1042,1043,1045,1046,1047,1049,1050,1051,1053,1054,1055,1057,1058,1059,1061,1062,1063,1065,1066,1067,1069,1070,1071,1073,1074,1075,1077,1078,1079,1081,1082,1083,1085,1086,1087,1089,1090,1091,1093,1094,1095,1097,1098,1099,1100,1101,1102,1103,1105,1106,1107,1109,1110,1111,1113,1114,1115,1117,1118,1119,1121,1122,1123,1125,1126,1127,1129,1130,1131,1133,1134,1135,1137,1138,1139,1141,1142,1143,1145,1146,1147,1149,1150,1151,1153,1154,1155,1157,1158,1159,1161,1162,1163,1165,1166,1167,1169,1170,1171,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1186,1187,1188,1190,1191,1192,1194,1195,1196,1198,1199,1200,1202,1203,1204,1206,1207,1208,1210,1211,1212,1214,1215,1216,1218,1219,1220,1222,1223,1224,1226,1227,1228,1230,1231,1232,1234,1235,1236,1238,1239,1240,1242,1243,1244,1245,1246,1247,1248,1250,1251,1252,1254,1255,1256,1258,1259,1260,1262,1263,1264,1266,1267,1268,1270,1271,1272,1274,1275,1276,1278,1279,1280,1282,1283,1284,1286,1287,1288,1290,1291,1292,1294,1295,1296,1298,1299,1300,1302,1303,1304,1306,1307,1308,1310,1311,1312,1314,1315,1316,1318,1319,1320,1321,1322,1323,1324,1326,1327,1328,1330,1331,1332,1334,1335,1336,1338,1339,1340,1342,1343,1344,1346,1347,1348,1350,1351,1352,1354,1355,1356,1358,1359,1360,1362,1363,1364,1366,1367,1368,1370,1371,1372,1374,1375,1376,1378,1379,1380,1382,1383,1384,1386,1387,1388,1390,1391,1392,1394,1395,1396,1397,1398,1399,1400,1402,1403,1404,1406,1407,1408,1410,1411,1412,1414,1415,1416,1418,1419,1420,1422,1423,1424,1426,1427,1428,1430,1431,1432,1434,1435,1436,1438,1439,1440,1442,1443,1444,1446,1447,1448,1450,1451,1452,1454,1455,1456,1458,1459,1460,1462,1463,1464,1466,1467,1468,1470,1471,1472,1474,1475,1476,1478,1479,1480,1482,1483,1484,1486,1487,1488,1490,1491,1492,1494,1495,1496,1497,1498,1499,1500,1502,1503,1504,1506,1507,1508,1510,1511,1512,1514,1515,1516,1518,1519,1520,1522,1523,1524,1526,1527,1528,1530,1531,1532,1534,1535,1536,1538,1539,1540,1542,1543,1544,1546,1547,1548,1550,1551,1552,1554,1555,1556,1558,1559,1560,1562,1563,1564,1566,1567, +1568,1570,1571,1572,1574,1575,1576,1578,1579,1580,1582,1583,1584,1586,1587,1588,1590,1591,1592,1594,1595,1596,1598,1599,1600,1602,1603,1604,1606,1607,1608,1610,1611,1612,1614,1615,1616,1618,1619,1620,1622,1623,1624,1626,1627,1628,1630,1631,1632,1634,1635,1636,1638,1639,1640,1642,1643,1644,1646,1647,1648,1650,1651,1652,1654,1655,1656,1658,1659,1660,1662,1663,1664,1666,1667,1668,1670,1671,1672,1674,1675,1676,1678,1679,1680,1682,1683,1684,1686,1687,1688,1690,1691,1692,1694,1696,1698,1700,1702,1703,1704,1706,1707,1708,1710,1711,1712,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1726,1727,1728,1730,1731,1732,1733,1735,1736,1737,1739,1740,1741,1743,1744,1745,1747,1748,1749,1751,1752,1753,1755,1756,1757,1759,1760,1761,1763,1764,1765,1767,1768,1769,1771,1772,1773,1775,1776,1777,1779,1780,1781,1783,1784,1785,1787,1788,1789,1791,1792,1793,1795,1796,1797,1799,1800,1801,1803,1804,1805,1807,1808,1809,1811,1812,1813,1815,1816,1817,1819,1820,1821,1823,1824,1825,1827,1828,1829,1831,1832,1833,1835,1836,1837,1839,1840,1841,1843,1844,1845,1847,1848,1849,1851,1852,1853,1855,1856,1857,1859,1860,1861,1863,1864,1865,1867,1868,1869,1871,1872,1873,1875,1876,1877,1879,1880,1881,1883,1884,1885,1887,1888,1889,1891,1892,1893,1895,1896,1897,1899,1900,1901,1903,1904,1905,1907,1908,1909,1911,1912,1913,1915,1916,1917,1919,1920,1921,1923,1924,1925,1927,1928,1929,1931,1932,1933,1935,1936,1937,1939,1940,1941,1943,1944,1945,1947,1948,1949,1951,1953,1955,1956,1957,1959,1960,1961,1963,1965,1967,1968,1969,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1983,1984,1985,1987,1988,1989,1990,1991,1992,1993,1995,1996,1997,1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2011,2012,2013,2015,2016,2017,2019,2020,2021,2023,2024,2025,2027,2028,2029,2031,2032,2033,2035,2036,2037,2039,2040,2041,2043,2044,2045,2047,2048,2049,2051,2052,2053,2055,2056,2057,2059,2060,2061,2063,2064,2065,2067,2068,2069,2071,2072,2073,2075,2076,2077,2079,2080,2081,2083,2084,2085,2087,2088,2089,2091,2092,2093,2095,2096,2097,2099,2100,2101,2103,2104,2105,2107,2108,2109,2111, +2112,2113,2115,2116,2117,2119,2120,2121,2123,2124,2125,2127,2128,2129,2131,2132,2133,2135,2136,2137,2139,2140,2141,2143,2144,2145,2147,2148,2149,2151,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2175,2179,2183,2187,2191,2195,2199,2203,2207,2211,2215,2219,2223,2227,2231,2235,2236,2237,2239,2243,2247,2251,2255,2259,2263,2267,2271,2275,2279,2283,2287,2291,2295,2299,2303,2305,2307,2311,2315,2319,2323,2327,2331,2335,2339,2343,2347,2351,2355,2359,2363,2364,2368,2370,2372,2376,2380,2384,2388,2392,2396,2400,2404,2408,2412,2416,2420,2424,2428,2432,2436,2438,2440,2444,2448,2452,2456,2460,2464,2468,2472,2476,2480,2484,2488,2492,2496,2500,2504,2505,2506,2507,2509,2510,2513,2514,2517,2518,2521,2522,2525,2526,2529,2530,2533,2534,2537,2538,2541,2542,2545,2546,2549,2550,2553,2554,2557,2558,2561,2562,2565,2566,2569,2570,2571,2573,2575,2578,2582,2586,2590,2594,2598,2602,2606,2610,2614,2618,2622,2626,2630,2634,2638,2641,2642,2644,2645,2646,2649,2650,2653,2654,2657,2658,2661,2662,2665,2666,2669,2670,2673,2674,2677,2678,2681,2682,2685,2686,2689,2690,2693,2694,2697,2698,2701,2702,2703,2706,2710,2714,2716,2718,2724,2728,2732,2733,2736,2740,2742,2743,2744,2745,2749,2750,2753,2757,2761,2765,2769,2773,2777,2781,2785,2789,2793,2797,2801,2805,2809,2813,2817,2821,2825,2829,2833,2837,2841,2845,2849,2853,2857,2861,2865,2869,2873,2877,2881,2885,2889,2893,2897,2901,2905,2909,2913,2917,2921,2925,2929,2933,2937,2941,2945,2949,2953,2957,2975,2977,2979,2981,2983,2987,2993,2997,3001,3005,3009,3013,3017,3019,3021,3025,3029,3033,3037,3041,3045,3049,3053,3057,3061,3065,3069,3073,3077,3081,3085,3089,3093,3097,3101,3105,3109,3113,3117,3121,3125,3129,3133,3137,3141,3145,3149,3153,3157,3161,3165,3169,3173,3177,3181,3185,3189,3193,3197,3201,3205,3209,3213,3217,3221,3242,3244,3246,3248,3250,3252,3258,3260,3266,3268,3274,3276,3282,3284,3290,3292,3298,3300,3306,3308,3314,3316,3322,3324,3330,3332,3338,3340,3346,3348,3354,3356,3362,3366,3368,3372,3380,3384,3402,3419,3436,3437,3439,3441,3442,3443,3444,3445,3446,3447,3448,3449,3450,3451,3453,3454,3455,3457,3458, +3459,3461,3462,3463,3465,3466,3467,3469,3470,3471,3473,3474,3475,3477,3478,3479,3481,3482,3483,3485,3486,3487,3489,3490,3491,3493,3494,3495,3497,3498,3499,3501,3502,3503,3505,3506,3507,3509,3510,3511,3513,3514,3515,3517,3518,3519,3521,3522,3523,3525,3526,3527,3529,3530,3531,3532,3533,3534,3535,3536,3537,3539,3541,3543,3545,3547,3549,3551,3553,3555,3556,3557,3561,3564,3565,3569,3570,3571,3575,3578,3579,3580,3581,3582,3583,3585,3586,3587,3588,3589,3590,3591,3593,3594,3595,3597,3598,3599,3601,3602,3603,3605,3606,3607,3609,3610,3611,3613,3614,3615,3617,3618,3619,3621,3622,3623,3625,3626,3627,3629,3630,3631,3633,3634,3635,3637,3638,3639,3641,3642,3643,3645,3646,3647,3649,3650,3651,3653,3654,3655,3657,3658,3659,3661,3662,3663,3665,3666,3667,3669,3670,3671,3673,3674,3675,3677,3678,3679,3681,3682,3683,3685,3686,3687,3689,3690,3691,3693,3694,3695,3697,3698,3699,3701,3702,3703,3705,3706,3707,3709,3710,3711,3713,3714,3715,3717,3718,3719,3721,3722,3723,3725,3726,3727,3729,3730,3731,3733,3734,3735,3737,3738,3739,3741,3742,3743,3745,3746,3747,3749,3750,3751,3753,3754,3755,3757,3758,3759,3761,3762,3763,3765,3766,3767,3769,3770,3771,3773,3774,3775,3777,3778,3779,3781,3782,3783,3785,3786,3787,3789,3790,3791,3793,3794,3795,3797,3798,3799,3801,3802,3803,3805,3806,3807,3809,3810,3811,3812,3813,3815,3816,3817,3819,3820,3824,3828,3835,3839,3842,3844,3846,3848,3850,3852,3854,3856,3858,3860,3862,3864,3866,3870,3874,3878,3882,3886,3890,3894,3898,3902,3906,3910,3914,3918,3922,3926,3930,3934,3938,3942,3946,3950,3954,3958,3962,3966,3970,3974,3978,3982,3986,3990,3994,3998,4002,4006,4010,4014,4018,4022,4026,4030,4034,4038,4042,4046,4050,4054,4058,4062,4066,4070,4074,4078,4082,4086,4090,4094,4098,4102,4106,4108,4110,4112,4114,4116,4118,4120,4124,4128 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *12588 { + a: 0,0.999999940395355,-6.77275579619163e-007,0,0.999999940395355,-0.000209073783480562,0,0.999999940395355,-6.3660735349913e-007,-0.123129539191723,-0.961523473262787,-0.245584085583687,-0.134296879172325,-0.954053103923798,-0.267855852842331,-0.123066082596779,-0.961489975452423,-0.245747268199921,-0.134247705340385,-0.954042494297028,-0.267918437719345,0,0.999999940395355,-9.82406277216796e-007,0,0.999999940395355,-6.77275579619163e-007,0,0.999999940395355,-6.3660735349913e-007,0,0.999999940395355,-6.2574753201261e-007,0,0.999999940395355,-8.56359406498086e-007,0.126252546906471,-0.962023437023163,0.242014437913895,0.137900203466415,-0.954665720462799,0.263812065124512,0.127787038683891,-0.961508214473724,0.243253946304321,0.13794581592083,-0.954899609088898,0.262940555810928,0,0.999999940395355,-4.86190174342482e-007,0,0.999999940395355,-9.82406277216796e-007,0,0.999999940395355,-8.56359406498086e-007,0,0.999999940395355,-7.41921894586994e-007,-0.131450578570366,-0.964159369468689,-0.230472207069397,-0.143587067723274,-0.957179129123688,-0.251377761363983,-0.132310286164284,-0.963931381702423,-0.230933710932732,-0.143432065844536,-0.957425177097321,-0.250527828931808,-1.31546744341904e-006,0.999999940395355,0,0,0.999999940395355,-4.86190174342482e-007,0,0.999999940395355,-7.41921894586994e-007,-8.416567425229e-007,0.999999940395355,0,0.144131630659103,-0.964372336864471,0.221838071942329,0.159639403223991,-0.956378757953644,0.244652584195137,0.146075487136841,-0.964074671268463,0.221860155463219,0.158780738711357,-0.957254767417908,0.24176824092865,-1.79408743861131e-006,0.999999940395355,-2.15610089071561e-006,-1.31546744341904e-006,0.999999940395355,0,-8.416567425229e-007,0.999999940395355,0,-1.93867072084686e-006,0.999999940395355,-1.39202154514351e-006,-0.161632269620895,-0.965039670467377,-0.206333175301552,-0.179750815033913,-0.956787526607513,-0.228576377034187,-0.163880810141563,-0.964603304862976,-0.206599667668343,-0.178331092000008,-0.957811057567596,-0.225379332900047,-9.358831789541e-007,0.999999940395355,-1.48457388604584e-006, +-1.79408743861131e-006,0.999999940395355,-2.15610089071561e-006,-1.93867072084686e-006,0.999999940395355,-1.39202154514351e-006,-1.13165833681705e-006,0.999999940395355,-2.20421816266025e-006,0.179300099611282,-0.965845704078674,0.187065213918686,0.199658587574959,-0.957649528980255,0.207469955086708,0.182106211781502,-0.965232372283936,0.187519207596779,0.19759675860405,-0.958829045295715,0.203966960310936,1.11337811858903e-007,0.999999940395355,-8.04795774911327e-007,-9.358831789541e-007,0.999999940395355,-1.48457388604584e-006,-1.13165833681705e-006,0.999999940395355,-2.20421816266025e-006,-8.50785681905109e-008,0.999999940395355,-5.59089983198646e-007,-0.196767270565033,-0.966735422611237,-0.163417130708694,-0.21850773692131,-0.958955049514771,-0.180719375610352,-0.200300946831703,-0.965905606746674,-0.164029240608215,-0.215638428926468,-0.960297226905823,-0.177000731229782,-4.25353761102087e-007,0.999999940395355,-1.30288344735163e-006,1.11337811858903e-007,0.999999940395355,-8.04795774911327e-007,-8.50785681905109e-008,0.999999940395355,-5.59089983198646e-007,-1.67745270118758e-007,0.999999940395355,-1.32454908907675e-006,0.213384836912155,-0.967595934867859,0.134999573230743,0.235109359025955,-0.960619151592255,0.148102536797524,0.217780500650406,-0.966528594493866,0.13562436401844,0.231288492679596,-0.962117195129395,0.144346848130226,-1.01354021353472e-006,0.999999940395355,1.30366913708713e-006,-4.25353761102087e-007,0.999999940395355,-1.30288344735163e-006,-1.67745270118758e-007,0.999999940395355,-1.32454908907675e-006,-1.04789671695471e-006,0.999999940395355,8.20861146166862e-007,-0.228280201554298,-0.968264937400818,-0.101739913225174,-0.248106509447098,-0.962458670139313,-0.110074102878571,-0.233579248189926,-0.96696013212204,-0.102121151983738,-0.243271812796593,-0.964087247848511,-0.106556825339794,-1.42609650310987e-007,0.999999940395355,-6.50051606498891e-006,-1.01354021353472e-006,0.999999940395355,1.30366913708713e-006,-1.04789671695471e-006,0.999999940395355,8.20861146166862e-007,-2.17229114696238e-007,0.999999940395355,-5.4751963034505e-006, +0.24044206738472,-0.968555212020874,0.0639396756887436,0.256243735551834,-0.96423214673996,0.0677907466888428,0.246497705578804,-0.967045485973358,0.0637328922748566,0.250498324632645,-0.965942919254303,0.064843624830246,-4.00312134786127e-013,0.999999940395355,-9.63827642408432e-006,-1.42609650310987e-007,0.999999940395355,-6.50051606498891e-006,-2.17229114696238e-007,0.999999940395355,-5.4751963034505e-006,5.07831786605156e-013,0.999999940395355,-9.63828551903134e-006,-0.248784631490707,-0.968298077583313,-0.0224702134728432,-0.258676767349243,-0.965686082839966,-0.0231663081794977,-0.255236208438873,-0.966642022132874,-0.0213930755853653,-0.252337247133255,-0.967409312725067,-0.0210961177945137,1.42613316711504e-007,0.999999940395355,1.50629534800828e-006,-4.00312134786127e-013,0.999999940395355,-9.63827642408432e-006,5.07831786605156e-013,0.999999940395355,-9.63828551903134e-006,2.17225490928286e-007,0.999999940395355,2.11144924833206e-006,0.252336710691452,-0.967409372329712,-0.0210991706699133,0.255235403776169,-0.966642022132874,-0.0213962495326996,0.258676260709763,-0.965686142444611,-0.0231727231293917,0.248784989118576,-0.968297839164734,-0.0224768742918968,4.7249727685994e-007,0.999999940395355,4.66450956082554e-006,1.42613316711504e-007,0.999999940395355,1.50629534800828e-006,2.17225490928286e-007,0.999999940395355,2.11144924833206e-006,3.82746179639071e-007,1,4.04727961722529e-006,-0.25049901008606,-0.965942919254303,0.0648410692811012,-0.246498167514801,-0.967045485973358,0.0637305080890656,-0.256243944168091,-0.96423214673996,0.0677868127822876,-0.240441992878914,-0.968555450439453,0.0639362260699272,-3.99124985506205e-007,0.999999940395355,3.48969564356594e-007,4.7249727685994e-007,0.999999940395355,4.66450956082554e-006,3.82746179639071e-007,1,4.04727961722529e-006,-5.32811668563227e-007,0.999999940395355,-8.12569300734367e-009,0.243272989988327,-0.964087247848511,-0.10655415058136,0.233579874038696,-0.966960370540619,-0.102117598056793,0.248106852173805,-0.962458610534668,-0.110074289143085,0.228280708193779,-0.968264758586884,-0.101740501821041, +-5.33322690898785e-007,0.999999940395355,-1.17187971682142e-006,-3.99124985506205e-007,0.999999940395355,3.48969564356594e-007,-5.32811668563227e-007,0.999999940395355,-8.12569300734367e-009,-3.70503499880215e-007,0.999999940395355,-1.22735616514547e-006,-0.231285884976387,-0.962116777896881,0.144354060292244,-0.217778474092484,-0.966528177261353,0.135631263256073,-0.235108658671379,-0.960618317127228,0.148108899593353,-0.213384747505188,-0.967595398426056,0.135003730654716,-1.98095904124784e-007,0.999999940395355,-2.58728448443435e-007,-5.33322690898785e-007,0.999999940395355,-1.17187971682142e-006,-3.70503499880215e-007,0.999999940395355,-1.22735616514547e-006,-2.94123537969426e-007,0.999999940395355,2.72011988045051e-007,0.215635389089584,-0.960296452045441,-0.177007928490639,0.200298473238945,-0.96590518951416,-0.164035454392433,0.218506082892418,-0.958953678607941,-0.180729284882545,0.196765840053558,-0.966734170913696,-0.163426294922829,-1.12631255433371e-007,0.999999940395355,2.67054986125004e-007,-1.98095904124784e-007,0.999999940395355,-2.58728448443435e-007,-2.94123537969426e-007,0.999999940395355,2.72011988045051e-007,8.06809552500454e-008,0.999999940395355,-2.80561948784452e-007,-0.197595536708832,-0.958828568458557,0.203969702124596,-0.182103976607323,-0.965232610702515,0.18752047419548,-0.199657276272774,-0.957649528980255,0.207471013069153,-0.179300174117088,-0.96584564447403,0.187065660953522,2.58566473121391e-007,0.999999940395355,-5.13899067300372e-007,-1.12631255433371e-007,0.999999940395355,2.67054986125004e-007,8.06809552500454e-008,0.999999940395355,-2.80561948784452e-007,1.65437768373522e-007,0.999999940395355,-1.05491501756205e-007,0.17833037674427,-0.957812011241913,-0.225376337766647,0.163881003856659,-0.964603304862976,-0.206599488854408,0.179750978946686,-0.956788539886475,-0.228572145104408,0.161633178591728,-0.96504020690918,-0.206329733133316,0,0.999999940395355,6.13136705851502e-007,2.58566473121391e-007,0.999999940395355,-5.13899067300372e-007,1.65437768373522e-007,0.999999940395355,-1.05491501756205e-007, +0,0.999999940395355,6.09512312621519e-007,-0.158782511949539,-0.957255601882935,0.241763815283775,-0.146078124642372,-0.964075446128845,0.221854940056801,-0.159708470106125,-0.956372737884521,0.244630992412567,-0.144236877560616,-0.964375615119934,0.221754670143127,0,0.999999940395355,3.72259762571048e-007,0,0.999999940395355,6.13136705851502e-007,0,0.999999940395355,6.09512312621519e-007,0,0.999999940395355,2.54727126502985e-007,0.1395673006773,-0.957110404968262,-0.25389090180397,0.12891598045826,-0.963671624660492,-0.233917906880379,0.139830023050308,-0.956485092639923,-0.256093263626099,0.12652151286602,-0.964267253875732,-0.23276774585247,-0.134428739547729,-0.953873574733734,0.268428951501846,-0.123137466609478,-0.961373209953308,0.246167808771133,-0.134304076433182,-0.954049170017242,0.267866432666779,-0.123139314353466,-0.961518287658691,0.245599716901779,0.134296208620071,-0.954053580760956,-0.26785472035408,0.123128622770309,-0.961524426937103,-0.245581015944481,0.134295776486397,-0.954053938388824,-0.267853885889053,0.123128101229668,-0.961524724960327,-0.245580032467842,-0.124698102474213,-0.960518896579742,0.248704195022583,-0.110610224306583,-0.969070672988892,0.220606818795204,-0.148031041026115,-0.943885564804077,0.295240193605423,-0.148031055927277,-0.943885564804077,0.295240193605423,0.707106590270996,1.42274672043641e-007,-0.707106828689575,0.707108020782471,-3.30988609675842e-006,-0.707105457782745,0.707107961177826,-3.26363442582078e-006,-0.70710551738739,0.707107186317444,3.69263972288536e-007,-0.707106292247772,-0.707106471061707,-4.32224123869673e-006,0.70710700750351,-0.707085013389587,-2.146810402337e-005,0.707128524780273,-0.70710700750351,-2.43422903167811e-007,0.707106411457062,-0.70710700750351,-3.26353415402991e-006,0.707106471061707,0.691347479820251,7.67118253861554e-005,-0.72252231836319,0.706707179546356,0.000473011721624061,-0.707505941390991,0.70710551738739,3.30968100570317e-006,-0.707107961177826,0.707106590270996,1.42274672043641e-007,-0.707106828689575,-0.706649303436279,-0.000482297880807891,0.707563698291779, +-0.69128429889679,-7.61363044148311e-005,0.722582817077637,-0.707085013389587,-2.146810402337e-005,0.707128524780273,-0.707045435905457,-1.59685823746258e-005,0.707167983055115,0.642951726913452,0.000354087329469621,-0.765906572341919,0.675355553627014,0.000949846638832241,-0.737491607666016,0.676116526126862,0.00045005464926362,-0.736794531345367,0.691347479820251,7.67118253861554e-005,-0.72252231836319,-0.67535662651062,-0.000938067911192775,0.737490653991699,-0.642901122570038,-0.000334645999828354,0.765949010848999,-0.69128429889679,-7.61363044148311e-005,0.722582817077637,-0.676113843917847,-0.000438447197666392,0.736797034740448,0.573717832565308,0.000174486121977679,-0.819052934646606,0.60798841714859,0.000997279770672321,-0.7939453125,0.609272241592407,0.000933395291212946,-0.792960464954376,0.642951726913452,0.000354087329469621,-0.765906572341919,-0.607998132705688,-0.000988467014394701,0.793937683105469,-0.573705315589905,-0.000173929744050838,0.819061636924744,-0.642901122570038,-0.000334645999828354,0.765949010848999,-0.609268307685852,-0.000925298081710935,0.792963564395905,0.500149011611938,0.000418230716604739,-0.865939140319824,0.537014782428741,0.00100837636273354,-0.84357225894928,0.538352131843567,0.00097976578399539,-0.842719316482544,0.573717832565308,0.000174486121977679,-0.819052934646606,-0.537014722824097,-0.00100110180210322,0.843572318553925,-0.50012868642807,-0.000412454508477822,0.8659508228302,-0.573705315589905,-0.000173929744050838,0.819061636924744,-0.538337409496307,-0.000971822126302868,0.842728734016418,0.422732502222061,0.000203691961360164,-0.906254410743713,0.46078297495842,0.0011021348182112,-0.88751208782196,0.462260723114014,0.000992326647974551,-0.886743426322937,0.500149011611938,0.000418230716604739,-0.865939140319824,-0.460802644491196,-0.00108629977330565,0.887502014636993,-0.422717064619064,-0.000202155963052064,0.906261622905731,-0.50012868642807,-0.000412454508477822,0.8659508228302,-0.462261557579041,-0.000978866359218955,0.886743128299713,0.342132270336151,0.000486210134113207,-0.939651727676392, +0.38234880566597,0.00106282799970359,-0.924017369747162,0.38385745882988,0.00108430103864521,-0.92339164018631,0.422732502222061,0.000203691961360164,-0.906254410743713,-0.382351249456406,-0.00105047121178359,0.924016416072845,-0.342111021280289,-0.000477634341223165,0.939659357070923,-0.422717064619064,-0.000202155963052064,0.906261622905731,-0.383839637041092,-0.0010699441190809,0.923399090766907,0.258893400430679,0.000231088371947408,-0.965905725955963,0.299574762582779,0.0011948118917644,-0.954071998596191,0.301201343536377,0.00104877783451229,-0.953559935092926,0.342132270336151,0.000486210134113207,-0.939651727676392,-0.299597084522247,-0.00117788754869252,0.954064965248108,-0.25888004899025,-0.000228960256208666,0.965909421443939,-0.342111021280289,-0.000477634341223165,0.939659357070923,-0.301198542118073,-0.00103593873791397,0.953560769557953,0.173708394169807,0.000541333865839988,-0.984796941280365,0.216061800718308,0.0011032031616196,-0.976379036903381,0.217701762914658,0.0011836924823001,-0.97601455450058,0.258893400430679,0.000231088371947408,-0.965905725955963,-0.216063663363457,-0.00108678417745978,0.976378619670868,-0.173694118857384,-0.000530617660842836,0.98479950428009,-0.25888004899025,-0.000228960256208666,0.965909421443939,-0.217677369713783,-0.00116334727499634,0.976020038127899,0.0871815755963326,0.000248495460255072,-0.996192395687103,0.12927708029747,0.00125267426483333,-0.99160772562027,0.130986571311951,0.00109595316462219,-0.991383492946625,0.173708394169807,0.000541333865839988,-0.984796941280365,-0.129304751753807,-0.00123025104403496,0.991604089736938,-0.0871760025620461,-0.000246039213379845,0.996192753314972,-0.173694118857384,-0.000530617660842836,0.98479950428009,-0.130984872579575,-0.00107876374386251,0.991383731365204,1.17230980478666e-008,0.000562945730052888,-0.999999821186066,0.043199647217989,0.00111541769001633,-0.999065756797791,0.0449124947190285,0.00124767702072859,-0.998990118503571,0.0871815755963326,0.000248495460255072,-0.996192395687103,-0.0432011559605598,-0.00109732220880687,0.999065697193146, +-8.76285852768888e-008,-0.000551345816347748,0.999999821186066,-0.0871760025620461,-0.000246039213379845,0.996192753314972,-0.0448841415345669,-0.0012244435492903,0.998991429805756,-0.0871815085411072,0.000248433614615351,-0.996192395687103,-0.0449125915765762,0.00124768249224871,-0.998990178108215,-0.0431997291743755,0.00111542060039938,-0.999065756797791,1.17230980478666e-008,0.000562945730052888,-0.999999821186066,0.0448841154575348,-0.00122483051382005,0.998991429805756,0.0871760323643684,-0.000246037408942357,0.996192753314972,-8.76285852768888e-008,-0.000551345816347748,0.999999821186066,0.0432012267410755,-0.00109775760211051,0.999065637588501,-0.173708364367485,0.00054123398149386,-0.984796941280365,-0.130986660718918,0.00109501811675727,-0.991383373737335,-0.129277110099792,0.00125175097491592,-0.991607666015625,-0.0871815085411072,0.000248433614615351,-0.996192395687103,0.130984857678413,-0.00107917352579534,0.991383671760559,0.173693999648094,-0.000530644960235804,0.98479950428009,0.0871760323643684,-0.000246037408942357,0.996192753314972,0.129304796457291,-0.00123067211825401,0.991604089736938,-0.25889328122139,0.00023112483904697,-0.965905785560608,-0.217702135443687,0.00118364382069558,-0.976014494895935,-0.216062128543854,0.00110320013482124,-0.976378917694092,-0.173708364367485,0.00054123398149386,-0.984796941280365,0.21767657995224,-0.00116316566709429,0.976020216941834,0.258879840373993,-0.000228985954890959,0.965909421443939,0.173693999648094,-0.000530644960235804,0.98479950428009,0.216062963008881,-0.00108651397749782,0.976378798484802,-0.34213200211525,0.000486268632812425,-0.939651727676392,-0.301199406385422,0.00105119287036359,-0.953560531139374,-0.299572914838791,0.00119721691589803,-0.954072594642639,-0.25889328122139,0.00023112483904697,-0.965905785560608,0.301198601722717,-0.00103476224467158,0.953560709953308,0.342110991477966,-0.000477676192531362,0.939659357070923,0.258879840373993,-0.000228985954890959,0.965909421443939,0.299597084522247,-0.00117666774895042,0.954065144062042,-0.422732412815094,0.000203606527065858,-0.906254470348358, +-0.383859694004059,0.00108595681376755,-0.923390746116638,-0.382351160049438,0.00106450635939837,-0.924016416072845,-0.34213200211525,0.000486268632812425,-0.939651727676392,0.38383936882019,-0.00107024807948619,0.923399329185486,0.422717124223709,-0.000202067123609595,0.906261503696442,0.342110991477966,-0.000477676192531362,0.939659357070923,0.382351160049438,-0.00105092476587743,0.92401647567749,-0.500148892402649,0.000418226496549323,-0.865939199924469,-0.462262123823166,0.000992285786196589,-0.8867427110672,-0.460784375667572,0.00110203528311104,-0.887511372566223,-0.422732412815094,0.000203606527065858,-0.906254470348358,0.462260663509369,-0.000980581389740109,0.886743545532227,0.500128626823425,-0.000411972694564611,0.86595094203949,0.422717124223709,-0.000202067123609595,0.906261503696442,0.460801750421524,-0.00108774390537292,0.887502372264862,-0.573718070983887,0.00017472033505328,-0.819052696228027,-0.538351953029633,0.000978345633484423,-0.842719316482544,-0.537014484405518,0.00100671465042979,-0.843572378158569,-0.500148892402649,0.000418226496549323,-0.865939199924469,0.5383380651474,-0.000972610607277602,0.842728316783905,0.573705196380615,-0.000173079664818943,0.819061696529388,0.500128626823425,-0.000411972694564611,0.86595094203949,0.537015438079834,-0.00100191065575928,0.843571782112122,-0.642951726913452,0.000354452669853345,-0.765906572341919,-0.609271824359894,0.000933478528168052,-0.792960822582245,-0.607987761497498,0.000997181632556021,-0.793945670127869,-0.573718070983887,0.00017472033505328,-0.819052696228027,0.609269022941589,-0.000926709559280425,0.792962968349457,0.642927646636963,-0.00036650785477832,0.765926659107208,0.573705196380615,-0.000173079664818943,0.819061696529388,0.607998311519623,-0.000988370040431619,0.793937742710114,-0.691341698169708,7.67282908782363e-005,-0.722527801990509,-0.67611563205719,0.000452834210591391,-0.73679530620575,-0.675354897975922,0.000953109876718372,-0.737492144107819,-0.642951726913452,0.000354452669853345,-0.765906572341919,0.67617392539978,-0.000458253372926265,0.736741781234741, +0.691334187984467,-7.63541393098421e-005,0.722535014152527,0.642927646636963,-0.00036650785477832,0.765926659107208,0.675419449806213,-0.000955127004999667,0.737433075904846,-0.70710676908493,-1.48291519508348e-007,-0.707106649875641,-0.707105934619904,3.30935336023686e-006,-0.707107484340668,-0.706706941127777,0.000473292486276478,-0.707506060600281,-0.691341698169708,7.67282908782363e-005,-0.722527801990509,0.691334187984467,-7.63541393098421e-005,0.722535014152527,0.707091152667999,2.06680033443263e-005,0.707122266292572,0.707083821296692,2.91770284093218e-005,0.707129657268524,0.707078635692596,3.53965515387245e-005,0.707134783267975,0.691218376159668,-1.27734935517765e-007,0.722645878791809,-0.707106411457062,-1.8572363558178e-007,-0.707107067108154,-0.707106947898865,-3.26363942804164e-006,-0.707106530666351,-0.707106649875641,-3.3098917811003e-006,-0.70710676908493,-0.70710676908493,-1.48291519508348e-007,-0.707106649875641,0.707091152667999,2.06680033443263e-005,0.707122266292572,0.707107722759247,-6.0464969919849e-008,0.707105755805969,0.707107841968536,0,0.70710563659668,0.707083821296692,2.91770284093218e-005,0.707129657268524,0.100992575287819,-0.974283337593079,0.201425895094872,-0.015247224830091,-0.999421000480652,-0.0304169561713934,0.0152474660426378,-0.999421358108521,0.0304058436304331,0.115416444838047,-0.966276109218597,0.230193823575974,-0.015247224830091,-0.999421000480652,-0.0304169561713934,-0.134296879172325,-0.954053103923798,-0.267855852842331,-0.123129539191723,-0.961523473262787,-0.245584085583687,0.0152474660426378,-0.999421358108521,0.0304058436304331,-0.123066082596779,-0.961489975452423,-0.245747268199921,0.0159337222576141,-0.999445557594299,0.0292362757027149,-0.0147036742419004,-0.999401688575745,-0.0313049554824829,-0.134247705340385,-0.954042494297028,-0.267918437719345,0.0159337222576141,-0.999445557594299,0.0292362757027149,0.137900203466415,-0.954665720462799,0.263812065124512,0.126252546906471,-0.962023437023163,0.242014437913895,-0.0147036742419004,-0.999401688575745,-0.0313049554824829, +0.127787038683891,-0.961508214473724,0.243253946304321,-0.0151436198502779,-0.999611616134644,-0.0233937837183475,0.0154015300795436,-0.999354779720306,0.0324454456567764,0.13794581592083,-0.954899609088898,0.262940555810928,-0.0151436198502779,-0.999611616134644,-0.0233937837183475,-0.143587067723274,-0.957179129123688,-0.251377761363983,-0.131450578570366,-0.964159369468689,-0.230472207069397,0.0154015300795436,-0.999354779720306,0.0324454456567764,-0.132310286164284,-0.963931381702423,-0.230933710932732,0.0218442529439926,-0.999319314956665,0.0297255013138056,-0.0135709010064602,-0.999491274356842,-0.0288636293262243,-0.143432065844536,-0.957425177097321,-0.250527828931808,0.0218442529439926,-0.999319314956665,0.0297255013138056,0.159639403223991,-0.956378757953644,0.244652584195137,0.144131630659103,-0.964372336864471,0.221838071942329,-0.0135709010064602,-0.999491274356842,-0.0288636293262243,0.146075487136841,-0.964074671268463,0.221860155463219,-0.0255906563252211,-0.999307096004486,-0.027024744078517,0.0148703893646598,-0.999460279941559,0.029289348050952,0.158780738711357,-0.957254767417908,0.24176824092865,-0.0255906563252211,-0.999307096004486,-0.027024744078517,-0.179750815033913,-0.956787526607513,-0.228576377034187,-0.161632269620895,-0.965039670467377,-0.206333175301552,0.0148703893646598,-0.999460279941559,0.029289348050952,-0.163880810141563,-0.964603304862976,-0.206599667668343,0.0278484746813774,-0.999346613883972,0.0230371970683336,-0.0166208110749722,-0.999470233917236,-0.0279791969805956,-0.178331092000008,-0.957811057567596,-0.225379332900047,0.0278484746813774,-0.999346613883972,0.0230371970683336,0.199658587574959,-0.957649528980255,0.207469955086708,0.179300099611282,-0.965845704078674,0.187065213918686,-0.0166208110749722,-0.999470233917236,-0.0279791969805956,0.182106211781502,-0.965232372283936,0.187519207596779,-0.0287802908569574,-0.999434888362885,-0.0173639208078384,0.0175538267940283,-0.999519288539886,0.0255525894463062,0.19759675860405,-0.958829045295715,0.203966960310936,-0.0287802908569574,-0.999434888362885,-0.0173639208078384, +-0.21850773692131,-0.958955049514771,-0.180719375610352,-0.196767270565033,-0.966735422611237,-0.163417130708694,0.0175538267940283,-0.999519288539886,0.0255525894463062,-0.200300946831703,-0.965905606746674,-0.164029240608215,0.0277864709496498,-0.999560177326202,0.0103667629882693,-0.0172408670186996,-0.999605417251587,-0.0221754740923643,-0.215638428926468,-0.960297226905823,-0.177000731229782,0.0277864709496498,-0.999560177326202,0.0103667629882693,0.235109359025955,-0.960619151592255,0.148102536797524,0.213384836912155,-0.967595934867859,0.134999573230743,-0.0172408670186996,-0.999605417251587,-0.0221754740923643,0.217780500650406,-0.966528594493866,0.13562436401844,-0.024346636608243,-0.999699473381042,-0.00283437198959291,0.0153207927942276,-0.999715745449066,0.0182649083435535,0.231288492679596,-0.962117195129395,0.144346848130226,-0.024346636608243,-0.999699473381042,-0.00283437198959291,-0.248106509447098,-0.962458670139313,-0.110074102878571,-0.228280201554298,-0.968264937400818,-0.101739913225174,0.0153207927942276,-0.999715745449066,0.0182649083435535,-0.233579248189926,-0.96696013212204,-0.102121151983738,0.0182486567646265,-0.999825060367584,-0.00406878488138318,-0.0116085018962622,-0.999827086925507,-0.0145186418667436,-0.243271812796593,-0.964087247848511,-0.106556825339794,0.0182486567646265,-0.999825060367584,-0.00406878488138318,0.256243735551834,-0.96423214673996,0.0677907466888428,0.24044206738472,-0.968555212020874,0.0639396756887436,-0.0116085018962622,-0.999827086925507,-0.0145186418667436,0.246497705578804,-0.967045485973358,0.0637328922748566,-0.0098147327080369,-0.999911367893219,0.00898595247417688,0.0062889507971704,-0.999910771846771,0.0117807649075985,0.250498324632645,-0.965942919254303,0.064843624830246,-0.0098147327080369,-0.999911367893219,0.00898595247417688,-0.258676767349243,-0.965686082839966,-0.0231663081794977,-0.248784631490707,-0.968298077583313,-0.0224702134728432,0.0062889507971704,-0.999910771846771,0.0117807649075985,-0.255236208438873,-0.966642022132874,-0.0213930755853653, +-1.4923796243238e-007,-0.999942064285278,-0.0107591906562448,1.16896650581566e-007,-0.999942123889923,-0.0107591897249222,-0.252337247133255,-0.967409312725067,-0.0210961177945137,-1.4923796243238e-007,-0.999942064285278,-0.0107591906562448,0.255235403776169,-0.966642022132874,-0.0213962495326996,0.252336710691452,-0.967409372329712,-0.0210991706699133,1.16896650581566e-007,-0.999942123889923,-0.0107591897249222,0.258676260709763,-0.965686142444611,-0.0231727231293917,0.00981586892157793,-0.999911367893219,0.00898293498903513,-0.00628749560564756,-0.999910831451416,0.0117783099412918,0.248784989118576,-0.968297839164734,-0.0224768742918968,0.00981586892157793,-0.999911367893219,0.00898293498903513,-0.246498167514801,-0.967045485973358,0.0637305080890656,-0.25049901008606,-0.965942919254303,0.0648410692811012,-0.00628749560564756,-0.999910831451416,0.0117783099412918,-0.256243944168091,-0.96423214673996,0.0677868127822876,-0.0182476863265038,-0.999825179576874,-0.00406463537365198,0.0116092134267092,-0.999827265739441,-0.0145133594051003,-0.240441992878914,-0.968555450439453,0.0639362260699272,-0.0182476863265038,-0.999825179576874,-0.00406463537365198,0.233579874038696,-0.966960370540619,-0.102117598056793,0.243272989988327,-0.964087247848511,-0.10655415058136,0.0116092134267092,-0.999827265739441,-0.0145133594051003,0.248106852173805,-0.962458610534668,-0.110074289143085,0.0243457239121199,-0.999699592590332,-0.00283335032872856,-0.0153204007074237,-0.999715745449066,0.0182660911232233,0.228280708193779,-0.968264758586884,-0.101740501821041,0.0243457239121199,-0.999699592590332,-0.00283335032872856,-0.217778474092484,-0.966528177261353,0.135631263256073,-0.231285884976387,-0.962116777896881,0.144354060292244,-0.0153204007074237,-0.999715745449066,0.0182660911232233,-0.235108658671379,-0.960618317127228,0.148108899593353,-0.027790043503046,-0.999559938907623,0.0103657385334373,0.017237538471818,-0.999605417251587,-0.0221757385879755,-0.213384747505188,-0.967595398426056,0.135003730654716,-0.027790043503046,-0.999559938907623,0.0103657385334373, +0.200298473238945,-0.96590518951416,-0.164035454392433,0.215635389089584,-0.960296452045441,-0.177007928490639,0.017237538471818,-0.999605417251587,-0.0221757385879755,0.218506082892418,-0.958953678607941,-0.180729284882545,0.0287829414010048,-0.99943470954895,-0.017369793727994,-0.017551438882947,-0.999519348144531,0.0255485940724611,0.196765840053558,-0.966734170913696,-0.163426294922829,0.0287829414010048,-0.99943470954895,-0.017369793727994,-0.182103976607323,-0.965232610702515,0.18752047419548,-0.197595536708832,-0.958828568458557,0.203969702124596,-0.017551438882947,-0.999519348144531,0.0255485940724611,-0.199657276272774,-0.957649528980255,0.207471013069153,-0.0278479680418968,-0.999346792697906,0.023030161857605,0.016618937253952,-0.999470174312592,-0.0279835537075996,-0.179300174117088,-0.96584564447403,0.187065660953522,-0.0278479680418968,-0.999346792697906,0.023030161857605,0.163881003856659,-0.964603304862976,-0.206599488854408,0.17833037674427,-0.957812011241913,-0.225376337766647,0.016618937253952,-0.999470174312592,-0.0279835537075996,0.179750978946686,-0.956788539886475,-0.228572145104408,0.0255907401442528,-0.999306976795197,-0.027028676122427,-0.014870441518724,-0.999460577964783,0.0292805526405573,0.161633178591728,-0.96504020690918,-0.206329733133316,0.0255907401442528,-0.999306976795197,-0.027028676122427,-0.146078124642372,-0.964075446128845,0.221854940056801,-0.158782511949539,-0.957255601882935,0.241763815283775,-0.014870441518724,-0.999460577964783,0.0292805526405573,-0.159708470106125,-0.956372737884521,0.244630992412567,-0.0225762035697699,-0.999316275119781,0.0292785465717316,0.0126480925828218,-0.999484896659851,-0.029494222253561,-0.144236877560616,-0.964375615119934,0.221754670143127,-0.0225762035697699,-0.999316275119781,0.0292785465717316,0.12891598045826,-0.963671624660492,-0.233917906880379,0.1395673006773,-0.957110404968262,-0.25389090180397,0.0126480925828218,-0.999484896659851,-0.029494222253561,0.139830023050308,-0.956485092639923,-0.256093263626099,0.0160598773509264,-0.99950647354126,-0.026997372508049, +-0.016517473384738,-0.99918657541275,0.0367877781391144,0.12652151286602,-0.964267253875732,-0.23276774585247,0.0160598773509264,-0.99950647354126,-0.026997372508049,-0.123137466609478,-0.961373209953308,0.246167808771133,-0.134428739547729,-0.953873574733734,0.268428951501846,-0.016517473384738,-0.99918657541275,0.0367877781391144,-0.134304076433182,-0.954049170017242,0.267866432666779,-0.0152475573122501,-0.999421119689941,0.0304133631289005,0.015248853713274,-0.999421119689941,-0.0304128378629684,-0.123139314353466,-0.961518287658691,0.245599716901779,-0.0152475573122501,-0.999421119689941,0.0304133631289005,0.123128622770309,-0.961524426937103,-0.245581015944481,0.134296208620071,-0.954053580760956,-0.26785472035408,0.015248853713274,-0.999421119689941,-0.0304128378629684,0.134295776486397,-0.954053938388824,-0.267853885889053,0.0152467731386423,-0.999421119689941,-0.0304117072373629,-0.0152477622032166,-0.999421238899231,0.0304093286395073,0.123128101229668,-0.961524724960327,-0.245580032467842,0.0152467731386423,-0.999421119689941,-0.0304117072373629,-0.110610224306583,-0.969070672988892,0.220606818795204,-0.124698102474213,-0.960518896579742,0.248704195022583,-0.0152477622032166,-0.999421238899231,0.0304093286395073,0.707107186317444,3.69263972288536e-007,-0.707106292247772,0.707107961177826,-3.26363442582078e-006,-0.70710551738739,0.707106709480286,0,-0.707106709480286,0.707107186317444,3.69263972288536e-007,-0.707106292247772,0.707106709480286,0,-0.707106709480286,0.707104980945587,1.05163881016779e-005,-0.707108438014984,-0.70710700750351,-2.43422903167811e-007,0.707106411457062,-0.707105100154877,-3.95148617826635e-006,0.707108438014984,-0.70710676908493,0,0.707106709480286,-0.70710700750351,-2.43422903167811e-007,0.707106411457062,-0.70710676908493,0,0.707106709480286,-0.70710700750351,-3.26353415402991e-006,0.707106471061707,0.707106590270996,1.42274672043641e-007,-0.707106828689575,0.70710551738739,3.30968100570317e-006,-0.707107961177826,0.707107782363892,0,-0.707105755805969,0.707106590270996,1.42274672043641e-007,-0.707106828689575, +0.707107782363892,0,-0.707105755805969,0.707108020782471,-3.30988609675842e-006,-0.707105457782745,-0.707085013389587,-2.146810402337e-005,0.707128524780273,-0.707106471061707,-4.32224123869673e-006,0.70710700750351,-0.70707494020462,-3.6989131331211e-005,0.707138419151306,-0.707085013389587,-2.146810402337e-005,0.707128524780273,-0.70707494020462,-3.6989131331211e-005,0.707138419151306,-0.707045435905457,-1.59685823746258e-005,0.707167983055115,0.691347479820251,7.67118253861554e-005,-0.72252231836319,0.676116526126862,0.00045005464926362,-0.736794531345367,0.691384553909302,0.0109176589176059,-0.722404301166534,0.691347479820251,7.67118253861554e-005,-0.72252231836319,0.691384553909302,0.0109176589176059,-0.722404301166534,0.706707179546356,0.000473011721624061,-0.707505941390991,-0.69128429889679,-7.61363044148311e-005,0.722582817077637,-0.706649303436279,-0.000482297880807891,0.707563698291779,-0.69135057926178,-0.010904373601079,0.722437083721161,-0.69128429889679,-7.61363044148311e-005,0.722582817077637,-0.69135057926178,-0.010904373601079,0.722437083721161,-0.676113843917847,-0.000438447197666392,0.736797034740448,0.642951726913452,0.000354087329469621,-0.765906572341919,0.609272241592407,0.000933395291212946,-0.792960464954376,0.641915321350098,0.0334380529820919,-0.766046047210693,0.642951726913452,0.000354087329469621,-0.765906572341919,0.641915321350098,0.0334380529820919,-0.766046047210693,0.675355553627014,0.000949846638832241,-0.737491607666016,-0.642901122570038,-0.000334645999828354,0.765949010848999,-0.67535662651062,-0.000938067911192775,0.737490653991699,-0.641911923885345,-0.0333690978586674,0.766051948070526,-0.642901122570038,-0.000334645999828354,0.765949010848999,-0.641911923885345,-0.0333690978586674,0.766051948070526,-0.609268307685852,-0.000925298081710935,0.792963564395905,0.573717832565308,0.000174486121977679,-0.819052934646606,0.538352131843567,0.00097976578399539,-0.842719316482544,0.573073506355286,0.0230355337262154,-0.819180011749268,0.573717832565308,0.000174486121977679,-0.819052934646606, +0.573073506355286,0.0230355337262154,-0.819180011749268,0.60798841714859,0.000997279770672321,-0.7939453125,-0.573705315589905,-0.000173929744050838,0.819061636924744,-0.607998132705688,-0.000988467014394701,0.793937683105469,-0.573069989681244,-0.0230608135461807,0.819181978702545,-0.573705315589905,-0.000173929744050838,0.819061636924744,-0.573069989681244,-0.0230608135461807,0.819181978702545,-0.538337409496307,-0.000971822126302868,0.842728734016418,0.500149011611938,0.000418230716604739,-0.865939140319824,0.462260723114014,0.000992326647974551,-0.886743426322937,0.499047607183456,0.0362859182059765,-0.865814507007599,0.500149011611938,0.000418230716604739,-0.865939140319824,0.499047607183456,0.0362859182059765,-0.865814507007599,0.537014782428741,0.00100837636273354,-0.84357225894928,-0.50012868642807,-0.000412454508477822,0.8659508228302,-0.537014722824097,-0.00100110180210322,0.843572318553925,-0.499045848846436,-0.0361604206264019,0.865820825099945,-0.50012868642807,-0.000412454508477822,0.8659508228302,-0.499045848846436,-0.0361604206264019,0.865820825099945,-0.462261557579041,-0.000978866359218955,0.886743128299713,0.422732502222061,0.000203691961360164,-0.906254410743713,0.38385745882988,0.00108430103864521,-0.92339164018631,0.422118037939072,0.0242889747023582,-0.906215369701386,0.422732502222061,0.000203691961360164,-0.906254410743713,0.422118037939072,0.0242889747023582,-0.906215369701386,0.46078297495842,0.0011021348182112,-0.88751208782196,-0.422717064619064,-0.000202155963052064,0.906261622905731,-0.460802644491196,-0.00108629977330565,0.887502014636993,-0.422112256288528,-0.0243196655064821,0.906217217445374,-0.422717064619064,-0.000202155963052064,0.906261622905731,-0.422112256288528,-0.0243196655064821,0.906217217445374,-0.383839637041092,-0.0010699441190809,0.923399090766907,0.342132270336151,0.000486210134113207,-0.939651727676392,0.301201343536377,0.00104877783451229,-0.953559935092926,0.3411625623703,0.0391793847084045,-0.939187467098236,0.342132270336151,0.000486210134113207,-0.939651727676392, +0.3411625623703,0.0391793847084045,-0.939187467098236,0.38234880566597,0.00106282799970359,-0.924017369747162,-0.342111021280289,-0.000477634341223165,0.939659357070923,-0.382351249456406,-0.00105047121178359,0.924016416072845,-0.341161400079727,-0.0390057191252708,0.939195096492767,-0.342111021280289,-0.000477634341223165,0.939659357070923,-0.341161400079727,-0.0390057191252708,0.939195096492767,-0.301198542118073,-0.00103593873791397,0.953560769557953,0.258893400430679,0.000231088371947408,-0.965905725955963,0.217701762914658,0.0011836924823001,-0.97601455450058,0.258441656827927,0.0253688059747219,-0.965693652629852,0.258893400430679,0.000231088371947408,-0.965905725955963,0.258441656827927,0.0253688059747219,-0.965693652629852,0.299574762582779,0.0011948118917644,-0.954071998596191,-0.25888004899025,-0.000228960256208666,0.965909421443939,-0.299597084522247,-0.00117788754869252,0.954064965248108,-0.258434951305389,-0.0254060681909323,0.96569436788559,-0.25888004899025,-0.000228960256208666,0.965909421443939,-0.258434951305389,-0.0254060681909323,0.96569436788559,-0.217677369713783,-0.00116334727499634,0.976020038127899,0.173708394169807,0.000541333865839988,-0.984796941280365,0.130986571311951,0.00109595316462219,-0.991383492946625,0.173126965761185,0.0414470694959164,-0.984026908874512,0.173708394169807,0.000541333865839988,-0.984796941280365,0.173126965761185,0.0414470694959164,-0.984026908874512,0.216061800718308,0.0011032031616196,-0.976379036903381,-0.173694118857384,-0.000530617660842836,0.98479950428009,-0.216063663363457,-0.00108678417745978,0.976378619670868,-0.173126697540283,-0.0412300266325474,0.984036147594452,-0.173694118857384,-0.000530617660842836,0.98479950428009,-0.173126697540283,-0.0412300266325474,0.984036147594452,-0.130984872579575,-0.00107876374386251,0.991383731365204,0.0871815755963326,0.000248495460255072,-0.996192395687103,0.0449124947190285,0.00124767702072859,-0.998990118503571,0.0870150774717331,0.0260103810578585,-0.995867311954498,0.0871815755963326,0.000248495460255072,-0.996192395687103, +0.0870150774717331,0.0260103810578585,-0.995867311954498,0.12927708029747,0.00125267426483333,-0.99160772562027,-0.0871760025620461,-0.000246039213379845,0.996192753314972,-0.129304751753807,-0.00123025104403496,0.991604089736938,-0.0870119780302048,-0.026054572314024,0.995866417884827,-0.0871760025620461,-0.000246039213379845,0.996192753314972,-0.0870119780302048,-0.026054572314024,0.995866417884827,-0.0448841415345669,-0.0012244435492903,0.998991429805756,1.17230980478666e-008,0.000562945730052888,-0.999999821186066,-0.0431997291743755,0.00111542060039938,-0.999065756797791,1.19880610327527e-007,0.0423209592700005,-0.999104082584381,1.17230980478666e-008,0.000562945730052888,-0.999999821186066,1.19880610327527e-007,0.0423209592700005,-0.999104082584381,0.043199647217989,0.00111541769001633,-0.999065756797791,-8.76285852768888e-008,-0.000551345816347748,0.999999821186066,-0.0432011559605598,-0.00109732220880687,0.999065697193146,-1.35385903377028e-007,-0.0420839376747608,0.999114036560059,-8.76285852768888e-008,-0.000551345816347748,0.999999821186066,-1.35385903377028e-007,-0.0420839376747608,0.999114036560059,0.0432012267410755,-0.00109775760211051,0.999065637588501,-0.0871815085411072,0.000248433614615351,-0.996192395687103,-0.129277110099792,0.00125175097491592,-0.991607666015625,-0.0870143547654152,0.0260103438049555,-0.995867371559143,-0.0871815085411072,0.000248433614615351,-0.996192395687103,-0.0870143547654152,0.0260103438049555,-0.995867371559143,-0.0449125915765762,0.00124768249224871,-0.998990178108215,0.0871760323643684,-0.000246037408942357,0.996192753314972,0.0448841154575348,-0.00122483051382005,0.998991429805756,0.0870118960738182,-0.026053773239255,0.995866477489471,0.0871760323643684,-0.000246037408942357,0.996192753314972,0.0870118960738182,-0.026053773239255,0.995866477489471,0.129304796457291,-0.00123067211825401,0.991604089736938,-0.173708364367485,0.00054123398149386,-0.984796941280365,-0.216062128543854,0.00110320013482124,-0.976378917694092,-0.173127472400665,0.0414470806717873,-0.984026968479156, +-0.173708364367485,0.00054123398149386,-0.984796941280365,-0.173127472400665,0.0414470806717873,-0.984026968479156,-0.130986660718918,0.00109501811675727,-0.991383373737335,0.173693999648094,-0.000530644960235804,0.98479950428009,0.130984857678413,-0.00107917352579534,0.991383671760559,0.173127800226212,-0.0412281304597855,0.984035968780518,0.173693999648094,-0.000530644960235804,0.98479950428009,0.173127800226212,-0.0412281304597855,0.984035968780518,0.216062963008881,-0.00108651397749782,0.976378798484802,-0.25889328122139,0.00023112483904697,-0.965905785560608,-0.299572914838791,0.00119721691589803,-0.954072594642639,-0.258442789316177,0.025368008762598,-0.965693414211273,-0.25889328122139,0.00023112483904697,-0.965905785560608,-0.258442789316177,0.025368008762598,-0.965693414211273,-0.217702135443687,0.00118364382069558,-0.976014494895935,0.258879840373993,-0.000228985954890959,0.965909421443939,0.21767657995224,-0.00116316566709429,0.976020216941834,0.258433550596237,-0.0254059247672558,0.965694844722748,0.258879840373993,-0.000228985954890959,0.965909421443939,0.258433550596237,-0.0254059247672558,0.965694844722748,0.299597084522247,-0.00117666774895042,0.954065144062042,-0.34213200211525,0.000486268632812425,-0.939651727676392,-0.382351160049438,0.00106450635939837,-0.924016416072845,-0.341161757707596,0.0391788966953754,-0.939187705516815,-0.34213200211525,0.000486268632812425,-0.939651727676392,-0.341161757707596,0.0391788966953754,-0.939187705516815,-0.301199406385422,0.00105119287036359,-0.953560531139374,0.342110991477966,-0.000477676192531362,0.939659357070923,0.301198601722717,-0.00103476224467158,0.953560709953308,0.341163694858551,-0.0390072986483574,0.939194083213806,0.342110991477966,-0.000477676192531362,0.939659357070923,0.341163694858551,-0.0390072986483574,0.939194083213806,0.382351160049438,-0.00105092476587743,0.92401647567749,-0.422732412815094,0.000203606527065858,-0.906254470348358,-0.460784375667572,0.00110203528311104,-0.887511372566223,-0.422117799520493,0.0242881625890732,-0.906215488910675, +-0.422732412815094,0.000203606527065858,-0.906254470348358,-0.422117799520493,0.0242881625890732,-0.906215488910675,-0.383859694004059,0.00108595681376755,-0.923390746116638,0.422717124223709,-0.000202067123609595,0.906261503696442,0.38383936882019,-0.00107024807948619,0.923399329185486,0.422110944986343,-0.0243170969188213,0.906217813491821,0.422717124223709,-0.000202067123609595,0.906261503696442,0.422110944986343,-0.0243170969188213,0.906217813491821,0.460801750421524,-0.00108774390537292,0.887502372264862,-0.500148892402649,0.000418226496549323,-0.865939199924469,-0.537014484405518,0.00100671465042979,-0.843572378158569,-0.499046862125397,0.0362844876945019,-0.865814983844757,-0.500148892402649,0.000418226496549323,-0.865939199924469,-0.499046862125397,0.0362844876945019,-0.865814983844757,-0.462262123823166,0.000992285786196589,-0.8867427110672,0.500128626823425,-0.000411972694564611,0.86595094203949,0.462260663509369,-0.000980581389740109,0.886743545532227,0.49904653429985,-0.0361623391509056,0.865820229053497,0.500128626823425,-0.000411972694564611,0.86595094203949,0.49904653429985,-0.0361623391509056,0.865820229053497,0.537015438079834,-0.00100191065575928,0.843571782112122,-0.573718070983887,0.00017472033505328,-0.819052696228027,-0.607987761497498,0.000997181632556021,-0.793945670127869,-0.573073625564575,0.0230366475880146,-0.819179952144623,-0.573718070983887,0.00017472033505328,-0.819052696228027,-0.573073625564575,0.0230366475880146,-0.819179952144623,-0.538351953029633,0.000978345633484423,-0.842719316482544,0.573705196380615,-0.000173079664818943,0.819061696529388,0.5383380651474,-0.000972610607277602,0.842728316783905,0.573067963123322,-0.0230598505586386,0.81918329000473,0.573705196380615,-0.000173079664818943,0.819061696529388,0.573067963123322,-0.0230598505586386,0.81918329000473,0.607998311519623,-0.000988370040431619,0.793937742710114,-0.642951726913452,0.000354452669853345,-0.765906572341919,-0.675354897975922,0.000953109876718372,-0.737492144107819,-0.641916811466217,0.0334394052624702,-0.766044855117798, +-0.642951726913452,0.000354452669853345,-0.765906572341919,-0.641916811466217,0.0334394052624702,-0.766044855117798,-0.609271824359894,0.000933478528168052,-0.792960822582245,0.642927646636963,-0.00036650785477832,0.765926659107208,0.609269022941589,-0.000926709559280425,0.792962968349457,0.641945540904999,-0.0333849042654037,0.76602303981781,0.642927646636963,-0.00036650785477832,0.765926659107208,0.641945540904999,-0.0333849042654037,0.76602303981781,0.675419449806213,-0.000955127004999667,0.737433075904846,-0.691341698169708,7.67282908782363e-005,-0.722527801990509,-0.706706941127777,0.000473292486276478,-0.707506060600281,-0.691372275352478,0.0109164593741298,-0.7224161028862,-0.691341698169708,7.67282908782363e-005,-0.722527801990509,-0.691372275352478,0.0109164593741298,-0.7224161028862,-0.67611563205719,0.000452834210591391,-0.73679530620575,0.691334187984467,-7.63541393098421e-005,0.722535014152527,0.67617392539978,-0.000458253372926265,0.736741781234741,0.691391050815582,-0.010900154709816,0.722398400306702,0.691334187984467,-7.63541393098421e-005,0.722535014152527,0.691391050815582,-0.010900154709816,0.722398400306702,0.706710398197174,-0.00045808037975803,0.707502782344818,-0.70710676908493,-1.48291519508348e-007,-0.707106649875641,-0.707106649875641,-3.3098917811003e-006,-0.70710676908493,-0.707106232643127,0,-0.707107186317444,-0.70710676908493,-1.48291519508348e-007,-0.707106649875641,-0.707106232643127,0,-0.707107186317444,-0.707105934619904,3.30935336023686e-006,-0.707107484340668,0.707091152667999,2.06680033443263e-005,0.707122266292572,0.707107901573181,9.92796321952483e-006,0.70710551738739,0.707106232643127,0,0.707107186317444,0.707091152667999,2.06680033443263e-005,0.707122266292572,0.707106232643127,0,0.707107186317444,0.707108199596405,0,0.707105278968811,-0.707106411457062,-1.8572363558178e-007,-0.707107067108154,-0.707106590270996,0,-0.707106947898865,-0.707108736038208,0,-0.707104742527008,-0.707106411457062,-1.8572363558178e-007,-0.707107067108154,-0.707108736038208,0,-0.707104742527008, +-0.707106947898865,-3.26363942804164e-006,-0.707106530666351,0.707107722759247,-6.0464969919849e-008,0.707105755805969,0.707108199596405,0,0.707105278968811,0.707105457782745,0,0.707108020782471,0.707107722759247,-6.0464969919849e-008,0.707105755805969,0.707105457782745,0,0.707108020782471,0.707104623317719,-2.92431354864675e-006,0.707108795642853,0.642927646636963,-0.00036650785477832,0.765926659107208,0.691334187984467,-7.63541393098421e-005,0.722535014152527,0.691218376159668,-1.27734935517765e-007,0.722645878791809,0.642897427082062,-1.68050628417404e-005,0.765952169895172,0.707107901573181,9.92796321952483e-006,0.70710551738739,0.707091152667999,2.06680033443263e-005,0.707122266292572,0.691334187984467,-7.63541393098421e-005,0.722535014152527,0.706710398197174,-0.00045808037975803,0.707502782344818,0.707108199596405,0,0.707105278968811,0.707107722759247,-6.0464969919849e-008,0.707105755805969,0.707091152667999,2.06680033443263e-005,0.707122266292572,0.707108199596405,0,0.707105278968811,0.573705196380615,-0.000173079664818943,0.819061696529388,0.642927646636963,-0.00036650785477832,0.765926659107208,0.642897427082062,-1.68050628417404e-005,0.765952169895172,0.573690056800842,5.04443903537322e-007,0.819072365760803,0.500128626823425,-0.000411972694564611,0.86595094203949,0.573705196380615,-0.000173079664818943,0.819061696529388,0.573690056800842,5.04443903537322e-007,0.819072365760803,0.500099658966064,2.47287630372739e-007,0.865967810153961,0.422717124223709,-0.000202067123609595,0.906261503696442,0.500128626823425,-0.000411972694564611,0.86595094203949,0.500099658966064,2.47287630372739e-007,0.865967810153961,0.422701776027679,-4.03023427963944e-008,0.906268775463104,0.342110991477966,-0.000477676192531362,0.939659357070923,0.422717124223709,-0.000202067123609595,0.906261503696442,0.422701776027679,-4.03023427963944e-008,0.906268775463104,0.34208670258522,2.35801049797146e-008,0.939668416976929,0.258879840373993,-0.000228985954890959,0.965909421443939,0.342110991477966,-0.000477676192531362,0.939659357070923, +0.34208670258522,2.35801049797146e-008,0.939668416976929,0.258868128061295,-3.64436161248705e-008,0.965912699699402,0.173693999648094,-0.000530644960235804,0.98479950428009,0.258879840373993,-0.000228985954890959,0.965909421443939,0.258868128061295,-3.64436161248705e-008,0.965912699699402,0.173680230975151,-5.85019712673329e-008,0.984802067279816,0.0871760323643684,-0.000246037408942357,0.996192753314972,0.173693999648094,-0.000530644960235804,0.98479950428009,0.173680230975151,-5.85019712673329e-008,0.984802067279816,0.0871715843677521,-3.00963201027571e-008,0.996193289756775,-8.76285852768888e-008,-0.000551345816347748,0.999999821186066,0.0871760323643684,-0.000246037408942357,0.996192753314972,0.0871715843677521,-3.00963201027571e-008,0.996193289756775,-1.0000957217926e-007,-6.4408808952976e-008,0.999999940395355,-0.0871760025620461,-0.000246039213379845,0.996192753314972,-8.76285852768888e-008,-0.000551345816347748,0.999999821186066,-1.0000957217926e-007,-6.4408808952976e-008,0.999999940395355,-0.0871715396642685,-3.88369088000218e-008,0.99619323015213,-0.173694118857384,-0.000530617660842836,0.98479950428009,-0.0871760025620461,-0.000246039213379845,0.996192753314972,-0.0871715396642685,-3.88369088000218e-008,0.99619323015213,-0.173680335283279,-6.93965063192081e-009,0.984802067279816,-0.25888004899025,-0.000228960256208666,0.965909421443939,-0.173694118857384,-0.000530617660842836,0.98479950428009,-0.173680335283279,-6.93965063192081e-009,0.984802067279816,-0.258868306875229,1.33019160131198e-008,0.965912580490112,-0.342111021280289,-0.000477634341223165,0.939659357070923,-0.25888004899025,-0.000228960256208666,0.965909421443939,-0.258868306875229,1.33019160131198e-008,0.965912580490112,-0.342086791992188,7.76351427589361e-008,0.939668297767639,-0.422717064619064,-0.000202155963052064,0.906261622905731,-0.342111021280289,-0.000477634341223165,0.939659357070923,-0.342086791992188,7.76351427589361e-008,0.939668297767639,-0.42270165681839,-1.45473251222938e-007,0.906268835067749,-0.50012868642807,-0.000412454508477822,0.8659508228302, +-0.422717064619064,-0.000202155963052064,0.906261622905731,-0.42270165681839,-1.45473251222938e-007,0.906268835067749,-0.500099658966064,-3.89354511298734e-007,0.865967929363251,-0.573705315589905,-0.000173929744050838,0.819061636924744,-0.50012868642807,-0.000412454508477822,0.8659508228302,-0.500099658966064,-3.89354511298734e-007,0.865967929363251,-0.573690235614777,-3.89684430501802e-007,0.819072246551514,-0.642901122570038,-0.000334645999828354,0.765949010848999,-0.573705315589905,-0.000173929744050838,0.819061636924744,-0.573690235614777,-3.89684430501802e-007,0.819072246551514,-0.64288991689682,1.71349729498615e-005,0.765958607196808,-0.69128429889679,-7.61363044148311e-005,0.722582817077637,-0.642901122570038,-0.000334645999828354,0.765949010848999,-0.64288991689682,1.71349729498615e-005,0.765958607196808,-0.691309571266174,3.18763341056183e-007,0.722558677196503,-0.707085013389587,-2.146810402337e-005,0.707128524780273,-0.69128429889679,-7.61363044148311e-005,0.722582817077637,-0.691309571266174,3.18763341056183e-007,0.722558677196503,-0.707074046134949,-3.52495226252358e-005,0.707139372825623,-0.707079529762268,-2.94031415251084e-005,0.707133829593658,-0.70710700750351,-2.43422903167811e-007,0.707106411457062,-0.707085013389587,-2.146810402337e-005,0.707128524780273,-0.707079529762268,-2.94031415251084e-005,0.707133829593658,-0.707107067108154,0,0.707106411457062,0.707107186317444,3.69263972288536e-007,-0.707106292247772,0.707104623317719,1.26040858958731e-005,-0.707108855247498,0.707107186317444,4.21694664964889e-007,-0.707106232643127,0.707106590270996,1.42274672043641e-007,-0.707106828689575,0.707107186317444,3.69263972288536e-007,-0.707106292247772,0.707107186317444,4.21694664964889e-007,-0.707106232643127,0.707107245922089,4.2230837493662e-007,-0.707106232643127,0.707106590270996,1.58592484922337e-007,-0.70710688829422,0.691347479820251,7.67118253861554e-005,-0.72252231836319,0.707106590270996,1.42274672043641e-007,-0.707106828689575,0.707106590270996,1.58592484922337e-007,-0.70710688829422,0.691306948661804,-6.20872029344355e-008,-0.722561120986938, +0.642951726913452,0.000354087329469621,-0.765906572341919,0.691347479820251,7.67118253861554e-005,-0.72252231836319,0.691306948661804,-6.20872029344355e-008,-0.722561120986938,0.64292186498642,-1.90611118000561e-007,-0.765931725502014,0.573717832565308,0.000174486121977679,-0.819052934646606,0.642951726913452,0.000354087329469621,-0.765906572341919,0.64292186498642,-1.90611118000561e-007,-0.765931725502014,0.573704659938812,-1.29539387216937e-007,-0.819062173366547,0.500149011611938,0.000418230716604739,-0.865939140319824,0.573717832565308,0.000174486121977679,-0.819052934646606,0.573704659938812,-1.29539387216937e-007,-0.819062173366547,0.500116527080536,0,-0.865958094596863,0.422732502222061,0.000203691961360164,-0.906254410743713,0.500149011611938,0.000418230716604739,-0.865939140319824,0.500116527080536,0,-0.865958094596863,0.422719746828079,6.01355694129779e-008,-0.906260371208191,0.342132270336151,0.000486210134113207,-0.939651727676392,0.422732502222061,0.000203691961360164,-0.906254410743713,0.422719746828079,6.01355694129779e-008,-0.906260371208191,0.342104315757751,6.69619311111092e-008,-0.939661860466003,0.258893400430679,0.000231088371947408,-0.965905725955963,0.342132270336151,0.000486210134113207,-0.939651727676392,0.342104315757751,6.69619311111092e-008,-0.939661860466003,0.258883982896805,1.03053761080218e-008,-0.965908408164978,0.173708394169807,0.000541333865839988,-0.984796941280365,0.258893400430679,0.000231088371947408,-0.965905725955963,0.258883982896805,1.03053761080218e-008,-0.965908408164978,0.173692211508751,9.04889319031099e-009,-0.984799861907959,0.0871815755963326,0.000248495460255072,-0.996192395687103,0.173708394169807,0.000541333865839988,-0.984796941280365,0.173692211508751,9.04889319031099e-009,-0.984799861907959,0.0871780663728714,5.56990009670244e-009,-0.996192693710327,1.17230980478666e-008,0.000562945730052888,-0.999999821186066,0.0871815755963326,0.000248495460255072,-0.996192395687103,0.0871780663728714,5.56990009670244e-009,-0.996192693710327,4.0552299296337e-009,3.81500603677254e-012,-0.999999940395355, +-0.0871815085411072,0.000248433614615351,-0.996192395687103,1.17230980478666e-008,0.000562945730052888,-0.999999821186066,4.0552299296337e-009,3.81500603677254e-012,-0.999999940395355,-0.0871779918670654,-4.3997662402262e-008,-0.996192693710327,-0.173708364367485,0.00054123398149386,-0.984796941280365,-0.0871815085411072,0.000248433614615351,-0.996192395687103,-0.0871779918670654,-4.3997662402262e-008,-0.996192693710327,-0.173692137002945,-6.94812172241654e-008,-0.984799861907959,-0.25889328122139,0.00023112483904697,-0.965905785560608,-0.173708364367485,0.00054123398149386,-0.984796941280365,-0.173692137002945,-6.94812172241654e-008,-0.984799861907959,-0.25888380408287,1.63037086053919e-008,-0.965908408164978,-0.34213200211525,0.000486268632812425,-0.939651727676392,-0.25889328122139,0.00023112483904697,-0.965905785560608,-0.25888380408287,1.63037086053919e-008,-0.965908408164978,-0.342104107141495,-7.59015961193654e-009,-0.939662039279938,-0.422732412815094,0.000203606527065858,-0.906254470348358,-0.34213200211525,0.000486268632812425,-0.939651727676392,-0.342104107141495,-7.59015961193654e-009,-0.939662039279938,-0.422719538211823,-4.93736322937366e-008,-0.906260371208191,-0.500148892402649,0.000418226496549323,-0.865939199924469,-0.422732412815094,0.000203606527065858,-0.906254470348358,-0.422719538211823,-4.93736322937366e-008,-0.906260371208191,-0.500116288661957,7.42986401292001e-008,-0.865958154201508,-0.573718070983887,0.00017472033505328,-0.819052696228027,-0.500148892402649,0.000418226496549323,-0.865939199924469,-0.500116288661957,7.42986401292001e-008,-0.865958154201508,-0.573704898357391,1.35362668629568e-007,-0.819061934947968,-0.642951726913452,0.000354452669853345,-0.765906572341919,-0.573718070983887,0.00017472033505328,-0.819052696228027,-0.573704898357391,1.35362668629568e-007,-0.819061934947968,-0.642921924591064,6.10663164479774e-008,-0.76593154668808,-0.691341698169708,7.67282908782363e-005,-0.722527801990509,-0.642951726913452,0.000354452669853345,-0.765906572341919,-0.642921924591064,6.10663164479774e-008,-0.76593154668808, +-0.691300690174103,-1.29587292008182e-007,-0.722567141056061,-0.70710676908493,-1.48291519508348e-007,-0.707106649875641,-0.691341698169708,7.67282908782363e-005,-0.722527801990509,-0.691300690174103,-1.29587292008182e-007,-0.722567141056061,-0.707107186317444,-2.63816531287375e-007,-0.707106292247772,-0.70710700750351,-2.1568841646058e-007,-0.707106411457062,-0.707106411457062,-1.8572363558178e-007,-0.707107067108154,-0.70710676908493,-1.48291519508348e-007,-0.707106649875641,-0.70710700750351,-2.1568841646058e-007,-0.707106411457062,-0.707106232643127,0,-0.707107245922089,0,0.999999940395355,0,0,0.999999940395355,0,0,0.999999940395355,3.72259762571048e-007,0,0.999999940395355,2.54727126502985e-007,-0.707106828689575,0,-0.707106590270996,-0.70710676908493,0,-0.70710676908493,-0.707106590270996,0,-0.707106947898865,-0.707106411457062,-1.8572363558178e-007,-0.707107067108154,0.707104921340942,-3.39268603966048e-006,0.707108557224274,0.707107841968536,0,0.70710563659668,0.707107722759247,-6.0464969919849e-008,0.707105755805969,0.707104980945587,-3.45451667271846e-006,0.707108497619629,0.707104921340942,-3.39268603966048e-006,0.707108557224274,0.707107722759247,-6.0464969919849e-008,0.707105755805969,0.707104623317719,-2.92431354864675e-006,0.707108795642853,-0.707106232643127,0,-0.707107245922089,-0.707106828689575,0,-0.707106590270996,-0.707106411457062,-1.8572363558178e-007,-0.707107067108154,0.148031264543533,-0.94388473033905,0.29524302482605,0.148031279444695,-0.94388473033905,0.29524302482605,0.100992575287819,-0.974283337593079,0.201425895094872,0.115416444838047,-0.966276109218597,0.230193823575974,0.707104623317719,1.28874571601045e-005,-0.707108914852142,0.707104623317719,1.26040858958731e-005,-0.707108855247498,0.707107186317444,3.69263972288536e-007,-0.707106292247772,0.707104980945587,1.05163881016779e-005,-0.707108438014984,-0.707105278968811,-5.42237103218213e-006,0.70710813999176,-0.707105398178101,-5.46179126104107e-006,0.707108080387115,-0.707105100154877,-3.95148617826635e-006,0.707108438014984,-0.70710700750351,-2.43422903167811e-007,0.707106411457062, +-0.707107067108154,0,0.707106411457062,-0.707105278968811,-5.42237103218213e-006,0.70710813999176,-0.70710700750351,-2.43422903167811e-007,0.707106411457062,-0.482682675123215,-0.707144021987915,0.516686320304871,-0.482623934745789,-0.707143485546112,0.516741812229156,-0.462678164243698,-0.704149782657623,0.538610994815826,-0.46243742108345,-0.704122722148895,0.538853108882904,-0.482623934745789,-0.707143485546112,0.516741812229156,-0.482682675123215,-0.707144021987915,0.516686320304871,-0.45150950551033,-0.707460343837738,0.543726861476898,-0.451509594917297,-0.707460343837738,0.543726742267609,-0.451509594917297,-0.707460343837738,0.543726742267609,-0.45150950551033,-0.707460343837738,0.543726861476898,-0.399398028850555,-0.707483649253845,0.583050608634949,-0.399397999048233,-0.70748370885849,0.583050489425659,-0.399397999048233,-0.70748370885849,0.583050489425659,-0.399398028850555,-0.707483649253845,0.583050608634949,-0.343898296356201,-0.707483470439911,0.617414653301239,-0.343898624181747,-0.707483470439911,0.617414534091949,-0.343898624181747,-0.707483470439911,0.617414534091949,-0.343898296356201,-0.707483470439911,0.617414653301239,-0.285463899374008,-0.707486212253571,0.646508693695068,-0.285463809967041,-0.707486212253571,0.646508693695068,-0.285463809967041,-0.707486212253571,0.646508693695068,-0.285463899374008,-0.707486212253571,0.646508693695068,-0.224593043327332,-0.70749032497406,0.670085966587067,-0.224592909216881,-0.707490384578705,0.670085906982422,-0.224592909216881,-0.707490384578705,0.670085906982422,-0.224593043327332,-0.70749032497406,0.670085966587067,-0.161805525422096,-0.707488656044006,0.68795245885849,-0.161805331707001,-0.707488715648651,0.687952518463135,-0.161805331707001,-0.707488715648651,0.687952518463135,-0.161805525422096,-0.707488656044006,0.68795245885849,-0.0976394414901733,-0.70748645067215,0.699949502944946,-0.0976395085453987,-0.707486510276794,0.699949502944946,-0.0976395085453987,-0.707486510276794,0.699949502944946,-0.0976394414901733,-0.70748645067215,0.699949502944946, +-0.0326396077871323,-0.707483053207397,0.705976128578186,-0.0326395854353905,-0.707483053207397,0.705976188182831,-0.0326395854353905,-0.707483053207397,0.705976188182831,-0.0326396077871323,-0.707483053207397,0.705976128578186,0.032639604061842,-0.707479774951935,0.705979406833649,0.0326395742595196,-0.707479774951935,0.705979406833649,0.0326395742595196,-0.707479774951935,0.705979406833649,0.032639604061842,-0.707479774951935,0.705979406833649,0.0976391211152077,-0.707483351230621,0.699952721595764,0.0976391807198524,-0.707483351230621,0.699952602386475,0.0976391807198524,-0.707483351230621,0.699952602386475,0.0976391211152077,-0.707483351230621,0.699952721595764,0.16180545091629,-0.707489252090454,0.687951862812042,0.161805257201195,-0.707489311695099,0.687951922416687,0.161805257201195,-0.707489311695099,0.687951922416687,0.16180545091629,-0.707489252090454,0.687951862812042,0.224591940641403,-0.707493960857391,0.670082449913025,0.224591851234436,-0.707493960857391,0.670082569122314,0.224591851234436,-0.707493960857391,0.670082569122314,0.224591940641403,-0.707493960857391,0.670082449913025,0.285461872816086,-0.707491099834442,0.646504282951355,0.285461813211441,-0.707490980625153,0.646504282951355,0.285461813211441,-0.707490980625153,0.646504282951355,0.285461872816086,-0.707491099834442,0.646504282951355,0.343897521495819,-0.70748507976532,0.617413282394409,0.343897819519043,-0.707485139369965,0.617413103580475,0.343897819519043,-0.707485139369965,0.617413103580475,0.343897521495819,-0.70748507976532,0.617413282394409,0.399399816989899,-0.707480490207672,0.583053231239319,0.399399727582932,-0.707480490207672,0.583053171634674,0.399399727582932,-0.707480490207672,0.583053171634674,0.399399816989899,-0.707480490207672,0.583053231239319,0.451515674591064,-0.707450687885284,0.543734431266785,0.451515734195709,-0.70745062828064,0.54373425245285,0.451515734195709,-0.70745062828064,0.54373425245285,0.451515674591064,-0.707450687885284,0.543734431266785,0.482688874006271,-0.707135140895844,0.516692578792572,0.482630282640457,-0.707134485244751,0.516748130321503, +0.482630282640457,-0.707134485244751,0.516748130321503,0.482688874006271,-0.707135140895844,0.516692578792572,0.462436616420746,-0.704123079776764,0.538853347301483,0.462677359580994,-0.704150140285492,0.53861129283905,-0.491028189659119,0.707340955734253,0.508487939834595,-0.490713685750961,0.707341492176056,0.508790612220764,-0.555838882923126,0.702130615711212,0.445034384727478,-0.555629551410675,0.702163457870483,0.445243865251541,-0.490713685750961,0.707341492176056,0.508790612220764,-0.491028189659119,0.707340955734253,0.508487939834595,-0.45145457983017,0.707544207572937,0.543663322925568,-0.451454341411591,0.707544267177582,0.543663561344147,-0.451454341411591,0.707544267177582,0.543663561344147,-0.45145457983017,0.707544207572937,0.543663322925568,-0.399400293827057,0.707484781742096,0.583047747612,-0.399400293827057,0.707484781742096,0.583047688007355,-0.399400293827057,0.707484781742096,0.583047688007355,-0.399400293827057,0.707484781742096,0.583047747612,-0.343899607658386,0.707481861114502,0.617415845394135,-0.34389927983284,0.707481861114502,0.617416083812714,-0.34389927983284,0.707481861114502,0.617416083812714,-0.343899607658386,0.707481861114502,0.617415845394135,-0.285463780164719,0.707486271858215,0.646508753299713,-0.285463839769363,0.707486212253571,0.646508693695068,-0.285463839769363,0.707486212253571,0.646508693695068,-0.285463780164719,0.707486271858215,0.646508753299713,-0.224591076374054,0.707484245300293,0.670093059539795,-0.224591165781021,0.707484185695648,0.67009311914444,-0.224591165781021,0.707484185695648,0.67009311914444,-0.224591076374054,0.707484245300293,0.670093059539795,-0.161803752183914,0.707482635974884,0.687959134578705,-0.161803960800171,0.707482576370239,0.687959134578705,-0.161803960800171,0.707482576370239,0.687959134578705,-0.161803752183914,0.707482635974884,0.687959134578705,-0.0976390838623047,0.707483410835266,0.699952602386475,-0.0976390168070793,0.707483410835266,0.699952602386475,-0.0976390168070793,0.707483410835266,0.699952602386475,-0.0976390838623047,0.707483410835266,0.699952602386475, +-0.0326393321156502,0.707476556301117,0.705982565879822,-0.0326393581926823,0.707476556301117,0.705982565879822,-0.0326393581926823,0.707476556301117,0.705982565879822,-0.0326393321156502,0.707476556301117,0.705982565879822,0.0326395034790039,0.70747983455658,0.705979347229004,0.0326395332813263,0.70747983455658,0.705979287624359,0.0326395332813263,0.70747983455658,0.705979287624359,0.0326395034790039,0.70747983455658,0.705979347229004,0.0976397171616554,0.707486629486084,0.699949264526367,0.0976396501064301,0.707486569881439,0.699949324131012,0.0976396501064301,0.707486569881439,0.699949324131012,0.0976397171616554,0.707486629486084,0.699949264526367,0.161803841590881,0.707482576370239,0.687959134578705,0.161804065108299,0.707482576370239,0.68795907497406,0.161804065108299,0.707482576370239,0.68795907497406,0.161803841590881,0.707482576370239,0.687959134578705,0.224590092897415,0.707487523555756,0.670090019702911,0.224590212106705,0.707487463951111,0.670089960098267,0.224590212106705,0.707487463951111,0.670089960098267,0.224590092897415,0.707487523555756,0.670090019702911,0.28546130657196,0.70748645067215,0.64650958776474,0.285461366176605,0.70748645067215,0.646509408950806,0.285461366176605,0.70748645067215,0.646509408950806,0.28546130657196,0.70748645067215,0.64650958776474,0.343898177146912,0.707479059696198,0.617419958114624,0.343897759914398,0.707479000091553,0.617420077323914,0.343897759914398,0.707479000091553,0.617420077323914,0.343898177146912,0.707479059696198,0.617419958114624,0.399403661489487,0.707484185695648,0.583046019077301,0.399403691291809,0.707484185695648,0.583045959472656,0.399403691291809,0.707484185695648,0.583045959472656,0.399403661489487,0.707484185695648,0.583046019077301,0.451460331678391,0.707540273666382,0.543663859367371,0.451460063457489,0.707540214061737,0.543664038181305,0.451460063457489,0.707540214061737,0.543664038181305,0.451460331678391,0.707540273666382,0.543663859367371,0.491029798984528,0.70733505487442,0.508494436740875,0.490715384483337,0.707335591316223,0.5087970495224, +0.490715384483337,0.707335591316223,0.5087970495224,0.491029798984528,0.70733505487442,0.508494436740875,0.555630207061768,0.702166140079498,0.445238828659058,0.555839478969574,0.702133297920227,0.445029199123383,0.492509990930557,0.684213042259216,-0.537853479385376,0.492175161838531,0.686408638954163,-0.535356521606445,0.48941445350647,0.689920663833618,-0.533369302749634,0.45203822851181,0.691637694835663,-0.563292682170868,0.444328039884567,0.702110469341278,-0.556428968906403,0.451279312372208,0.707483410835266,-0.543888032436371,0.45127934217453,0.707483410835266,-0.543887794017792,0.399398952722549,0.707484126091003,-0.583049297332764,0.399398982524872,0.707484185695648,-0.583049297332764,0.399398982524872,0.707484185695648,-0.583049297332764,0.399398952722549,0.707484126091003,-0.583049297332764,0.343897670507431,0.707486629486084,-0.617411553859711,0.343897700309753,0.707486629486084,-0.617411434650421,0.343897700309753,0.707486629486084,-0.617411434650421,0.343897670507431,0.707486629486084,-0.617411553859711,0.285462141036987,0.707481145858765,-0.646515071392059,0.285462111234665,0.707481145858765,-0.646515071392059,0.285462111234665,0.707481145858765,-0.646515071392059,0.285462141036987,0.707481145858765,-0.646515071392059,0.224592670798302,0.707483351230621,-0.670093595981598,0.224592655897141,0.707483291625977,-0.670093595981598,0.224592655897141,0.707483291625977,-0.670093595981598,0.224592670798302,0.707483351230621,-0.670093595981598,0.16180631518364,0.707487761974335,-0.687953293323517,0.161806464195251,0.70748770236969,-0.687953233718872,0.161806464195251,0.70748770236969,-0.687953233718872,0.16180631518364,0.707487761974335,-0.687953293323517,0.0976399630308151,0.70748895406723,-0.699946880340576,0.0976398959755898,0.70748895406723,-0.699946939945221,0.0976398959755898,0.70748895406723,-0.699946939945221,0.0976399630308151,0.70748895406723,-0.699946880340576,0.0326396860182285,0.707491099834442,-0.705968081951141,0.0326397009193897,0.707491040229797,-0.705968081951141,0.0326397009193897,0.707491040229797,-0.705968081951141, +0.0326396860182285,0.707491099834442,-0.705968081951141,-0.0326396822929382,0.70748770236969,-0.705971479415894,-0.0326397009193897,0.70748770236969,-0.705971479415894,-0.0326397009193897,0.70748770236969,-0.705971479415894,-0.0326396822929382,0.70748770236969,-0.705971479415894,-0.0976395159959793,0.707485616207123,-0.699950337409973,-0.0976394489407539,0.707485556602478,-0.699950397014618,-0.0976394489407539,0.707485556602478,-0.699950397014618,-0.0976395159959793,0.707485616207123,-0.699950337409973,-0.161806434392929,0.70748770236969,-0.687953293323517,-0.161806598305702,0.70748770236969,-0.687953174114227,-0.161806598305702,0.70748770236969,-0.687953174114227,-0.161806434392929,0.70748770236969,-0.687953293323517,-0.224592253565788,0.707485020160675,-0.670091986656189,-0.224592268466949,0.707485020160675,-0.670091986656189,-0.224592268466949,0.707485020160675,-0.670091986656189,-0.224592253565788,0.707485020160675,-0.670091986656189,-0.285460650920868,0.707484424114227,-0.646512091159821,-0.285460650920868,0.707484364509583,-0.646512150764465,-0.285460650920868,0.707484364509583,-0.646512150764465,-0.285460650920868,0.707484424114227,-0.646512091159821,-0.343896865844727,0.707488298416138,-0.617410004138947,-0.343896925449371,0.707488238811493,-0.617409944534302,-0.343896925449371,0.707488238811493,-0.617409944534302,-0.343896865844727,0.707488298416138,-0.617410004138947,-0.399399161338806,0.707484066486359,-0.583049297332764,-0.399399131536484,0.707484126091003,-0.583049237728119,-0.399399131536484,0.707484126091003,-0.583049237728119,-0.399399161338806,0.707484066486359,-0.583049297332764,-0.451279908418655,0.707477390766144,-0.543895244598389,-0.451279759407043,0.707477390766144,-0.543895304203033,-0.451279759407043,0.707477390766144,-0.543895304203033,-0.451279908418655,0.707477390766144,-0.543895244598389,-0.492512315511703,0.684202611446381,-0.537864506244659,-0.672601997852325,0.0576485246419907,-0.737755477428436,0.485205411911011,-0.707231462001801,-0.514197587966919,0.485205441713333,-0.707231462001801,-0.514197647571564, +0.538861453533173,-0.704083323478699,-0.462487757205963,0.538620114326477,-0.704109966754913,-0.462728232145309,0.485205441713333,-0.707231462001801,-0.514197647571564,0.485205411911011,-0.707231462001801,-0.514197587966919,0.451475888490677,-0.707506239414215,-0.543695092201233,0.451475918292999,-0.707506239414215,-0.543694913387299,0.451475918292999,-0.707506239414215,-0.543694913387299,0.451475888490677,-0.707506239414215,-0.543695092201233,0.399399042129517,-0.707484126091003,-0.583049237728119,0.399399042129517,-0.707484126091003,-0.583049297332764,0.399399042129517,-0.707484126091003,-0.583049297332764,0.399399042129517,-0.707484126091003,-0.583049237728119,0.343897670507431,-0.707486569881439,-0.617411494255066,0.343897610902786,-0.707486569881439,-0.617411613464355,0.343897610902786,-0.707486569881439,-0.617411613464355,0.343897670507431,-0.707486569881439,-0.617411494255066,0.285463213920593,-0.707484126091003,-0.646511256694794,0.285463213920593,-0.707484126091003,-0.646511256694794,0.285463213920593,-0.707484126091003,-0.646511256694794,0.285463213920593,-0.707484126091003,-0.646511256694794,0.224592715501785,-0.707483291625977,-0.670093536376953,0.224592760205269,-0.707483351230621,-0.670093536376953,0.224592760205269,-0.707483351230621,-0.670093536376953,0.224592715501785,-0.707483291625977,-0.670093536376953,0.161806359887123,-0.70748770236969,-0.687953233718872,0.161806181073189,-0.707487761974335,-0.687953233718872,0.161806181073189,-0.707487761974335,-0.687953233718872,0.161806359887123,-0.70748770236969,-0.687953233718872,0.0976390540599823,-0.707482278347015,-0.69995379447937,0.0976391285657883,-0.707482278347015,-0.69995379447937,0.0976391285657883,-0.707482278347015,-0.69995379447937,0.0976390540599823,-0.707482278347015,-0.69995379447937,0.0326391458511353,-0.707477629184723,-0.705981552600861,0.0326391309499741,-0.707477688789368,-0.705981552600861,0.0326391309499741,-0.707477688789368,-0.705981552600861,0.0326391458511353,-0.707477629184723,-0.705981552600861,-0.0326393321156502,-0.707481026649475,-0.705978155136108, +-0.0326393060386181,-0.707481026649475,-0.705978155136108,-0.0326393060386181,-0.707481026649475,-0.705978155136108,-0.0326393321156502,-0.707481026649475,-0.705978155136108,-0.0976395606994629,-0.707485616207123,-0.699950397014618,-0.0976396203041077,-0.707485616207123,-0.699950337409973,-0.0976396203041077,-0.707485616207123,-0.699950337409973,-0.0976395606994629,-0.707485616207123,-0.699950397014618,-0.161806508898735,-0.70748770236969,-0.687953233718872,-0.161806344985962,-0.70748770236969,-0.687953293323517,-0.161806344985962,-0.70748770236969,-0.687953293323517,-0.161806508898735,-0.70748770236969,-0.687953233718872,-0.224592357873917,-0.70748496055603,-0.670091867446899,-0.224592357873917,-0.707485020160675,-0.670091986656189,-0.224592357873917,-0.707485020160675,-0.670091986656189,-0.224592357873917,-0.70748496055603,-0.670091867446899,-0.285461902618408,-0.707487404346466,-0.64650821685791,-0.285461962223053,-0.707487463951111,-0.64650821685791,-0.285461962223053,-0.707487463951111,-0.64650821685791,-0.285461902618408,-0.707487404346466,-0.64650821685791,-0.343896865844727,-0.707488238811493,-0.617410063743591,-0.343896836042404,-0.707488238811493,-0.617410123348236,-0.343896836042404,-0.707488238811493,-0.617410123348236,-0.343896865844727,-0.707488238811493,-0.617410063743591,-0.399399310350418,-0.707484126091003,-0.583049178123474,-0.399399250745773,-0.707484126091003,-0.583049178123474,-0.399399250745773,-0.707484126091003,-0.583049178123474,-0.399399310350418,-0.707484126091003,-0.583049178123474,-0.451476335525513,-0.707500338554382,-0.543702244758606,-0.451476484537125,-0.707500338554382,-0.543702304363251,-0.451476484537125,-0.707500338554382,-0.543702304363251,-0.451476335525513,-0.707500338554382,-0.543702244758606,-0.48520627617836,-0.707219898700714,-0.514212667942047,-0.485206335783005,-0.707219898700714,-0.514212608337402,-0.485206335783005,-0.707219898700714,-0.514212608337402,-0.48520627617836,-0.707219898700714,-0.514212667942047,-0.538620173931122,-0.704100966453552,-0.462741851806641,-0.538861453533173,-0.704074323177338,-0.462501347064972, +-0.490708649158478,-0.707344949245453,0.508790791034698,-0.491022944450378,-0.707344353199005,0.508488237857819,-0.555616497993469,-0.702168345451355,0.445252478122711,-0.555825233459473,-0.702135622501373,0.445043534040451,-0.491022944450378,-0.707344353199005,0.508488237857819,-0.490708649158478,-0.707344949245453,0.508790791034698,-0.451454043388367,-0.707546710968018,0.543660521507263,-0.451454281806946,-0.707546710968018,0.543660342693329,-0.451454281806946,-0.707546710968018,0.543660342693329,-0.451454043388367,-0.707546710968018,0.543660521507263,-0.399396270513535,-0.707487523555756,0.583046972751617,-0.399396300315857,-0.7074875831604,0.583047091960907,-0.399396300315857,-0.7074875831604,0.583047091960907,-0.399396270513535,-0.707487523555756,0.583046972751617,-0.343895494937897,-0.707488059997559,0.617411077022552,-0.343895763158798,-0.707488000392914,0.617410957813263,-0.343895763158798,-0.707488000392914,0.617410957813263,-0.343895494937897,-0.707488059997559,0.617411077022552,-0.285460829734802,-0.707489311695099,0.646506726741791,-0.28546068072319,-0.707489311695099,0.646506726741791,-0.28546068072319,-0.707489311695099,0.646506726741791,-0.285460829734802,-0.707489311695099,0.646506726741791,-0.224590182304382,-0.707492232322693,0.670084953308105,-0.224590063095093,-0.707492232322693,0.670085072517395,-0.224590063095093,-0.707492232322693,0.670085072517395,-0.224590182304382,-0.707492232322693,0.670084953308105,-0.161804422736168,-0.707492291927338,0.687948942184448,-0.161804184317589,-0.707492291927338,0.687949001789093,-0.161804184317589,-0.707492291927338,0.687949001789093,-0.161804422736168,-0.707492291927338,0.687948942184448,-0.0976386591792107,-0.707485198974609,0.699950873851776,-0.0976388975977898,-0.707485258579254,0.699950814247131,-0.0976388975977898,-0.707485258579254,0.699950814247131,-0.0976386591792107,-0.707485198974609,0.699950873851776,-0.0326391533017159,-0.707480251789093,0.70597892999649,-0.0326391533017159,-0.707480192184448,0.705978989601135,-0.0326391533017159,-0.707480192184448,0.705978989601135, +-0.0326391533017159,-0.707480251789093,0.70597892999649,0.0326396264135838,-0.707479596138,0.705979585647583,0.0326396226882935,-0.707479596138,0.705979466438293,0.0326396226882935,-0.707479596138,0.705979466438293,0.0326396264135838,-0.707479596138,0.705979585647583,0.0976387113332748,-0.707483947277069,0.699952065944672,0.0976389721035957,-0.707484006881714,0.699952125549316,0.0976389721035957,-0.707484006881714,0.699952125549316,0.0976387113332748,-0.707483947277069,0.699952065944672,0.161804437637329,-0.707491278648376,0.687950015068054,0.161804258823395,-0.707491278648376,0.687950074672699,0.161804258823395,-0.707491278648376,0.687950074672699,0.161804437637329,-0.707491278648376,0.687950015068054,0.224590614438057,-0.707491755485535,0.670085251331329,0.224590420722961,-0.707491815090179,0.670085370540619,0.224590420722961,-0.707491815090179,0.670085370540619,0.224590614438057,-0.707491755485535,0.670085251331329,0.285460859537125,-0.707489371299744,0.646506607532501,0.285460859537125,-0.707489371299744,0.646506607532501,0.285460859537125,-0.707489371299744,0.646506607532501,0.285460859537125,-0.707489371299744,0.646506607532501,0.343896389007568,-0.707486391067505,0.617412328720093,0.343896567821503,-0.70748645067215,0.617412209510803,0.343896567821503,-0.70748645067215,0.617412209510803,0.343896389007568,-0.707486391067505,0.617412328720093,0.399399101734161,-0.707482814788818,0.583050787448883,0.399399101734161,-0.707482755184174,0.583050906658173,0.399399101734161,-0.707482755184174,0.583050906658173,0.399399101734161,-0.707482814788818,0.583050787448883,0.451458275318146,-0.707540273666382,0.543665289878845,0.451458424329758,-0.707540273666382,0.543665111064911,0.451458424329758,-0.707540273666382,0.543665111064911,0.451458275318146,-0.707540273666382,0.543665289878845,0.490713208913803,-0.707338452339172,0.508795440196991,0.491027504205704,-0.707337915897369,0.508492887020111,0.491027504205704,-0.707337915897369,0.508492887020111,0.490713208913803,-0.707338452339172,0.508795440196991,0.555825591087341,-0.702135443687439,0.445043385028839, +0.555616974830627,-0.702167987823486,0.445252269506454,-0.482619643211365,0.70714259147644,0.516747176647186,-0.482678234577179,0.707143068313599,0.5166916847229,-0.462437093257904,0.704125642776489,0.538849651813507,-0.462677299976349,0.704152524471283,0.538608074188232,-0.482678234577179,0.707143068313599,0.5166916847229,-0.482619643211365,0.70714259147644,0.516747176647186,-0.451510667800903,0.707462072372437,0.543723702430725,-0.451510548591614,0.707462072372437,0.54372376203537,-0.451510548591614,0.707462072372437,0.54372376203537,-0.451510667800903,0.707462072372437,0.543723702430725,-0.399397850036621,0.707484841346741,0.583049237728119,-0.399397909641266,0.707484841346741,0.583049178123474,-0.399397909641266,0.707484841346741,0.583049178123474,-0.399397850036621,0.707484841346741,0.583049237728119,-0.343897521495819,0.707485139369965,0.617413222789764,-0.343897223472595,0.707485198974609,0.617413282394409,-0.343897223472595,0.707485198974609,0.617413282394409,-0.343897521495819,0.707485139369965,0.617413222789764,-0.285461217164993,0.707488715648651,0.646507084369659,-0.285461366176605,0.707488775253296,0.646507024765015,-0.285461366176605,0.707488775253296,0.646507024765015,-0.285461217164993,0.707488715648651,0.646507084369659,-0.224590063095093,0.707491397857666,0.670085906982422,-0.224590227007866,0.707491397857666,0.670085906982422,-0.224590227007866,0.707491397857666,0.670085906982422,-0.224590063095093,0.707491397857666,0.670085906982422,-0.161805585026741,0.70748382806778,0.687957465648651,-0.161805808544159,0.70748382806778,0.687957346439362,-0.161805808544159,0.70748382806778,0.687957346439362,-0.161805585026741,0.70748382806778,0.687957465648651,-0.0976404920220375,0.707474589347839,0.699961364269257,-0.097640261054039,0.707474529743195,0.699961364269257,-0.097640261054039,0.707474529743195,0.699961364269257,-0.0976404920220375,0.707474589347839,0.699961364269257,-0.0326396152377129,0.707477152347565,0.705982029438019,-0.0326396189630032,0.707477152347565,0.705982029438019,-0.0326396189630032,0.707477152347565,0.705982029438019, +-0.0326396152377129,0.707477152347565,0.705982029438019,0.0326400808990002,0.707476913928986,0.705982148647308,0.0326400920748711,0.707476913928986,0.705982208251953,0.0326400920748711,0.707476913928986,0.705982208251953,0.0326400808990002,0.707476913928986,0.705982148647308,0.0976406112313271,0.707473814487457,0.699962198734283,0.0976403802633286,0.707473814487457,0.699962198734283,0.0976403802633286,0.707473814487457,0.699962198734283,0.0976406112313271,0.707473814487457,0.699962198734283,0.161805495619774,0.707483291625977,0.687958002090454,0.161805674433708,0.707483232021332,0.687958002090454,0.161805674433708,0.707483232021332,0.687958002090454,0.161805495619774,0.707483291625977,0.687958002090454,0.224590346217155,0.707491338253021,0.670085966587067,0.22459052503109,0.707491278648376,0.670085787773132,0.22459052503109,0.707491278648376,0.670085787773132,0.224590346217155,0.707491338253021,0.670085966587067,0.285461336374283,0.707488715648651,0.646507084369659,0.285461395978928,0.707488656044006,0.646507084369659,0.285461395978928,0.707488656044006,0.646507084369659,0.285461336374283,0.707488715648651,0.646507084369659,0.343898355960846,0.7074835896492,0.617414712905884,0.343898147344589,0.707483530044556,0.617414712905884,0.343898147344589,0.707483530044556,0.617414712905884,0.343898355960846,0.7074835896492,0.617414712905884,0.399400651454926,0.707479953765869,0.583053171634674,0.39940071105957,0.707479953765869,0.583053231239319,0.39940071105957,0.707479953765869,0.583053231239319,0.399400651454926,0.707479953765869,0.583053171634674,0.451516956090927,0.707452297210693,0.543731212615967,0.451516836881638,0.707452356815338,0.543731272220612,0.451516836881638,0.707452356815338,0.543731272220612,0.451516956090927,0.707452297210693,0.543731212615967,0.482624351978302,0.707135796546936,0.516751945018768,0.482682943344116,0.707136392593384,0.516696393489838,0.482682943344116,0.707136392593384,0.516696393489838,0.482624351978302,0.707135796546936,0.516751945018768,0.462674260139465,0.704156100749969,0.538606107234955, +0.462434142827988,0.704129159450531,0.538847506046295,0.555839478969574,0.702133297920227,0.445029199123383,0.555630207061768,0.702166140079498,0.445238828659058,0.646781265735626,0.674310505390167,0.356341451406479,0.647080957889557,0.674181699752808,0.356041133403778,0.462677359580994,-0.704150140285492,0.53861129283905,0.462436616420746,-0.704123079776764,0.538853347301483,0.367919534444809,-0.678227782249451,0.63611501455307,0.368299216032028,-0.678379058837891,0.635733783245087,-0.538861453533173,-0.704074323177338,-0.462501347064972,-0.538620173931122,-0.704100966453552,-0.462741851806641,-0.635725319385529,-0.678380966186523,-0.368310183286667,-0.636106729507446,-0.678229570388794,-0.367930442094803,0.647080957889557,0.674181699752808,0.356041133403778,0.646781265735626,0.674310505390167,0.356341451406479,0.763977825641632,0.598722517490387,0.240560382604599,0.764238059520721,0.598495185375214,0.240298956632614,0.368299216032028,-0.678379058837891,0.635733783245087,0.367919534444809,-0.678227782249451,0.63611501455307,0.243654876947403,-0.600365698337555,0.761704206466675,0.243992671370506,-0.600655198097229,0.761367619037628,-0.636106729507446,-0.678229570388794,-0.367930442094803,-0.635725319385529,-0.678380966186523,-0.368310183286667,-0.76137363910675,-0.600646376609802,-0.243995875120163,-0.761708855628967,-0.600357830524445,-0.243659362196922,-0.355662167072296,0.674020230770111,-0.647457301616669,-0.355361133813858,0.673891007900238,-0.647757112979889,-0.240291401743889,0.59849601984024,-0.764239728450775,-0.240552306175232,0.5987229347229,-0.763979852199554,0.764238059520721,0.598495185375214,0.240298956632614,0.763977825641632,0.598722517490387,0.240560382604599,0.867361903190613,0.478563070297241,0.136603727936745,0.867511212825775,0.478335291147232,0.136453449726105,0.243992671370506,-0.600655198097229,0.761367619037628,0.243654876947403,-0.600365698337555,0.761704206466675,0.136167392134666,-0.477284878492355,0.868134498596191,0.13635079562664,-0.477561771869659,0.867953419685364,-0.761708855628967,-0.600357830524445,-0.243659362196922, +-0.76137363910675,-0.600646376609802,-0.243995875120163,-0.867954254150391,-0.47756227850914,-0.136343687772751,-0.868135333061218,-0.477285325527191,-0.136160209774971,-0.240552306175232,0.5987229347229,-0.763979852199554,-0.240291401743889,0.59849601984024,-0.764239728450775,-0.136455118656158,0.478327333927155,-0.867515325546265,-0.136605381965637,0.478555142879486,-0.867365896701813,0.867511212825775,0.478335291147232,0.136453449726105,0.867361903190613,0.478563070297241,0.136603727936745,0.935613811016083,0.346612423658371,0.066982589662075,0.935676693916321,0.346454679965973,0.0669191628694534,0.13635079562664,-0.477561771869659,0.867953419685364,0.136167392134666,-0.477284878492355,0.868134498596191,0.0670884549617767,-0.346478641033173,0.93565571308136,0.0671620815992355,-0.346660047769547,0.935583293437958,-0.868135333061218,-0.477285325527191,-0.136160209774971,-0.867954254150391,-0.47756227850914,-0.136343687772751,-0.935582756996155,-0.346665799617767,-0.0671387538313866,-0.935654819011688,-0.346485435962677,-0.0670655369758606,-0.136605381965637,0.478555142879486,-0.867365896701813,-0.136455118656158,0.478327333927155,-0.867515325546265,-0.0669071078300476,0.346446961164474,-0.935680329799652,-0.0669702365994453,0.346603840589523,-0.935617804527283,0.935676693916321,0.346454679965973,0.0669191628694534,0.935613811016083,0.346612423658371,0.066982589662075,0.97310471534729,0.228593811392784,0.0284943804144859,0.973126292228699,0.228505045175552,0.0284727178514004,0.0671620815992355,-0.346660047769547,0.935583293437958,0.0670884549617767,-0.346478641033173,0.93565571308136,0.0289592538028955,-0.230122402310371,0.97273063659668,0.0289838071912527,-0.230221375823021,0.972706496715546,-0.935654819011688,-0.346485435962677,-0.0670655369758606,-0.935582756996155,-0.346665799617767,-0.0671387538313866,-0.972706973552704,-0.230220392346382,-0.0289766993373632,-0.972730994224548,-0.23012176156044,-0.0289522744715214,-0.0669702365994453,0.346603840589523,-0.935617804527283,-0.0669071078300476,0.346446961164474,-0.935680329799652, +-0.0284632407128811,0.228499710559845,-0.973127782344818,-0.0284849293529987,0.228588730096817,-0.973106205463409,0.973126292228699,0.228505045175552,0.0284727178514004,0.97310471534729,0.228593811392784,0.0284943804144859,0.991605937480927,0.128948703408241,0.00947749987244606,0.99161159992218,0.128905266523361,0.00947175268083811,0.0289838071912527,-0.230221375823021,0.972706496715546,0.0289592538028955,-0.230122402310371,0.97273063659668,0.00974462553858757,-0.130555152893066,0.991393089294434,0.00975100509822369,-0.130602493882179,0.991386711597443,-0.972730994224548,-0.23012176156044,-0.0289522744715214,-0.972706973552704,-0.230220392346382,-0.0289766993373632,-0.991386771202087,-0.130602493882179,-0.00975536648184061,-0.991393089294434,-0.13055507838726,-0.00974896550178528,-0.0284849293529987,0.228588730096817,-0.973106205463409,-0.0284632407128811,0.228499710559845,-0.973127782344818,-0.00947134848684072,0.128903016448021,-0.991611957550049,-0.00947711803019047,0.128946557641029,-0.99160623550415,0.99161159992218,0.128905266523361,0.00947175268083811,0.991605937480927,0.128948703408241,0.00947749987244606,0.999132513999939,0.0416060276329517,0.00174752261955291,0.999133050441742,0.0415931269526482,0.00174698082264513,0.00975100509822369,-0.130602493882179,0.991386711597443,0.00974462553858757,-0.130555152893066,0.991393089294434,0.00182107579894364,-0.0422462821006775,0.999105513095856,0.00182168453466147,-0.0422604791820049,0.999104917049408,-0.991393089294434,-0.13055507838726,-0.00974896550178528,-0.991386771202087,-0.130602493882179,-0.00975536648184061,-0.999105036258698,-0.0422580614686012,-0.00181378703564405,-0.999105632305145,-0.0422439277172089,-0.00181318039540201,-0.00947711803019047,0.128946557641029,-0.99160623550415,-0.00947134848684072,0.128903016448021,-0.991611957550049,-0.00174250791314989,0.0415908098220825,-0.999133050441742,-0.00174304447136819,0.0416036210954189,-0.999132633209229,0.999133050441742,0.0415931269526482,0.00174698082264513,0.999132513999939,0.0416060276329517,0.00174752261955291, +0.999132633209229,-0.0416023582220078,0.00175211823079735,0.999133110046387,-0.0415894985198975,0.00175157631747425,0.00182168453466147,-0.0422604791820049,0.999104917049408,0.00182107579894364,-0.0422462821006775,0.999105513095856,0.00181142590008676,0.0422468520700932,0.999105513095856,0.00181203021202236,0.0422610193490982,0.999104917049408,-0.999105632305145,-0.0422439277172089,-0.00181318039540201,-0.999105036258698,-0.0422580614686012,-0.00181378703564405,-0.999104857444763,0.0422600768506527,-0.001813834765926,-0.9991055727005,0.0422459281980991,-0.00181322731077671,-0.00174304447136819,0.0416036210954189,-0.999132633209229,-0.00174250791314989,0.0415908098220825,-0.999133050441742,-0.00174247135873884,-0.0415926389396191,-0.999133050441742,-0.00174301140941679,-0.0416055358946323,-0.999132513999939,0.999133110046387,-0.0415894985198975,0.00175157631747425,0.999132633209229,-0.0416023582220078,0.00175211823079735,0.991606831550598,-0.128941357135773,0.00948478560894728,0.991612434387207,-0.128898039460182,0.00947905890643597,0.00181203021202236,0.0422610193490982,0.999104917049408,0.00181142590008676,0.0422468520700932,0.999105513095856,0.00973523780703545,0.130556628108025,0.991393029689789,0.00974164064973593,0.130604073405266,0.991386711597443,-0.9991055727005,0.0422459281980991,-0.00181322731077671,-0.999104857444763,0.0422600768506527,-0.001813834765926,-0.991386771202087,0.13060274720192,-0.00975304469466209,-0.991393029689789,0.130555689334869,-0.00974669400602579,-0.00174301140941679,-0.0416055358946323,-0.999132513999939,-0.00174247135873884,-0.0415926389396191,-0.999133050441742,-0.00946606509387493,-0.128904193639755,-0.991611838340759,-0.00947175361216068,-0.128947168588638,-0.991606175899506,0.991612434387207,-0.128898039460182,0.00947905890643597,0.991606831550598,-0.128941357135773,0.00948478560894728,0.973105669021606,-0.228590488433838,0.0284895580261946,0.97312718629837,-0.228501483798027,0.028467858210206,0.00974164064973593,0.130604073405266,0.991386711597443,0.00973523780703545,0.130556628108025,0.991393029689789, +0.0289422981441021,0.230125471949577,0.972730457782745,0.0289668049663305,0.230224370956421,0.972706377506256,-0.991393029689789,0.130555689334869,-0.00974669400602579,-0.991386771202087,0.13060274720192,-0.00975304469466209,-0.972706139087677,0.230224296450615,-0.028973700478673,-0.972730100154877,0.23012563586235,-0.0289492662996054,-0.00947175361216068,-0.128947168588638,-0.991606175899506,-0.00946606509387493,-0.128904193639755,-0.991611838340759,-0.0284691285341978,-0.228503823280334,-0.973126530647278,-0.028490761294961,-0.228592485189438,-0.973105192184448,0.97312718629837,-0.228501483798027,0.028467858210206,0.973105669021606,-0.228590488433838,0.0284895580261946,0.935613334178925,-0.346615195274353,0.0669738128781319,0.935676336288452,-0.346457093954086,0.0669102221727371,0.0289668049663305,0.230224370956421,0.972706377506256,0.0289422981441021,0.230125471949577,0.972730457782745,0.0670647472143173,0.346484035253525,0.935655415058136,0.0671381130814552,0.346664696931839,0.935583114624023,-0.972730100154877,0.23012563586235,-0.0289492662996054,-0.972706139087677,0.230224296450615,-0.028973700478673,-0.935579419136047,0.346673756837845,-0.0671428218483925,-0.935651838779449,0.346492767333984,-0.0670693293213844,-0.028490761294961,-0.228592485189438,-0.973105192184448,-0.0284691285341978,-0.228503823280334,-0.973126530647278,-0.066919669508934,-0.346451938152313,-0.935677707195282,-0.0669831559062004,-0.346609771251678,-0.935614764690399,0.935676336288452,-0.346457093954086,0.0669102221727371,0.935613334178925,-0.346615195274353,0.0669738128781319,0.867364585399628,-0.478558778762817,0.136602118611336,0.867514252662659,-0.478330314159393,0.136451378464699,0.0671381130814552,0.346664696931839,0.935583114624023,0.0670647472143173,0.346484035253525,0.935655415058136,0.136157229542732,0.477284908294678,0.868136048316956,0.13634081184864,0.477562010288239,0.867954730987549,-0.935651838779449,0.346492767333984,-0.0670693293213844,-0.935579419136047,0.346673756837845,-0.0671428218483925,-0.867949724197388,0.477568715810776,-0.136349186301231, +-0.868131399154663,0.477291315793991,-0.136165350675583,-0.0669831559062004,-0.346609771251678,-0.935614764690399,-0.066919669508934,-0.346451938152313,-0.935677707195282,-0.136460855603218,-0.478334665298462,-0.867510378360748,-0.136611521244049,-0.478563070297241,-0.867360591888428,0.867514252662659,-0.478330314159393,0.136451378464699,0.867364585399628,-0.478558778762817,0.136602118611336,0.763979136943817,-0.598723530769348,0.240553230047226,0.764239847660065,-0.598495960235596,0.240291595458984,0.13634081184864,0.477562010288239,0.867954730987549,0.136157229542732,0.477284908294678,0.868136048316956,0.243649542331696,0.600366830825806,0.761704981327057,0.243986308574677,0.600655555725098,0.761369526386261,-0.868131399154663,0.477291315793991,-0.136165350675583,-0.867949724197388,0.477568715810776,-0.136349186301231,-0.761376917362213,0.60064297914505,-0.243994191288948,-0.761711835861206,0.600354671478271,-0.24365796148777,-0.136611521244049,-0.478563070297241,-0.867360591888428,-0.136460855603218,-0.478334665298462,-0.867510378360748,-0.240297332406044,-0.598501443862915,-0.764233648777008,-0.240558624267578,-0.598728597164154,-0.763973593711853,0.764239847660065,-0.598495960235596,0.240291595458984,0.763979136943817,-0.598723530769348,0.240553230047226,0.646768093109131,-0.674321353435516,0.356344789266586,0.647067368030548,-0.674192726612091,0.356044828891754,0.243986308574677,0.600655555725098,0.761369526386261,0.243649542331696,0.600366830825806,0.761704981327057,0.367922902107239,0.678237318992615,0.636102855205536,0.368302822113037,0.678388774394989,0.635721266269684,-0.761711835861206,0.600354671478271,-0.24365796148777,-0.761376917362213,0.60064297914505,-0.243994191288948,-0.635726988315582,0.678381860256195,-0.368305683135986,-0.636108636856079,0.678230285644531,-0.367925703525543,-0.240558624267578,-0.598728597164154,-0.763973593711853,-0.240297332406044,-0.598501443862915,-0.764233648777008,-0.356044232845306,-0.674181401729584,-0.647079527378082,-0.35634458065033,-0.674310207366943,-0.646779835224152, +0.647067368030548,-0.674192726612091,0.356044828891754,0.646768093109131,-0.674321353435516,0.356344789266586,0.555616974830627,-0.702167987823486,0.445252269506454,0.555825591087341,-0.702135443687439,0.445043385028839,0.368302822113037,0.678388774394989,0.635721266269684,0.367922902107239,0.678237318992615,0.636102855205536,0.462434142827988,0.704129159450531,0.538847506046295,0.462674260139465,0.704156100749969,0.538606107234955,-0.636108636856079,0.678230285644531,-0.367925703525543,-0.635726988315582,0.678381860256195,-0.368305683135986,-0.538595020771027,0.704161822795868,-0.462678611278534,-0.538836717605591,0.70413476228714,-0.46243816614151,-0.35634458065033,-0.674310207366943,-0.646779835224152,-0.356044232845306,-0.674181401729584,-0.647079527378082,-0.445027619600296,-0.702146172523499,-0.555824637413025,-0.445236682891846,-0.702179074287415,-0.555615544319153,-0.538836717605591,0.70413476228714,-0.46243816614151,-0.538595020771027,0.704161822795868,-0.462678611278534,-0.503736972808838,0.707155406475067,-0.496165454387665,-0.503736913204193,0.707155406475067,-0.496165335178375,-0.445236682891846,-0.702179074287415,-0.555615544319153,-0.445027619600296,-0.702146172523499,-0.555824637413025,-0.478407740592957,-0.706670224666595,-0.521289885044098,-0.478407740592957,-0.706670224666595,-0.521289825439453,0.522558391094208,0.707105398178101,-0.476376414299011,0.522558450698853,0.707105398178101,-0.476376444101334,0.447547346353531,0.710118055343628,-0.543538093566895,0.447546601295471,0.710118114948273,-0.543538749217987,0.522561967372894,-0.707101583480835,-0.476378172636032,0.522562026977539,-0.70710164308548,-0.476378202438354,0.447548866271973,-0.710114479064941,-0.543541491031647,0.447549641132355,-0.710114479064941,-0.543540835380554,-0.555629551410675,0.702163457870483,0.445243865251541,-0.555838882923126,0.702130615711212,0.445034384727478,-0.647075414657593,0.674181759357452,0.356050878763199,-0.646775722503662,0.674310624599457,0.356351345777512,0.444328039884567,0.702110469341278,-0.556428968906403, +0.45203822851181,0.691637694835663,-0.563292682170868,0.69258052110672,0.066249705851078,-0.718291759490967,0.355665177106857,0.674006164073944,-0.647470235824585,0.355364739894867,0.67387717962265,-0.647769451141357,0.538620114326477,-0.704109966754913,-0.462728232145309,0.538861453533173,-0.704083323478699,-0.462487757205963,0.63610714673996,-0.678232371807098,-0.367924362421036,0.635725915431976,-0.678383886814117,-0.368304044008255,-0.46243742108345,-0.704122722148895,0.538853108882904,-0.462678164243698,-0.704149782657623,0.538610994815826,-0.368305861949921,-0.678377330303192,0.635731756687164,-0.367926150560379,-0.678225874900818,0.636113047599792,-0.646775722503662,0.674310624599457,0.356351345777512,-0.647075414657593,0.674181759357452,0.356050878763199,-0.764231443405151,0.598499000072479,0.240310654044151,-0.763971149921417,0.598726272583008,0.240572094917297,0.355364739894867,0.67387717962265,-0.647769451141357,0.355665177106857,0.674006164073944,-0.647470235824585,0.240559369325638,0.598713159561157,-0.763985395431519,0.240298464894295,0.598486304283142,-0.764245212078094,0.635725915431976,-0.678383886814117,-0.368304044008255,0.63610714673996,-0.678232371807098,-0.367924362421036,0.761705935001373,-0.600358486175537,-0.243667483329773,0.761370658874512,-0.600646913051605,-0.244003847241402,-0.367926150560379,-0.678225874900818,0.636113047599792,-0.368305861949921,-0.678377330303192,0.635731756687164,-0.244000241160393,-0.600651204586029,0.761368453502655,-0.243662789463997,-0.600361883640289,0.761704742908478,-0.763971149921417,0.598726272583008,0.240572094917297,-0.764231443405151,0.598499000072479,0.240310654044151,-0.86750602722168,0.478340059518814,0.136469528079033,-0.86735612154007,0.478568613529205,0.136620387434959,0.240298464894295,0.598486304283142,-0.764245212078094,0.240559369325638,0.598713159561157,-0.763985395431519,0.136608868837357,0.478544026613235,-0.867371737957001,0.136458605527878,0.478316247463226,-0.867520928382874,0.761370658874512,-0.600646913051605,-0.244003847241402,0.761705935001373,-0.600358486175537,-0.243667483329773, +0.868133187294006,-0.477285891771317,-0.136171191930771,0.867952108383179,-0.477562755346298,-0.13635465502739,-0.243662789463997,-0.600361883640289,0.761704742908478,-0.244000241160393,-0.600651204586029,0.761368453502655,-0.136351078748703,-0.477563053369522,0.867952525615692,-0.136167570948601,-0.477286070585251,0.868133783340454,-0.86735612154007,0.478568613529205,0.136620387434959,-0.86750602722168,0.478340059518814,0.136469528079033,-0.935675203800201,0.346459180116653,0.0669168159365654,-0.935612380504608,0.346616327762604,0.0669800341129303,0.136458605527878,0.478316247463226,-0.867520928382874,0.136608868837357,0.478544026613235,-0.867371737957001,0.0669864416122437,0.346597611904144,-0.935618937015533,0.0669233873486519,0.346440851688385,-0.935681402683258,0.867952108383179,-0.477562755346298,-0.13635465502739,0.868133187294006,-0.477285891771317,-0.136171191930771,0.935653567314148,-0.346488237380981,-0.0670686364173889,0.935581505298615,-0.346668601036072,-0.0671418681740761,-0.136167570948601,-0.477286070585251,0.868133783340454,-0.136351078748703,-0.477563053369522,0.867952525615692,-0.0671404525637627,-0.346663057804108,0.935583651065826,-0.0670673549175262,-0.346483081579208,0.93565559387207,-0.935612380504608,0.346616327762604,0.0669800341129303,-0.935675203800201,0.346459180116653,0.0669168159365654,-0.973125636577606,0.228507548570633,0.0284736659377813,-0.973104178905487,0.228596329689026,0.0284953135997057,0.0669233873486519,0.346440851688385,-0.935681402683258,0.0669864416122437,0.346597611904144,-0.935618937015533,0.028490100055933,0.228589817881584,-0.973105788230896,0.0284683406352997,0.228500694036484,-0.973127365112305,0.935581505298615,-0.346668601036072,-0.0671418681740761,0.935653567314148,-0.346488237380981,-0.0670686364173889,0.972730338573456,-0.23012438416481,-0.0289536379277706,0.972706198692322,-0.230223000049591,-0.0289780665189028,-0.0670673549175262,-0.346483081579208,0.93565559387207,-0.0671404525637627,-0.346663057804108,0.935583651065826,-0.0289726667106152,-0.230224281549454,0.972706139087677, +-0.0289481543004513,-0.230125308036804,0.972730219364166,-0.973104178905487,0.228596329689026,0.0284953135997057,-0.973125636577606,0.228507548570633,0.0284736659377813,-0.99161159992218,0.128904536366463,0.00948285311460495,-0.991605877876282,0.128948196768761,0.00948862545192242,0.0284683406352997,0.228500694036484,-0.973127365112305,0.028490100055933,0.228589817881584,-0.973105788230896,0.0094723841175437,0.128947541117668,-0.991606116294861,0.00946670211851597,0.128904551267624,-0.991611778736115,0.972706198692322,-0.230223000049591,-0.0289780665189028,0.972730338573456,-0.23012438416481,-0.0289536379277706,0.991392731666565,-0.130557581782341,-0.00975023023784161,0.991386413574219,-0.130604982376099,-0.00975663028657436,-0.0289481543004513,-0.230125308036804,0.972730219364166,-0.0289726667106152,-0.230224281549454,0.972706139087677,-0.00975606311112642,-0.130604803562164,0.991386473178864,-0.00974967703223228,-0.13055744767189,0.991392731666565,-0.991605877876282,0.128948196768761,0.00948862545192242,-0.99161159992218,0.128904536366463,0.00948285311460495,-0.999133050441742,0.0415906645357609,0.00175207736901939,-0.999132513999939,0.0416035801172256,0.00175262149423361,0.00946670211851597,0.128904551267624,-0.991611778736115,0.0094723841175437,0.128947541117668,-0.991606116294861,0.00174758024513721,0.0416046716272831,-0.999132573604584,0.00174704112578183,0.0415918380022049,-0.999133050441742,0.991386413574219,-0.130604982376099,-0.00975663028657436,0.991392731666565,-0.130557581782341,-0.00975023023784161,0.9991055727005,-0.042247973382473,-0.00181319809053093,0.999104857444763,-0.0422620922327042,-0.0018138037994504,-0.00974967703223228,-0.13055744767189,0.991392731666565,-0.00975606311112642,-0.130604803562164,0.991386473178864,-0.00182168511673808,-0.0422607213258743,0.999104917049408,-0.00182107638102025,-0.0422465316951275,0.999105513095856,-0.999132513999939,0.0416035801172256,0.00175262149423361,-0.999133050441742,0.0415906645357609,0.00175207736901939,-0.999133110046387,-0.0415915735065937,0.00174674729350954, +-0.999132633209229,-0.0416044369339943,0.00174728757701814,0.00174704112578183,0.0415918380022049,-0.999133050441742,0.00174758024513721,0.0416046716272831,-0.999132573604584,0.00174754939507693,-0.041606642305851,-0.999132573604584,0.00174700771458447,-0.041593749076128,-0.999133110046387,0.999104857444763,-0.0422620922327042,-0.0018138037994504,0.9991055727005,-0.042247973382473,-0.00181319809053093,0.999105513095856,0.04224743694067,-0.00181354314554483,0.999104797840118,0.0422615967690945,-0.00181415083352476,-0.00182107638102025,-0.0422465316951275,0.999105513095856,-0.00182168511673808,-0.0422607213258743,0.999104917049408,-0.00181687599979341,0.0422608032822609,0.999104917049408,-0.0018162700580433,0.0422466322779655,0.999105513095856,-0.999132633209229,-0.0416044369339943,0.00174728757701814,-0.999133110046387,-0.0415915735065937,0.00174674729350954,-0.991612255573273,-0.128900602459908,0.00946998037397861,-0.991606593132019,-0.128943726420403,0.00947568379342556,0.00174700771458447,-0.041593749076128,-0.999133110046387,0.00174754939507693,-0.041606642305851,-0.999132573604584,0.00947645865380764,-0.128948405385017,-0.991605997085571,0.00947077479213476,-0.128905445337296,-0.99161159992218,0.999104797840118,0.0422615967690945,-0.00181415083352476,0.999105513095856,0.04224743694067,-0.00181354314554483,0.991392612457275,0.130558103322983,-0.00974699854850769,0.991386353969574,0.130605518817902,-0.00975339580327272,-0.0018162700580433,0.0422466322779655,0.999105513095856,-0.00181687599979341,0.0422608032822609,0.999104917049408,-0.00975176692008972,0.130606427788734,0.991386294364929,-0.00974540784955025,0.130559310317039,0.991392493247986,-0.991606593132019,-0.128943726420403,0.00947568379342556,-0.991612255573273,-0.128900602459908,0.00946998037397861,-0.973128855228424,-0.228494644165039,0.0284685865044594,-0.97310733795166,-0.22858327627182,0.0284902174025774,0.00947077479213476,-0.128905445337296,-0.99161159992218,0.00947645865380764,-0.128948405385017,-0.991605997085571,0.0284905824810266,-0.228596061468124,-0.973104357719421, +0.0284689608961344,-0.228507444262505,-0.973125755786896,0.991386353969574,0.130605518817902,-0.00975339580327272,0.991392612457275,0.130558103322983,-0.00974699854850769,0.972729504108429,0.230128437280655,-0.0289506744593382,0.97270542383194,0.230227008461952,-0.0289750974625349,-0.00974540784955025,0.130559310317039,0.991392493247986,-0.00975176692008972,0.130606427788734,0.991386294364929,-0.0289723165333271,0.230229601264,0.972705006599426,-0.0289478208869696,0.230130702257156,0.97272914648056,-0.97310733795166,-0.22858327627182,0.0284902174025774,-0.973128855228424,-0.228494644165039,0.0284685865044594,-0.93568366765976,-0.34643480181694,0.0669245794415474,-0.935620427131653,-0.346593260765076,0.0669883489608765,0.0284689608961344,-0.228507444262505,-0.973125755786896,0.0284905824810266,-0.228596061468124,-0.973104357719421,0.0669934973120689,-0.346606343984604,-0.935615181922913,0.0669297575950623,-0.346448004245758,-0.935678422451019,0.97270542383194,0.230227008461952,-0.0289750974625349,0.972729504108429,0.230128437280655,-0.0289506744593382,0.935653984546661,0.346486955881119,-0.0670693665742874,0.935581564903259,0.346668004989624,-0.0671428963541985,-0.0289478208869696,0.230130702257156,0.97272914648056,-0.0289723165333271,0.230229601264,0.972705006599426,-0.0671410262584686,0.346673011779785,0.935580015182495,-0.0670676380395889,0.346492320299149,0.935652136802673,-0.935620427131653,-0.346593260765076,0.0669883489608765,-0.93568366765976,-0.34643480181694,0.0669245794415474,-0.867519974708557,-0.478316396474838,0.13646388053894,-0.867369651794434,-0.478545725345612,0.136615142226219,0.0669297575950623,-0.346448004245758,-0.935678422451019,0.0669934973120689,-0.346606343984604,-0.935615181922913,0.136623501777649,-0.478551357984543,-0.867365181446075,0.136472627520561,-0.478322595357895,-0.867515206336975,0.935581564903259,0.346668004989624,-0.0671428963541985,0.935653984546661,0.346486955881119,-0.0670693665742874,0.868136048316956,0.477283269166946,-0.136163055896759,0.86795449256897,0.477560698986053,-0.136346906423569, +-0.0670676380395889,0.346492320299149,0.935652136802673,-0.0671410262584686,0.346673011779785,0.935580015182495,-0.136352300643921,0.477556347846985,0.867956161499023,-0.136168569326401,0.47727906703949,0.868137538433075,-0.867369651794434,-0.478545725345612,0.136615142226219,-0.867519974708557,-0.478316396474838,0.13646388053894,-0.764244854450226,-0.598487496376038,0.240296483039856,-0.763984382152557,-0.59871506690979,0.240558132529259,0.136472627520561,-0.478322595357895,-0.867515206336975,0.136623501777649,-0.478551357984543,-0.867365181446075,0.240562543272972,-0.598724246025085,-0.76397567987442,0.240301370620728,-0.598497092723846,-0.76423579454422,0.86795449256897,0.477560698986053,-0.136346906423569,0.868136048316956,0.477283269166946,-0.136163055896759,0.76170152425766,0.600369870662689,-0.243652790784836,0.761366546154022,0.600658118724823,-0.243988931179047,-0.136168569326401,0.47727906703949,0.868137538433075,-0.136352300643921,0.477556347846985,0.867956161499023,-0.243996471166611,0.600645065307617,0.761374473571777,-0.243659719824791,0.600356221199036,0.761709988117218,-0.763984382152557,-0.59871506690979,0.240558132529259,-0.764244854450226,-0.598487496376038,0.240296483039856,-0.647077620029449,-0.674180448055267,0.35604926943779,-0.646778345108032,-0.674309253692627,0.356349289417267,0.240301370620728,-0.598497092723846,-0.76423579454422,0.240562543272972,-0.598724246025085,-0.76397567987442,0.35634782910347,-0.674309492111206,-0.646778762340546,0.356047034263611,-0.674180567264557,-0.6470787525177,0.761366546154022,0.600658118724823,-0.243988931179047,0.76170152425766,0.600369870662689,-0.243652790784836,0.636101305484772,0.678239345550537,-0.367921531200409,0.635719835758209,0.678390920162201,-0.368301540613174,-0.243659719824791,0.600356221199036,0.761709988117218,-0.243996471166611,0.600645065307617,0.761374473571777,-0.368303626775742,0.678389489650726,0.635720014572144,-0.367923676967621,0.678237915039063,0.63610166311264,-0.646778345108032,-0.674309253692627,0.356349289417267,-0.647077620029449,-0.674180448055267,0.35604926943779, +-0.555825233459473,-0.702135622501373,0.445043534040451,-0.555616497993469,-0.702168345451355,0.445252478122711,0.356047034263611,-0.674180567264557,-0.6470787525177,0.35634782910347,-0.674309492111206,-0.646778762340546,0.445235192775726,-0.702182352542877,-0.555612683296204,0.445025563240051,-0.702149271965027,-0.555822312831879,0.635719835758209,0.678390920162201,-0.368301540613174,0.636101305484772,0.678239345550537,-0.367921531200409,0.538836717605591,0.704135239124298,-0.462437599897385,0.538595020771027,0.704162299633026,-0.462677985429764,-0.367923676967621,0.678237915039063,0.63610166311264,-0.368303626775742,0.678389489650726,0.635720014572144,-0.462677299976349,0.704152524471283,0.538608074188232,-0.462437093257904,0.704125642776489,0.538849651813507,0.445025563240051,-0.702149271965027,-0.555822312831879,0.445235192775726,-0.702182352542877,-0.555612683296204,0.478403866291046,-0.706676781177521,-0.521284520626068,0.478403836488724,-0.706676721572876,-0.521284461021423,0.538595020771027,0.704162299633026,-0.462677985429764,0.538836717605591,0.704135239124298,-0.462437599897385,0.503732919692993,0.707162320613861,-0.49615952372551,0.503733038902283,0.707162439823151,-0.496159583330154,-0.522553622722626,-0.707112491130829,-0.476371288299561,-0.522553563117981,-0.707112550735474,-0.476371347904205,-0.447550565004349,-0.710111677646637,-0.543543696403503,-0.447550237178802,-0.710111618041992,-0.543544054031372,-0.522550702095032,0.707116007804871,-0.476369321346283,-0.522550702095032,0.707116007804871,-0.476369321346283,-0.44754832983017,0.710115075111389,-0.543541133403778,-0.447548627853394,0.710115015506744,-0.543540894985199,-0.447548627853394,0.710115015506744,-0.543540894985199,-0.44754832983017,0.710115075111389,-0.543541133403778,-0.211014673113823,0.719250619411469,-0.661929786205292,-0.211013212800026,0.719250679016113,-0.66193026304245,-0.447550237178802,-0.710111618041992,-0.543544054031372,-0.447550565004349,-0.710111677646637,-0.543543696403503,-0.211013659834862,-0.719247996807098,-0.661933183670044, +-0.211015194654465,-0.719247937202454,-0.661932647228241,0.438323557376862,0.707379341125488,-0.554514825344086,0.438323527574539,0.707379400730133,-0.55451488494873,0.395809412002563,0.710112869739532,-0.582300961017609,0.395809054374695,0.710112869739532,-0.582301199436188,0.438323527574539,0.707379400730133,-0.55451488494873,0.438323557376862,0.707379341125488,-0.554514825344086,0.399399369955063,0.707482516765594,-0.583051025867462,0.399399429559708,0.707482516765594,-0.583050966262817,0.399399429559708,0.707482516765594,-0.583050966262817,0.399399369955063,0.707482516765594,-0.583051025867462,0.343896359205246,0.707487344741821,-0.617411434650421,0.343896448612213,0.707487404346466,-0.617411375045776,0.438322812318802,-0.707381546497345,-0.554512619972229,0.438322842121124,-0.70738160610199,-0.554512619972229,0.39580711722374,-0.710118472576141,-0.582295656204224,0.395807474851608,-0.710118532180786,-0.582295417785645,0.438322842121124,-0.70738160610199,-0.554512619972229,0.438322812318802,-0.707381546497345,-0.554512619972229,0.399397939443588,-0.707484602928162,-0.583049356937408,0.399397969245911,-0.707484662532806,-0.583049476146698,0.399397969245911,-0.707484662532806,-0.583049476146698,0.399397939443588,-0.707484602928162,-0.583049356937408,0.343895643949509,-0.707487940788269,-0.617411077022552,0.343895435333252,-0.707487940788269,-0.617411077022552,0.343896448612213,0.707487404346466,-0.617411375045776,0.343896359205246,0.707487344741821,-0.617411434650421,0.28546068072319,0.707489788532257,-0.646506130695343,0.285460561513901,0.707489907741547,-0.646506249904633,0.343895435333252,-0.707487940788269,-0.617411077022552,0.343895643949509,-0.707487940788269,-0.617411077022552,0.28546130657196,-0.707486808300018,-0.646509110927582,0.28546154499054,-0.707486808300018,-0.646509110927582,0.285460561513901,0.707489907741547,-0.646506249904633,0.28546068072319,0.707489788532257,-0.646506130695343,0.22459089756012,0.707488596439362,-0.670088648796082,0.22459103167057,0.707488536834717,-0.670088529586792,0.28546154499054,-0.707486808300018,-0.646509110927582, +0.28546130657196,-0.707486808300018,-0.646509110927582,0.224592015147209,-0.707485496997833,-0.670091450214386,0.224591866135597,-0.707485496997833,-0.670091569423676,0.22459103167057,0.707488536834717,-0.670088529586792,0.22459089756012,0.707488596439362,-0.670088648796082,0.161804348230362,0.707490146160126,-0.687951326370239,0.161804333329201,0.707490146160126,-0.687951266765594,0.224591866135597,-0.707485496997833,-0.670091569423676,0.224592015147209,-0.707485496997833,-0.670091450214386,0.161805137991905,-0.707487761974335,-0.687953531742096,0.161805123090744,-0.707487761974335,-0.687953412532806,0.161804333329201,0.707490146160126,-0.687951266765594,0.161804348230362,0.707490146160126,-0.687951326370239,0.0976380035281181,0.707491397857666,-0.699944674968719,0.0976380929350853,0.707491397857666,-0.699944674968719,0.161805123090744,-0.707487761974335,-0.687953412532806,0.161805137991905,-0.707487761974335,-0.687953531742096,0.0976382121443748,-0.707490503787994,-0.699945628643036,0.0976381003856659,-0.70749044418335,-0.699945688247681,0.0976380929350853,0.707491397857666,-0.699944674968719,0.0976380035281181,0.707491397857666,-0.699944674968719,0.0326393507421017,0.707486748695374,-0.705972373485565,0.0326394252479076,0.707486748695374,-0.70597231388092,0.0976381003856659,-0.70749044418335,-0.699945688247681,0.0976382121443748,-0.707490503787994,-0.699945628643036,0.0326393134891987,-0.707487761974335,-0.705971419811249,0.0326393321156502,-0.707487761974335,-0.705971419811249,0.0326394252479076,0.707486748695374,-0.70597231388092,0.0326393507421017,0.707486748695374,-0.705972373485565,-0.0326394625008106,0.707483291625977,-0.705975830554962,-0.032639492303133,0.707483291625977,-0.705975890159607,0.0326393321156502,-0.707487761974335,-0.705971419811249,0.0326393134891987,-0.707487761974335,-0.705971419811249,-0.0326394028961658,-0.707483947277069,-0.705975294113159,-0.0326393693685532,-0.707483947277069,-0.70597517490387,-0.032639492303133,0.707483291625977,-0.705975890159607,-0.0326394625008106,0.707483291625977,-0.705975830554962, +-0.0976396277546883,0.707482814788818,-0.699953138828278,-0.0976395830512047,0.707482874393463,-0.699953138828278,-0.0326393693685532,-0.707483947277069,-0.70597517490387,-0.0326394028961658,-0.707483947277069,-0.705975294113159,-0.0976396203041077,-0.707481503486633,-0.699954450130463,-0.097639687359333,-0.707481503486633,-0.699954450130463,-0.0976395830512047,0.707482874393463,-0.699953138828278,-0.0976396277546883,0.707482814788818,-0.699953138828278,-0.161805883049965,0.707484543323517,-0.687956690788269,-0.161805778741837,0.707484424114227,-0.687956750392914,-0.097639687359333,-0.707481503486633,-0.699954450130463,-0.0976396203041077,-0.707481503486633,-0.699954450130463,-0.161806523799896,-0.707482218742371,-0.687958836555481,-0.161806628108025,-0.707482278347015,-0.687958776950836,-0.161805778741837,0.707484424114227,-0.687956750392914,-0.161805883049965,0.707484543323517,-0.687956690788269,-0.224589586257935,0.707493126392365,-0.670084238052368,-0.224589869379997,0.707493126392365,-0.670084059238434,-0.161806628108025,-0.707482278347015,-0.687958776950836,-0.161806523799896,-0.707482218742371,-0.687958836555481,-0.224590614438057,-0.707490086555481,-0.670086979866028,-0.224590361118317,-0.707490146160126,-0.670087158679962,-0.224589869379997,0.707493126392365,-0.670084059238434,-0.224589586257935,0.707493126392365,-0.670084238052368,-0.285457491874695,0.707496881484985,-0.646499872207642,-0.285457849502563,0.707496881484985,-0.646499693393707,-0.224590361118317,-0.707490146160126,-0.670087158679962,-0.224590614438057,-0.707490086555481,-0.670086979866028,-0.285457581281662,-0.707497000694275,-0.646499633789063,-0.285457193851471,-0.70749694108963,-0.646499812602997,-0.285457849502563,0.707496881484985,-0.646499693393707,-0.285457491874695,0.707496881484985,-0.646499872207642,-0.343894749879837,0.70749044418335,-0.617408692836761,-0.343894809484482,0.707490503787994,-0.617408573627472,-0.285457193851471,-0.70749694108963,-0.646499812602997,-0.285457581281662,-0.707497000694275,-0.646499633789063,-0.343893140554428,-0.707493484020233,-0.617406189441681, +-0.343892991542816,-0.707493484020233,-0.617406249046326,-0.343894809484482,0.707490503787994,-0.617408573627472,-0.343894749879837,0.70749044418335,-0.617408692836761,-0.399397909641266,0.707485496997833,-0.583048403263092,-0.399397939443588,0.707485437393188,-0.583048343658447,-0.343892991542816,-0.707493484020233,-0.617406249046326,-0.343893140554428,-0.707493484020233,-0.617406189441681,-0.399396240711212,-0.707488417625427,-0.583046078681946,-0.399396181106567,-0.707488417625427,-0.583046019077301,-0.399397939443588,0.707485437393188,-0.583048343658447,-0.399397909641266,0.707485496997833,-0.583048403263092,-0.438322305679321,0.707381963729858,-0.554512500762939,-0.438322246074677,0.707381963729858,-0.554512560367584,-0.399396181106567,-0.707488417625427,-0.583046019077301,-0.399396240711212,-0.707488417625427,-0.583046078681946,-0.438320457935333,-0.707385897636414,-0.554508924484253,-0.438320577144623,-0.707385957241058,-0.554508924484253,-0.438322246074677,0.707381963729858,-0.554512560367584,-0.438322305679321,0.707381963729858,-0.554512500762939,-0.39580699801445,0.710115671157837,-0.58229923248291,-0.395807415246964,0.710115611553192,-0.582298934459686,-0.438320577144623,-0.707385957241058,-0.554508924484253,-0.438320457935333,-0.707385897636414,-0.554508924484253,-0.395805865526199,-0.710119903087616,-0.582294940948486,-0.395805478096008,-0.710119843482971,-0.582295179367065,0.447546601295471,0.710118114948273,-0.543538749217987,0.447547346353531,0.710118055343628,-0.543538093566895,0.211011067032814,0.719258248806,-0.661922812461853,0.211012691259384,0.719258248806,-0.66192227602005,-0.395807415246964,0.710115611553192,-0.582298934459686,-0.39580699801445,0.710115671157837,-0.58229923248291,-0.149038761854172,0.71925288438797,-0.678573906421661,-0.149039462208748,0.719252943992615,-0.678573787212372,0.447549641132355,-0.710114479064941,-0.543540835380554,0.447548866271973,-0.710114479064941,-0.543541491031647,0.211012944579124,-0.719255924224854,-0.661924719810486,0.211011379957199,-0.719255983829498,-0.661925196647644, +-0.395805478096008,-0.710119843482971,-0.582295179367065,-0.395805865526199,-0.710119903087616,-0.582294940948486,-0.149037942290306,-0.719254493713379,-0.678572416305542,-0.149037331342697,-0.719254493713379,-0.678572475910187,0.395809054374695,0.710112869739532,-0.582301199436188,0.395809412002563,0.710112869739532,-0.582300961017609,0.149040043354034,0.719250082969666,-0.678576648235321,0.149039521813393,0.719250023365021,-0.678576767444611,0.395807474851608,-0.710118532180786,-0.582295417785645,0.39580711722374,-0.710118472576141,-0.582295656204224,0.149037957191467,-0.719251215457916,-0.678575813770294,0.149038508534431,-0.719251215457916,-0.678575694561005,-0.211013212800026,0.719250679016113,-0.66193026304245,-0.211014673113823,0.719250619411469,-0.661929786205292,0.149039521813393,0.719250023365021,-0.678576767444611,0.149040043354034,0.719250082969666,-0.678576648235321,-0.211015194654465,-0.719247937202454,-0.661932647228241,-0.211013659834862,-0.719247996807098,-0.661933183670044,0.149038508534431,-0.719251215457916,-0.678575694561005,0.149037957191467,-0.719251215457916,-0.678575813770294,-0.149039462208748,0.719252943992615,-0.678573787212372,-0.149038761854172,0.71925288438797,-0.678573906421661,0.211012691259384,0.719258248806,-0.66192227602005,0.211011067032814,0.719258248806,-0.661922812461853,-0.149037331342697,-0.719254493713379,-0.678572475910187,-0.149037942290306,-0.719254493713379,-0.678572416305542,0.211011379957199,-0.719255983829498,-0.661925196647644,0.211012944579124,-0.719255924224854,-0.661924719810486,-0.686134934425354,-3.75032250303775e-005,0.72747415304184,-0.638846457004547,0,0.769334137439728,-0.638846397399902,0,0.769334197044373,-0.685862421989441,-3.66751555702649e-005,0.727731227874756,-0.638846457004547,0,0.769334137439728,-0.565136194229126,0,0.82499760389328,-0.565136194229126,0,0.82499760389328,-0.638846397399902,0,0.769334197044373,-0.565136194229126,0,0.82499760389328,-0.486604362726212,0,0.873622357845306,-0.486604362726212,0,0.873622357845306,-0.565136194229126,0,0.82499760389328, +-0.486604362726212,0,0.873622357845306,-0.40392079949379,0,0.914793908596039,-0.40392079949379,0,0.914793908596039,-0.486604362726212,0,0.873622357845306,-0.40392079949379,0,0.914793908596039,-0.317791253328323,0,0.948160529136658,-0.317791253328323,0,0.948160529136658,-0.40392079949379,0,0.914793908596039,-0.317791253328323,0,0.948160529136658,-0.228950336575508,0,0.973438024520874,-0.228950336575508,0,0.973438024520874,-0.317791253328323,0,0.948160529136658,-0.228950336575508,0,0.973438024520874,-0.138156443834305,0,0.990410387516022,-0.138156443834305,0,0.990410387516022,-0.228950336575508,0,0.973438024520874,-0.138156443834305,0,0.990410387516022,-0.0461838357150555,0,0.998932898044586,-0.0461838357150555,0,0.998932898044586,-0.138156443834305,0,0.990410387516022,-0.0461838357150555,0,0.998932898044586,0.0461839586496353,0,0.998932898044586,0.0461839586496353,0,0.998932898044586,-0.0461838357150555,0,0.998932898044586,0.0461839586496353,0,0.998932898044586,0.138156563043594,0,0.990410268306732,0.138156563043594,0,0.990410268306732,0.0461839586496353,0,0.998932898044586,0.138156563043594,0,0.990410268306732,0.22895048558712,0,0.973438024520874,0.22895048558712,0,0.973438024520874,0.138156563043594,0,0.990410268306732,0.22895048558712,0,0.973438024520874,0.317791432142258,0,0.948160469532013,0.317791432142258,0,0.948160469532013,0.22895048558712,0,0.973438024520874,0.317791432142258,0,0.948160469532013,0.403921067714691,0,0.914793789386749,0.403921067714691,0,0.914793789386749,0.317791432142258,0,0.948160469532013,0.403921067714691,0,0.914793789386749,0.486604690551758,0,0.873622238636017,0.486604690551758,0,0.873622238636017,0.403921067714691,0,0.914793789386749,0.486604690551758,0,0.873622238636017,0.565136194229126,0,0.82499760389328,0.565136194229126,0,0.82499760389328,0.486604690551758,0,0.873622238636017,0.565136194229126,0,0.82499760389328,0.638846457004547,0,0.769334137439728,0.638846457004547,0,0.769334197044373,0.565136194229126,0,0.82499760389328,0.638846457004547,0,0.769334137439728,0.686135053634644,-3.75032068404835e-005,0.72747415304184, +0.685862421989441,-3.66751737601589e-005,0.727731108665466,0.638846457004547,0,0.769334197044373,-0.00817491393536329,0.999933063983917,-0.00817150250077248,-1.17474110084004e-005,0.999999940395355,6.00420025875792e-006,-1.17474382932414e-005,0.999999940395355,6.00421481067315e-006,-0.0078024473041296,0.999939143657684,-0.00779755134135485,-1.17474110084004e-005,0.999999940395355,6.00420025875792e-006,0,0.999999940395355,3.87351377639789e-007,0,0.999999940395355,3.8735129237466e-007,-1.17474382932414e-005,0.999999940395355,6.00421481067315e-006,0,0.999999940395355,3.87351377639789e-007,0,0.999999940395355,1.93675276705108e-007,0,0.999999940395355,1.93676768844853e-007,0,0.999999940395355,3.8735129237466e-007,0,0.999999940395355,1.93675276705108e-007,0,0.999999940395355,-9.68376738796906e-008,0,0.999999940395355,-9.68377236176821e-008,0,0.999999940395355,1.93676768844853e-007,0,0.999999940395355,-9.68376738796906e-008,0,0.999999940395355,-5.8102693856199e-007,0,0.999999940395355,-5.81027677526436e-007,0,0.999999940395355,-9.68377236176821e-008,0,0.999999940395355,-5.8102693856199e-007,0,0.999999940395355,-1.21047446555167e-006,0,0.999999940395355,-1.21047412449116e-006,0,0.999999940395355,-5.81027677526436e-007,0,0.999999940395355,-1.21047446555167e-006,0,0.999999940395355,-1.54940653374069e-006,0,0.999999940395355,-1.54940573793283e-006,0,0.999999940395355,-1.21047412449116e-006,0,0.999999940395355,-1.54940653374069e-006,0,0.999999940395355,-2.39673545365804e-006,0,0.999999940395355,-2.39673499891069e-006,0,0.999999940395355,-1.54940573793283e-006,0,0.999999940395355,-2.39673545365804e-006,0,0.999999940395355,-1.28310091440653e-006,0,0.999999940395355,-1.28310068703286e-006,0,0.999999940395355,-2.39673499891069e-006,0,0.999999940395355,-1.28310091440653e-006,0,0.999999940395355,-4.35770289186621e-007,0,0.999999940395355,-4.35770488138587e-007,0,0.999999940395355,-1.28310068703286e-006,0,0.999999940395355,-4.35770289186621e-007,0,0.999999940395355,-7.74703380557185e-007,0,0.999999940395355,-7.74703380557185e-007,0,0.999999940395355,-4.35770488138587e-007, +0,0.999999940395355,-7.74703380557185e-007,0,0.999999940395355,-1.11363704036194e-006,0,0.999999940395355,-1.11363681298826e-006,0,0.999999940395355,-7.74703380557185e-007,0,0.999999940395355,-1.11363704036194e-006,0,0.999999940395355,-9.68379595178703e-007,0,0.999999940395355,-9.68379708865541e-007,0,0.999999940395355,-1.11363681298826e-006,0,0.999999940395355,-9.68379595178703e-007,0,0.999999940395355,9.68371693943482e-008,0,0.999999940395355,9.68384057387084e-008,0,0.999999940395355,-9.68379708865541e-007,0,0.999999940395355,9.68371693943482e-008,0,0.999999940395355,5.81026824875153e-007,0,0.999999940395355,5.81026768031734e-007,0,0.999999940395355,9.68384057387084e-008,0,0.999999940395355,5.81026824875153e-007,1.17473982754746e-005,0.999999940395355,6.58524595564813e-006,1.17474373837467e-005,0.999999940395355,6.58526732877363e-006,0,0.999999940395355,5.81026768031734e-007,1.17473982754746e-005,0.999999940395355,6.58524595564813e-006,0.00817459914833307,0.999933183193207,-0.00817013718187809,0.00780216697603464,0.999939203262329,-0.0077962507493794,1.17474373837467e-005,0.999999940395355,6.58526732877363e-006,0.638820946216583,4.4055873331672e-006,-0.769355297088623,0.565136194229126,0,-0.824997544288635,0.565136194229126,0,-0.824997544288635,0.638820946216583,4.40559188064071e-006,-0.769355297088623,0.565136194229126,0,-0.824997544288635,0.486604332923889,0,-0.873622417449951,0.486604332923889,0,-0.873622417449951,0.565136194229126,0,-0.824997544288635,0.486604332923889,0,-0.873622417449951,0.403921157121658,0,-0.914793729782104,0.403921157121658,0,-0.914793729782104,0.486604332923889,0,-0.873622417449951,0.403921157121658,0,-0.914793729782104,0.317791432142258,0,-0.948160588741302,0.317791432142258,0,-0.948160588741302,0.403921157121658,0,-0.914793729782104,0.317791432142258,0,-0.948160588741302,0.228950455784798,0,-0.973438024520874,0.228950455784798,0,-0.973438024520874,0.317791432142258,0,-0.948160588741302,0.228950455784798,0,-0.973438024520874,0.138156667351723,0,-0.990410327911377,0.138156667351723,0,-0.990410327911377, +0.228950455784798,0,-0.973438024520874,0.138156667351723,0,-0.990410327911377,0.0461835525929928,0,-0.998932838439941,0.0461835525929928,0,-0.998932838439941,0.138156667351723,0,-0.990410327911377,0.0461835525929928,0,-0.998932838439941,-0.0461836941540241,0,-0.998932838439941,-0.0461836941540241,0,-0.998932838439941,0.0461835525929928,0,-0.998932838439941,-0.0461836941540241,0,-0.998932838439941,-0.138156801462173,0,-0.990410327911377,-0.138156801462173,0,-0.990410327911377,-0.0461836941540241,0,-0.998932838439941,-0.138156801462173,0,-0.990410327911377,-0.228950589895248,0,-0.973437905311584,-0.228950589895248,0,-0.973437905311584,-0.138156801462173,0,-0.990410327911377,-0.228950589895248,0,-0.973437905311584,-0.317791551351547,0,-0.948160529136658,-0.317791551351547,0,-0.948160529136658,-0.228950589895248,0,-0.973437905311584,-0.317791551351547,0,-0.948160529136658,-0.403921246528625,0,-0.914793729782104,-0.403921246528625,0,-0.914793729782104,-0.317791551351547,0,-0.948160529136658,-0.403921246528625,0,-0.914793729782104,-0.486604243516922,0,-0.873622477054596,-0.486604243516922,0,-0.873622477054596,-0.403921246528625,0,-0.914793729782104,-0.486604243516922,0,-0.873622477054596,-0.565136551856995,0,-0.824997305870056,-0.565136551856995,0,-0.824997305870056,-0.486604243516922,0,-0.873622477054596,-0.565136551856995,0,-0.824997305870056,-0.638821303844452,4.56553925687331e-006,-0.769355058670044,-0.638821303844452,4.56554380434682e-006,-0.769355058670044,-0.565136551856995,0,-0.824997305870056,-0.638821303844452,4.56553925687331e-006,-0.769355058670044,-0.672601997852325,0.0576485246419907,-0.737755477428436,-0.673727691173553,0.00137342023663223,-0.738978266716003,-0.673698425292969,9.12832365429495e-006,-0.739006280899048,-0.638821303844452,4.56554380434682e-006,-0.769355058670044,0.00329330540262163,-0.999989211559296,0.0032876399345696,5.12980477651581e-006,-0.999999940395355,-4.06736262448248e-006,5.12979158884264e-006,-0.999999940395355,-4.06735216529341e-006,0.00345196854323149,-0.999988079071045,0.00344691821373999, +5.12980477651581e-006,-0.999999940395355,-4.06736262448248e-006,0,-0.999999940395355,1.93675546711347e-007,0,-0.999999940395355,1.93675560922202e-007,5.12979158884264e-006,-0.999999940395355,-4.06735216529341e-006,0,-0.999999940395355,1.93675546711347e-007,0,-0.999999940395355,1.93675845139296e-007,0,-0.999999940395355,1.93675560922202e-007,0,-0.999999940395355,1.93675560922202e-007,0,-0.999999940395355,1.93675845139296e-007,0,-0.999999940395355,6.77864932185912e-007,0,-0.999999940395355,6.77864989029331e-007,0,-0.999999940395355,1.93675560922202e-007,0,-0.999999940395355,6.77864932185912e-007,0,-0.999999940395355,1.06521679299476e-006,0,-0.999999940395355,1.06521713405527e-006,0,-0.999999940395355,6.77864989029331e-007,0,-0.999999940395355,1.06521679299476e-006,0,-0.999999940395355,-2.90514122980312e-007,0,-0.999999940395355,-2.90513554546123e-007,0,-0.999999940395355,1.06521713405527e-006,0,-0.999999940395355,-2.90514122980312e-007,0,-0.999999940395355,-1.01679790986964e-006,0,-0.999999940395355,-1.01679756880912e-006,0,-0.999999940395355,-2.90513554546123e-007,0,-0.999999940395355,-1.01679790986964e-006,0,-0.999999940395355,-5.20503192547039e-007,0,-0.999999940395355,-5.20503078860202e-007,0,-0.999999940395355,-1.01679756880912e-006,0,-0.999999940395355,-5.20503192547039e-007,0,-0.999999940395355,-1.06521576981322e-006,0,-0.999999940395355,-1.06521565612638e-006,0,-0.999999940395355,-5.20503078860202e-007,0,-0.999999940395355,-1.06521576981322e-006,0,-0.999999940395355,-1.31941590097995e-006,0,-0.999999940395355,-1.3194163557273e-006,0,-0.999999940395355,-1.06521565612638e-006,0,-0.999999940395355,-1.31941590097995e-006,0,-0.999999940395355,-5.32608680714475e-007,0,-0.999999940395355,-5.32608510184218e-007,0,-0.999999940395355,-1.3194163557273e-006,0,-0.999999940395355,-5.32608680714475e-007,0,-0.999999940395355,2.90513838763218e-007,0,-0.999999940395355,2.90514122980312e-007,0,-0.999999940395355,-5.32608510184218e-007,0,-0.999999940395355,2.90513838763218e-007,0,-0.999999940395355,4.84189683902514e-007,0,-0.999999940395355,4.84189683902514e-007, +0,-0.999999940395355,2.90514122980312e-007,0,-0.999999940395355,4.84189683902514e-007,0,-0.999999940395355,9.68377236176821e-008,0,-0.999999940395355,9.68379083587934e-008,0,-0.999999940395355,4.84189683902514e-007,0,-0.999999940395355,9.68377236176821e-008,0,-0.999999940395355,-1.93675461446219e-007,0,-0.999999940395355,-1.93675475657074e-007,0,-0.999999940395355,9.68379083587934e-008,0,-0.999999940395355,-1.93675461446219e-007,-5.12980295752641e-006,-0.999999940395355,-3.29262479681347e-006,-5.12978431288502e-006,-0.999999940395355,-3.2926143376244e-006,0,-0.999999940395355,-1.93675475657074e-007,-5.12980295752641e-006,-0.999999940395355,-3.29262479681347e-006,-0.00329300877638161,-0.999989151954651,0.00328897964209318,-0.00345165352337062,-0.99998813867569,0.00344822439365089,-5.12978431288502e-006,-0.999999940395355,-3.2926143376244e-006,-0.685862958431244,3.66751737601589e-005,0.727730631828308,-0.638846635818481,0,0.769334077835083,-0.638846635818481,0,0.769334018230438,-0.686135590076447,3.75032832380384e-005,0.727473616600037,-0.638846635818481,0,0.769334077835083,-0.565136253833771,0,0.82499748468399,-0.565136253833771,0,0.82499748468399,-0.638846635818481,0,0.769334018230438,-0.565136253833771,0,0.82499748468399,-0.486604422330856,0,0.873622238636017,-0.486604422330856,0,0.873622238636017,-0.565136253833771,0,0.82499748468399,-0.486604422330856,0,0.873622238636017,-0.403920948505402,0,0.914793848991394,-0.403920948505402,0,0.914793848991394,-0.486604422330856,0,0.873622238636017,-0.403920948505402,0,0.914793848991394,-0.317791551351547,0,0.948160529136658,-0.317791491746902,0,0.948160469532013,-0.403920948505402,0,0.914793848991394,-0.317791551351547,0,0.948160529136658,-0.228950321674347,0,0.973437964916229,-0.228950336575508,0,0.973438024520874,-0.317791491746902,0,0.948160469532013,-0.228950321674347,0,0.973437964916229,-0.138155966997147,0,0.990410447120667,-0.138155981898308,0,0.990410447120667,-0.228950336575508,0,0.973438024520874,-0.138155966997147,0,0.990410447120667,-0.0461833812296391,0,0.998932957649231, +-0.0461833775043488,0,0.998932838439941,-0.138155981898308,0,0.990410447120667,-0.0461833812296391,0,0.998932957649231,0.0461840592324734,0,0.998932898044586,0.0461840555071831,0,0.998932898044586,-0.0461833775043488,0,0.998932838439941,0.0461840592324734,0,0.998932898044586,0.138155773282051,0,0.990410387516022,0.138155788183212,0,0.990410387516022,0.0461840555071831,0,0.998932898044586,0.138155773282051,0,0.990410387516022,0.228949964046478,0,0.973438143730164,0.228949993848801,0,0.973438143730164,0.138155788183212,0,0.990410387516022,0.228949964046478,0,0.973438143730164,0.317791879177094,0,0.948160350322723,0.317791908979416,0,0.948160350322723,0.228949993848801,0,0.973438143730164,0.317791879177094,0,0.948160350322723,0.403921097517014,0,0.91479367017746,0.403921097517014,0,0.91479367017746,0.317791908979416,0,0.948160350322723,0.403921097517014,0,0.91479367017746,0.486604541540146,0,0.873622298240662,0.486604541540146,0,0.873622298240662,0.403921097517014,0,0.91479367017746,0.486604541540146,0,0.873622298240662,0.56513637304306,0,0.824997365474701,0.56513637304306,0,0.824997365474701,0.486604541540146,0,0.873622298240662,0.56513637304306,0,0.824997365474701,0.638846695423126,0,0.769334018230438,0.638846695423126,0,0.769334018230438,0.56513637304306,0,0.824997365474701,0.638846695423126,0,0.769334018230438,0.685862720012665,3.63009276043158e-005,0.727730810642242,0.686135351657867,3.71205824194476e-005,0.727473795413971,0.638846695423126,0,0.769334018230438,0.00326843559741974,0.999989330768585,0.00325691723264754,5.40158453077311e-006,0.999999940395355,-3.59079194822698e-006,1.54286988163221e-006,0.999999940395355,-7.93113315467053e-007,3.58468287231517e-006,0.999999940395355,-2.32788261200767e-006,0.00234573241323233,0.999994397163391,0.00233277003280818,5.40158453077311e-006,0.999999940395355,-3.59079194822698e-006,7.56545375679707e-007,0.999999940395355,-9.50518710851611e-007,2.80659662621474e-007,0.999999940395355,-1.0463888600043e-007,1.54286988163221e-006,0.999999940395355,-7.93113315467053e-007,7.56545375679707e-007,0.999999940395355,-9.50518710851611e-007, +4.1036827269636e-007,0.999999940395355,-8.8342392245977e-007,-6.80723175605635e-008,0.999999940395355,-3.06603737953992e-007,2.80659662621474e-007,0.999999940395355,-1.0463888600043e-007,4.1036827269636e-007,0.999999940395355,-8.8342392245977e-007,-1.43287707032869e-007,0.999999940395355,2.79563323601906e-008,-1.9421602814873e-007,0.999999940395355,-1.35349409902119e-007,-6.80723175605635e-008,0.999999940395355,-3.06603737953992e-007,-1.43287707032869e-007,0.999999940395355,2.79563323601906e-008,-2.70829730197875e-007,0.999999940395355,7.99556460151507e-007,-1.6573590500002e-008,0.999999940395355,5.43974998379326e-008,-1.9421602814873e-007,0.999999940395355,-1.35349409902119e-007,-2.70829730197875e-007,0.999999940395355,7.99556460151507e-007,-1.13751511321425e-007,0.999999940395355,6.15042381468811e-007,1.11040328931722e-007,0.999999940395355,4.20550350099802e-008,-1.6573590500002e-008,0.999999940395355,5.43974998379326e-008,-1.13751511321425e-007,0.999999940395355,6.15042381468811e-007,1.59885175321506e-007,0.999999940395355,1.23008362606924e-007,1.91991318843066e-007,0.999999940395355,-2.97128277537695e-008,1.11040328931722e-007,0.999999940395355,4.20550350099802e-008,1.59885175321506e-007,0.999999940395355,1.23008362606924e-007,1.62280244353497e-007,0.999999940395355,1.5376063089434e-008,1.11701218941107e-007,0.999999940395355,1.2913625724309e-008,1.91991318843066e-007,0.999999940395355,-2.97128277537695e-008,1.62280244353497e-007,0.999999940395355,1.5376063089434e-008,-1.62280230142642e-007,0.999999940395355,1.67738729572875e-008,-1.11701154992261e-007,0.999999940395355,3.31620704230318e-008,1.11701218941107e-007,0.999999940395355,1.2913625724309e-008,-1.62280230142642e-007,0.999999940395355,1.67738729572875e-008,-1.59885317430053e-007,0.999999940395355,1.35588919647489e-007,-1.91991460951613e-007,0.999999940395355,-5.18416731765114e-009,-1.11701154992261e-007,0.999999940395355,3.31620704230318e-008,-1.59885317430053e-007,0.999999940395355,1.35588919647489e-007,1.13751866592793e-007,0.999999940395355,6.37407538306434e-007, +-1.11040229455739e-007,0.999999940395355,4.101623218844e-008,-1.91991460951613e-007,0.999999940395355,-5.18416731765114e-009,1.13751866592793e-007,0.999999940395355,6.37407538306434e-007,2.70829758619584e-007,0.999999940395355,8.1632953197186e-007,1.65736508961345e-008,0.999999940395355,5.05326731570221e-008,-1.11040229455739e-007,0.999999940395355,4.101623218844e-008,2.70829758619584e-007,0.999999940395355,8.1632953197186e-007,1.43287593346031e-007,0.999999940395355,5.59119284204712e-009,1.94215914461893e-007,0.999999940395355,-1.52138156295223e-007,1.65736508961345e-008,0.999999940395355,5.05326731570221e-008,1.43287593346031e-007,0.999999940395355,5.59119284204712e-009,-3.91183732517675e-007,0.999999940395355,-8.33103001696145e-007,5.17173148750771e-008,0.999999940395355,-3.26426089714005e-007,1.94215914461893e-007,0.999999940395355,-1.52138156295223e-007,-3.91183732517675e-007,0.999999940395355,-8.33103001696145e-007,-6.55317251130327e-007,0.999999940395355,-7.71598536175588e-007,-2.94672474865365e-007,0.999999940395355,-1.01979537703301e-007,5.17173148750771e-008,0.999999940395355,-3.26426089714005e-007,-6.55317251130327e-007,0.999999940395355,-7.71598536175588e-007,-5.26017993252026e-006,1,-3.44537124874478e-006,-1.5232648138408e-006,0.999999940395355,-7.99458121036878e-007,-2.94672474865365e-007,0.999999940395355,-1.01979537703301e-007,-5.26017993252026e-006,1,-3.44537124874478e-006,-0.0032683121971786,0.99998939037323,0.00325681455433369,-0.00234561460092664,0.999994516372681,0.00233272672630847,-3.53971358890703e-006,0.999999940395355,-2.33828313866979e-006,-1.5232648138408e-006,0.999999940395355,-7.99458121036878e-007,0.561634242534637,4.53231876917926e-007,-0.827385544776917,0.561634302139282,4.53231962183054e-007,-0.827385485172272,0.620182693004608,-1.5011266896181e-007,-0.784457325935364,0.620182394981384,-1.50117600128397e-007,-0.784457504749298,0.620182693004608,-1.5011266896181e-007,-0.784457325935364,0.565136075019836,-5.27141708062118e-007,-0.82499760389328,0.565136432647705,-5.27141708062118e-007,-0.824997425079346, +0.620182394981384,-1.50117600128397e-007,-0.784457504749298,0.565136075019836,-5.27141708062118e-007,-0.82499760389328,0.486604422330856,-9.23016756360084e-008,-0.873622238636017,0.486604273319244,-9.22991887364333e-008,-0.873622477054596,0.565136432647705,-5.27141708062118e-007,-0.824997425079346,0.486604422330856,-9.23016756360084e-008,-0.873622238636017,0.403920829296112,1.85712977440744e-007,-0.914793789386749,0.403920650482178,1.85712238476299e-007,-0.914793848991394,0.486604273319244,-9.22991887364333e-008,-0.873622477054596,0.403920829296112,1.85712977440744e-007,-0.914793789386749,0.317791253328323,1.62391884828139e-007,-0.948160529136658,0.317791312932968,1.62391899038994e-007,-0.948160588741302,0.403920650482178,1.85712238476299e-007,-0.914793848991394,0.317791253328323,1.62391884828139e-007,-0.948160529136658,0.228950500488281,1.33899874299459e-007,-0.973438024520874,0.228950336575508,1.33899277443561e-007,-0.973438084125519,0.317791312932968,1.62391899038994e-007,-0.948160588741302,0.228950500488281,1.33899874299459e-007,-0.973438024520874,0.138156399130821,-6.15460180597438e-008,-0.990410387516022,0.138156369328499,-6.15460180597438e-008,-0.990410387516022,0.228950336575508,1.33899277443561e-007,-0.973438084125519,0.138156399130821,-6.15460180597438e-008,-0.990410387516022,0.0461841076612473,-3.90892864743364e-008,-0.998932898044586,0.0461842007935047,-3.90893717394647e-008,-0.998932957649231,0.138156369328499,-6.15460180597438e-008,-0.990410387516022,0.0461841076612473,-3.90892864743364e-008,-0.998932898044586,-0.0461837500333786,-5.86339119479362e-008,-0.998932898044586,-0.0461837388575077,-5.86338977370815e-008,-0.998932898044586,0.0461842007935047,-3.90893717394647e-008,-0.998932957649231,-0.0461837500333786,-5.86339119479362e-008,-0.998932898044586,-0.138156622648239,-1.7590099332665e-007,-0.990410327911377,-0.138156771659851,-1.75901178067761e-007,-0.990410327911377,-0.0461837388575077,-5.86338977370815e-008,-0.998932898044586,-0.138156622648239,-1.7590099332665e-007,-0.990410327911377,-0.228950828313828,1.00635787703141e-007,-0.97343784570694, +-0.228950753808022,1.00634800048738e-007,-0.973437964916229,-0.138156771659851,-1.75901178067761e-007,-0.990410327911377,-0.228950828313828,1.00635787703141e-007,-0.97343784570694,-0.317791700363159,1.06815143396943e-007,-0.948160409927368,-0.317791700363159,1.06815051026388e-007,-0.948160409927368,-0.228950753808022,1.00634800048738e-007,-0.973437964916229,-0.317791700363159,1.06815143396943e-007,-0.948160409927368,-0.403920888900757,-1.15109919818224e-007,-0.914793848991394,-0.403920859098434,-1.15110040610489e-007,-0.914793908596039,-0.317791700363159,1.06815051026388e-007,-0.948160409927368,-0.403920888900757,-1.15109919818224e-007,-0.914793848991394,-0.486604422330856,-1.39638265395092e-008,-0.873622238636017,-0.486604601144791,-1.39638602902892e-008,-0.873622238636017,-0.403920859098434,-1.15110040610489e-007,-0.914793908596039,-0.486604422330856,-1.39638265395092e-008,-0.873622238636017,-0.565136611461639,-4.81208417113521e-007,-0.824997305870056,-0.565136909484863,-4.81212680369936e-007,-0.824997007846832,-0.486604601144791,-1.39638602902892e-008,-0.873622238636017,-0.565136611461639,-4.81208417113521e-007,-0.824997305870056,-0.620182454586029,-9.82677420324762e-007,-0.784457564353943,-0.620182394981384,-9.82677079264249e-007,-0.784457564353943,-0.565136909484863,-4.81212680369936e-007,-0.824997007846832,-0.620182454586029,-9.82677420324762e-007,-0.784457564353943,-0.561632931232452,-1.15324326088739e-006,-0.827386438846588,-0.561632990837097,-1.15324314720056e-006,-0.827386379241943,-0.620182394981384,-9.82677079264249e-007,-0.784457564353943,-3.06279957840161e-006,-0.999999940395355,2.11532210414589e-006,-2.84219439095068e-008,-0.999999940395355,6.12528694432513e-008,-2.13682582739239e-008,-0.999999940395355,8.97612224548539e-008,-1.15069615276298e-005,-1,7.50591334508499e-006,-2.84219439095068e-008,-0.999999940395355,6.12528694432513e-008,-4.79960462484996e-008,-0.999999940395355,5.3143271117051e-008,-1.43477876690667e-007,-0.999999940395355,1.94058713987033e-007,-2.13682582739239e-008,-0.999999940395355,8.97612224548539e-008, +-4.79960462484996e-008,-0.999999940395355,5.3143271117051e-008,-3.20978159606966e-008,-0.999999940395355,-4.38813394509907e-008,-4.64919125420238e-008,-0.999999940395355,-2.0388625898704e-007,-1.43477876690667e-007,-0.999999940395355,1.94058713987033e-007,-3.20978159606966e-008,-0.999999940395355,-4.38813394509907e-008,3.4919590774507e-008,-0.999999940395355,-1.12914229077887e-007,1.37813529477171e-007,-0.999999940395355,-4.27119687174127e-007,-4.64919125420238e-008,-0.999999940395355,-2.0388625898704e-007,3.4919590774507e-008,-0.999999940395355,-1.12914229077887e-007,-2.26367546929396e-008,-0.999999940395355,-1.6894109222676e-008,7.16016330670755e-008,-0.999999940395355,2.05571506484148e-008,1.37813529477171e-007,-0.999999940395355,-4.27119687174127e-007,-2.26367546929396e-008,-0.999999940395355,-1.6894109222676e-008,-2.19702116055487e-007,-0.999999940395355,5.90294462199381e-008,-2.35729999076284e-007,-0.999999940395355,1.98698742792658e-007,7.16016330670755e-008,-0.999999940395355,2.05571506484148e-008,-2.19702116055487e-007,-0.999999940395355,5.90294462199381e-008,-1.48727693272122e-007,-0.999999940395355,1.05255022475603e-008,-1.94834996136706e-007,-0.999999940395355,-8.1750850533524e-010,-2.35729999076284e-007,-0.999999940395355,1.98698742792658e-007,-1.48727693272122e-007,-0.999999940395355,1.05255022475603e-008,1.48727622217848e-007,-0.999999940395355,1.05254978066682e-008,1.94834868239013e-007,-0.999999940395355,-8.17575118716718e-010,-1.94834996136706e-007,-0.999999940395355,-8.1750850533524e-010,1.48727622217848e-007,-0.999999940395355,1.05254978066682e-008,2.19702172898906e-007,-0.999999940395355,5.90294106928013e-008,2.35730027497993e-007,-0.999999940395355,1.98698927533769e-007,1.94834868239013e-007,-0.999999940395355,-8.17575118716718e-010,2.19702172898906e-007,-0.999999940395355,5.90294106928013e-008,2.26366374533882e-008,-0.999999940395355,-1.6894153631597e-008,-7.16019599167339e-008,-0.999999940395355,2.055717018834e-008,2.35730027497993e-007,-0.999999940395355,1.98698927533769e-007,2.26366374533882e-008,-0.999999940395355,-1.6894153631597e-008, +-1.65621631964541e-008,-0.999999940395355,-1.22109724998154e-007,-1.44142717317663e-007,-0.999999940395355,-4.97668054322276e-007,-7.16019599167339e-008,-0.999999940395355,2.055717018834e-008,-1.65621631964541e-008,-0.999999940395355,-1.22109724998154e-007,4.87227431733572e-008,-0.999999940395355,-5.65562672250053e-008,-2.05210035630898e-008,-0.999999940395355,-3.96305409822162e-007,-1.44142717317663e-007,-0.999999940395355,-4.97668054322276e-007,4.87227431733572e-008,-0.999999940395355,-5.65562672250053e-008,2.78624341376599e-008,-0.999999940395355,5.87718460565156e-008,3.03092804188054e-008,-0.999999940395355,2.46235583034604e-008,-2.05210035630898e-008,-0.999999940395355,-3.96305409822162e-007,2.78624341376599e-008,-0.999999940395355,5.87718460565156e-008,1.00207397935037e-008,-0.999999940395355,7.03606062302242e-008,-3.111677671086e-008,-0.999999940395355,4.21952712770235e-008,3.03092804188054e-008,-0.999999940395355,2.46235583034604e-008,1.00207397935037e-008,-0.999999940395355,7.03606062302242e-008,3.06257220472617e-006,-0.999999940395355,2.11517772186198e-006,1.15061066026101e-005,-0.999999940395355,7.50537128624273e-006,-3.111677671086e-008,-0.999999940395355,4.21952712770235e-008,3.06257220472617e-006,-0.999999940395355,2.11517772186198e-006,8.23828759166645e-006,-0.999999940395355,5.53500649402849e-006,0.00557108130306005,-0.999969065189362,-0.00554143497720361,0.00774445664137602,-0.99994021654129,-0.00771815702319145,1.15061066026101e-005,-0.999999940395355,7.50537128624273e-006,0.712200820446014,0.00040806716424413,0.701975584030151,0.712177574634552,0.000436556903878227,0.701999247074127,0.686135351657867,3.71205824194476e-005,0.727473795413971,0.685862720012665,3.63009276043158e-005,0.727730810642242,-0.0582698099315166,0.996598720550537,0.058269489556551,-0.0582698471844196,0.996598839759827,0.0582695230841637,-0.00234561460092664,0.999994516372681,0.00233272672630847,-0.0032683121971786,0.99998939037323,0.00325681455433369,-0.701999306678772,0.000437213864643127,-0.712177395820618,-0.701975703239441,0.000408661464462057,-0.71220064163208, +-0.701735496520996,0.000117599207442254,-0.712437510490417,-0.701735436916351,0.000117599214718211,-0.712437570095062,0.0725920870900154,-0.994716465473175,-0.0725914984941483,0.0725923255085945,-0.99471640586853,-0.0725917369127274,0.00774445664137602,-0.99994021654129,-0.00771815702319145,0.00557108130306005,-0.999969065189362,-0.00554143497720361,0.685862421989441,-3.66751737601589e-005,0.727731108665466,0.686135053634644,-3.75032068404835e-005,0.72747415304184,0.712177455425262,-0.000437178503489122,0.701999306678772,0.712200701236725,-0.00040874071419239,0.701975643634796,-0.00345165352337062,-0.99998813867569,0.00344822439365089,-0.00329300877638161,-0.999989151954651,0.00328897964209318,-0.058239508420229,-0.996601521968842,0.0582520887255669,-0.0582395605742931,-0.996601581573486,0.0582521483302116,0.00780216697603464,0.999939203262329,-0.0077962507493794,0.00817459914833307,0.999933183193207,-0.00817013718187809,0.0725527405738831,0.994719803333282,-0.0725831240415573,0.0725531578063965,0.994719803333282,-0.0725835338234901,0.712200701236725,-0.00040874071419239,0.701975643634796,0.712177455425262,-0.000437178503489122,0.701999306678772,0.711510956287384,-0.00133867654949427,0.702673673629761,0.711565673351288,-0.00126002624165267,0.702618300914764,-0.0582395605742931,-0.996601581573486,0.0582521483302116,-0.058239508420229,-0.996601521968842,0.0582520887255669,-0.193470925092697,-0.961841106414795,0.193469643592834,-0.193470671772957,-0.96184116601944,0.193469360470772,-0.70225715637207,-0.000751536921598017,-0.711922943592072,-0.70209139585495,0.00159979064483196,-0.712084889411926,-0.692579448223114,0.0662549734115601,-0.718292355537415,-0.702618002891541,-0.00126177864149213,-0.711565971374512,-0.702673554420471,-0.00134028901811689,-0.711511015892029,0.0725531578063965,0.994719803333282,-0.0725835338234901,0.0725527405738831,0.994719803333282,-0.0725831240415573,0.201028928160667,0.958736121654511,-0.201027676463127,0.201029524207115,0.958735883235931,-0.201028272509575,0.711565673351288,-0.00126002624165267,0.702618300914764, +0.711510956287384,-0.00133867654949427,0.702673673629761,0.710478007793427,-0.00232538697309792,0.703715443611145,0.710564017295837,-0.0022670435719192,0.703628778457642,-0.193470671772957,-0.96184116601944,0.193469360470772,-0.193470925092697,-0.961841106414795,0.193469643592834,-0.370507508516312,-0.851733207702637,0.370505958795547,-0.370507478713989,-0.851733326911926,0.370505958795547,-0.702673554420471,-0.00134028901811689,-0.711511015892029,-0.702618002891541,-0.00126177864149213,-0.711565971374512,-0.703629672527313,-0.00226755067706108,-0.710563182830811,-0.703716397285461,-0.00232598348520696,-0.710477113723755,0.201029524207115,0.958735883235931,-0.201028272509575,0.201028928160667,0.958736121654511,-0.201027676463127,0.367933213710785,0.853962659835815,-0.36793041229248,0.36793327331543,0.853962600231171,-0.367930471897125,0.710564017295837,-0.0022670435719192,0.703628778457642,0.710478007793427,-0.00232538697309792,0.703715443611145,0.709249019622803,-0.00269896280951798,0.704952836036682,0.709314942359924,-0.00269954348914325,0.704886436462402,-0.370507478713989,-0.851733326911926,0.370505958795547,-0.370507508516312,-0.851733207702637,0.370505958795547,-0.521234273910522,-0.675745487213135,0.521231889724731,-0.521234154701233,-0.675745666027069,0.521231770515442,-0.703716397285461,-0.00232598348520696,-0.710477113723755,-0.703629672527313,-0.00226755067706108,-0.710563182830811,-0.704887449741364,-0.00270128063857555,-0.709313869476318,-0.704953789710999,-0.00270076049491763,-0.709248006343842,0.36793327331543,0.853962600231171,-0.367930471897125,0.367933213710785,0.853962659835815,-0.36793041229248,0.516361355781555,0.683187067508698,-0.51635867357254,0.516361117362976,0.683187365531921,-0.516358435153961,0.709314942359924,-0.00269954348914325,0.704886436462402,0.709249019622803,-0.00269896280951798,0.704952836036682,0.708240866661072,-0.00238283886574209,0.705966770648956,0.708269476890564,-0.00240230862982571,0.705938041210175,-0.521234154701233,-0.675745666027069,0.521231770515442,-0.521234273910522,-0.675745487213135,0.521231889724731, +-0.616617500782013,-0.489459097385406,0.616613745689392,-0.616617500782013,-0.489459246397018,0.616613686084747,-0.704953789710999,-0.00270076049491763,-0.709248006343842,-0.704887449741364,-0.00270128063857555,-0.709313869476318,-0.705939650535584,-0.00240451097488403,-0.708267748355865,-0.705968499183655,-0.00238503352738917,-0.708239138126373,0.516361117362976,0.683187365531921,-0.516358435153961,0.516361355781555,0.683187067508698,-0.51635867357254,0.614584505558014,0.49454402923584,-0.614582717418671,0.614584386348724,0.494544327259064,-0.614582538604736,0.708269476890564,-0.00240230862982571,0.705938041210175,0.708240866661072,-0.00238283886574209,0.705966770648956,0.707610070705414,-0.00173840392380953,0.706600844860077,0.70761901140213,-0.00175220682285726,0.706591904163361,-0.616617500782013,-0.489459246397018,0.616613686084747,-0.616617500782013,-0.489459097385406,0.616613745689392,-0.668814480304718,-0.324619084596634,0.668812036514282,-0.668814420700073,-0.324619174003601,0.668812096118927,-0.705968499183655,-0.00238503352738917,-0.708239138126373,-0.705939650535584,-0.00240451097488403,-0.708267748355865,-0.70659351348877,-0.00175322976429015,-0.707617342472076,-0.706602454185486,-0.00173938507214189,-0.70760852098465,0.614584386348724,0.494544327259064,-0.614582538604736,0.614584505558014,0.49454402923584,-0.614582717418671,0.6684929728508,0.32594296336174,-0.668489456176758,0.66849285364151,0.325943231582642,-0.668489456176758,0.70761901140213,-0.00175220682285726,0.706591904163361,0.707610070705414,-0.00173840392380953,0.706600844860077,0.707278251647949,-0.00103540846612304,0.706934452056885,0.707280397415161,-0.00104211654979736,0.706932365894318,-0.668814420700073,-0.324619174003601,0.668812096118927,-0.668814480304718,-0.324619084596634,0.668812036514282,-0.69503253698349,-0.18402037024498,0.695029675960541,-0.695032477378845,-0.184020519256592,0.695029616355896,-0.706602454185486,-0.00173938507214189,-0.70760852098465,-0.70659351348877,-0.00175322976429015,-0.707617342472076,-0.706933319568634,-0.0010425818618387,-0.707279324531555, +-0.706935465335846,-0.00103588192723691,-0.707277238368988,0.66849285364151,0.325943231582642,-0.668489456176758,0.6684929728508,0.32594296336174,-0.668489456176758,0.695061802864075,0.183797791600227,-0.695059180259705,0.695061862468719,0.183797836303711,-0.695059239864349,0.707280397415161,-0.00104211654979736,0.706932365894318,0.707278251647949,-0.00103540846612304,0.706934452056885,0.707139551639557,-0.0003436490369495,0.707073867321014,0.707139730453491,-0.000345641688909382,0.707073748111725,-0.695032477378845,-0.184020519256592,0.695029616355896,-0.69503253698349,-0.18402037024498,0.695029675960541,-0.705855429172516,-0.0595241077244282,0.705850422382355,-0.705855429172516,-0.0595242232084274,0.705850422382355,-0.706935465335846,-0.00103588192723691,-0.707277238368988,-0.706933319568634,-0.0010425818618387,-0.707279324531555,-0.707074880599976,-0.00034577728365548,-0.707138538360596,-0.707074999809265,-0.000343778694514185,-0.707138299942017,0.695061862468719,0.183797836303711,-0.695059239864349,0.695061802864075,0.183797791600227,-0.695059180259705,0.705863416194916,0.059296615421772,-0.705861628055573,0.705863416194916,0.0592968612909317,-0.705861568450928,0.707139730453491,-0.000345641688909382,0.707073748111725,0.707139551639557,-0.0003436490369495,0.707073867321014,0.707139730453491,0.000343374616932124,0.707073628902435,0.70713996887207,0.000345362292136997,0.707073509693146,-0.705855429172516,-0.0595242232084274,0.705850422382355,-0.705855429172516,-0.0595241077244282,0.705850422382355,-0.70585560798645,0.0595244877040386,0.705850303173065,-0.705855667591095,0.0595244131982327,0.70585024356842,-0.707074999809265,-0.000343778694514185,-0.707138299942017,-0.707074880599976,-0.00034577728365548,-0.707138538360596,-0.70707505941391,0.000346029293723404,-0.707138359546661,-0.707075238227844,0.000344042462529615,-0.707138180732727,0.705863416194916,0.0592968612909317,-0.705861568450928,0.705863416194916,0.059296615421772,-0.705861628055573,0.705864369869232,-0.0592965148389339,-0.705860733985901,0.705864310264587,-0.0592963472008705,-0.705860733985901, +0.70713996887207,0.000345362292136997,0.707073509693146,0.707139730453491,0.000343374616932124,0.707073628902435,0.707278728485107,0.00103503430727869,0.706933856010437,0.707280933856964,0.00104175764136016,0.706931829452515,-0.705855667591095,0.0595244131982327,0.70585024356842,-0.70585560798645,0.0595244877040386,0.705850303173065,-0.695033431053162,0.184020966291428,0.69502854347229,-0.695033490657806,0.184020906686783,0.69502854347229,-0.707075238227844,0.000344042462529615,-0.707138180732727,-0.70707505941391,0.000346029293723404,-0.707138359546661,-0.706933975219727,0.00104211340658367,-0.707278728485107,-0.706936061382294,0.0010353981051594,-0.70727664232254,0.705864310264587,-0.0592963472008705,-0.705860733985901,0.705864369869232,-0.0592965148389339,-0.705860733985901,0.695063352584839,-0.183798536658287,-0.695057451725006,0.695063412189484,-0.183798223733902,-0.695057511329651,0.707280933856964,0.00104175764136016,0.706931829452515,0.707278728485107,0.00103503430727869,0.706933856010437,0.707609713077545,0.00173987320158631,0.706601202487946,0.707618594169617,0.00175371766090393,0.706592321395874,-0.695033490657806,0.184020906686783,0.69502854347229,-0.695033431053162,0.184020966291428,0.69502854347229,-0.6688152551651,0.324619799852371,0.668810963630676,-0.668815195560455,0.324619650840759,0.668811023235321,-0.706936061382294,0.0010353981051594,-0.70727664232254,-0.706933975219727,0.00104211340658367,-0.707278728485107,-0.706593632698059,0.00175347202457488,-0.707617342472076,-0.706602573394775,0.00173964002169669,-0.70760840177536,0.695063412189484,-0.183798223733902,-0.695057511329651,0.695063352584839,-0.183798536658287,-0.695057451725006,0.668494343757629,-0.325943827629089,-0.668487668037415,0.668494522571564,-0.325943320989609,-0.668487846851349,0.707618594169617,0.00175371766090393,0.706592321395874,0.707609713077545,0.00173987320158631,0.706601202487946,0.7082399725914,0.00238309823907912,0.705967664718628,0.708268523216248,0.00240239221602678,0.705938935279846,-0.668815195560455,0.324619650840759,0.668811023235321, +-0.6688152551651,0.324619799852371,0.668810963630676,-0.616616368293762,0.489462167024612,0.616612493991852,-0.616616308689117,0.489462226629257,0.616612434387207,-0.706602573394775,0.00173964002169669,-0.70760840177536,-0.706593632698059,0.00175347202457488,-0.707617342472076,-0.705939590930939,0.00240392005071044,-0.708267867565155,-0.705968379974365,0.00238448660820723,-0.708239197731018,0.668494522571564,-0.325943320989609,-0.668487846851349,0.668494343757629,-0.325943827629089,-0.668487668037415,0.614585697650909,-0.494544953107834,-0.614580810070038,0.614585936069489,-0.494544327259064,-0.614581108093262,0.708268523216248,0.00240239221602678,0.705938935279846,0.7082399725914,0.00238309823907912,0.705967664718628,0.709249079227448,0.00269569433294237,0.704952657222748,0.709315061569214,0.00269618816673756,0.704886317253113,-0.616616308689117,0.489462226629257,0.616612434387207,-0.616616368293762,0.489462167024612,0.616612493991852,-0.521231055259705,0.675749778747559,0.521229565143585,-0.521231055259705,0.675749778747559,0.521229565143585,-0.705968379974365,0.00238448660820723,-0.708239197731018,-0.705939590930939,0.00240392005071044,-0.708267867565155,-0.704887390136719,0.00270002521574497,-0.709313988685608,-0.704953789710999,0.00269951135851443,-0.709248065948486,0.614585936069489,-0.494544327259064,-0.614581108093262,0.614585697650909,-0.494544953107834,-0.614580810070038,0.516362071037292,-0.683187127113342,-0.516357839107513,0.516362607479095,-0.683186292648315,-0.516358375549316,0.709315061569214,0.00269618816673756,0.704886317253113,0.709249079227448,0.00269569433294237,0.704952657222748,0.710478782653809,0.00232182210311294,0.703714728355408,0.710564792156219,0.00226357439532876,0.703628122806549,-0.521231055259705,0.675749778747559,0.521229565143585,-0.521231055259705,0.675749778747559,0.521229565143585,-0.370504170656204,0.851735234260559,0.370504558086395,-0.37050449848175,0.85173511505127,0.370504826307297,-0.704953789710999,0.00269951135851443,-0.709248065948486,-0.704887390136719,0.00270002521574497,-0.709313988685608, +-0.703628540039063,0.00226764404214919,-0.710564315319061,-0.703715205192566,0.00232588406652212,-0.710478246212006,0.516362607479095,-0.683186292648315,-0.516358375549316,0.516362071037292,-0.683187127113342,-0.516357839107513,0.367933988571167,-0.853962421417236,-0.367929995059967,0.367934763431549,-0.853961884975433,-0.367930769920349,0.710564792156219,0.00226357439532876,0.703628122806549,0.710478782653809,0.00232182210311294,0.703714728355408,0.711511492729187,0.00133715849369764,0.702673017978668,0.71156632900238,0.00125871121417731,0.702617764472961,-0.37050449848175,0.85173511505127,0.370504826307297,-0.370504170656204,0.851735234260559,0.370504558086395,-0.193471863865852,0.961840689182281,0.193471387028694,-0.193471983075142,0.961840629577637,0.193471491336823,-0.703715205192566,0.00232588406652212,-0.710478246212006,-0.703628540039063,0.00226764404214919,-0.710564315319061,-0.702617406845093,0.00126127956900746,-0.711566627025604,-0.702672719955444,0.00133992440532893,-0.711511850357056,0.367934763431549,-0.853961884975433,-0.367930769920349,0.367933988571167,-0.853962421417236,-0.367929995059967,0.201029449701309,-0.958736300468445,-0.201026827096939,0.201029539108276,-0.958736181259155,-0.201026931405067,0.71156632900238,0.00125871121417731,0.702617764472961,0.711511492729187,0.00133715849369764,0.702673017978668,0.712177574634552,0.000436556903878227,0.701999247074127,0.712200820446014,0.00040806716424413,0.701975584030151,-0.193471983075142,0.961840629577637,0.193471491336823,-0.193471863865852,0.961840689182281,0.193471387028694,-0.0582698471844196,0.996598839759827,0.0582695230841637,-0.0582698099315166,0.996598720550537,0.058269489556551,-0.702672719955444,0.00133992440532893,-0.711511850357056,-0.702617406845093,0.00126127956900746,-0.711566627025604,-0.701975703239441,0.000408661464462057,-0.71220064163208,-0.701999306678772,0.000437213864643127,-0.712177395820618,0.201029539108276,-0.958736181259155,-0.201026931405067,0.201029449701309,-0.958736300468445,-0.201026827096939,0.0725923255085945,-0.99471640586853,-0.0725917369127274, +0.0725920870900154,-0.994716465473175,-0.0725914984941483,-0.0725920051336288,-0.99471640586853,-0.0725921094417572,-0.0725917294621468,-0.994716346263886,-0.0725918263196945,-0.00557107385247946,-0.999969065189362,-0.00554148014634848,-0.0077444645576179,-0.999940276145935,-0.00771824037656188,0.701976239681244,0.000410496402764693,-0.712200164794922,0.701999723911285,0.000439110532170162,-0.712176978588104,0.70173579454422,0.000118811592983548,-0.712437212467194,0.70173579454422,0.000118811578431632,-0.712437152862549,0.0582700967788696,0.996598780155182,0.0582702159881592,0.0582699738442898,0.996598780155182,0.0582700930535793,0.00326843559741974,0.999989330768585,0.00325691723264754,0.00234573241323233,0.999994397163391,0.00233277003280818,-0.712178409099579,0.000437804847024381,0.701998293399811,-0.712201654911041,0.000409312313422561,0.70197468996048,-0.685862958431244,3.66751737601589e-005,0.727730631828308,-0.686135590076447,3.75032832380384e-005,0.727473616600037,-0.00817491393536329,0.999933063983917,-0.00817150250077248,-0.0078024473041296,0.999939143657684,-0.00779755134135485,-0.0725536197423935,0.994719684123993,-0.0725851133465767,-0.0725531578063965,0.994719743728638,-0.0725846588611603,0.00329330540262163,-0.999989211559296,0.0032876399345696,0.00345196854323149,-0.999988079071045,0.00344691821373999,0.0582403726875782,-0.996601581573486,0.0582522228360176,0.0582403019070625,-0.996601462364197,0.0582521520555019,-0.686134934425354,-3.75032250303775e-005,0.72747415304184,-0.685862421989441,-3.66751555702649e-005,0.727731227874756,-0.712201535701752,-0.000409920554375276,0.701974868774414,-0.712178289890289,-0.000438474264228716,0.701998472213745,-0.0725531578063965,0.994719743728638,-0.0725846588611603,-0.0725536197423935,0.994719684123993,-0.0725851133465767,-0.201028853654861,0.958736181259155,-0.201027929782867,-0.201028570532799,0.958736300468445,-0.201027631759644,0.0582403019070625,-0.996601462364197,0.0582521520555019,0.0582403726875782,-0.996601581573486,0.0582522228360176,0.193470701575279,-0.961840987205505,0.193470627069473, +0.193470850586891,-0.961840987205505,0.193470790982246,-0.712178289890289,-0.000438474264228716,0.701998472213745,-0.712201535701752,-0.000409920554375276,0.701974868774414,-0.711566805839539,-0.00126264442224056,0.702617287635803,-0.7115119099617,-0.00134130055084825,0.702672600746155,-0.201028570532799,0.958736300468445,-0.201027631759644,-0.201028853654861,0.958736181259155,-0.201027929782867,-0.367931336164474,0.853962600231171,-0.367932111024857,-0.367931693792343,0.853962481021881,-0.367932498455048,0.70261937379837,-0.00126389553770423,-0.711564660072327,0.702674746513367,-0.00134213594719768,-0.711509943008423,0.703717112541199,-0.00232598488219082,-0.710476338863373,0.703630328178406,-0.0022675518412143,-0.710562527179718,0.193470850586891,-0.961840987205505,0.193470790982246,0.193470701575279,-0.961840987205505,0.193470627069473,0.370508253574371,-0.851732432842255,0.37050673365593,0.370508372783661,-0.851732432842255,0.370506823062897,-0.7115119099617,-0.00134130055084825,0.702672600746155,-0.711566805839539,-0.00126264442224056,0.702617287635803,-0.71056455373764,-0.00226968876086175,0.703628301620483,-0.710478544235229,-0.00232802587561309,0.703714966773987,-0.367931693792343,0.853962481021881,-0.367932498455048,-0.367931336164474,0.853962600231171,-0.367932111024857,-0.516359269618988,0.683186709880829,-0.516361236572266,-0.516359567642212,0.68318647146225,-0.5163614153862,0.703630328178406,-0.0022675518412143,-0.710562527179718,0.703717112541199,-0.00232598488219082,-0.710476338863373,0.704955339431763,-0.00269814836792648,-0.709246456623077,0.704889118671417,-0.00269892672076821,-0.709312379360199,0.370508372783661,-0.851732432842255,0.370506823062897,0.370508253574371,-0.851732432842255,0.37050673365593,0.521235704421997,-0.675744712352753,0.521231472492218,0.521235823631287,-0.675744593143463,0.521231532096863,-0.710478544235229,-0.00232802587561309,0.703714966773987,-0.71056455373764,-0.00226968876086175,0.703628301620483,-0.7093146443367,-0.00270144059322774,0.704886734485626,-0.709248661994934,-0.00270078261382878,0.704953134059906, +-0.516359567642212,0.68318647146225,-0.5163614153862,-0.516359269618988,0.683186709880829,-0.516361236572266,-0.61458283662796,0.494543761014938,-0.614584624767303,-0.61458295583725,0.494543641805649,-0.614584684371948,0.704889118671417,-0.00269892672076821,-0.709312379360199,0.704955339431763,-0.00269814836792648,-0.709246456623077,0.705968856811523,-0.00238343887031078,-0.708238840103149,0.705940186977386,-0.00240271771326661,-0.708267331123352,0.521235823631287,-0.675744593143463,0.521231532096863,0.521235704421997,-0.675744712352753,0.521231472492218,0.616616427898407,-0.489459127187729,0.616614758968353,0.616616547107697,-0.489458918571472,0.616614878177643,-0.709248661994934,-0.00270078261382878,0.704953134059906,-0.7093146443367,-0.00270144059322774,0.704886734485626,-0.708267986774445,-0.00240451144054532,0.705939412117004,-0.708239495754242,-0.00238511036150157,0.705968141555786,-0.61458295583725,0.494543641805649,-0.614584684371948,-0.61458283662796,0.494543761014938,-0.614584624767303,-0.668489813804626,0.325942695140839,-0.66849273443222,-0.668489873409271,0.325942546129227,-0.66849273443222,0.705940186977386,-0.00240271771326661,-0.708267331123352,0.705968856811523,-0.00238343887031078,-0.708238840103149,0.706603288650513,-0.00174040079582483,-0.707607686519623,0.706594228744507,-0.00175424828194082,-0.707616627216339,0.616616547107697,-0.489458918571472,0.616614878177643,0.616616427898407,-0.489459127187729,0.616614758968353,0.668812215328217,-0.324618369340897,0.668814659118652,0.668812215328217,-0.324618458747864,0.668814599514008,-0.708239495754242,-0.00238511036150157,0.705968141555786,-0.708267986774445,-0.00240451144054532,0.705939412117004,-0.707616925239563,-0.00175426388159394,0.706594049930573,-0.707607984542847,-0.00174041697755456,0.706602931022644,-0.668489873409271,0.325942546129227,-0.66849273443222,-0.668489813804626,0.325942695140839,-0.66849273443222,-0.695057928562164,0.183798059821129,-0.695062935352325,-0.695057988166809,0.183798030018806,-0.695062935352325,0.706594228744507,-0.00175424828194082,-0.707616627216339, +0.706603288650513,-0.00174040079582483,-0.707607686519623,0.706936895847321,-0.00103634945116937,-0.707275807857513,0.706934750080109,-0.00104305800050497,-0.707277894020081,0.668812215328217,-0.324618458747864,0.668814599514008,0.668812215328217,-0.324618369340897,0.668814659118652,0.695030570030212,-0.18401962518692,0.695031821727753,0.695030570030212,-0.184019595384598,0.695031762123108,-0.707607984542847,-0.00174041697755456,0.706602931022644,-0.707616925239563,-0.00175426388159394,0.706594049930573,-0.707278251647949,-0.00104224123060703,0.706934452056885,-0.707276046276093,-0.00103551684878767,0.706936597824097,-0.695057988166809,0.183798030018806,-0.695062935352325,-0.695057928562164,0.183798059821129,-0.695062935352325,-0.705859661102295,0.0592971928417683,-0.705865263938904,-0.705859661102295,0.0592971406877041,-0.705865263938904,0.706934750080109,-0.00104305800050497,-0.707277894020081,0.706936895847321,-0.00103634945116937,-0.707275807857513,0.707076191902161,-0.000343966588843614,-0.707137227058411,0.707075953483582,-0.000345963781001046,-0.707137405872345,0.695030570030212,-0.184019595384598,0.695031762123108,0.695030570030212,-0.18401962518692,0.695031821727753,0.705853283405304,-0.0595242455601692,0.705852627754211,0.705853283405304,-0.059524342417717,0.705852627754211,-0.707276046276093,-0.00103551684878767,0.706936597824097,-0.707278251647949,-0.00104224123060703,0.706934452056885,-0.707137286663055,-0.000345595588441938,0.707076072692871,-0.707137048244476,-0.000343605235684663,0.70707631111145,-0.705859661102295,0.0592971406877041,-0.705865263938904,-0.705859661102295,0.0592971928417683,-0.705865263938904,-0.705860376358032,-0.0592969059944153,-0.705864667892456,-0.705860376358032,-0.0592969618737698,-0.705864667892456,0.707075953483582,-0.000345963781001046,-0.707137405872345,0.707076191902161,-0.000343966588843614,-0.707137227058411,0.707076191902161,0.000344308617059141,-0.707137227058411,0.707076013088226,0.000346299057127908,-0.707137405872345,0.705853283405304,-0.059524342417717,0.705852627754211, +0.705853283405304,-0.0595242455601692,0.705852627754211,0.705853521823883,0.0595246963202953,0.705852270126343,0.705853521823883,0.0595246888697147,0.705852270126343,-0.707137048244476,-0.000343605235684663,0.70707631111145,-0.707137286663055,-0.000345595588441938,0.707076072692871,-0.707137882709503,0.000345406122505665,0.707075536251068,-0.707137703895569,0.000343415595125407,0.707075655460358,-0.705860376358032,-0.0592969618737698,-0.705864667892456,-0.705860376358032,-0.0592969059944153,-0.705864667892456,-0.695059299468994,-0.183798015117645,-0.69506162405014,-0.695059299468994,-0.183798164129257,-0.69506162405014,0.707076013088226,0.000346299057127908,-0.707137405872345,0.707076191902161,0.000344308617059141,-0.707137227058411,0.706936597824097,0.00103563966695219,-0.707276105880737,0.70693451166153,0.00104234111495316,-0.707278251647949,0.705853521823883,0.0595246888697147,0.705852270126343,0.705853521823883,0.0595246963202953,0.705852270126343,0.695031404495239,0.184020981192589,0.695030510425568,0.695031404495239,0.184020921587944,0.695030570030212,-0.707137703895569,0.000343415595125407,0.707075655460358,-0.707137882709503,0.000345406122505665,0.707075536251068,-0.707278966903687,0.00104234402533621,0.706933796405792,-0.707276880741119,0.00103562406729907,0.706935822963715,-0.695059299468994,-0.183798164129257,-0.69506162405014,-0.695059299468994,-0.183798015117645,-0.69506162405014,-0.668490707874298,-0.32594221830368,-0.668492019176483,-0.668490648269653,-0.325942575931549,-0.668492019176483,0.70693451166153,0.00104234111495316,-0.707278251647949,0.706936597824097,0.00103563966695219,-0.707276105880737,0.706603467464447,0.00174012721981853,-0.707607448101044,0.706594526767731,0.00175399880390614,-0.707616329193115,0.695031404495239,0.184020921587944,0.695030570030212,0.695031404495239,0.184020981192589,0.695030510425568,0.668812394142151,0.324619054794312,0.668814122676849,0.668812334537506,0.324619114398956,0.668814063072205,-0.707276880741119,0.00103562406729907,0.706935822963715,-0.707278966903687,0.00104234402533621,0.706933796405792, +-0.70761638879776,0.0017542204586789,0.706594467163086,-0.707607567310333,0.00174037693068385,0.706603407859802,-0.668490648269653,-0.325942575931549,-0.668492019176483,-0.668490707874298,-0.32594221830368,-0.668492019176483,-0.614582359790802,-0.494543999433517,-0.614584863185883,-0.614582300186157,-0.494544446468353,-0.614584743976593,0.706594526767731,0.00175399880390614,-0.707616329193115,0.706603467464447,0.00174012721981853,-0.707607448101044,0.705969274044037,0.00238535227254033,-0.708238303661346,0.705940544605255,0.00240473099984229,-0.708266913890839,0.668812334537506,0.324619114398956,0.668814063072205,0.668812394142151,0.324619054794312,0.668814122676849,0.616613686084747,0.489462107419968,0.616615235805511,0.616613686084747,0.489462107419968,0.616615176200867,-0.707607567310333,0.00174037693068385,0.706603407859802,-0.70761638879776,0.0017542204586789,0.706594467163086,-0.708267450332642,0.00240382272750139,0.705940067768097,-0.708238840103149,0.00238446751609445,0.705968856811523,-0.614582300186157,-0.494544446468353,-0.614584743976593,-0.614582359790802,-0.494543999433517,-0.614584863185883,-0.51635867357254,-0.683186769485474,-0.516361773014069,-0.516358375549316,-0.683187246322632,-0.516361474990845,0.705940544605255,0.00240473099984229,-0.708266913890839,0.705969274044037,0.00238535227254033,-0.708238303661346,0.704954504966736,0.00269951019436121,-0.709247291088104,0.704888164997101,0.00270002475008368,-0.709313213825226,0.616613686084747,0.489462107419968,0.616615176200867,0.616613686084747,0.489462107419968,0.616615235805511,0.52122974395752,0.675749957561493,0.521230757236481,0.521229803562164,0.675749838352203,0.521230816841125,-0.708238840103149,0.00238446751609445,0.705968856811523,-0.708267450332642,0.00240382272750139,0.705940067768097,-0.70931476354599,0.00269999378360808,0.704886615276337,-0.709248781204224,0.00269934698008001,0.704953014850616,-0.516358375549316,-0.683187246322632,-0.516361474990845,-0.51635867357254,-0.683186769485474,-0.516361773014069,-0.367931813001633,-0.853962063789368,-0.367933183908463, +-0.367931485176086,-0.853962242603302,-0.367932856082916,0.704888164997101,0.00270002475008368,-0.709313213825226,0.704954504966736,0.00269951019436121,-0.709247291088104,0.703716576099396,0.00232465262524784,-0.710476875305176,0.703629970550537,0.00226622214540839,-0.710562884807587,0.521229803562164,0.675749838352203,0.521230816841125,0.52122974395752,0.675749957561493,0.521230757236481,0.370505303144455,0.851734161376953,0.370505899190903,0.370505303144455,0.851734161376953,0.37050586938858,-0.709248781204224,0.00269934698008001,0.704953014850616,-0.70931476354599,0.00269999378360808,0.704886615276337,-0.710563957691193,0.00226672505959868,0.703628838062286,-0.710478067398071,0.00232524517923594,0.7037153840065,-0.367931485176086,-0.853962242603302,-0.367932856082916,-0.367931813001633,-0.853962063789368,-0.367933183908463,-0.201028272509575,-0.958736300468445,-0.201028108596802,-0.201028317213058,-0.958736300468445,-0.201028138399124,0.703629970550537,0.00226622214540839,-0.710562884807587,0.703716576099396,0.00232465262524784,-0.710476875305176,0.702673971652985,0.00133976130746305,-0.71151065826416,0.702618539333344,0.00126147933769971,-0.711565494537354,0.370505303144455,0.851734161376953,0.37050586938858,0.370505303144455,0.851734161376953,0.370505899190903,0.193472996354103,0.961840152740479,0.193472623825073,0.193473190069199,0.961840033531189,0.193472847342491,-0.710478067398071,0.00232524517923594,0.7037153840065,-0.710563957691193,0.00226672505959868,0.703628838062286,-0.71156632900238,0.00126001914031804,0.702617704868317,-0.711511433124542,0.00133846921380609,0.702673256397247,-0.201028317213058,-0.958736300468445,-0.201028138399124,-0.201028272509575,-0.958736300468445,-0.201028108596802,-0.0725917294621468,-0.994716346263886,-0.0725918263196945,-0.0725920051336288,-0.99471640586853,-0.0725921094417572,0.702618539333344,0.00126147933769971,-0.711565494537354,0.702673971652985,0.00133976130746305,-0.71151065826416,0.701999723911285,0.000439110532170162,-0.712176978588104,0.701976239681244,0.000410496402764693,-0.712200164794922, +0.193473190069199,0.961840033531189,0.193472847342491,0.193472996354103,0.961840152740479,0.193472623825073,0.0582699738442898,0.996598780155182,0.0582700930535793,0.0582700967788696,0.996598780155182,0.0582702159881592,-0.711511433124542,0.00133846921380609,0.702673256397247,-0.71156632900238,0.00126001914031804,0.702617704868317,-0.712201654911041,0.000409312313422561,0.70197468996048,-0.712178409099579,0.000437804847024381,0.701998293399811,-0.635246872901917,0,-0.772309124469757,-0.739008128643036,0,-0.673696339130402,-0.739008128643036,0,-0.673696398735046,-0.635246813297272,0,-0.772309124469757,1.54286988163221e-006,0.999999940395355,-7.93113315467053e-007,2.80659662621474e-007,0.999999940395355,-1.0463888600043e-007,1.13341123153532e-007,0.999999940395355,1.92766293594104e-007,1.0110088055626e-007,0.999999940395355,2.52210782036855e-007,-2.84219439095068e-008,-0.999999940395355,6.12528694432513e-008,-3.06279957840161e-006,-0.999999940395355,2.11532210414589e-006,9.22658784929808e-008,-0.999999940395355,1.01188582846135e-007,-3.09019689836987e-008,-0.999999940395355,5.12295663668283e-008,2.80659662621474e-007,0.999999940395355,-1.0463888600043e-007,-6.80723175605635e-008,0.999999940395355,-3.06603737953992e-007,-2.3628878409454e-007,0.999999940395355,-1.0379736181676e-007,1.13341123153532e-007,0.999999940395355,1.92766293594104e-007,-4.79960462484996e-008,-0.999999940395355,5.3143271117051e-008,-2.84219439095068e-008,-0.999999940395355,6.12528694432513e-008,-3.09019689836987e-008,-0.999999940395355,5.12295663668283e-008,-1.44252831901781e-008,-0.999999940395355,3.59837981633859e-009,-6.80723175605635e-008,0.999999940395355,-3.06603737953992e-007,-1.9421602814873e-007,0.999999940395355,-1.35349409902119e-007,-2.12122287734928e-007,0.999999940395355,-1.92766464124361e-007,-2.3628878409454e-007,0.999999940395355,-1.0379736181676e-007,-3.20978159606966e-008,-0.999999940395355,-4.38813394509907e-008,-4.79960462484996e-008,-0.999999940395355,5.3143271117051e-008,-1.44252831901781e-008,-0.999999940395355,3.59837981633859e-009, +-2.70369984178842e-008,-0.999999940395355,1.23754624326011e-008,-1.9421602814873e-007,0.999999940395355,-1.35349409902119e-007,-1.6573590500002e-008,0.999999940395355,5.43974998379326e-008,7.28207965039473e-008,0.999999940395355,-2.07594496259844e-007,-2.12122287734928e-007,0.999999940395355,-1.92766464124361e-007,3.4919590774507e-008,-0.999999940395355,-1.12914229077887e-007,-3.20978159606966e-008,-0.999999940395355,-4.38813394509907e-008,-2.70369984178842e-008,-0.999999940395355,1.23754624326011e-008,-1.2572110019704e-009,-0.999999940395355,-2.44187359221826e-009,-1.6573590500002e-008,0.999999940395355,5.43974998379326e-008,1.11040328931722e-007,0.999999940395355,4.20550350099802e-008,1.90075454042926e-007,0.999999940395355,-1.59403057864438e-007,7.28207965039473e-008,0.999999940395355,-2.07594496259844e-007,-2.26367546929396e-008,-0.999999940395355,-1.6894109222676e-008,3.4919590774507e-008,-0.999999940395355,-1.12914229077887e-007,-1.2572110019704e-009,-0.999999940395355,-2.44187359221826e-009,-5.57704069592546e-008,-0.999999940395355,-3.00616775916751e-008,1.11040328931722e-007,0.999999940395355,4.20550350099802e-008,1.91991318843066e-007,0.999999940395355,-2.97128277537695e-008,2.03279682864377e-007,0.999999940395355,-8.34085724932265e-008,1.90075454042926e-007,0.999999940395355,-1.59403057864438e-007,-2.19702116055487e-007,-0.999999940395355,5.90294462199381e-008,-2.26367546929396e-008,-0.999999940395355,-1.6894109222676e-008,-5.57704069592546e-008,-0.999999940395355,-3.00616775916751e-008,-2.14066815829028e-007,-0.999999940395355,9.92259074905633e-009,1.91991318843066e-007,0.999999940395355,-2.97128277537695e-008,1.11701218941107e-007,0.999999940395355,1.2913625724309e-008,9.39178832481957e-008,0.999999940395355,1.20479333176604e-008,2.03279682864377e-007,0.999999940395355,-8.34085724932265e-008,-1.48727693272122e-007,-0.999999940395355,1.05255022475603e-008,-2.19702116055487e-007,-0.999999940395355,5.90294462199381e-008,-2.14066815829028e-007,-0.999999940395355,9.92259074905633e-009,-1.32516703388319e-007,-0.999999940395355,1.4513643620262e-008, +1.11701218941107e-007,0.999999940395355,1.2913625724309e-008,-1.11701154992261e-007,0.999999940395355,3.31620704230318e-008,-9.39179187753325e-008,0.999999940395355,3.89240248921396e-008,9.39178832481957e-008,0.999999940395355,1.20479333176604e-008,1.48727622217848e-007,-0.999999940395355,1.05254978066682e-008,-1.48727693272122e-007,-0.999999940395355,1.05255022475603e-008,-1.32516703388319e-007,-0.999999940395355,1.4513643620262e-008,1.325166465449e-007,-0.999999940395355,1.4513637403013e-008,-1.11701154992261e-007,0.999999940395355,3.31620704230318e-008,-1.91991460951613e-007,0.999999940395355,-5.18416731765114e-009,-2.03279711286086e-007,0.999999940395355,-5.46789848954177e-008,-9.39179187753325e-008,0.999999940395355,3.89240248921396e-008,2.19702172898906e-007,-0.999999940395355,5.90294106928013e-008,1.48727622217848e-007,-0.999999940395355,1.05254978066682e-008,1.325166465449e-007,-0.999999940395355,1.4513637403013e-008,2.14066830039883e-007,-0.999999940395355,9.92252680021011e-009,-1.91991460951613e-007,0.999999940395355,-5.18416731765114e-009,-1.11040229455739e-007,0.999999940395355,4.101623218844e-008,-1.90075539308054e-007,0.999999940395355,-1.68670595712683e-007,-2.03279711286086e-007,0.999999940395355,-5.46789848954177e-008,2.26366374533882e-008,-0.999999940395355,-1.6894153631597e-008,2.19702172898906e-007,-0.999999940395355,5.90294106928013e-008,2.14066830039883e-007,-0.999999940395355,9.92252680021011e-009,5.57705099879513e-008,-0.999999940395355,-3.00617060133845e-008,-1.11040229455739e-007,0.999999940395355,4.101623218844e-008,1.65736508961345e-008,0.999999940395355,5.05326731570221e-008,-7.28209812450586e-008,0.999999940395355,-2.18715669575431e-007,-1.90075539308054e-007,0.999999940395355,-1.68670595712683e-007,-1.65621631964541e-008,-0.999999940395355,-1.22109724998154e-007,2.26366374533882e-008,-0.999999940395355,-1.6894153631597e-008,5.57705099879513e-008,-0.999999940395355,-3.00617060133845e-008,2.82940550988542e-008,-0.999999940395355,9.93358995060589e-009,1.65736508961345e-008,0.999999940395355,5.05326731570221e-008, +1.94215914461893e-007,0.999999940395355,-1.52138156295223e-007,2.12122188258945e-007,0.999999940395355,-2.07594553103263e-007,-7.28209812450586e-008,0.999999940395355,-2.18715669575431e-007,4.87227431733572e-008,-0.999999940395355,-5.65562672250053e-008,-1.65621631964541e-008,-0.999999940395355,-1.22109724998154e-007,2.82940550988542e-008,-0.999999940395355,9.93358995060589e-009,7.30682643279579e-008,-0.999999940395355,6.28967811167058e-008,1.94215914461893e-007,0.999999940395355,-1.52138156295223e-007,5.17173148750771e-008,0.999999940395355,-3.26426089714005e-007,2.07438020538575e-007,0.999999940395355,-1.48281870337996e-007,2.12122188258945e-007,0.999999940395355,-2.07594553103263e-007,2.78624341376599e-008,-0.999999940395355,5.87718460565156e-008,4.87227431733572e-008,-0.999999940395355,-5.65562672250053e-008,7.30682643279579e-008,-0.999999940395355,6.28967811167058e-008,2.70020947823468e-008,-0.999999940395355,7.07780500874833e-008,5.17173148750771e-008,0.999999940395355,-3.26426089714005e-007,-2.94672474865365e-007,0.999999940395355,-1.01979537703301e-007,-1.67872457268459e-007,0.999999940395355,1.33453696093966e-007,2.07438020538575e-007,0.999999940395355,-1.48281870337996e-007,1.00207397935037e-008,-0.999999940395355,7.03606062302242e-008,2.78624341376599e-008,-0.999999940395355,5.87718460565156e-008,2.70020947823468e-008,-0.999999940395355,7.07780500874833e-008,2.44844358121554e-008,-0.999999940395355,8.02633977059486e-008,-2.94672474865365e-007,0.999999940395355,-1.01979537703301e-007,-1.5232648138408e-006,0.999999940395355,-7.99458121036878e-007,-1.27007069750107e-007,0.999999940395355,1.89157702834564e-007,-1.67872457268459e-007,0.999999940395355,1.33453696093966e-007,3.06257220472617e-006,-0.999999940395355,2.11517772186198e-006,1.00207397935037e-008,-0.999999940395355,7.03606062302242e-008,2.44844358121554e-008,-0.999999940395355,8.02633977059486e-008,-9.22661413937931e-008,-0.999999940395355,1.01188476264724e-007,0.635247647762299,0,-0.772308468818665,0.739009261131287,0,-0.673695206642151,0.739009261131287,0,-0.673695206642151, +0.635247588157654,0,-0.772308468818665,-0.635246813297272,0,-0.772309124469757,-0.303152590990067,0,-0.95294201374054,-0.303152590990067,0,-0.952941954135895,-0.635246872901917,0,-0.772309124469757,-0.303152590990067,0,-0.95294201374054,-0.0461830161511898,0,-0.998933017253876,-0.0461830161511898,0,-0.998932957649231,-0.303152590990067,0,-0.952941954135895,0.45947140455246,0,-0.888192415237427,0.561634302139282,4.53231962183054e-007,-0.827385485172272,0.561634242534637,4.53231876917926e-007,-0.827385544776917,0.459471434354782,0,-0.888192474842072,-0.561632931232452,-1.15324326088739e-006,-0.827386438846588,-0.45947140455246,-1.17162176138663e-006,-0.888192474842072,-0.459471434354782,-1.17162198876031e-006,-0.888192534446716,-0.561632990837097,-1.15324314720056e-006,-0.827386379241943,0.0461838319897652,-4.11893012142173e-007,-0.998932838439941,0.0461838357150555,-4.11893040563882e-007,-0.998932898044586,0.0461838394403458,-4.11893068985592e-007,-0.998932898044586,0.0461838357150555,-4.11893068985592e-007,-0.998932898044586,0.539463400840759,0,-0.842009007930756,0.635247647762299,0,-0.772308468818665,0.635247588157654,0,-0.772308468818665,0.539463341236115,0,-0.842009007930756,-1.14132411965784e-007,0.999999940395355,6.72959998837541e-008,-1.14132419071211e-007,0.999999940395355,6.72959998837541e-008,-1.14132426176639e-007,0.999999940395355,6.72960069891815e-008,3.58468287231517e-006,0.999999940395355,-2.32788261200767e-006,1.54286988163221e-006,0.999999940395355,-7.93113315467053e-007,1.0110088055626e-007,0.999999940395355,2.52210782036855e-007,-1.14132426176639e-007,0.999999940395355,6.72959998837541e-008,2.34338898508213e-007,-0.999999940395355,1.07912207170102e-007,2.34338898508213e-007,-0.999999940395355,1.07912200064675e-007,2.34338884297358e-007,-0.999999940395355,1.07912207170102e-007,9.22658784929808e-008,-0.999999940395355,1.01188582846135e-007,-3.06279957840161e-006,-0.999999940395355,2.11532210414589e-006,-8.23889513412723e-006,-0.999999940395355,5.53539075553999e-006,2.34338870086503e-007,-0.999999940395355,1.07912200064675e-007, +1.17106608854556e-007,0.999999940395355,0,1.17106594643701e-007,0.999999940395355,0,1.17106587538274e-007,0.999999940395355,0,-1.27007069750107e-007,0.999999940395355,1.89157702834564e-007,-1.5232648138408e-006,0.999999940395355,-7.99458121036878e-007,-3.53971358890703e-006,0.999999940395355,-2.33828313866979e-006,1.17106587538274e-007,0.999999940395355,0,-2.34339410098983e-007,-0.999999940395355,1.07912242697239e-007,8.23828759166645e-006,-0.999999940395355,5.53500649402849e-006,3.06257220472617e-006,-0.999999940395355,2.11517772186198e-006,-9.22661413937931e-008,-0.999999940395355,1.01188476264724e-007,-2.34339395888128e-007,-0.999999940395355,1.07912235591812e-007,-2.34339410098983e-007,-0.999999940395355,1.07912249802666e-007,-2.34339410098983e-007,-0.999999940395355,1.07912228486384e-007,-0.00557107385247946,-0.999969065189362,-0.00554148014634848,-8.23889513412723e-006,-0.999999940395355,5.53539075553999e-006,-3.06279957840161e-006,-0.999999940395355,2.11532210414589e-006,-1.15069615276298e-005,-1,7.50591334508499e-006,-0.0077444645576179,-0.999940276145935,-0.00771824037656188,0.0190604254603386,0.568274319171906,-0.822618365287781,0.0190604254603386,0.568274259567261,-0.822618424892426,0.0190604273229837,0.568274319171906,-0.822618424892426,0.0190742742270231,-0.568303346633911,-0.822597861289978,0.0190742779523134,-0.568303465843201,-0.822597980499268,0.0190742779523134,-0.568303406238556,-0.822597920894623,-0.0190894585102797,-0.568283140659332,-0.822611570358276,-0.0190894603729248,-0.568283140659332,-0.822611570358276,-0.0190894585102797,-0.568283081054688,-0.822611510753632,-0.0190455634146929,0.56827437877655,-0.82261860370636,-0.0190455634146929,0.56827437877655,-0.82261860370636,-0.0190455634146929,0.568274438381195,-0.82261860370636,-0.0105106672272086,-0.999880790710449,0.011308298446238,-0.0106544271111488,-0.99988067150116,0.0111874593421817,-0.0113585498183966,-0.99987930059433,0.0105955852195621,-0.0113585498183966,-0.99987930059433,0.0105955852195621,0.0113593144342303,-0.99987930059433,0.0105963386595249, +0.0113593144342303,-0.99987930059433,0.0105963386595249,0.0106547428295016,-0.999880611896515,0.0111887147650123,0.0105108851566911,-0.999880731105804,0.0113096628338099,0.00714113004505634,-0.999881982803345,0.013599039055407,0.00744556356221437,-0.9998819231987,0.0134416632354259,0.00487630348652601,-0.999880611896515,0.0146546727046371,0.00468466011807323,-0.999880492687225,0.0147288199514151,0.00247988430783153,-0.999879896640778,0.0152971195057034,0.00268623768351972,-0.999879837036133,0.0152615616098046,-0.000318829115713015,-0.99987918138504,0.0155367832630873,-0.000491580227389932,-0.999879121780396,0.015541622415185,-0.000491580227389932,-0.999879121780396,0.015541622415185,-0.000318829115713015,-0.99987918138504,0.0155367832630873,-0.00245660613290966,-0.999879121780396,0.0153509695082903,-0.00252516660839319,-0.999879121780396,0.0153390010818839,-0.00252516660839319,-0.999879121780396,0.0153390010818839,-0.00245660613290966,-0.999879121780396,0.0153509695082903,-0.00432269088923931,-0.999879062175751,0.0149366147816181,-0.00433902209624648,-0.999879062175751,0.0149315912276506,-0.00433902209624648,-0.999879062175751,0.0149315912276506,-0.00432269088923931,-0.999879062175751,0.0149366147816181,-0.00525987707078457,-0.99987930059433,0.0146226054057479,-0.00526147894561291,-0.99987930059433,0.0146219655871391,-0.00526147894561291,-0.99987930059433,0.0146219655871391,-0.00525987707078457,-0.99987930059433,0.0146226054057479,-0.0055574937723577,-0.999879479408264,0.0144935231655836,-0.00555739784613252,-0.999879479408264,0.0144936218857765,-0.00555739784613252,-0.999879479408264,0.0144936218857765,-0.0055574937723577,-0.999879479408264,0.0144935231655836,-0.00538267521187663,-0.999879837036133,0.0145378783345222,-0.00538495136424899,-0.999879777431488,0.0145371435210109,-0.00538495136424899,-0.999879777431488,0.0145371435210109,-0.00538267521187663,-0.999879837036133,0.0145378783345222,-0.00482724932953715,-0.999880135059357,0.0147103499621153,-0.00483253411948681,-0.999880015850067,0.0147087406367064,-0.00483253411948681,-0.999880015850067,0.0147087406367064, +-0.00482724932953715,-0.999880135059357,0.0147103499621153,-0.00394987734034657,-0.999880373477936,0.0149511136114597,-0.00395712302997708,-0.999880373477936,0.0149492807686329,-0.00395712302997708,-0.999880373477936,0.0149492807686329,-0.00394987734034657,-0.999880373477936,0.0149511136114597,-0.00280143902637064,-0.99988055229187,0.0151950409635901,-0.00280852057039738,-0.99988067150116,0.0151937715709209,-0.00280852057039738,-0.99988067150116,0.0151937715709209,-0.00280143902637064,-0.99988055229187,0.0151950409635901,-0.00145049777347595,-0.999880731105804,0.0153744779527187,-0.00145489897113293,-0.99988067150116,0.0153740774840117,-0.00145489897113293,-0.99988067150116,0.0153740774840117,-0.00145049777347595,-0.999880731105804,0.0153744779527187,2.68064781039357e-007,-0.999880731105804,0.0154413534328341,2.69874817604432e-007,-0.999880790710449,0.0154413543641567,2.69874817604432e-007,-0.999880790710449,0.0154413543641567,2.68064781039357e-007,-0.999880731105804,0.0154413534328341,0.00145107042044401,-0.999880731105804,0.0153759755194187,0.00145547511056066,-0.99988067150116,0.0153755629435182,0.00145547511056066,-0.99988067150116,0.0153755629435182,0.00145107042044401,-0.999880731105804,0.0153759755194187,0.00280162901617587,-0.99988055229187,0.0151950446888804,0.00280870846472681,-0.999880611896515,0.0151937762275338,0.00280870846472681,-0.999880611896515,0.0151937762275338,0.00280162901617587,-0.99988055229187,0.0151950446888804,0.00395011901855469,-0.999880373477936,0.0149511182680726,0.00395737402141094,-0.999880373477936,0.0149492854252458,0.00395737402141094,-0.999880373477936,0.0149492854252458,0.00395011901855469,-0.999880373477936,0.0149511182680726,0.00482765957713127,-0.999880075454712,0.0147096505388618,0.0048329415731132,-0.999880015850067,0.0147080291062593,0.0048329415731132,-0.999880015850067,0.0147080291062593,0.00482765957713127,-0.999880075454712,0.0147096505388618,0.00538237346336246,-0.999879837036133,0.0145364869385958,0.0053846463561058,-0.999879896640778,0.0145357567816973,0.0053846463561058,-0.999879896640778,0.0145357567816973, +0.00538237346336246,-0.999879837036133,0.0145364869385958,0.00555754266679287,-0.999879479408264,0.0144921410828829,0.00555745186284184,-0.999879479408264,0.0144922416657209,0.00555745186284184,-0.999879479408264,0.0144922416657209,0.00555754266679287,-0.999879479408264,0.0144921410828829,0.00525992177426815,-0.999879240989685,0.0146219152957201,0.00526152784004807,-0.999879240989685,0.0146212745457888,0.00526152784004807,-0.999879240989685,0.0146212745457888,0.00525992177426815,-0.999879240989685,0.0146219152957201,0.00432145828381181,-0.999879062175751,0.0149366278201342,0.00433779880404472,-0.999879062175751,0.0149316051974893,0.00433779880404472,-0.999879062175751,0.0149316051974893,0.00432145828381181,-0.999879062175751,0.0149366278201342,0.00245627365075052,-0.999879002571106,0.0153517946600914,0.00252474751323462,-0.999879121780396,0.015339782461524,0.00252474751323462,-0.999879121780396,0.015339782461524,0.00245627365075052,-0.999879002571106,0.0153517946600914,0.000319064332870767,-0.99987918138504,0.0155375516042113,0.000491964456159621,-0.999879121780396,0.0155425565317273,-0.00248113460838795,-0.999879896640778,0.0152970626950264,-0.00268747773952782,-0.999879896640778,0.0152616528794169,-0.00487618381157517,-0.99988067150116,0.0146555285900831,-0.00468478258699179,-0.999880492687225,0.0147296776995063,-0.00714085716754198,-0.9998819231987,0.0135983293876052,-0.00744548859074712,-0.9998819231987,0.0134406192228198,-0.0106544271111488,-0.99988067150116,0.0111874593421817,-0.0105106672272086,-0.999880790710449,0.011308298446238,-0.00468478258699179,-0.999880492687225,0.0147296776995063,-0.00487618381157517,-0.99988067150116,0.0146555285900831,-0.00744548859074712,-0.9998819231987,0.0134406192228198,-0.00714085716754198,-0.9998819231987,0.0135983293876052,0.000491964456159621,-0.999879121780396,0.0155425565317273,0.000319064332870767,-0.99987918138504,0.0155375516042113,-0.00268747773952782,-0.999879896640778,0.0152616528794169,-0.00248113460838795,-0.999879896640778,0.0152970626950264,0.0105108851566911,-0.999880731105804,0.0113096628338099, +0.0106547428295016,-0.999880611896515,0.0111887147650123,0.00744556356221437,-0.9998819231987,0.0134416632354259,0.00714113004505634,-0.999881982803345,0.013599039055407,0.00468466011807323,-0.999880492687225,0.0147288199514151,0.00487630348652601,-0.999880611896515,0.0146546727046371,0.00268623768351972,-0.999879837036133,0.0152615616098046,0.00247988430783153,-0.999879896640778,0.0152971195057034,0.69258052110672,0.066249705851078,-0.718291759490967,0.702093660831451,0.00159587385132909,-0.712082743644714,0.702259421348572,-0.00075539801036939,-0.711920738220215,0.702674746513367,-0.00134213594719768,-0.711509943008423,0.70261937379837,-0.00126389553770423,-0.711564660072327,0.672602593898773,0.0576497130095959,-0.737754821777344,0.492509990930557,0.684213042259216,-0.537853479385376,0.45127934217453,0.707483410835266,-0.543887794017792,0.451279312372208,0.707483410835266,-0.543888032436371,0.673727691173553,0.00137309439014643,-0.738978266716003,0.672602593898773,0.0576497130095959,-0.737754821777344,0.638820946216583,4.4055873331672e-006,-0.769355297088623,0.638820946216583,4.40559188064071e-006,-0.769355297088623,0.673698425292969,8.80851894180523e-006,-0.739006280899048,-0.692579448223114,0.0662549734115601,-0.718292355537415,-0.452041566371918,0.691643595695496,-0.56328272819519,-0.444331377744675,0.702116191387177,-0.556419253349304,-0.355361133813858,0.673891007900238,-0.647757112979889,-0.355662167072296,0.674020230770111,-0.647457301616669,-0.492179602384567,0.686401307582855,-0.53536182641983,-0.492512315511703,0.684202611446381,-0.537864506244659,-0.444331377744675,0.702116191387177,-0.556419253349304,-0.452041566371918,0.691643595695496,-0.56328272819519,-0.489418894052505,0.689913988113403,-0.533373892307281,-0.383498281240463,0.68536388874054,-0.619035661220551,-0.383498340845108,0.685363948345184,-0.619035661220551,-0.338924586772919,0.687195122241974,-0.64256751537323,-0.338918298482895,0.687195181846619,-0.642570674419403,-0.338918298482895,0.687195181846619,-0.642570674419403,-0.338924586772919,0.687195122241974,-0.64256751537323, +-0.162948578596115,0.687391817569733,-0.707771182060242,-0.162462383508682,0.687392234802246,-0.707882642745972,0.365432262420654,0.719523131847382,0.590546727180481,0.365432322025299,0.719523191452026,0.590546786785126,0.32150587439537,0.721647083759308,0.613073706626892,0.321797013282776,0.721638798713684,0.612930595874786,0.321797013282776,0.721638798713684,0.612930595874786,0.32150587439537,0.721647083759308,0.613073706626892,0.138442024588585,0.721792697906494,0.678121566772461,0.138806313276291,0.721792578697205,0.67804741859436,-0.162462383508682,0.687392234802246,-0.707882642745972,-0.162948578596115,0.687391817569733,-0.707771182060242,-0.0402094908058643,0.68602728843689,-0.726463735103607,-0.0399280115962029,0.686027407646179,-0.726479232311249,0.138806313276291,0.721792578697205,0.67804741859436,0.138442024588585,0.721792697906494,0.678121566772461,0.0211235377937555,0.720210075378418,0.693434298038483,0.0213157050311565,0.720210492610931,0.693427920341492,-0.0399280115962029,0.686027407646179,-0.726479232311249,-0.0402094908058643,0.68602728843689,-0.726463735103607,0.0580754019320011,0.686258852481842,-0.725035071372986,0.0583713613450527,0.686259031295776,-0.725011229515076,0.0583713613450527,0.686259031295776,-0.725011229515076,0.0580754019320011,0.686258852481842,-0.725035071372986,0.179052919149399,0.686231672763824,-0.705000698566437,0.179291248321533,0.68622875213623,-0.704942882061005,0.0213157050311565,0.720210492610931,0.693427920341492,0.0211235377937555,0.720210075378418,0.693434298038483,-0.0661668032407761,0.720267534255981,0.690533518791199,-0.0659657269716263,0.720267534255981,0.690552711486816,-0.0659657269716263,0.720267534255981,0.690552711486816,-0.0661668032407761,0.720267534255981,0.690533518791199,-0.174090653657913,0.720040559768677,0.671739518642426,-0.173943772912025,0.720042645931244,0.671775221824646,0.179291248321533,0.68622875213623,-0.704942882061005,0.179052919149399,0.686231672763824,-0.705000698566437,0.256237685680389,0.686144411563873,-0.680843591690063,0.256386369466782,0.686144351959229,-0.680787742137909, +0.256386369466782,0.686144351959229,-0.680787742137909,0.256237685680389,0.686144411563873,-0.680843591690063,0.318016082048416,0.685619592666626,-0.654821634292603,0.318068236112595,0.685619652271271,-0.654796302318573,-0.173943772912025,0.720042645931244,0.671775221824646,-0.174090653657913,0.720040559768677,0.671739518642426,-0.242325529456139,0.719878375530243,0.650425493717194,-0.242199197411537,0.719878792762756,0.650471985340118,-0.242199197411537,0.719878792762756,0.650471985340118,-0.242325529456139,0.719878375530243,0.650425493717194,-0.297666609287262,0.719325721263886,0.627666294574738,-0.297616750001907,0.719325840473175,0.627689838409424,0.318068236112595,0.685619652271271,-0.654796302318573,0.318016082048416,0.685619592666626,-0.654821634292603,0.342151582241058,0.685478627681732,-0.642690539360046,0.342131197452545,0.685478687286377,-0.64270144701004,-0.297616750001907,0.719325840473175,0.627689838409424,-0.297666609287262,0.719325721263886,0.627666294574738,-0.320342540740967,0.719149827957153,0.616606831550598,-0.320324659347534,0.719149887561798,0.616616070270538,0.342131197452545,0.685478687286377,-0.64270144701004,0.342151582241058,0.685478627681732,-0.642690539360046,0.340912818908691,0.685494065284729,-0.643332064151764,0.340912759304047,0.685494065284729,-0.643332123756409,-0.320324659347534,0.719149887561798,0.616616070270538,-0.320342540740967,0.719149827957153,0.616606831550598,-0.31976056098938,0.719134509563446,0.616926729679108,-0.31976056098938,0.719134569168091,0.616926729679108,0.340912759304047,0.685494065284729,-0.643332123756409,0.340912818908691,0.685494065284729,-0.643332064151764,0.320244610309601,0.685579359531403,-0.653776943683624,0.320227265357971,0.685579299926758,-0.653785407543182,-0.31976056098938,0.719134569168091,0.616926729679108,-0.31976056098938,0.719134509563446,0.616926729679108,-0.300814151763916,0.719200074672699,0.626308083534241,-0.300814241170883,0.719200134277344,0.626308143138886,0.320227265357971,0.685579299926758,-0.653785407543182,0.320244610309601,0.685579359531403,-0.653776943683624, +0.282692462205887,0.685693264007568,-0.670752942562103,0.282672554254532,0.685693323612213,-0.670761406421661,-0.300814241170883,0.719200134277344,0.626308143138886,-0.300814151763916,0.719200074672699,0.626308083534241,-0.265767216682434,0.719316244125366,0.641834676265717,-0.265794187784195,0.719316244125366,0.641823530197144,0.282672554254532,0.685693323612213,-0.670761406421661,0.282692462205887,0.685693264007568,-0.670752942562103,0.22958716750145,0.685834527015686,-0.690594434738159,0.229568511247635,0.685834527015686,-0.690600514411926,-0.265794187784195,0.719316244125366,0.641823530197144,-0.265767216682434,0.719316244125366,0.641834676265717,-0.215921372175217,0.719452500343323,0.66012567281723,-0.215948820114136,0.719452500343323,0.660116732120514,0.229568511247635,0.685834527015686,-0.690600514411926,0.22958716750145,0.685834527015686,-0.690594434738159,0.162498667836189,0.685973882675171,-0.709248781204224,0.162483796477318,0.685973882675171,-0.709252178668976,-0.215948820114136,0.719452500343323,0.660116732120514,-0.215921372175217,0.719452500343323,0.66012567281723,-0.152828946709633,0.719589054584503,0.677373468875885,-0.152851581573486,0.719589114189148,0.67736828327179,0.162483796477318,0.685973882675171,-0.709252178668976,0.162498667836189,0.685973882675171,-0.709248781204224,0.084364153444767,0.686083495616913,-0.722614645957947,0.0843560323119164,0.686083495616913,-0.722615599632263,-0.152851581573486,0.719589114189148,0.67736828327179,-0.152828946709633,0.719589054584503,0.677373468875885,-0.0793238133192062,0.719706952571869,0.689731538295746,-0.0793369337916374,0.719706892967224,0.689730048179626,0.0843560323119164,0.686083495616913,-0.722615599632263,0.084364153444767,0.686083495616913,-0.722614645957947,-2.88596851305556e-007,0.686125338077545,-0.72748327255249,-2.38546874697931e-007,0.6861252784729,-0.72748327255249,-0.0793369337916374,0.719706892967224,0.689730048179626,-0.0793238133192062,0.719706952571869,0.689731538295746,9.44135081226705e-007,0.719751358032227,0.694231867790222,8.24454048142798e-007,0.719751358032227,0.694231748580933, +-2.38546874697931e-007,0.6861252784729,-0.72748327255249,-2.88596851305556e-007,0.686125338077545,-0.72748327255249,-0.084365613758564,0.686079919338226,-0.722617864608765,-0.0843574106693268,0.686079919338226,-0.722618877887726,8.24454048142798e-007,0.719751358032227,0.694231748580933,9.44135081226705e-007,0.719751358032227,0.694231867790222,0.0793255418539047,0.719706416130066,0.689731895923615,0.0793384239077568,0.719706356525421,0.689730405807495,-0.0843574106693268,0.686079919338226,-0.722618877887726,-0.084365613758564,0.686079919338226,-0.722617864608765,-0.162500694394112,0.685973465442657,-0.709248781204224,-0.162485763430595,0.685973465442657,-0.709252178668976,0.0793384239077568,0.719706356525421,0.689730405807495,0.0793255418539047,0.719706416130066,0.689731895923615,0.152832329273224,0.719600915908813,0.677360057830811,0.152854770421982,0.719600856304169,0.677354991436005,-0.162485763430595,0.685973465442657,-0.709252178668976,-0.162500694394112,0.685973465442657,-0.709248781204224,-0.229590386152267,0.685838460922241,-0.690589427947998,-0.22957170009613,0.685838520526886,-0.69059556722641,0.152854770421982,0.719600856304169,0.677354991436005,0.152832329273224,0.719600915908813,0.677360057830811,0.215923085808754,0.719459056854248,0.660117924213409,0.215950459241867,0.719459056854248,0.660108983516693,-0.22957170009613,0.685838520526886,-0.69059556722641,-0.229590386152267,0.685838460922241,-0.690589427947998,-0.282696217298508,0.685694098472595,-0.670750617980957,-0.282676160335541,0.685694098472595,-0.670759081840515,0.215950459241867,0.719459056854248,0.660108983516693,0.215923085808754,0.719459056854248,0.660117924213409,0.265764862298965,0.719314634799957,0.641837537288666,0.265791684389114,0.719314575195313,0.641826510429382,-0.282676160335541,0.685694098472595,-0.670759081840515,-0.282696217298508,0.685694098472595,-0.670750617980957,-0.320244997739792,0.685571670532227,-0.653784811496735,-0.32022762298584,0.685571551322937,-0.653793275356293,0.265791684389114,0.719314575195313,0.641826510429382, +0.265764862298965,0.719314634799957,0.641837537288666,0.300814002752304,0.719201803207397,0.626306176185608,0.300814002752304,0.719201982021332,0.626306176185608,-0.32022762298584,0.685571551322937,-0.653793275356293,-0.320244997739792,0.685571670532227,-0.653784811496735,-0.340912669897079,0.685487031936646,-0.64333963394165,-0.340912669897079,0.68548709154129,-0.643339693546295,0.300814002752304,0.719201982021332,0.626306176185608,0.300814002752304,0.719201803207397,0.626306176185608,0.319761753082275,0.719135463237762,0.616925060749054,0.319761782884598,0.719135463237762,0.616925120353699,-0.340912669897079,0.68548709154129,-0.643339693546295,-0.340912669897079,0.685487031936646,-0.64333963394165,-0.342153310775757,0.685474991798401,-0.642693638801575,-0.342132925987244,0.685474991798401,-0.642704427242279,0.319761782884598,0.719135463237762,0.616925120353699,0.319761753082275,0.719135463237762,0.616925060749054,0.320341855287552,0.719149351119995,0.616607844829559,0.320323973894119,0.719149351119995,0.61661696434021,-0.342132925987244,0.685474991798401,-0.642704427242279,-0.342153310775757,0.685474991798401,-0.642693638801575,-0.318023294210434,0.68562126159668,-0.654816448688507,-0.318075388669968,0.685621201992035,-0.654791176319122,0.320323973894119,0.719149351119995,0.61661696434021,0.320341855287552,0.719149351119995,0.616607844829559,0.297664821147919,0.719327211380005,0.627665519714355,0.297614902257919,0.719327330589294,0.627689003944397,-0.318075388669968,0.685621201992035,-0.654791176319122,-0.318023294210434,0.68562126159668,-0.654816448688507,-0.256243616342545,0.686142086982727,-0.680843710899353,-0.256393074989319,0.686141967773438,-0.680787444114685,0.297614902257919,0.719327330589294,0.627689003944397,0.297664821147919,0.719327211380005,0.627665519714355,0.242323637008667,0.719872057437897,0.65043318271637,0.242197304964066,0.719872415065765,0.650479733943939,-0.256393074989319,0.686141967773438,-0.680787444114685,-0.256243616342545,0.686142086982727,-0.680843710899353,-0.179055020213127,0.686225235462189,-0.70500648021698, +-0.179293647408485,0.686222314834595,-0.704948663711548,0.242197304964066,0.719872415065765,0.650479733943939,0.242323637008667,0.719872057437897,0.65043318271637,0.174084365367889,0.720028698444366,0.671753764152527,0.173938184976578,0.720030784606934,0.671789407730103,-0.179293647408485,0.686222314834595,-0.704948663711548,-0.179055020213127,0.686225235462189,-0.70500648021698,-0.0580752529203892,0.686269223690033,-0.725025296211243,-0.0583709292113781,0.686269402503967,-0.725001454353333,0.173938184976578,0.720030784606934,0.671789407730103,0.174084365367889,0.720028698444366,0.671753764152527,0.0661780834197998,0.72026002407074,0.690540373325348,0.065977044403553,0.72026002407074,0.690559446811676,-0.0583709292113781,0.686269402503967,-0.725001454353333,-0.0580752529203892,0.686269223690033,-0.725025296211243,0.0401956140995026,0.68602591753006,-0.726465821266174,0.0399142876267433,0.686026096343994,-0.726481199264526,0.065977044403553,0.72026002407074,0.690559446811676,0.0661780834197998,0.72026002407074,0.690540373325348,-0.0211333427578211,0.720214307308197,0.69342964887619,-0.0213255565613508,0.720214784145355,0.693423211574554,0.0399142876267433,0.686026096343994,-0.726481199264526,0.0401956140995026,0.68602591753006,-0.726465821266174,0.16287662088871,0.687505722045898,-0.707677125930786,0.162391528487206,0.687505304813385,-0.70778900384903,0.162391528487206,0.687505304813385,-0.70778900384903,0.16287662088871,0.687505722045898,-0.707677125930786,0.339071542024612,0.687274038791656,-0.642405331134796,0.338742852210999,0.687281608581543,-0.642570734024048,-0.0213255565613508,0.720214784145355,0.693423211574554,-0.0211333427578211,0.720214307308197,0.69342964887619,-0.138489559292793,0.721896827220917,0.67800110578537,-0.138850584626198,0.721897065639496,0.677926957607269,-0.138850584626198,0.721897065639496,0.677926957607269,-0.138489559292793,0.721896827220917,0.67800110578537,-0.321610242128372,0.721701502799988,0.612954914569855,-0.32161009311676,0.721701502799988,0.612955033779144,0.383515685796738,0.685370922088623,-0.61901718378067, +0.383515685796738,0.685370981693268,-0.61901718378067,0.338742852210999,0.687281608581543,-0.642570734024048,0.339071542024612,0.687274038791656,-0.642405331134796,-0.365410685539246,0.719522297382355,0.590561151504517,-0.365410715341568,0.719522297382355,0.590561151504517,-0.32161009311676,0.721701502799988,0.612955033779144,-0.321610242128372,0.721701502799988,0.612954914569855,0.0131631745025516,0.999333202838898,-0.0340579077601433,0.0126317422837019,0.99933385848999,-0.0342398285865784,0.015389365144074,0.999327003955841,-0.0332957096397877,0.0153893642127514,0.999327003955841,-0.033295713365078,-0.460911393165588,-0.0015001556603238,0.887444853782654,-0.460845828056335,-0.00150016788393259,0.88747900724411,-0.52176171541214,-0.00148511060979217,0.853089928627014,-0.521761655807495,-0.00148511037696153,0.853089928627014,0.47009265422821,-0.0242825504392385,-0.882282912731171,0.470315217971802,-0.0242821630090475,-0.882164418697357,0.529598116874695,-0.024118160828948,-0.847905576229095,0.529598116874695,-0.0241181626915932,-0.84790563583374,-0.0131643153727055,0.999333143234253,-0.0340595357120037,-0.0153902359306812,0.999326884746552,-0.0332980714738369,-0.0153902349993587,0.999326825141907,-0.0332980677485466,-0.0126328654587269,0.999333798885345,-0.0342413075268269,0.460884869098663,-0.00148310395888984,0.887458622455597,0.521760523319244,-0.00148593739140779,0.853090643882751,0.5217604637146,-0.00148593727499247,0.853090584278107,0.460872918367386,-0.00148310279473662,0.887464880943298,-0.529596745967865,-0.0241164900362492,-0.847906589508057,-0.529596745967865,-0.0241164918988943,-0.847906589508057,-0.470346659421921,-0.0242615062743425,-0.882148087024689,-0.470063239336014,-0.024261923506856,-0.882299244403839,-0.00376740307547152,0.999321699142456,-0.0366325415670872,-0.00286277197301388,0.999319493770599,-0.0367751084268093,0.00312694348394871,0.999315798282623,-0.0368516109883785,0.00262344162911177,0.999313712120056,-0.0369480066001415,0.195184916257858,-0.0014299291651696,0.980765402317047,0.195183932781219,-0.00142992869950831,0.980765461921692, +0.0253604594618082,-0.00139178044628352,0.999677360057831,0.0253602173179388,-0.00139178044628352,0.999677360057831,-0.22788493335247,-0.0242961775511503,-0.973384857177734,-0.228314444422722,-0.0242962781339884,-0.973284184932709,-0.0589788295328617,-0.0242542717605829,-0.99796450138092,-0.0587277039885521,-0.0242546051740646,-0.997979283332825,0.00719420751556754,0.999327301979065,-0.0359572172164917,0.00764755439013243,0.999328017234802,-0.0358454324305058,0.0128326592966914,0.999336004257202,-0.0340977013111115,0.0125016625970602,0.999335765838623,-0.034229651093483,-0.0999671965837479,-0.00137442408595234,0.99498975276947,-0.0999697670340538,-0.00137442362029105,0.994989395141602,-0.254808723926544,-0.00134705530945212,0.96699047088623,-0.254807084798813,-0.0013470557751134,0.966990947723389,0.0764444246888161,-0.0243818759918213,-0.99677562713623,0.0761941745877266,-0.0243817735463381,-0.996794819831848,0.242582231760025,-0.0244307331740856,-0.969823062419891,0.242784962058067,-0.0244306679815054,-0.969772458076477,0.0125016625970602,0.999335765838623,-0.034229651093483,0.0128326592966914,0.999336004257202,-0.0340977013111115,0.0158067941665649,0.999346613883972,-0.0325015783309937,0.0156991463154554,0.999346196651459,-0.0325697809457779,-0.254807084798813,-0.0013470557751134,0.966990947723389,-0.254808723926544,-0.00134705530945212,0.96699047088623,-0.352188467979431,-0.00133378047030419,0.935928165912628,-0.352180182933807,-0.00133378128521144,0.935931205749512,0.242784962058067,-0.0244306679815054,-0.969772458076477,0.242582231760025,-0.0244307331740856,-0.969823062419891,0.349012762308121,-0.0245249420404434,-0.936796903610229,0.349080473184586,-0.0245250444859266,-0.936771750450134,0.0156991463154554,0.999346196651459,-0.0325697809457779,0.0158067941665649,0.999346613883972,-0.0325015783309937,0.0180271118879318,0.999356627464294,-0.0310048777610064,0.0180081818252802,0.99935644865036,-0.0310193449258804,-0.352180182933807,-0.00133378128521144,0.935931205749512,-0.352188467979431,-0.00133378047030419,0.935928165912628, +-0.43111976981163,-0.00132315163500607,0.902293682098389,-0.431115567684174,-0.001323152333498,0.902295768260956,0.349080473184586,-0.0245250444859266,-0.936771750450134,0.349012762308121,-0.0245249420404434,-0.936796903610229,0.43428310751915,-0.0246105510741472,-0.900440216064453,0.434295833110809,-0.024610560387373,-0.900433957576752,0.0180081818252802,0.99935644865036,-0.0310193449258804,0.0180271118879318,0.999356627464294,-0.0310048777610064,0.0187046583741903,0.999361515045166,-0.0304397344589233,0.0187044516205788,0.999361515045166,-0.0304401498287916,-0.431115567684174,-0.001323152333498,0.902295768260956,-0.43111976981163,-0.00132315163500607,0.902293682098389,-0.463271737098694,-0.00131704576779157,0.886215269565582,-0.463270574808121,-0.00131704588420689,0.88621574640274,0.434295833110809,-0.024610560387373,-0.900433957576752,0.43428310751915,-0.0246105510741472,-0.900440216064453,0.467806398868561,-0.0246429499238729,-0.883487403392792,0.467806607484818,-0.0246429461985826,-0.883487045764923,0.0187044516205788,0.999361515045166,-0.0304401498287916,0.0187046583741903,0.999361515045166,-0.0304397344589233,0.0183111783117056,0.999363839626312,-0.030603151768446,0.0183082558214664,0.999363839626312,-0.0306047648191452,-0.463270574808121,-0.00131704588420689,0.88621574640274,-0.463271737098694,-0.00131704576779157,0.886215269565582,-0.462133705615997,-0.00131395109929144,0.886809110641479,-0.46213698387146,-0.00131395133212209,0.886807382106781,0.467806607484818,-0.0246429461985826,-0.883487045764923,0.467806398868561,-0.0246429499238729,-0.883487403392792,0.466500252485275,-0.0246493443846703,-0.884177505970001,0.466500133275986,-0.0246493425220251,-0.884177505970001,0.0183082558214664,0.999363839626312,-0.0306047648191452,0.0183111783117056,0.999363839626312,-0.030603151768446,0.0170473419129848,0.999364912509918,-0.0312883779406548,0.0170355159789324,0.999364972114563,-0.0312947332859039,-0.46213698387146,-0.00131395133212209,0.886807382106781,-0.462133705615997,-0.00131395109929144,0.886809110641479,-0.434638142585754,-0.00131313630845398,0.90060418844223, +-0.434645384550095,-0.00131313619203866,0.900600671768188,0.466500133275986,-0.0246493425220251,-0.884177505970001,0.466500252485275,-0.0246493443846703,-0.884177505970001,0.43844810128212,-0.0246416572481394,-0.898418545722961,0.438455283641815,-0.0246416609734297,-0.898415088653564,0.0170355159789324,0.999364972114563,-0.0312947332859039,0.0170473419129848,0.999364912509918,-0.0312883779406548,0.0149852689355612,0.999365508556366,-0.0323123820126057,0.0149642154574394,0.999365389347076,-0.0323222279548645,-0.434645384550095,-0.00131313619203866,0.900600671768188,-0.434638142585754,-0.00131313630845398,0.90060418844223,-0.384021282196045,-0.00131650688126683,0.923323214054108,-0.384024977684021,-0.00131650664843619,0.923321723937988,0.438455283641815,-0.0246416609734297,-0.898415088653564,0.43844810128212,-0.0246416572481394,-0.898418545722961,0.387191861867905,-0.0246272254735231,-0.921670138835907,0.387204706668854,-0.0246272329241037,-0.921664774417877,0.0149642154574394,0.999365389347076,-0.0323222279548645,0.0149852689355612,0.999365508556366,-0.0323123820126057,0.0121525842696428,0.999365389347076,-0.0334807820618153,0.0121258422732353,0.999365389347076,-0.0334906280040741,-0.384024977684021,-0.00131650664843619,0.923321723937988,-0.384021282196045,-0.00131650688126683,0.923323214054108,-0.312054842710495,-0.0013214967912063,0.950063109397888,-0.312058836221695,-0.00132149655837566,0.950061798095703,0.387204706668854,-0.0246272329241037,-0.921664774417877,0.387191861867905,-0.0246272254735231,-0.921670138835907,0.314557641744614,-0.0246115271002054,-0.948919117450714,0.31457382440567,-0.0246115326881409,-0.948913872241974,0.0121258422732353,0.999365389347076,-0.0334906280040741,0.0121525842696428,0.999365389347076,-0.0334807820618153,0.00860310904681683,0.999365329742432,-0.034568402916193,0.00857762061059475,0.999365210533142,-0.0345748588442802,-0.312058836221695,-0.00132149655837566,0.950061798095703,-0.312054842710495,-0.0013214967912063,0.950063109397888,-0.220922365784645,-0.00132442137692124,0.975290477275848, +-0.220925733447075,-0.00132442126050591,0.975289702415466,0.31457382440567,-0.0246115326881409,-0.948913872241974,0.314557641744614,-0.0246115271002054,-0.948919117450714,0.222691595554352,-0.0245956927537918,-0.974578499794006,0.222706869244576,-0.0245956983417273,-0.974575102329254,0.00857762061059475,0.999365210533142,-0.0345748588442802,0.00860310904681683,0.999365329742432,-0.034568402916193,0.00447287643328309,0.999365091323853,-0.0353453904390335,0.00445707002654672,0.999365091323853,-0.0353474207222462,-0.220925733447075,-0.00132442126050591,0.975289702415466,-0.220922365784645,-0.00132442137692124,0.975290477275848,-0.114692710340023,-0.00132638728246093,0.993400156497955,-0.114694803953171,-0.00132638728246093,0.993399858474731,0.222706869244576,-0.0245956983417273,-0.974575102329254,0.222691595554352,-0.0245956927537918,-0.974578499794006,0.115630611777306,-0.0245844181627035,-0.992987930774689,0.115640066564083,-0.0245844163000584,-0.992986857891083,0.00445707002654672,0.999365091323853,-0.0353474207222462,0.00447287643328309,0.999365091323853,-0.0353453904390335,-1.9959877306519e-008,0.999365091323853,-0.0356280356645584,-2.55647432112482e-008,0.999365150928497,-0.0356280393898487,-0.114694803953171,-0.00132638728246093,0.993399858474731,-0.114692710340023,-0.00132638728246093,0.993400156497955,7.60219336370938e-007,-0.00132701348047704,0.999999046325684,5.23635890203877e-007,-0.00132701324764639,0.999998986721039,0.115640066564083,-0.0245844163000584,-0.992986857891083,0.115630611777306,-0.0245844181627035,-0.992987930774689,-5.94260257003043e-007,-0.0245804917067289,-0.999697864055634,-5.11501411892823e-007,-0.0245804879814386,-0.999697804450989,-2.55647432112482e-008,0.999365150928497,-0.0356280393898487,-1.9959877306519e-008,0.999365091323853,-0.0356280356645584,-0.00447338819503784,0.999364972114563,-0.0353463552892208,-0.00445759017020464,0.999365091323853,-0.0353483855724335,5.23635890203877e-007,-0.00132701324764639,0.999998986721039,7.60219336370938e-007,-0.00132701348047704,0.999999046325684, +0.114693880081177,-0.00132633664179593,0.993399918079376,0.11469554156065,-0.00132633652538061,0.993399739265442,-5.11501411892823e-007,-0.0245804879814386,-0.999697804450989,-5.94260257003043e-007,-0.0245804917067289,-0.999697864055634,-0.115631923079491,-0.0245840959250927,-0.992987811565399,-0.115641176700592,-0.0245840977877378,-0.992986738681793,-0.00445759017020464,0.999365091323853,-0.0353483855724335,-0.00447338819503784,0.999364972114563,-0.0353463552892208,-0.00860353372991085,0.999365210533142,-0.0345694310963154,-0.00857806019484997,0.999365150928497,-0.0345758944749832,0.11469554156065,-0.00132633652538061,0.993399739265442,0.114693880081177,-0.00132633664179593,0.993399918079376,0.220923021435738,-0.00132473604753613,0.975290358066559,0.22092604637146,-0.00132473604753613,0.975289702415466,-0.115641176700592,-0.0245840977877378,-0.992986738681793,-0.115631923079491,-0.0245840959250927,-0.992987811565399,-0.222693011164665,-0.0245950035750866,-0.974578261375427,-0.222708120942116,-0.024595009163022,-0.97457492351532,-0.00857806019484997,0.999365150928497,-0.0345758944749832,-0.00860353372991085,0.999365210533142,-0.0345694310963154,-0.0121529549360275,0.999365389347076,-0.0334810242056847,-0.01212621293962,0.999365448951721,-0.0334908738732338,0.22092604637146,-0.00132473604753613,0.975289702415466,0.220923021435738,-0.00132473604753613,0.975290358066559,0.312055915594101,-0.00132230448070914,0.95006275177002,0.312059581279755,-0.00132230448070914,0.950061559677124,-0.222708120942116,-0.024595009163022,-0.97457492351532,-0.222693011164665,-0.0245950035750866,-0.974578261375427,-0.314557820558548,-0.0246100202202797,-0.948919177055359,-0.314573764801025,-0.0246100220829248,-0.948913931846619,-0.01212621293962,0.999365448951721,-0.0334908738732338,-0.0121529549360275,0.999365389347076,-0.0334810242056847,-0.0149861099198461,0.999365389347076,-0.0323134325444698,-0.0149650610983372,0.999365448951721,-0.0323232747614384,0.312059581279755,-0.00132230448070914,0.950061559677124,0.312055915594101,-0.00132230448070914,0.95006275177002, +0.384022444486618,-0.00131748872809112,0.923322737216949,0.384026020765305,-0.00131748849526048,0.92332124710083,-0.314573764801025,-0.0246100220829248,-0.948913931846619,-0.314557820558548,-0.0246100202202797,-0.948919177055359,-0.38719242811203,-0.0246253795921803,-0.921670079231262,-0.387205064296722,-0.0246253814548254,-0.921664655208588,-0.0149650610983372,0.999365448951721,-0.0323232747614384,-0.0149861099198461,0.999365389347076,-0.0323134325444698,-0.0170477982610464,0.999364972114563,-0.0312885195016861,-0.0170359797775745,0.999364972114563,-0.0312948934733868,0.384026020765305,-0.00131748849526048,0.92332124710083,0.384022444486618,-0.00131748872809112,0.923322737216949,0.434638351202011,-0.00131459441035986,0.900604069232941,0.434645563364029,-0.0013145946431905,0.900600552558899,-0.387205064296722,-0.0246253814548254,-0.921664655208588,-0.38719242811203,-0.0246253795921803,-0.921670079231262,-0.43844872713089,-0.024639330804348,-0.898418307304382,-0.438455790281296,-0.0246393345296383,-0.898414790630341,-0.0170359797775745,0.999364972114563,-0.0312948934733868,-0.0170477982610464,0.999364972114563,-0.0312885195016861,-0.0183112397789955,0.999363780021667,-0.030601654201746,-0.0183083191514015,0.999363839626312,-0.0306032691150904,0.434645563364029,-0.0013145946431905,0.900600552558899,0.434638351202011,-0.00131459441035986,0.900604069232941,0.462134152650833,-0.00131517648696899,0.88680899143219,0.462137460708618,-0.00131517683621496,0.886807322502136,-0.438455790281296,-0.0246393345296383,-0.898414790630341,-0.43844872713089,-0.024639330804348,-0.898418307304382,-0.466499716043472,-0.0246468484401703,-0.88417786359787,-0.466499507427216,-0.0246468484401703,-0.884177923202515,-0.0183083191514015,0.999363839626312,-0.0306032691150904,-0.0183112397789955,0.999363780021667,-0.030601654201746,-0.0187042988836765,0.999361574649811,-0.0304380990564823,-0.0187040884047747,0.999361574649811,-0.0304385125637054,0.462137460708618,-0.00131517683621496,0.886807322502136,0.462134152650833,-0.00131517648696899,0.88680899143219, +0.463272273540497,-0.00131704297382385,0.886214971542358,0.463271230459213,-0.00131704343948513,0.886215627193451,-0.466499507427216,-0.0246468484401703,-0.884177923202515,-0.466499716043472,-0.0246468484401703,-0.88417786359787,-0.467806994915009,-0.0246409345418215,-0.883487045764923,-0.467807292938232,-0.0246409326791763,-0.883486747741699,-0.0187040884047747,0.999361574649811,-0.0304385125637054,-0.0187042988836765,0.999361574649811,-0.0304380990564823,-0.0180262289941311,0.999356687068939,-0.0310027878731489,-0.0180072914808989,0.999356508255005,-0.0310172438621521,0.463271230459213,-0.00131704343948513,0.886215627193451,0.463272273540497,-0.00131704297382385,0.886214971542358,0.431119650602341,-0.00132260541431606,0.902293741703033,0.431115508079529,-0.00132260611280799,0.902295827865601,-0.467807292938232,-0.0246409326791763,-0.883486747741699,-0.467806994915009,-0.0246409345418215,-0.883487045764923,-0.434283167123795,-0.024608762934804,-0.900440096855164,-0.434296250343323,-0.0246087852865458,-0.900433838367462,-0.0180072914808989,0.999356508255005,-0.0310172438621521,-0.0180262289941311,0.999356687068939,-0.0310027878731489,-0.0158059261739254,0.999346673488617,-0.0325006693601608,-0.0156982764601707,0.999346137046814,-0.032568983733654,0.431115508079529,-0.00132260611280799,0.902295827865601,0.431119650602341,-0.00132260541431606,0.902293741703033,0.352187633514404,-0.00133318325970322,0.935928404331207,0.352179825305939,-0.00133318407461047,0.935931324958801,-0.434296250343323,-0.0246087852865458,-0.900433838367462,-0.434283167123795,-0.024608762934804,-0.900440096855164,-0.349011093378067,-0.0245229639112949,-0.936797618865967,-0.349079012870789,-0.024523064494133,-0.936772286891937,-0.0156982764601707,0.999346137046814,-0.032568983733654,-0.0158059261739254,0.999346673488617,-0.0325006693601608,-0.0128314904868603,0.999336063861847,-0.0340994633734226,-0.0125004034489393,0.999335706233978,-0.0342316552996635,0.352179825305939,-0.00133318407461047,0.935931324958801,0.352187633514404,-0.00133318325970322,0.935928404331207, +0.254807651042938,-0.00134640850592405,0.966990649700165,0.254805713891983,-0.0013464093208313,0.966991364955902,-0.349079012870789,-0.024523064494133,-0.936772286891937,-0.349011093378067,-0.0245229639112949,-0.936797618865967,-0.242581218481064,-0.0244281105697155,-0.96982342004776,-0.242784574627876,-0.0244280435144901,-0.969772636890411,-0.00719341542571783,0.99932724237442,-0.0359595641493797,-0.00764655787497759,0.999328017234802,-0.0358480922877789,-0.00312637072056532,0.999315857887268,-0.0368501283228397,-0.00262271333485842,0.999313831329346,-0.0369459018111229,0.0999695733189583,-0.00137380301021039,0.994989573955536,0.0999707505106926,-0.00137380277737975,0.994989395141602,-0.0253609754145145,-0.00139124237466604,0.999677240848541,-0.0253613106906414,-0.00139124237466604,0.999677300453186,-0.0764440819621086,-0.0243785437196493,-0.996775686740875,-0.0761935859918594,-0.0243784338235855,-0.996794879436493,0.0589798465371132,-0.024250665679574,-0.997964441776276,0.058727853000164,-0.0242510046809912,-0.997979402542114,0.00376733532175422,0.999321758747101,-0.0366305820643902,0.00286316918209195,0.999319493770599,-0.036772582679987,0.0126317422837019,0.99933385848999,-0.0342398285865784,0.0131631745025516,0.999333202838898,-0.0340579077601433,-0.195252671837807,-0.00146022799890488,0.980751812458038,-0.195247769355774,-0.00146022567059845,0.980752825737,-0.460845828056335,-0.00150016788393259,0.88747900724411,-0.460911393165588,-0.0015001556603238,0.887444853782654,0.227837592363358,-0.0243255347013474,-0.973395168781281,0.228268876671791,-0.0243257712572813,-0.973294138908386,0.470315217971802,-0.0242821630090475,-0.882164418697357,0.47009265422821,-0.0242825504392385,-0.882282912731171,-0.00262271333485842,0.999313831329346,-0.0369459018111229,-0.00312637072056532,0.999315857887268,-0.0368501283228397,0.00286316918209195,0.999319493770599,-0.036772582679987,0.00376733532175422,0.999321758747101,-0.0366305820643902,-0.0253613106906414,-0.00139124237466604,0.999677300453186,-0.0253609754145145,-0.00139124237466604,0.999677240848541, +-0.195247769355774,-0.00146022567059845,0.980752825737,-0.195252671837807,-0.00146022799890488,0.980751812458038,0.058727853000164,-0.0242510046809912,-0.997979402542114,0.0589798465371132,-0.024250665679574,-0.997964441776276,0.228268876671791,-0.0243257712572813,-0.973294138908386,0.227837592363358,-0.0243255347013474,-0.973395168781281,-0.0125004034489393,0.999335706233978,-0.0342316552996635,-0.0128314904868603,0.999336063861847,-0.0340994633734226,-0.00764655787497759,0.999328017234802,-0.0358480922877789,-0.00719341542571783,0.99932724237442,-0.0359595641493797,0.254805713891983,-0.0013464093208313,0.966991364955902,0.254807651042938,-0.00134640850592405,0.966990649700165,0.0999707505106926,-0.00137380277737975,0.994989395141602,0.0999695733189583,-0.00137380301021039,0.994989573955536,-0.242784574627876,-0.0244280435144901,-0.969772636890411,-0.242581218481064,-0.0244281105697155,-0.96982342004776,-0.0761935859918594,-0.0243784338235855,-0.996794879436493,-0.0764440819621086,-0.0243785437196493,-0.996775686740875,-0.0131643153727055,0.999333143234253,-0.0340595357120037,-0.0126328654587269,0.999333798885345,-0.0342413075268269,-0.00286277197301388,0.999319493770599,-0.0367751084268093,-0.00376740307547152,0.999321699142456,-0.0366325415670872,0.460884869098663,-0.00148310395888984,0.887458622455597,0.460872918367386,-0.00148310279473662,0.887464880943298,0.195183932781219,-0.00142992869950831,0.980765461921692,0.195184916257858,-0.0014299291651696,0.980765402317047,-0.470063239336014,-0.024261923506856,-0.882299244403839,-0.470346659421921,-0.0242615062743425,-0.882148087024689,-0.228314444422722,-0.0242962781339884,-0.973284184932709,-0.22788493335247,-0.0242961775511503,-0.973384857177734,0.00262344162911177,0.999313712120056,-0.0369480066001415,0.00312694348394871,0.999315798282623,-0.0368516109883785,0.00764755439013243,0.999328017234802,-0.0358454324305058,0.00719420751556754,0.999327301979065,-0.0359572172164917,0.0253602173179388,-0.00139178044628352,0.999677360057831,0.0253604594618082,-0.00139178044628352,0.999677360057831, +-0.0999697670340538,-0.00137442362029105,0.994989395141602,-0.0999671965837479,-0.00137442408595234,0.99498975276947,-0.0587277039885521,-0.0242546051740646,-0.997979283332825,-0.0589788295328617,-0.0242542717605829,-0.99796450138092,0.0761941745877266,-0.0243817735463381,-0.996794819831848,0.0764444246888161,-0.0243818759918213,-0.99677562713623,0.702093660831451,0.00159587385132909,-0.712082743644714,0.69258052110672,0.066249705851078,-0.718291759490967,0.45203822851181,0.691637694835663,-0.563292682170868,0.48941445350647,0.689920663833618,-0.533369302749634,0.492175161838531,0.686408638954163,-0.535356521606445,0.492509990930557,0.684213042259216,-0.537853479385376,0.672602593898773,0.0576497130095959,-0.737754821777344,0.673727691173553,0.00137309439014643,-0.738978266716003,-0.489418894052505,0.689913988113403,-0.533373892307281,-0.452041566371918,0.691643595695496,-0.56328272819519,-0.692579448223114,0.0662549734115601,-0.718292355537415,-0.70209139585495,0.00159979064483196,-0.712084889411926,-0.673727691173553,0.00137342023663223,-0.738978266716003,-0.672601997852325,0.0576485246419907,-0.737755477428436,-0.492512315511703,0.684202611446381,-0.537864506244659,-0.492179602384567,0.686401307582855,-0.53536182641983 + } + NormalsW: *4196 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *3396 { + a: 0.674125075340271,0.73811537027359,0.67329478263855,0.7376469373703,0.680572211742401,0.723486304283142,0.681468546390533,0.723825216293335,0.665161728858948,0.748410165309906,0.664431989192963,0.747825562953949,0.668484508991241,0.730102598667145,0.674614429473877,0.718050956726074,0.686076104640961,0.705978870391846,0.687008619308472,0.706202030181885,0.679355502128601,0.73811537027359,0.68661892414093,0.723825216293335,0.655097723007202,0.754486441612244,0.654481589794159,0.753832817077637,0.661335051059723,0.738450407981873,0.67951625585556,0.70243626832962,0.689765155315399,0.685916900634766,0.690715432167053,0.686042666435242,0.692098259925842,0.706202030181885,0.644631266593933,0.757023751735687,0.644102811813354,0.756348788738251,0.653164148330688,0.743396639823914,0.682931542396545,0.683941125869751,0.691617608070374,0.664237141609192,0.692575097084045,0.664277672767639,0.695764005184174,0.686042666435242,0.634286344051361,0.757538020610809,0.633798241615295,0.756861388683319,0.643915235996246,0.745467901229858,0.684681713581085,0.663603901863098,0.691617608070374,0.642002046108246,0.692575097084045,0.641961574554443,0.69760262966156,0.664277672767639,0.633798241615295,0.745683908462524,0.684681713581085,0.642635345458984,0.689765155315399,0.620322227478027,0.690715372562408,0.620196580886841,0.69760262966156,0.641961574554443,0.612925827503204,0.74568384885788,0.612925827503204,0.756861448287964,0.682931542396545,0.622298061847687,0.686076164245605,0.600260257720947,0.687008500099182,0.600037157535553,0.695764005184174,0.620196580886841,0.594255030155182,0.74568384885788,0.594255030155182,0.756861448287964,0.679516196250916,0.603802978992462,0.680572271347046,0.582752764225006,0.681468427181244,0.582413971424103,0.692098200321198,0.600037157535553,0.577945172786713,0.74568384885788,0.577945172786713,0.756861448287964,0.674614250659943,0.588188350200653,0.673294961452484,0.568592011928558,0.674124896526337,0.568123817443848,0.686618804931641,0.582413971424103,0.668484330177307,0.576136887073517, +0.664432168006897,0.55841326713562,0.665161490440369,0.557829022407532,0.679355263710022,0.568123817443848,0.661334812641144,0.567789375782013,0.654481709003448,0.552405953407288,0.655097424983978,0.551752746105194,0.653163969516754,0.562843143939972,0.644102931022644,0.549890160560608,0.644631028175354,0.549215495586395,0.643915235996246,0.560771703720093,0.633798241615295,0.549377858638763,0.634286344051361,0.548701167106628,0.633798241615295,0.560555279254913,0.612925827503204,0.549377739429474,0.612925827503204,0.560555398464203,0.594255030155182,0.549377739429474,0.594255030155182,0.560555398464203,0.577945172786713,0.549377739429474,0.577945172786713,0.560555398464203,0.474232137203217,0.738327622413635,0.473399639129639,0.738792598247528,0.467349499464035,0.726740956306458,0.46824648976326,0.726403892040253,0.481182307004929,0.74655693769455,0.480450361967087,0.747140407562256,0.468588531017303,0.746337175369263,0.461391359567642,0.73217636346817,0.462508320808411,0.711126267910004,0.463440716266632,0.71090304851532,0.479462027549744,0.738327622413635,0.473396629095078,0.726403892040253,0.489117443561554,0.751430928707123,0.488503992557526,0.752086639404297,0.477352231740952,0.756515979766846,0.455948263406754,0.714668929576874,0.459133982658386,0.692631125450134,0.460084170103073,0.692504823207855,0.468530267477036,0.71090304851532,0.498137444257736,0.753481388092041,0.497617065906525,0.754157900810242,0.487185209989548,0.762523293495178,0.45230033993721,0.694606959819794,0.45740482211113,0.672293901443481,0.458362311124802,0.672253012657166,0.465132713317871,0.692504823207855,0.508071660995483,0.753696739673615,0.507576584815979,0.754373788833618,0.497444957494736,0.764092683792114,0.496852964162827,0.764897644519806,0.450468957424164,0.67292720079422,0.457404851913452,0.651325345039368,0.458362311124802,0.651366114616394,0.463389873504639,0.672253012657166,0.498111099004745,0.765073478221893,0.497801154851913,0.765624403953552,0.450468957424164,0.650692105293274,0.459134042263031,0.630988001823425,0.460084170103073, +0.631114304065704,0.463389873504639,0.651366114616394,0.452300399541855,0.629012286663055,0.462508380413055,0.612492978572845,0.46344068646431,0.61271607875824,0.465132743120193,0.631114304065704,0.455948323011398,0.60895037651062,0.467349678277969,0.596878290176392,0.468246340751648,0.597215294837952,0.468530386686325,0.612716138362885,0.461391478776932,0.591442823410034,0.473399847745895,0.5848268866539,0.474231868982315,0.585291504859924,0.473396807909012,0.597215294837952,0.468588680028915,0.577282249927521,0.480450600385666,0.576479315757751,0.481181889772415,0.577062249183655,0.479462325572968,0.585291504859924,0.477352410554886,0.567103624343872,0.488504081964493,0.571533143520355,0.489116996526718,0.572188258171082,0.487185269594193,0.561096370220184,0.497617065906525,0.569461703300476,0.498137205839157,0.570137858390808,0.497428596019745,0.55858051776886,0.507580161094666,0.569245338439941,0.508058965206146,0.569922387599945,0.507580161094666,0.558067739009857,0.72804582118988,0.737646579742432,0.72721540927887,0.738115012645721,0.719871997833252,0.723824918270111,0.720768451690674,0.723485946655273,0.736908614635468,0.74782520532608,0.736178755760193,0.748409807682037,0.721985101699829,0.738115012645721,0.7147216796875,0.723824858665466,0.714331984519959,0.706201672554016,0.715264439582825,0.705978512763977,0.732856094837189,0.730102181434631,0.726726174354553,0.718050539493561,0.746858954429626,0.753832459449768,0.746242880821228,0.75448602437973,0.740005552768707,0.738449990749359,0.709242284297943,0.706201612949371,0.710625112056732,0.686042308807373,0.711575448513031,0.685916543006897,0.72182434797287,0.702435851097107,0.757237732410431,0.756348371505737,0.756709337234497,0.757023334503174,0.748176455497742,0.743396282196045,0.705576598644257,0.686042308807373,0.70876544713974,0.664277315139771,0.709722936153412,0.664236783981323,0.718408942222595,0.683940827846527,0.76754242181778,0.756860971450806,0.767054200172424,0.757537722587585,0.757425367832184,0.74546754360199,0.703737854957581,0.664277315139771, +0.70876544713974,0.641961216926575,0.709722936153412,0.642001688480377,0.7166588306427,0.663603484630585,0.76754242181778,0.745683550834656,0.703737854957581,0.641961216926575,0.710625231266022,0.620196223258972,0.711575388908386,0.620321929454803,0.7166588306427,0.642634987831116,0.788414776325226,0.745683491230011,0.788414776325226,0.756861090660095,0.705576598644257,0.620196223258972,0.714331984519959,0.600036859512329,0.71526437997818,0.600259959697723,0.71840900182724,0.622297704219818,0.807085573673248,0.745683491230011,0.807085573673248,0.756861090660095,0.709242403507233,0.600036859512329,0.719872176647186,0.582413613796234,0.72076827287674,0.582752466201782,0.721824407577515,0.603802680969238,0.823395371437073,0.745683491230011,0.823395371437073,0.756861090660095,0.714721739292145,0.582413613796234,0.727215707302094,0.568123459815979,0.728045582771301,0.56859165430069,0.726726353168488,0.588187992572784,0.721985280513763,0.568123459815979,0.736179113388062,0.557828664779663,0.736908495426178,0.558412909507751,0.732856333255768,0.576136529445648,0.746243178844452,0.551752388477325,0.746858894824982,0.552405595779419,0.740005731582642,0.567789018154144,0.756709575653076,0.549215197563171,0.757237732410431,0.549889862537384,0.748176574707031,0.562842786312103,0.767054200172424,0.54870080947876,0.76754242181778,0.549377501010895,0.757425367832184,0.560771346092224,0.76754242181778,0.560554981231689,0.788414776325226,0.549377381801605,0.788414776325226,0.560555040836334,0.807085573673248,0.549377381801605,0.807085573673248,0.560555040836334,0.823395371437073,0.549377381801605,0.823395371437073,0.560555040836334,0.548879086971283,0.738792538642883,0.548046588897705,0.738327622413635,0.554032206535339,0.726403832435608,0.554929196834564,0.726740896701813,0.541828393936157,0.747140347957611,0.541096448898315,0.74655693769455,0.542816758155823,0.738327622413635,0.548882126808167,0.726403832435608,0.55883800983429,0.71090304851532,0.559770405292511,0.711126148700714,0.553690195083618,0.746337175369263,0.560887396335602, +0.73217636346817,0.533774733543396,0.752086639404297,0.533161282539368,0.751430928707123,0.544926464557648,0.756515920162201,0.553748488426209,0.71090304851532,0.562194526195526,0.692504823207855,0.563144743442535,0.692631125450134,0.56633049249649,0.714668929576874,0.524661660194397,0.754157900810242,0.524141252040863,0.753481388092041,0.535093545913696,0.762523233890533,0.557145953178406,0.692504823207855,0.563916444778442,0.672253012657166,0.564873874187469,0.672293901443481,0.569978415966034,0.694606900215149,0.514702141284943,0.754373788833618,0.514207005500793,0.753696739673615,0.525425732135773,0.764897644519806,0.524833798408508,0.764092683792114,0.558888852596283,0.672253012657166,0.563916444778442,0.651366114616394,0.564873874187469,0.651325345039368,0.571809828281403,0.67292720079422,0.524477541446686,0.765624344348907,0.524167656898499,0.765073418617249,0.558888852596283,0.651366114616394,0.562194585800171,0.631114304065704,0.563144683837891,0.630988001823425,0.571809768676758,0.650692105293274,0.557145953178406,0.631114304065704,0.558838069438934,0.61271607875824,0.559770345687866,0.612492978572845,0.569978356361389,0.629012286663055,0.553748369216919,0.61271607875824,0.554032385349274,0.597215294837952,0.554929077625275,0.596878290176392,0.566330432891846,0.60895037651062,0.548881947994232,0.597215294837952,0.548046886920929,0.585291564464569,0.548878848552704,0.5848268866539,0.560887277126312,0.591442883014679,0.542816400527954,0.585291564464569,0.541096806526184,0.577062249183655,0.541828155517578,0.576479375362396,0.553690016269684,0.577282249927521,0.533161699771881,0.572188258171082,0.533774614334106,0.571533143520355,0.544926285743713,0.567103683948517,0.524141550064087,0.570137858390808,0.524661660194397,0.569461703300476,0.535093426704407,0.561096370220184,0.514219641685486,0.569922387599945,0.514698445796967,0.569245338439941,0.524850130081177,0.55858051776886,0.514698445796967,0.558067739009857,0.962978482246399,0.509928226470947,0.963084995746613,0.510034739971161,0.962798714637756,0.510286748409271, +0.943281710147858,0.490231513977051,0.960986316204071,0.511882901191711,0.941963672637939,0.492860287427902,0.923792243003845,0.468970507383347,0.922319173812866,0.471433579921722,0.906229078769684,0.446089595556259,0.904604732990265,0.448355674743652,0.890727400779724,0.421764671802521,0.888956725597382,0.423801183700562,0.877405345439911,0.396180987358093,0.875497162342072,0.397953420877457,0.866364359855652,0.369533360004425,0.86433219909668,0.371006458997726,0.857688546180725,0.342024594545364,0.855551421642303,0.34316498041153,0.851443886756897,0.313864231109619,0.849226534366608,0.314642757177353,0.847678005695343,0.285266637802124,0.845410168170929,0.28566175699234,0.846419453620911,0.256449669599533,0.844134330749512,0.256449669599533,0.847678005695343,0.227632761001587,0.845410108566284,0.227237597107887,0.851443886756897,0.199035197496414,0.849226534366608,0.198256582021713,0.857688546180725,0.170874819159508,0.855551421642303,0.169734433293343,0.866364359855652,0.143366053700447,0.86433219909668,0.141892954707146,0.877405345439911,0.116718411445618,0.875497162342072,0.11494592577219,0.890727400779724,0.0911346822977066,0.888956725597382,0.0890980884432793,0.906229019165039,0.0668097659945488,0.904604613780975,0.0645437389612198,0.923792243003845,0.043928898870945,0.922319114208221,0.0414658486843109,0.943281710147858,0.022667845711112,0.941887497901917,0.0201187059283257,0.960012912750244,0.00199021096341312,0.962037086486816,0.00391250289976597,0.0178544688969851,0.558632075786591,0.0165364313870668,0.556003332138062,0.0278674438595772,0.54467236995697,0.0291865319013596,0.547300040721893,0.0123535860329866,0.560186207294464,0.0136715872213244,0.562814950942993,0.0320503227412701,0.540489494800568,0.033368818461895,0.543117582798004,0.00817073974758387,0.564369022846222,0.00948874186724424,0.566997885704041,0.0362331718206406,0.53630656003952,0.0375519767403603,0.53893381357193,0.00681797228753567,0.569668591022491,0.0042959158308804,0.568243861198425,0.0475661791861057,0.524973571300507,0.0489606969058514, +0.527523219585419,0.051716223359108,0.52072811126709,0.0531105287373066,0.523277401924133,0.0558085590600967,0.516362011432648,0.0572027936577797,0.518911182880402,0.0671687945723534,0.503969192504883,0.0686431229114532,0.506430923938751,0.071157842874527,0.499411314725876,0.0726316124200821,0.501873731613159,0.0750000402331352,0.494628638029099,0.0764743387699127,0.497090250253677,0.0850207358598709,0.481573969125748,0.0866454243659973,0.483839601278305,0.0887080803513527,0.476533800363541,0.0903326645493507,0.478799641132355,0.0922249630093575,0.471276015043259,0.0938496515154839,0.473541557788849,0.100861310958862,0.45772397518158,0.102632328867912,0.459759920835495,0.10419587045908,0.452214777469635,0.105966784060001,0.454251110553741,0.107335060834885,0.446500033140183,0.109106041491032,0.448535919189453,0.11457647383213,0.432593584060669,0.116484977304935,0.43436536192894,0.117503620684147,0.42664036154747,0.119412057101727,0.428412526845932,0.120209999382496,0.420499473810196,0.122118435800076,0.422271221876144,0.126066967844963,0.40636345744133,0.128099411725998,0.407835930585861,0.128530651330948,0.400005787611008,0.130563095211983,0.40147864818573,0.130748853087425,0.393485277891159,0.132781237363815,0.394957691431046,0.135248005390167,0.379219681024551,0.137385353446007,0.380359470844269,0.137193873524666,0.372514307498932,0.139331221580505,0.373654425144196,0.138872027397156,0.365678161382675,0.141009300947189,0.36681792140007,0.142048582434654,0.351353466510773,0.144266054034233,0.352131605148315,0.143428325653076,0.344375103712082,0.145645871758461,0.345153480768204,0.144522562623024,0.337304949760437,0.14674000442028,0.338083058595657,0.14641135931015,0.322961926460266,0.148679241538048,0.323356747627258,0.14718759059906,0.315801799297333,0.149455606937408,0.316196799278259,0.147666737437248,0.308594346046448,0.149934589862823,0.30898916721344,0.148293197154999,0.294249147176743,0.150578305125237,0.294249147176743,0.14844374358654,0.287010878324509,0.150729060173035,0.287010878324509,0.148293197154999, +0.279772609472275,0.150578305125237,0.279772579669952,0.147666737437248,0.26542741060257,0.149934589862823,0.265032589435577,0.14718759059906,0.258219927549362,0.149455651640892,0.257824957370758,0.14641135931015,0.251059830188751,0.148679241538048,0.250665009021759,0.144522607326508,0.23671680688858,0.14674000442028,0.235938712954521,0.143428325653076,0.229646652936935,0.145645871758461,0.228868290781975,0.142048582434654,0.222668260335922,0.144266054034233,0.221890166401863,0.138872057199478,0.208343610167503,0.141009300947189,0.20720386505127,0.137193873524666,0.201507464051247,0.139331221580505,0.200367331504822,0.135248005390167,0.194802105426788,0.137385353446007,0.193662285804749,0.130748853087425,0.180536478757858,0.132781267166138,0.179064035415649,0.12853068113327,0.17401596903801,0.130563095211983,0.172543108463287,0.126066997647285,0.167658299207687,0.128099456429482,0.166185840964317,0.120209999382496,0.153522297739983,0.122118435800076,0.151750504970551,0.11750365793705,0.147381410002708,0.119412057101727,0.145609244704247,0.114576511085033,0.141428217291832,0.116484977304935,0.139656394720078,0.107335060834885,0.127521678805351,0.109106041491032,0.125485837459564,0.10419587045908,0.121806941926479,0.105966821312904,0.119770705699921,0.100861310958862,0.116297744214535,0.102632366120815,0.114261820912361,0.0922250002622604,0.102745749056339,0.0938496887683868,0.10048021376133,0.0887080803513527,0.0974879860877991,0.0903327018022537,0.0952221006155014,0.0850207731127739,0.0924478024244308,0.0866454616189003,0.0901822000741959,0.0750000774860382,0.0793931037187576,0.0764734968543053,0.0769304037094116,0.07115788012743,0.0746104940772057,0.0726311579346657,0.0721476525068283,0.0671688318252563,0.0700526162981987,0.0686419978737831,0.0675903037190437,0.0558116100728512,0.0576630719006062,0.0571318231523037,0.0550359077751637,0.0517178028821945,0.0532952733337879,0.0530369281768799,0.0506674088537693,0.0475693382322788,0.0490513145923615,0.0488894097507,0.0464245714247227,0.0362331718206406,0.0377151444554329, +0.0375512056052685,0.0350863710045815,0.0320503599941731,0.0335322991013527,0.0333683602511883,0.0309035237878561,0.0278674773871899,0.0293494537472725,0.0291854795068502,0.0267206784337759,0.0165364667773247,0.0180184077471495,0.0178544688969851,0.0153896315023303,0.0123535860329866,0.0138355614617467,0.0136715872213244,0.0112067852169275,0.00817073974758387,0.00965264532715082,0.00948874186724424,0.00702393939718604,0.00199203519150615,0.00347397569566965,0.00445504812523723,0.00199021096341312,0.503993153572083,0.514742851257324,0.483154028654099,0.49188357591629,0.489393383264542,0.486702501773834,0.509706676006317,0.508985042572021,0.503504991531372,0.51521247625351,0.482632637023926,0.492316573858261,0.464520990848541,0.467209458351135,0.471211791038513,0.462626129388809,0.509527623653412,0.507783651351929,0.489914834499359,0.486269474029541,0.519920408725739,0.519352078437805,0.514338076114655,0.524934470653534,0.463961839675903,0.467592418193817,0.448244124650955,0.440921276807785,0.455329239368439,0.436974883079529,0.471770912408829,0.46224308013916,0.510892689228058,0.509223639965057,0.519667327404022,0.518131077289581,0.519977271556854,0.519282221794128,0.530251383781433,0.529818475246429,0.524804532527924,0.535265326499939,0.447652012109756,0.441251128911972,0.434462159872055,0.413243502378464,0.441881209611893,0.409967660903931,0.455921351909637,0.436645120382309,0.530370354652405,0.500995874404907,0.519927501678467,0.494451522827148,0.520925462245941,0.519407093524933,0.53059321641922,0.529202699661255,0.540197968482971,0.53988242149353,0.534868538379669,0.545211851596832,0.433842122554779,0.413517206907272,0.423292845487595,0.384412050247192,0.430982440710068,0.381834775209427,0.442501246929169,0.409693866968155,0.520333468914032,0.518807590007782,0.531205892562866,0.501402199268341,0.510191142559052,0.508511543273926,0.519038438796997,0.494045972824097,0.522129595279694,0.487510025501251,0.533461928367615,0.492220014333725,0.540426135063171,0.539153158664703,0.549062311649323,0.548845946788788,0.543831944465637, +0.554076254367828,0.422650218009949,0.384627461433411,0.41483137011528,0.354673117399216,0.422725975513458,0.352816373109818,0.431625068187714,0.381619393825531,0.534367680549622,0.492429047822952,0.521171987056732,0.48732003569603,0.522744596004486,0.480269372463226,0.53459358215332,0.482916444540024,0.549189865589142,0.548016011714935,0.414171636104584,0.354828268289566,0.409149974584579,0.324280261993408,0.417182236909866,0.323159873485565,0.423385798931122,0.352661162614822,0.535517811775208,0.482967376708984,0.52177357673645,0.480244815349579,0.522495210170746,0.472939640283585,0.53454852104187,0.473720073699951,0.408478707075119,0.324373930692673,0.406297087669373,0.29349285364151,0.414398461580276,0.293118327856064,0.417853504419327,0.323066204786301,0.53547191619873,0.473646700382233,0.521528244018555,0.473037391901016,0.521274507045746,0.465707957744598,0.533190846443176,0.464646071195602,0.405620068311691,0.293524205684662,0.406297087669373,0.262573540210724,0.414398461580276,0.262948155403137,0.415075540542603,0.293087035417557,0.534094095230103,0.464441001415253,0.520329177379608,0.465932190418243,0.516482651233673,0.450136035680771,0.527742326259613,0.446592032909393,0.405620068311691,0.262542247772217,0.409149974584579,0.231786206364632,0.417182236909866,0.232906669378281,0.415075540542603,0.262979447841644,0.528609752655029,0.446268707513809,0.515572845935822,0.450475484132767,0.509138464927673,0.43349677324295,0.519771337509155,0.428691297769547,0.408478707075119,0.231692537665367,0.41483137011528,0.201393350958824,0.422725975513458,0.203250169754028,0.417853504419327,0.233000263571739,0.520603835582733,0.428289741277695,0.508263111114502,0.433913975954056,0.500165104866028,0.415999889373779,0.510403871536255,0.410670697689056,0.414171636104584,0.201238140463829,0.423292845487595,0.171654403209686,0.430982500314713,0.174231678247452,0.423385798931122,0.203405380249023,0.511223495006561,0.410244315862656,0.499305367469788,0.416447401046753,0.490462899208069,0.397774934768677,0.500557363033295,0.392413675785065, +0.422650218009949,0.171439006924629,0.4344622194767,0.142822980880737,0.441881209611893,0.146098807454109,0.431625127792358,0.17444708943367,0.501375377178192,0.391984194517136,0.489604383707047,0.398224622011185,0.480842530727386,0.378917068243027,0.490982174873352,0.373859196901321,0.433842182159424,0.142549201846123,0.448244124650955,0.115145191550255,0.455329239368439,0.119091585278511,0.442501246929169,0.146372586488724,0.491812855005264,0.373454362154007,0.479970246553421,0.379339873790741,0.471995711326599,0.359500646591187,0.482315570116043,0.355027735233307,0.447652012109756,0.114815421402454,0.464521050453186,0.08885707706213,0.471211791038513,0.0934403464198112,0.455921351909637,0.119421355426311,0.483168065547943,0.354670375585556,0.471100300550461,0.359872847795486,0.464496552944183,0.339603304862976,0.475068509578705,0.335967093706131,0.463961839675903,0.0884740501642227,0.483154088258743,0.0641829520463943,0.489393383264542,0.0693640261888504,0.471771001815796,0.0938233733177185,0.475946456193924,0.335676908493042,0.463574826717377,0.339905709028244,0.458801329135895,0.319315433502197,0.469628393650055,0.316740125417709,0.482632637023926,0.0637499690055847,0.503993153572083,0.0413236953318119,0.509706735610962,0.0470814518630505,0.489914834499359,0.06979700922966,0.470530331134796,0.316534817218781,0.457854747772217,0.319529503583908,0.455245614051819,0.29874786734581,0.46626204252243,0.297410398721695,0.503505051136017,0.0408540181815624,0.514338076114655,0.031132047995925,0.519920408725739,0.036714393645525,0.509527623653412,0.0482828058302403,0.467181175947189,0.297303825616837,0.454281210899353,0.298859030008316,0.454037040472031,0.278033137321472,0.465123206377029,0.278033137321472,0.524804532527924,0.0208011940121651,0.530251383781433,0.02624805085361,0.510892689228058,0.0468428209424019,0.519977331161499,0.0367843471467495,0.519667327404022,0.0379354618489742,0.46604859828949,0.278033137321472,0.453066170215607,0.278033137321472,0.455245614051819,0.257318437099457,0.46626204252243,0.258655846118927, +0.534868538379669,0.0108546307310462,0.540197968482971,0.0161839611828327,0.520925462245941,0.0366593822836876,0.53059321641922,0.0268637426197529,0.530370950698853,0.0550702884793282,0.519926905632019,0.0616152174770832,0.467181265354156,0.258762508630753,0.454281270503998,0.257207304239273,0.45880138874054,0.236750900745392,0.4696284532547,0.239326134324074,0.543831944465637,0.00199021096341312,0.549062311649323,0.00722053973004222,0.540426135063171,0.0169132500886917,0.533462703227997,0.063846230506897,0.522129058837891,0.0685565769672394,0.510191142559052,0.0475549884140491,0.519035935401917,0.0620162785053253,0.520333468914032,0.037258867174387,0.53120893239975,0.054668951779604,0.470530420541763,0.239531442523003,0.457854807376862,0.236536830663681,0.464496701955795,0.216463029384613,0.475068509578705,0.220099225640297,0.549189865589142,0.0080505134537816,0.534593999385834,0.0731499493122101,0.522744953632355,0.0757971107959747,0.521171987056732,0.0687464401125908,0.534367740154266,0.0636373534798622,0.475946545600891,0.220389351248741,0.463574886322021,0.216160625219345,0.471995860338211,0.196565613150597,0.482315629720688,0.201038599014282,0.534549057483673,0.0823463872075081,0.522494971752167,0.0831267535686493,0.521773636341095,0.0758216679096222,0.535517811775208,0.0730990841984749,0.483168125152588,0.201395943760872,0.471100360155106,0.196193471550941,0.480842679738998,0.177149251103401,0.490982264280319,0.182207047939301,0.53319126367569,0.0914204567670822,0.521274566650391,0.0903585255146027,0.521528303623199,0.0830290839076042,0.53547191619873,0.0824197083711624,0.491812944412231,0.182611897587776,0.479970306158066,0.176726520061493,0.490463048219681,0.158291399478912,0.500557422637939,0.163652658462524,0.527742624282837,0.109474442899227,0.516482472419739,0.105930298566818,0.520329236984253,0.0901342034339905,0.534094154834747,0.0916254073381424,0.501375436782837,0.164082139730453,0.489604443311691,0.15784178674221,0.500165164470673,0.140066504478455,0.5104039311409,0.145395621657372,0.519771456718445, +0.127375110983849,0.509138464927673,0.122569628059864,0.515572905540466,0.105590984225273,0.528609812259674,0.109797686338425,0.511223554611206,0.145822018384933,0.499305486679077,0.139618992805481,0.508263230323792,0.122152432799339,0.520603895187378,0.127776592969894,0.589529037475586,0.50430166721344,0.609842300415039,0.482019186019897,0.616081595420837,0.487200260162354,0.595242559909821,0.510059535503387,0.589033901691437,0.503839671611786,0.609320819377899,0.481586217880249,0.62802392244339,0.457942873239517,0.634714722633362,0.462526142597198,0.595730721950531,0.510529220104218,0.616603076457977,0.487633287906647,0.585176408290863,0.519971907138824,0.579594731330872,0.514390170574188,0.627464771270752,0.457559823989868,0.643906533718109,0.432291626930237,0.650991559028625,0.436237990856171,0.635273873806,0.462909162044525,0.585613667964935,0.520492255687714,0.57602059841156,0.528991878032684,0.570574760437012,0.523546099662781,0.643314301967621,0.431961834430695,0.657354474067688,0.405284374952316,0.664773523807526,0.408560186624527,0.651583731174469,0.436567783355713,0.576364755630493,0.529605388641357,0.56796807050705,0.536927044391632,0.562639534473419,0.531598567962646,0.656734466552734,0.405010610818863,0.668253242969513,0.377151489257813,0.675942838191986,0.3797287940979,0.665393471717834,0.40883395075798,0.568193793296814,0.537658989429474,0.560919284820557,0.543877184391022,0.55568939447403,0.538647353649139,0.6676105260849,0.376936107873917,0.676509618759155,0.348133027553558,0.684404313564301,0.349989831447601,0.676585495471954,0.379944205284119,0.56104439496994,0.5447096824646,0.675849914550781,0.347977876663208,0.682053446769714,0.318476557731628,0.690085709095001,0.319597005844116,0.685064077377319,0.350145012140274,0.681382179260254,0.318382918834686,0.684837222099304,0.288435071706772,0.692938625812531,0.288809597492218,0.690756976604462,0.319690644741058,0.684160113334656,0.288403779268265,0.684837222099304,0.258264869451523,0.692938625812531,0.257890284061432,0.693615674972534,0.288840889930725, +0.684160113334656,0.25829616189003,0.682053446769714,0.228223368525505,0.690085709095001,0.227102920413017,0.693615674972534,0.257858991622925,0.681382119655609,0.228317007422447,0.676509618759155,0.198566883802414,0.684404313564301,0.196710050106049,0.690756976604462,0.227009251713753,0.675849854946136,0.198722049593925,0.668253242969513,0.169548392295837,0.675942838191986,0.166971117258072,0.685064077377319,0.196554884314537,0.6676105260849,0.169763803482056,0.657354474067688,0.141415521502495,0.664773523807526,0.138139724731445,0.676585495471954,0.166755706071854,0.656734466552734,0.141689300537109,0.64390641450882,0.114408291876316,0.650991559028625,0.11046189814806,0.665393471717834,0.137865945696831,0.643314301967621,0.11473809927702,0.628023862838745,0.0887570530176163,0.634714722633362,0.084173783659935,0.651583671569824,0.110132128000259,0.627464771270752,0.0891400799155235,0.609842300415039,0.0646807327866554,0.616081595420837,0.0594996586441994,0.63527375459671,0.0837907567620277,0.609320819377899,0.0651137158274651,0.589528977870941,0.0423982292413712,0.595242559909821,0.0366404019296169,0.616603076457977,0.0590666756033897,0.589033901691437,0.0428602583706379,0.579594731330872,0.0323096849024296,0.585176408290863,0.0267280451953411,0.595730721950531,0.0361707583069801,0.570574700832367,0.0231538042426109,0.57602059841156,0.0177079997956753,0.585613608360291,0.0262075662612915,0.562639594078064,0.0151012558490038,0.56796807050705,0.00977283716201782,0.576364755630493,0.0170944835990667,0.55568939447403,0.00805254839360714,0.560919284820557,0.00282264035195112,0.568193793296814,0.00904088281095028,0.56104439496994,0.00199021096341312,0.798284947872162,0.510059356689453,0.7774458527565,0.487200111150742,0.784206688404083,0.48158597946167,0.804033815860748,0.503335475921631,0.804011166095734,0.504314601421356,0.797796785831451,0.510528981685638,0.776924431324005,0.487633109092712,0.758812785148621,0.462525993585587,0.766062796115875,0.457559615373611,0.816269218921661,0.479021430015564,0.815805375576019,0.489054411649704, +0.810337424278259,0.497588992118835,0.8058061003685,0.463650017976761,0.811612010002136,0.470018714666367,0.804489970207214,0.503835797309875,0.81393301486969,0.514389753341675,0.80835086107254,0.519972026348114,0.807913839817047,0.520492136478424,0.758253633975983,0.462908953428268,0.742535948753357,0.436237812042236,0.750213146209717,0.43196165561676,0.789225041866302,0.441693097352982,0.816473364830017,0.489266961812973,0.816953897476196,0.478871464729309,0.810859441757202,0.498029291629791,0.80632758140564,0.463216960430145,0.812172412872314,0.4696284532547,0.822953224182129,0.523545503616333,0.817506492137909,0.528992116451263,0.8171626329422,0.529605031013489,0.741943836212158,0.436567664146423,0.728753983974457,0.408560007810593,0.736793041229248,0.405010402202606,0.774740636348724,0.418299943208694,0.789784252643585,0.441310048103333,0.830888330936432,0.531597971916199,0.825558960437775,0.536927282810211,0.825333476066589,0.537658631801605,0.728133916854858,0.408833742141724,0.717584669589996,0.379728585481644,0.725916862487793,0.37693589925766,0.762476444244385,0.393670111894608,0.775332748889923,0.41797012090683,0.837838351726532,0.538646817207336,0.832607924938202,0.543877303600311,0.832482933998108,0.544709324836731,0.716942012310028,0.379943996667862,0.709123194217682,0.349989652633667,0.717677652835846,0.347977697849274,0.752537071704865,0.368013739585876,0.763096451759338,0.393396317958832,0.708463430404663,0.350144803524017,0.703441798686981,0.31959679722786,0.712145388126373,0.318382740020752,0.745007455348969,0.341549813747406,0.753179788589478,0.367798328399658,0.702770531177521,0.319690465927124,0.700588881969452,0.288809388875961,0.709367394447327,0.288403570652008,0.739951729774475,0.314503967761993,0.745667219161987,0.341394603252411,0.699911892414093,0.288840740919113,0.700588881969452,0.257890075445175,0.709367394447327,0.258295983076096,0.737413048744202,0.287106931209564,0.74062305688858,0.314410299062729,0.699911892414093,0.257858783006668,0.703441798686981,0.227102741599083,0.712145328521729, +0.22831679880619,0.737413048744202,0.259592622518539,0.738090038299561,0.287075638771057,0.702770590782166,0.227009072899818,0.709123194217682,0.196709871292114,0.717677652835846,0.198721915483475,0.739951729774475,0.232195615768433,0.738090038299561,0.259623914957047,0.708463370800018,0.19655467569828,0.717584669589996,0.166970938444138,0.725916981697083,0.169763624668121,0.745007455348969,0.205149799585342,0.740622997283936,0.232289284467697,0.716942012310028,0.166755542159081,0.728754043579102,0.138139516115189,0.736793041229248,0.141689121723175,0.752537071704865,0.178685858845711,0.745667219161987,0.205305010080338,0.728134036064148,0.137865737080574,0.742535948753357,0.110461719334126,0.750213146209717,0.114737883210182,0.76247650384903,0.153029426932335,0.753179788589478,0.178901195526123,0.741943836212158,0.110131949186325,0.758812844753265,0.0841736048460007,0.766062796115875,0.0891399085521698,0.774740636348724,0.128399580717087,0.763096511363983,0.153303205966949,0.758253633975983,0.0837905779480934,0.777445912361145,0.0594994835555553,0.784206688404083,0.0651135370135307,0.789225101470947,0.105006515979767,0.775332748889923,0.128729417920113,0.776924431324005,0.0590665005147457,0.798284947872162,0.0366402268409729,0.804011225700378,0.0423849336802959,0.804033935070038,0.0433640740811825,0.805806159973145,0.0830495730042458,0.789784252643585,0.105389475822449,0.797796845436096,0.0361705496907234,0.80835086107254,0.0267275534570217,0.81393301486969,0.0323097556829453,0.804490029811859,0.042863804847002,0.815805375576019,0.057645108550787,0.816269278526306,0.0676781162619591,0.811612069606781,0.0766808316111565,0.810337424278259,0.0491105318069458,0.806327641010284,0.0834825560450554,0.807913839817047,0.0262074247002602,0.817506492137909,0.0177073683589697,0.822953224182129,0.0231540855020285,0.810859441757202,0.0486701801419258,0.816953957080841,0.0678280591964722,0.816473364830017,0.0574325807392597,0.812172472476959,0.0770710855722427,0.8171626329422,0.0170944128185511,0.825558960437775,0.00977220572531223, +0.830888330936432,0.0151016069576144,0.825333476066589,0.00904095359146595,0.832607924938202,0.0028222193941474,0.837838351726532,0.00805261824280024,0.832482933998108,0.00199021096341312,0.314825654029846,0.486269801855087,0.332969516515732,0.462243437767029,0.340219438076019,0.467209756374359,0.321586400270462,0.491883873939514,0.293226212263107,0.468333721160889,0.309807181358337,0.446376919746399,0.348819106817245,0.43664538860321,0.356496393680573,0.440921604633331,0.322107821702957,0.492316901683807,0.34077861905098,0.467592775821686,0.295021116733551,0.508998394012451,0.294998407363892,0.508019268512726,0.300747275352478,0.514743149280548,0.283226907253265,0.493738234043121,0.282763063907623,0.483705222606659,0.287420302629471,0.474702537059784,0.288694888353348,0.502272844314575,0.292704790830612,0.467900723218918,0.309248030185699,0.44599387049675,0.32429164648056,0.422983705997467,0.362239211797714,0.409694194793701,0.370278269052505,0.413243800401688,0.357088506221771,0.441251397132874,0.301235496997833,0.515212774276733,0.29454231262207,0.50851958990097,0.29040265083313,0.524935007095337,0.284820288419724,0.519352614879608,0.282558977603912,0.493950694799423,0.282078355550766,0.483555287122726,0.286859899759293,0.474312275648117,0.288172900676727,0.502713084220886,0.323699533939362,0.42265385389328,0.336555868387222,0.398353844881058,0.373115360736847,0.381619721651077,0.381447613239288,0.384412407875061,0.370898306369781,0.413517564535141,0.284390658140183,0.518824219703674,0.279936283826828,0.535265922546387,0.274489432573318,0.529819130897522,0.335935801267624,0.398080110549927,0.346495151519775,0.372697532176971,0.381354689598084,0.352661490440369,0.389909088611603,0.354673445224762,0.382090240716934,0.384627819061279,0.274147391319275,0.529202997684479,0.269872188568115,0.54521256685257,0.264542818069458,0.539883136749268,0.34585252404213,0.372482150793076,0.354024797677994,0.346233516931534,0.386886924505234,0.323066532611847,0.395590484142303,0.324280619621277,0.390568882226944,0.354828596115112, +0.264314472675323,0.539153337478638,0.260908782482147,0.554076910018921,0.25567838549614,0.548846423625946,0.353365063667297,0.346078336238861,0.35908055305481,0.319187730550766,0.38966491818428,0.293087363243103,0.39844337105751,0.293493211269379,0.396261751651764,0.324374228715897,0.255550742149353,0.54801607131958,0.358409255743027,0.319094061851501,0.361619263887405,0.291790753602982,0.38966491818428,0.262979775667191,0.39844337105751,0.262573897838593,0.399120390415192,0.293524503707886,0.360942214727402,0.291759431362152,0.361619293689728,0.264276385307312,0.386886924505234,0.233000621199608,0.395590484142303,0.231786534190178,0.399120390415192,0.262542605400085,0.360942244529724,0.264307677745819,0.359080523252487,0.236879408359528,0.381354689598084,0.203405663371086,0.389909088611603,0.201393663883209,0.396261721849442,0.231692865490913,0.358409255743027,0.23697304725647,0.354024797677994,0.20983362197876,0.373115360736847,0.174447402358055,0.381447613239288,0.171654731035233,0.390568882226944,0.201238498091698,0.353365063667297,0.209988832473755,0.346495151519775,0.183369636535645,0.362239211797714,0.14637291431427,0.370278269052505,0.142823323607445,0.382090240716934,0.171439319849014,0.345852494239807,0.183585003018379,0.336555808782578,0.15771321952343,0.348819106817245,0.1194217056036,0.356496334075928,0.11514550447464,0.370898276567459,0.14254954457283,0.335935771465302,0.157986998558044,0.324291586875916,0.133083358407021,0.332969516515732,0.0938236936926842,0.340219438076019,0.088857389986515,0.357088446617126,0.114815734326839,0.323699474334717,0.133413165807724,0.309807151556015,0.109690196812153,0.314825624227524,0.0697973221540451,0.321586400270462,0.0641832649707794,0.340778589248657,0.0884743630886078,0.309247970581055,0.11007322371006,0.293226093053818,0.0877333581447601,0.294998377561569,0.0480478927493095,0.295021116733551,0.04706871509552,0.300747245550156,0.0413240119814873,0.322107821702957,0.0637502819299698,0.292704641819,0.0881663411855698,0.288694858551025,0.0537943169474602,0.287420213222504, +0.0813646167516708,0.282763034105301,0.0723619014024735,0.283226877450943,0.0623288936913013,0.294542223215103,0.0475475527346134,0.284820288419724,0.036714531481266,0.290402621030808,0.0311321187764406,0.301235467195511,0.0408543683588505,0.286859810352325,0.0817548707127571,0.288172870874405,0.0533539988100529,0.282078325748444,0.0725118443369865,0.28255894780159,0.0621163994073868,0.284390658140183,0.0372428707778454,0.274489432573318,0.0262479800730944,0.279936254024506,0.0208012647926807,0.27414733171463,0.0268641635775566,0.264542818069458,0.016183890402317,0.269872188568115,0.0108546307310462,0.264314472675323,0.016913739964366,0.25567838549614,0.0072206100448966,0.260908782482147,0.00199021096341312,0.255550742149353,0.00805093441158533,0.932035326957703,0.540456295013428,0.920083105564117,0.533234596252441,0.930924892425537,0.51587438583374,0.940884411334991,0.52598774433136,0.929900884628296,0.547184467315674,0.916941404342651,0.542165040969849,0.929298877716064,0.554262101650238,0.915800213813782,0.551586508750916,0.92954421043396,0.561471700668335,0.915849089622498,0.560871660709381,0.930743515491486,0.568578898906708,0.917223632335663,0.570042073726654,0.935500800609589,0.584038257598877,0.922695398330688,0.588168978691101,0.94281131029129,0.600601255893707,0.93068939447403,0.606124460697174,0.951769471168518,0.618068337440491,0.940062522888184,0.624160468578339,0.961471617221832,0.636292994022369,0.949908852577209,0.642421722412109,0.971105635166168,0.655177235603333,0.959471702575684,0.66095632314682,0.979974567890167,0.674642145633698,0.968120276927948,0.679751992225647,0.98749977350235,0.694608509540558,0.975346982479095,0.698761940002441,0.993219673633575,0.714983582496643,0.980768203735352,0.717925012111664,0.996793031692505,0.735652804374695,0.984121084213257,0.737180411815643,0.998008012771606,0.756477296352386,0.985255181789398,0.756477355957031,0.996793031692505,0.777301788330078,0.984121143817902,0.775774300098419,0.99321973323822,0.797971069812775,0.980768203735352,0.795029699802399,0.987499892711639, +0.818346261978149,0.97534704208374,0.814192712306976,0.979974627494812,0.83831262588501,0.968120336532593,0.83320277929306,0.971105694770813,0.857777535915375,0.959471821784973,0.851998448371887,0.961471736431122,0.876661777496338,0.949908971786499,0.870533108711243,0.951769590377808,0.894886374473572,0.940062582492828,0.888794362545013,0.942811369895935,0.912353515625,0.930689513683319,0.906830430030823,0.935500860214233,0.92891651391983,0.922695457935333,0.924785852432251,0.93074357509613,0.944375932216644,0.917223691940308,0.942912817001343,0.929544270038605,0.951483190059662,0.915849149227142,0.952083289623261,0.929298996925354,0.958692789077759,0.915800273418427,0.961368441581726,0.929900884628296,0.965770363807678,0.916941404342651,0.970789849758148,0.932035326957703,0.972498595714569,0.920083165168762,0.9797203540802,0.940884411334991,0.986967146396637,0.930924892425537,0.997080504894257,0.23483806848526,0.425258278846741,0.242078885436058,0.431109726428986,0.247106999158859,0.445016294717789,0.244088098406792,0.450842022895813,0.24107763171196,0.425156563520432,0.24813349545002,0.450731009244919,0.20682692527771,0.450842022895813,0.206827059388161,0.425258278846741,0.242130234837532,0.419015616178513,0.247160598635674,0.456240177154541,0.23483806848526,0.475167006254196,0.206827059388161,0.475167006254196,0.244088098406792,0.398610711097717,0.20682692527771,0.398610711097717,0.247037246823311,0.404879629611969,0.242007166147232,0.469792157411575,0.244088098406792,0.498047888278961,0.206827059388161,0.498047888278961,0.23483806848526,0.371101945638657,0.206827059388161,0.371101945638657,0.248066559433937,0.398522049188614,0.241008594632149,0.47504997253418,0.241953566670418,0.480090171098709,0.247231185436249,0.493144780397415,0.23483806848526,0.519308805465698,0.206827059388161,0.519308805465698,0.242193952202797,0.37773585319519,0.246990948915482,0.392001509666443,0.244088098406792,0.342941522598267,0.20682692527771,0.342941522598267,0.248201563954353,0.497927486896515,0.247282683849335,0.502485334873199, +0.241890981793404,0.514878213405609,0.244088098406792,0.53900557756424,0.206827059388161,0.53900557756424,0.241138532757759,0.371030390262604,0.246937617659569,0.349869668483734,0.242232263088226,0.364194273948669,0.23483806848526,0.314343929290771,0.20682692527771,0.314343929290771,0.240968883037567,0.519244372844696,0.24192675948143,0.523489713668823,0.247249007225037,0.534822821617126,0.23483806848526,0.558702409267426,0.232987269759178,0.558702409267426,0.206827059388161,0.539112091064453,0.248015761375427,0.342891275882721,0.242270857095718,0.321478098630905,0.246910259127617,0.335821092128754,0.244088098406792,0.285527020692825,0.206827059388161,0.285527020692825,0.248197495937347,0.53900557756424,0.247249007225037,0.543188512325287,0.241927608847618,0.554519474506378,0.235308304429054,0.560440540313721,0.241175308823586,0.314317971467972,0.246889904141426,0.292765319347382,0.242285162210464,0.307110548019409,0.23483806848526,0.256710112094879,0.20682692527771,0.256710112094879,0.240979120135307,0.558702409267426,0.243747383356094,0.566760063171387,0.241927608847618,0.562885165214539,0.247996538877487,0.285527020692825,0.242285162210464,0.263943493366241,0.246889904141426,0.278288751840591,0.244088098406792,0.228112548589706,0.20682692527771,0.228112548589706,0.241175308823586,0.256736069917679,0.246910259127617,0.235232964158058,0.242270857095718,0.249575957655907,0.23483806848526,0.199952244758606,0.206827059388161,0.199952244758606,0.248015761375427,0.228162780404091,0.242232263088226,0.206859782338142,0.246937617659569,0.221184387803078,0.244088098406792,0.172443330287933,0.206827059388161,0.172443330287933,0.241138532757759,0.200023666024208,0.246990948915482,0.17905268073082,0.242193952202797,0.193318352103233,0.23483806848526,0.145795777440071,0.206827059388161,0.145795777440071,0.248066559433937,0.172532171010971,0.242130234837532,0.152038425207138,0.247037246823311,0.166174441576004,0.244088098406792,0.120212033390999,0.20682692527771,0.120212033390999,0.24107763171196,0.145897582173347,0.247106999158859, +0.12603785097599,0.242078885436058,0.139944344758987,0.23483806848526,0.095887117087841,0.206827059388161,0.095887117087841,0.24813349545002,0.120323106646538,0.242007166147232,0.101261913776398,0.247160598635674,0.11481387168169,0.244088098406792,0.0730062574148178,0.206827059388161,0.0730062574148178,0.241008594632149,0.0960041508078575,0.247231185436249,0.0779092684388161,0.241953566670418,0.0909639671444893,0.23483806848526,0.0517452023923397,0.206827059388161,0.0517452023923397,0.248201563954353,0.0731266587972641,0.241892382502556,0.0561792366206646,0.247282683849335,0.0685687810182571,0.244088098406792,0.0320484638214111,0.206827059388161,0.0329898595809937,0.207980990409851,0.0320484638214111,0.240968883037567,0.0518114380538464,0.247249007225037,0.0362313091754913,0.241925224661827,0.0475674793124199,0.23483806848526,0.0123517271131277,0.23212718963623,0.0123517271131277,0.248197495937347,0.0320484638214111,0.241927608847618,0.0165345724672079,0.247249007225037,0.0278656184673309,0.235535770654678,0.00957118533551693,0.240979120135307,0.0123517271131277,0.244829326868057,0.00199021096341312,0.241927608847618,0.00816888082772493,0.164256349205971,0.434365302324295,0.171475455164909,0.428514569997787,0.162225335836411,0.454362273216248,0.159185156226158,0.448535889387131,0.165248543024063,0.42841249704361,0.199486449360847,0.428514569997787,0.199486449360847,0.454362332820892,0.158168718218803,0.454251050949097,0.164206996560097,0.422271221876144,0.162225335836411,0.401567548513412,0.199486449360847,0.401567608118057,0.171475455164909,0.478916823863983,0.199486449360847,0.478916823863983,0.159133404493332,0.45975986123085,0.159251779317856,0.407835900783539,0.171475455164909,0.37372612953186,0.199486449360847,0.37372612953186,0.164325222373009,0.473541557788849,0.162225335836411,0.501994729042053,0.199486449360847,0.501994729042053,0.158232644200325,0.401478588581085,0.164146304130554,0.380359441041946,0.159296154975891,0.394957661628723,0.162225335836411,0.345203965902328,0.199486449360847,0.345203936100006, +0.165314823389053,0.47879958152771,0.16437703371048,0.483839571475983,0.159065917134285,0.497090250253677,0.171475455164909,0.523346066474915,0.199486449360847,0.523421406745911,0.165190488100052,0.373654395341873,0.159346774220467,0.352131575345993,0.164109751582146,0.366817891597748,0.171475455164909,0.316222906112671,0.199486449360847,0.316222906112671,0.15810514986515,0.501873672008514,0.159022301435471,0.506430864334106,0.164430290460587,0.518911123275757,0.162225335836411,0.543118178844452,0.199486449360847,0.542444050312042,0.19858618080616,0.543118178844452,0.158280909061432,0.345153450965881,0.164073184132576,0.323356717824936,0.159372955560684,0.338083028793335,0.162225335836411,0.287010818719864,0.199486449360847,0.287010818719864,0.165348842740059,0.523277401924133,0.164394408464432,0.527523159980774,0.159057289361954,0.538933753967285,0.171475455164909,0.562814891338348,0.172283753752708,0.562814891338348,0.165155723690987,0.316196769475937,0.159392103552818,0.29424911737442,0.164059609174728,0.308989137411118,0.171475455164909,0.257798790931702,0.199486449360847,0.257798790931702,0.158113777637482,0.543117523193359,0.159063950181007,0.547299981117249,0.164385765790939,0.558632075786591,0.17127001285553,0.563574016094208,0.158299162983894,0.287010818719864,0.164059579372406,0.265032559633255,0.159392103552818,0.27977254986763,0.162225335836411,0.228817731142044,0.199486449360847,0.228817731142044,0.165334329009056,0.562814891338348,0.163131520152092,0.569668531417847,0.164385810494423,0.566997826099396,0.165155723690987,0.257824927568436,0.159372955560684,0.235938683152199,0.164073184132576,0.250664979219437,0.171475455164909,0.200295552611351,0.199486449360847,0.200295597314835,0.158280953764915,0.228868260979652,0.164109751582146,0.207203835248947,0.159346774220467,0.221890136599541,0.162225335836411,0.172454074025154,0.199486449360847,0.172454074025154,0.165190488100052,0.200367301702499,0.159296154975891,0.179064005613327,0.164146304130554,0.193662256002426,0.171475455164909,0.145507112145424,0.199486449360847, +0.145507112145424,0.158232644200325,0.172543078660965,0.164206996560097,0.151750475168228,0.159251779317856,0.166185796260834,0.162225335836411,0.119659386575222,0.199486449360847,0.119659282267094,0.165248587727547,0.145609200000763,0.159185156226158,0.125485792756081,0.164256393909454,0.139656364917755,0.171475455164909,0.0951048955321312,0.199486449360847,0.0951048955321312,0.158168718218803,0.119770668447018,0.164325222373009,0.100480183959007,0.159133404493332,0.114261783659458,0.162225335836411,0.0720270052552223,0.199486449360847,0.0720270052552223,0.165314823389053,0.0952220633625984,0.159065499901772,0.0769303664565086,0.164377003908157,0.0901821628212929,0.171475455164909,0.0506044700741768,0.199486449360847,0.0506798624992371,0.158103123307228,0.0721476152539253,0.164435237646103,0.055035874247551,0.15901543200016,0.0675902739167213,0.162225335836411,0.0309034883975983,0.197466522455215,0.0309034883975983,0.199486449360847,0.0325513333082199,0.165348783135414,0.0506673753261566,0.159064441919327,0.0350863710045815,0.164389133453369,0.04642453789711,0.171475455164909,0.0112067498266697,0.173320427536964,0.0112067498266697,0.158115893602371,0.0309034883975983,0.164385810494423,0.0153895961120725,0.159064441919327,0.0267206430435181,0.170952841639519,0.00927544198930264,0.165334329009056,0.0112067498266697,0.162021860480309,0.00199017580598593,0.164385810494423,0.00702390447258949,0.37750768661499,0.712034046649933,0.376675188541412,0.71156907081604,0.382660835981369,0.699645340442657,0.383557796478271,0.699982404708862,0.387466579675674,0.684144496917725,0.388399004936218,0.684367656707764,0.390823155641556,0.66574627161026,0.391773343086243,0.665872573852539,0.392545014619827,0.64549446105957,0.393502473831177,0.645535290241241,0.392545014619827,0.624607563018799,0.393502473831177,0.624566793441772,0.390823185443878,0.604355752468109,0.391773283481598,0.604229509830475,0.387466669082642,0.585957586765289,0.388398945331573,0.58573442697525,0.382660955190659,0.570456743240356,0.383557677268982,0.570119798183441, +0.376675456762314,0.558532953262329,0.377507477998734,0.558068335056305,0.425053507089615,0.558536052703857,0.425883442163467,0.558067739009857,0.433227032423019,0.572358012199402,0.432330876588821,0.57269674539566,0.438767164945602,0.589981138706207,0.437834739685059,0.590204298496246,0.442474007606506,0.61014062166214,0.441523790359497,0.610266208648682,0.444333672523499,0.631905615329742,0.443376183509827,0.6319460272789,0.444333732128143,0.654221653938293,0.443376183509827,0.654181122779846,0.442474007606506,0.675986647605896,0.441523730754852,0.67586088180542,0.438767224550247,0.696145951747894,0.437834680080414,0.6959228515625,0.433227121829987,0.713769257068634,0.432330787181854,0.713430345058441,0.425883710384369,0.728059351444244,0.425053387880325,0.727590918540955,0.418087989091873,0.55806839466095,0.418917894363403,0.558536648750305,0.411640554666519,0.572697401046753,0.410744458436966,0.57235860824585,0.406136691570282,0.590204894542694,0.405204355716705,0.5899817943573,0.402447730302811,0.610266864299774,0.401497453451157,0.610141277313232,0.400595247745514,0.631946682929993,0.399637788534164,0.63190621137619,0.400595247745514,0.654181718826294,0.399637758731842,0.654222309589386,0.402447730302811,0.675861537456512,0.401497423648834,0.675987243652344,0.406136751174927,0.695923447608948,0.405204206705093,0.696146607398987,0.411640703678131,0.713431000709534,0.410744279623032,0.713769912719727,0.41891810297966,0.727591574192047,0.418087780475616,0.728060007095337,0.370539873838425,0.71156907081604,0.369707375764847,0.712033987045288,0.363657265901566,0.699982345104218,0.364554286003113,0.699645280838013,0.358816057443619,0.684367597103119,0.359748482704163,0.684144496917725,0.355441749095917,0.665872573852539,0.356391936540604,0.66574627161026,0.35371258854866,0.645535230636597,0.35467004776001,0.64549446105957,0.353712618350983,0.624566793441772,0.354670077562332,0.624607563018799,0.355441778898239,0.60422945022583,0.356391906738281,0.604355752468109,0.358816117048264,0.58573442697525,0.359748423099518, +0.585957586765289,0.363657414913177,0.570119798183441,0.364554107189178,0.570456743240356,0.369707584381104,0.558068335056305,0.370539605617523,0.558533012866974,0.846843659877777,0.842310011386871,0.846843659877777,0.814576148986816,0.858021259307861,0.814576148986816,0.858021259307861,0.842310011386871,0.846843659877777,0.785686433315277,0.858021259307861,0.785686433315277,0.846843659877777,0.75588721036911,0.858021259307861,0.75588721036911,0.846843659877777,0.725432813167572,0.858021259307861,0.725432813167572,0.846843659877777,0.694583117961884,0.858021259307861,0.694583117961884,0.846843659877777,0.663601219654083,0.858021259307861,0.663601219654083,0.846843659877777,0.632751524448395,0.858021259307861,0.632751524448395,0.846843659877777,0.602297127246857,0.858021259307861,0.602297127246857,0.846843659877777,0.572497963905334,0.858021259307861,0.572497963905334,0.846843659877777,0.54360818862915,0.858021259307861,0.54360818862915,0.846843659877777,0.515874326229095,0.858021259307861,0.515874326229095,0.898487150669098,0.905676603317261,0.898487150669098,0.878725528717041,0.909664869308472,0.878725528717041,0.909664869308472,0.905676603317261,0.898487150669098,0.85065096616745,0.909664869308472,0.85065096616745,0.898487150669098,0.931274652481079,0.909664869308472,0.931274652481079,0.898487150669098,0.821692705154419,0.909664869308472,0.821692705154419,0.898487150669098,0.95530104637146,0.909664869308472,0.95530104637146,0.898487150669098,0.792097687721252,0.909664869308472,0.792097687721252,0.899459481239319,0.977543115615845,0.898487150669098,0.976815223693848,0.909664869308472,0.977554500102997,0.898487150669098,0.762118577957153,0.909664869308472,0.762118577957153,0.898522675037384,0.978255152702332,0.897810220718384,0.978016555309296,0.898487150669098,0.732010960578918,0.909664869308472,0.732010960578918,0.898487150669098,0.702031850814819,0.909664869308472,0.702031850814819,0.898487150669098,0.672436952590942,0.909664869308472,0.672436952590942,0.898487150669098,0.643478631973267,0.909664869308472,0.643478631973267, +0.898487150669098,0.61540412902832,0.909664869308472,0.61540412902832,0.898487150669098,0.588452935218811,0.909664869308472,0.588452935218811,0.898487150669098,0.562854945659637,0.909664869308472,0.562854945659637,0.898487150669098,0.538828551769257,0.909664869308472,0.538828551769257,0.898487150669098,0.517314374446869,0.899459481239319,0.516586542129517,0.909664869308472,0.51657509803772,0.897810220718384,0.516112983226776,0.898522675037384,0.51587438583374,0.829530775547028,0.87513655424118,0.829530775547028,0.847402632236481,0.840708434581757,0.847402632236481,0.840708434581757,0.87513655424118,0.829530775547028,0.818512856960297,0.840708434581757,0.818512856960297,0.829530775547028,0.788713693618774,0.840708374977112,0.788713693618774,0.829530775547028,0.758259356021881,0.840708374977112,0.758259356021881,0.829530775547028,0.727409601211548,0.840708434581757,0.727409601211548,0.829530775547028,0.696427643299103,0.840708434581757,0.696427643299103,0.829530775547028,0.66557788848877,0.840708374977112,0.66557788848877,0.829530775547028,0.635123550891876,0.840708374977112,0.635123550891876,0.829530775547028,0.605324447154999,0.840708434581757,0.605324447154999,0.829530775547028,0.57643461227417,0.840708434581757,0.57643461227417,0.829530775547028,0.54870080947876,0.840708434581757,0.54870080947876,0.864156603813171,0.890980660915375,0.864156603813171,0.866406917572021,0.875334203243256,0.866406917572021,0.875334203243256,0.890980660915375,0.864156603813171,0.840808987617493,0.875334203243256,0.840808987617493,0.864156603813171,0.914320588111877,0.875334203243256,0.914320707321167,0.864156603813171,0.814405202865601,0.875334203243256,0.814405202865601,0.864156603813171,0.936227560043335,0.875334203243256,0.936227560043335,0.864156603813171,0.787420809268951,0.875334203243256,0.787420809268951,0.875334203243256,0.942639052867889,0.864156603813171,0.942639052867889,0.864156603813171,0.760086178779602,0.875334203243256,0.760086178779602,0.864156603813171,0.951882064342499,0.875334203243256,0.951882064342499,0.864156603813171, +0.732634544372559,0.875334203243256,0.732634544372559,0.864156603813171,0.962277472019196,0.875334203243256,0.962277472019196,0.864156603813171,0.705299913883209,0.875334203243256,0.70529979467392,0.864156603813171,0.971039891242981,0.875334203243256,0.971039891242981,0.864156603813171,0.678315579891205,0.875334203243256,0.678315579891205,0.875334203243256,0.976846396923065,0.864156603813171,0.976846396923065,0.864156603813171,0.651911795139313,0.875334203243256,0.651911795139313,0.864156603813171,0.626313745975494,0.875334203243256,0.626313745975494,0.864156603813171,0.601739943027496,0.875334203243256,0.601739943027496,0.864156603813171,0.578400075435638,0.875334203243256,0.578400075435638,0.864156603813171,0.55649322271347,0.875334203243256,0.55649322271347,0.864156603813171,0.550081610679626,0.875334203243256,0.550081610679626,0.864156603813171,0.540838718414307,0.875334203243256,0.540838718414307,0.864156603813171,0.53044319152832,0.875334203243256,0.53044319152832,0.864156603813171,0.521680772304535,0.875334203243256,0.521680772304535,0.864156603813171,0.51587438583374,0.875334203243256,0.51587438583374,0.891548752784729,0.955650806427002,0.881579279899597,0.955656945705414,0.881614089012146,0.948579370975494,0.891509532928467,0.948575556278229,0.891588807106018,0.962376713752747,0.881544649600983,0.962385177612305,0.881647646427155,0.941369831562042,0.891470789909363,0.941368162631989,0.891674995422363,0.976842403411865,0.881469428539276,0.976853728294373,0.881677806377411,0.934262454509735,0.891436278820038,0.934263050556183,0.881735503673553,0.918803036212921,0.891369342803955,0.918806254863739,0.881787240505219,0.90224015712738,0.891308903694153,0.902244806289673,0.881833136081696,0.884773015975952,0.891255080699921,0.884778261184692,0.88187301158905,0.866548299789429,0.891207933425903,0.866555452346802,0.881906986236572,0.84766411781311,0.89116770029068,0.84767073392868,0.881934881210327,0.828199148178101,0.891134560108185,0.828203618526459,0.881956815719604,0.808232724666595,0.891108512878418,0.808236539363861, +0.88197249174118,0.787857711315155,0.891089797019959,0.78786027431488,0.881982207298279,0.767188429832459,0.891078293323517,0.767189860343933,0.881985425949097,0.746363937854767,0.891074359416962,0.746363937854767,0.881982207298279,0.725539445877075,0.891078293323517,0.725538074970245,0.88197249174118,0.704870164394379,0.891089797019959,0.704867660999298,0.881956815719604,0.684495031833649,0.891108453273773,0.684491395950317,0.881934881210327,0.664528727531433,0.891134560108185,0.664524257183075,0.881906986236572,0.645063817501068,0.891167759895325,0.645057260990143,0.881873071193695,0.62617963552475,0.891207933425903,0.626172542572021,0.881833136081696,0.607954919338226,0.891255080699921,0.607949733734131,0.881787359714508,0.590487897396088,0.891308963298798,0.590483248233795,0.881735503673553,0.573924839496613,0.891369462013245,0.573921740055084,0.881677806377411,0.558465480804443,0.891436278820038,0.558465003967285,0.881647646427155,0.551358282566071,0.891471087932587,0.551359891891479,0.881614089012146,0.544148683547974,0.891509234905243,0.544152438640594,0.881579279899597,0.537071049213409,0.891549348831177,0.537077248096466,0.881544649600983,0.530342876911163,0.891589522361755,0.530347049236298,0.881469428539276,0.515874326229095,0.891674995422363,0.515885770320892,0.980637073516846,0.457077026367188,0.970933794975281,0.457160383462906,0.970970094203949,0.44769874215126,0.980601727962494,0.447655498981476,0.980673253536224,0.466007560491562,0.970896601676941,0.466133564710617,0.971005201339722,0.438378095626831,0.980567872524261,0.438370376825333,0.980751037597656,0.483367592096329,0.970816195011139,0.483538955450058,0.971038162708282,0.429172396659851,0.980536043643951,0.429199904203415,0.971100330352783,0.41100013256073,0.980476379394531,0.411072969436646,0.971155941486359,0.393021076917648,0.980422675609589,0.393117487430573,0.971205294132233,0.374975651502609,0.980374932289124,0.375081479549408,0.971248388290405,0.356715530157089,0.980333268642426,0.356820225715637,0.971285164356232,0.338185697793961,0.980297923088074, +0.338285624980927,0.971315443515778,0.319401741027832,0.980268716812134,0.319489866495132,0.971339166164398,0.300408244132996,0.98024582862854,0.300479829311371,0.971356332302094,0.281266152858734,0.980229437351227,0.281316816806793,0.971366703510284,0.262035250663757,0.980219304561615,0.262061476707459,0.971370339393616,0.242764472961426,0.980215787887573,0.242764472961426,0.971366703510284,0.223493844270706,0.980219304561615,0.223467454314232,0.971356332302094,0.204262793064117,0.980229258537292,0.204212129116058,0.971339166164398,0.185120701789856,0.98024582862854,0.185049131512642,0.971315443515778,0.166127219796181,0.980268716812134,0.16603909432888,0.971285164356232,0.147343248128891,0.980297923088074,0.147243469953537,0.971248388290405,0.128813475370407,0.980333268642426,0.12870879471302,0.971205294132233,0.110553354024887,0.980374932289124,0.11044754832983,0.971155762672424,0.0925079360604286,0.980422675609589,0.092411532998085,0.971100091934204,0.0745290294289589,0.980476379394531,0.0744561329483986,0.971037745475769,0.0563567541539669,0.980536043643951,0.0563291795551777,0.971004784107208,0.0471510551869869,0.980567872524261,0.047158770263195,0.970969676971436,0.0378304272890091,0.980601727962494,0.0378736481070518,0.970933079719543,0.0283686965703964,0.980637073516846,0.028452193364501,0.970896005630493,0.019400293007493,0.980673253536224,0.0195216778665781,0.970816195011139,0.00199021096341312,0.980751037597656,0.00216155219823122 + } + UVIndex: *4196 { + a: 284,285,286,328,329,330,331,287,284,286,288,289,339,338,342,343,290,287,289,291,347,346,348,349,292,290,291,293,353,352,354,355,294,292,293,295,359,358,360,361,296,294,295,297,365,364,366,367,298,296,297,299,371,370,372,373,300,298,299,301,377,376,378,379,302,300,301,303,383,382,384,385,304,302,303,305,389,388,390,391,306,304,305,307,395,394,396,397,308,306,307,309,401,400,402,403,310,308,309,311,407,406,408,409,312,310,311,313,413,412,414,415,314,312,313,315,419,418,420,421,316,314,315,317,425,424,426,427,318,316,317,319,431,430,432,433,320,318,319,321,437,436,438,439,322,320,321,323,443,442,444,445,324,322,323,325,449,448,450,451,455,454,456,457,461,460,462,463,467,466,468,469,1143,1162,1163,1153,1288,1269,1280,1289,1134,1151,1152,1143,1278,1259,1269,1279,1126,1141,1142,1134,1267,1249,1259,1268,1120,1132,1133,1126,1257,1242,1249,1258,1113,1119,1125,1120,1244,1233,1242,1248,1110,1111,1112,1113,1231,1232,1233,1234,1122,1124,1118,1110,1245,1240,1232,1239,1128,1136,1137,1122,1252,1246,1240,1253,1138,1146,1147,1128,1262,1254,1246,1263,1148,1157,1158,1138,1273,1264,1254,1274,1159,1166,1167,1148,1283,1275,1264,1284,1168,1174,1175,1159,1292,1285,1275,1293,1176,1179,1180,1168,1300,1294,1285,1301,1181,1184,1185,1176,1305,1302,1294,1306,1186,1189,1190,1181,1310,1307,1302,1311,1191,1194,1195,1186,1315,1312,1307,1316,1196,1199,1200,1191,1320,1317,1312,1321,1201,1204,1205,1196,1325,1322,1317,1326,1206,1209,1210,1201,1330,1327,1322,1331,1211,1214,1215,1206,1335,1332,1327,1336,1216,1220,1221,1211,1332,1337,1338,1339,1333,1222,1225,1226,1216,1337,1343,1344,1338,336,332,333,337,332,329,328,333,330,334,335,331,334,338,339,335,342,344,345,343,344,346,347,345,348,350,351,349,350,352,353,351,354,356,357,355,356,358,359,357,360,362,363,361,362,364,365,363,366,368,369,367,368,370,371,369,372,374,375,373,374,376,377,375,378,380,381,379,380,382,383,381,384,386,387,385,386,388,389,387,390,392,393,391,392,394,395,393,396,398,399,397,398,400,401,399,402,404,405,403,404,406,407,405,408,410,411,409,410,412,413,411,414, +416,417,415,416,418,419,417,420,422,423,421,422,424,425,423,426,428,429,427,428,430,431,429,432,434,435,433,434,436,437,435,438,440,441,439,440,442,443,441,444,446,447,445,446,448,449,447,450,452,453,451,452,454,455,453,456,458,459,457,458,460,461,459,462,464,465,463,464,466,467,465,1153,1163,1170,1153,1170,1172,1280,1298,1296,1280,1296,1289,1143,1152,1161,1143,1161,1162,1269,1288,1287,1269,1287,1279,1134,1142,1150,1134,1150,1151,1259,1278,1277,1259,1277,1268,1126,1133,1140,1126,1140,1141,1249,1267,1266,1249,1266,1258,1120,1125,1131,1120,1131,1132,1242,1257,1256,1242,1256,1248,1113,1112,1115,1113,1115,1119,1233,1244,1238,1233,1238,1234,1110,1118,1114,1110,1114,1111,1232,1231,1235,1232,1235,1239,1122,1137,1130,1122,1130,1124,1240,1245,1251,1240,1251,1253,1128,1147,1145,1128,1145,1136,1246,1252,1261,1246,1261,1263,1138,1158,1156,1138,1156,1146,1254,1262,1272,1254,1272,1274,1148,1167,1165,1148,1165,1157,1264,1273,1282,1264,1282,1284,1159,1175,1173,1159,1173,1166,1275,1283,1291,1275,1291,1293,1168,1180,1178,1168,1178,1174,1285,1292,1299,1285,1299,1301,1176,1185,1183,1176,1183,1179,1294,1300,1304,1294,1304,1306,1181,1190,1188,1181,1188,1184,1302,1305,1309,1302,1309,1311,1186,1195,1193,1186,1193,1189,1307,1310,1314,1307,1314,1316,1191,1200,1198,1191,1198,1194,1312,1315,1319,1312,1319,1321,1196,1205,1203,1196,1203,1199,1317,1320,1324,1317,1324,1326,1201,1210,1208,1201,1208,1204,1322,1325,1329,1322,1329,1331,1206,1215,1213,1206,1213,1209,1327,1330,1334,1327,1334,1336,1211,1221,1219,1211,1219,1214,1332,1335,1340,1332,1340,1342,1216,1226,1224,1216,1224,1220,1337,1341,1345,1337,1345,1347,1222,1230,1228,1222,1228,1225,1343,1346,1349,1343,1349,1351,1327,1332,1333,1328,1341,1337,1332,1342,1346,1343,1337,1347,1322,1327,1328,1323,1317,1322,1323,1318,1312,1317,1318,1313,1307,1312,1313,1308,1302,1307,1308,1303,1294,1302,1303,1295,1285,1294,1295,1286,1275,1285,1286,1276,1264,1275,1276,1265,1254,1264,1265,1255,1246,1254,1255,1247,1240,1246,1247,1241,1232,1240,1241,1236,1233,1232,1236,1237,1242,1233,1237,1243,1249,1242,1243,1250,1259, +1249,1250,1260,1269,1259,1260,1270,1271,1280,1269,1271,1281,1153,1164,1154,1143,1153,1154,1155,1144,1134,1143,1144,1135,1126,1134,1135,1127,1120,1126,1127,1121,1113,1120,1121,1116,1110,1113,1116,1117,1122,1110,1117,1123,1128,1122,1123,1129,1138,1128,1129,1139,1148,1138,1139,1149,1159,1148,1149,1160,1168,1159,1160,1169,1176,1168,1169,1177,1181,1176,1177,1182,1186,1181,1182,1187,1191,1186,1187,1192,1196,1191,1192,1197,1201,1196,1197,1202,1206,1201,1202,1207,1211,1206,1207,1212,1216,1211,1212,1217,1218,1222,1216,1218,1223,326,327,324,325,1227,1229,1230,1222,1348,1344,1343,1350,1348,1343,1351,1223,1227,1222,340,341,336,337,1171,1164,1153,1172,1290,1297,1298,1280,1281,1290,1280,695,700,708,702,700,695,694,701,701,694,699,707,707,699,706,714,714,706,713,721,721,713,720,728,728,720,727,733,733,727,732,737,737,732,736,741,741,736,740,745,745,740,744,749,749,744,748,753,753,748,752,757,757,752,756,761,761,756,760,765,765,760,764,769,769,764,768,773,773,768,772,777,777,772,776,780,168,169,162,161,470,474,475,471,471,475,482,476,476,482,491,483,483,491,501,492,492,501,514,502,502,514,523,515,515,523,531,524,524,531,539,532,532,539,547,540,540,547,555,548,548,555,563,556,556,563,571,564,564,571,579,572,572,579,587,580,580,587,595,588,588,595,603,596,596,603,611,604,26,27,20,19,473,486,487,488,480,479,472,477,485,485,477,484,494,494,484,493,504,504,493,503,517,517,503,516,526,526,516,525,534,534,525,533,542,542,533,541,550,550,541,549,558,558,549,557,566,566,557,565,574,574,565,573,582,582,573,581,590,590,581,589,598,598,589,597,606,606,597,605,614,244,245,238,237,692,696,697,693,693,697,704,698,698,704,711,705,705,711,718,712,712,718,725,719,719,725,730,726,726,730,734,731,731,734,738,735,735,738,742,739,739,742,746,743,743,746,750,747,747,750,754,751,751,754,758,755,755,758,762,759,759,762,766,763,763,766,770,767,767,770,774,771,102,103,96,95,208,209,206,205,941,930,921,926,926,921,920,927,927,920,925,940,940,925,939,953,953,939,952,961,961,952,960,969,969,960,968,977,977,968,976,983,983,976,982,988,988,982,987,993,993,987,992, +998,998,992,997,1003,1003,997,1002,1008,1008,1002,1007,1013,1013,1007,1012,1018,1018,1012,1017,1024,1024,1017,1023,1033,67,68,65,64,793,788,804,805,788,793,794,789,789,794,806,795,795,806,818,807,807,818,826,819,819,826,834,827,827,834,839,835,835,839,844,840,840,844,849,845,845,849,854,850,850,854,859,855,855,859,864,860,860,864,869,865,865,869,874,870,870,874,879,875,875,879,884,880,880,884,889,885,885,889,895,890,890,895,904,896,19,20,13,12,780,776,779,783,95,96,89,88,12,13,5,4,783,779,782,786,88,89,81,80,631,620,629,640,4,5,1,0,786,782,785,787,80,81,77,76,640,629,639,651,0,1,2,3,1352,1353,1354,1355,76,77,78,79,1372,1373,1374,1375,3,2,8,9,1355,1354,1356,1357,79,78,84,85,1375,1374,1376,1377,9,8,16,17,1357,1356,1358,1359,85,84,92,93,1377,1376,1378,1379,17,16,23,24,1359,1358,1360,1361,93,92,99,100,1379,1378,1380,1381,24,23,30,31,1361,1360,1362,1363,100,99,107,108,1381,1380,1382,1383,31,30,35,36,1363,1362,1364,1365,108,107,113,114,1383,1382,1384,1385,36,35,41,42,1365,1364,1366,1367,114,113,117,118,1385,1384,1386,1387,42,41,47,48,1367,1366,1368,1369,118,117,121,122,1387,1386,1388,1389,48,47,53,54,1369,1368,1370,1371,122,121,125,126,1389,1388,1390,1391,54,53,57,58,917,915,912,914,126,125,129,130,1047,1045,1042,1044,58,57,61,62,914,912,905,911,130,129,133,134,1044,1042,1039,1041,62,61,64,65,911,905,896,904,134,133,136,137,1041,1039,1031,1038,137,136,139,140,1038,1031,1022,1030,892,898,907,902,1030,1021,1026,1035,161,162,155,154,480,488,497,498,489,237,238,231,230,702,708,715,709,154,155,147,146,489,498,511,499,230,231,223,222,709,715,722,716,146,147,143,142,499,511,522,512,222,223,219,218,716,722,729,723,142,143,144,145,1392,1393,1394,1395,218,219,220,221,1412,1413,1414,1415,145,144,150,151,1395,1394,1396,1397,221,220,226,227,1415,1414,1416,1417,151,150,158,159,1397,1396,1398,1399,227,226,234,235,1417,1416,1418,1419,159,158,165,166,1399,1398,1400,1401,235,234,241,242,1419,1418,1420,1421,166,165,172,173,1401,1400,1402,1403,242,241,249,250,1421,1420,1422,1423,173,172,177,178,1403,1402,1404,1405,250,249,255,256,1423,1422, +1424,1425,178,177,183,184,1405,1404,1406,1407,256,255,259,260,1425,1424,1426,1427,184,183,189,190,1407,1406,1408,1409,260,259,263,264,1427,1426,1428,1429,190,189,195,196,1409,1408,1410,1411,264,263,267,268,1429,1428,1430,1431,196,195,199,200,972,978,970,964,268,267,271,272,832,833,825,824,200,199,202,203,964,970,962,956,272,271,274,275,824,825,817,816,203,202,205,206,956,962,954,944,275,274,277,278,816,817,805,804,944,954,942,928,278,277,280,281,929,942,948,934,802,791,799,812,812,799,798,810,934,948,945,931,800,813,814,801,813,800,809,822,822,809,821,830,935,922,933,947,922,935,936,923,923,936,949,937,830,821,829,838,937,949,957,950,838,829,837,843,950,957,965,958,843,837,842,848,958,965,973,966,848,842,847,853,966,973,979,974,853,847,852,858,974,979,984,980,858,852,857,863,980,984,989,985,863,857,862,868,985,989,994,990,868,862,867,873,990,994,999,995,873,867,872,878,995,999,1004,1000,878,872,877,883,1000,1004,1009,1005,883,877,882,888,1005,1009,1014,1010,888,882,887,894,1010,1014,1019,1015,894,887,893,903,1015,1019,1025,1020,903,893,901,910,1020,1025,1034,1027,902,907,909,899,910,901,900,908,1035,1026,1029,1037,1027,1034,1036,1028,801,814,811,797,947,933,932,946,810,798,797,811,931,945,946,932,908,900,899,909,1028,1036,1037,1029,175,180,181,168,180,186,187,181,186,192,193,187,1432,1433,1434,1435,1433,1436,1437,1434,1436,1438,1439,1437,1438,1440,1441,1439,1440,1442,1443,1441,1442,1444,1445,1443,1444,1446,1447,1445,1446,1448,1449,1447,1448,1450,1451,1449,1450,1452,1453,1451,1452,1454,1455,1453,50,44,45,51,44,38,39,45,38,33,27,39,470,471,472,473,471,476,477,472,476,483,484,477,483,492,493,484,492,502,503,493,502,515,516,503,515,524,525,516,524,532,533,525,532,540,541,533,540,548,549,541,548,556,557,549,556,564,565,557,564,572,573,565,572,580,581,573,580,588,589,581,588,596,597,589,596,604,605,597,1466,1462,1463,1467,1462,1456,1459,1463,1456,1457,1458,1459,1457,1460,1461,1458,1460,1464,1465,1461,1464,1468,1469,1465,1468,1473,1474,1469,1473,1477,1478,1474,1477,1479,1480,1478,1479,1481,1482,1480,1481,1483,1484,1482,1483, +1485,1486,1484,1485,1487,1488,1486,1487,1489,1490,1488,1489,1491,1492,1490,1491,1493,1494,1495,1492,692,693,694,695,693,698,699,694,698,705,706,699,705,712,713,706,712,719,720,713,719,726,727,720,726,731,732,727,731,735,736,732,735,739,740,736,739,743,744,740,743,747,748,744,747,751,752,748,751,755,756,752,755,759,760,756,759,763,764,760,763,767,768,764,767,771,772,768,209,212,213,211,212,214,215,213,214,216,217,215,1498,1499,1500,1501,1499,1502,1503,1500,1502,1504,1505,1503,1504,1506,1507,1505,1506,1508,1509,1507,1508,1510,1511,1509,1510,1512,1513,1511,1512,1514,1515,1513,1514,1516,1517,1515,1516,1518,1519,1517,1518,1520,1521,1519,74,72,73,75,72,70,71,73,70,67,69,71,788,789,790,791,792,789,795,796,790,795,807,808,796,807,819,820,808,819,827,828,820,827,835,836,828,835,840,841,836,840,845,846,841,845,850,851,846,850,855,856,851,855,860,861,856,860,865,866,861,865,870,871,866,870,875,876,871,875,880,881,876,880,885,886,881,885,890,891,892,886,1536,1537,1532,1533,1532,1528,1529,1533,1528,1522,1525,1529,1522,1523,1524,1525,1523,1526,1527,1524,1526,1530,1531,1527,1530,1534,1535,1531,1534,1538,1539,1535,1538,1542,1543,1539,1542,1546,1547,1543,1546,1550,1551,1547,1550,1554,1555,1551,1554,1556,1557,1555,1556,1558,1559,1557,1558,1560,1561,1559,1560,1562,1563,1561,1562,1564,1565,1563,918,919,920,921,919,924,925,920,924,938,939,925,938,951,952,939,951,959,960,952,959,967,968,960,967,975,976,968,975,981,982,976,981,986,987,982,986,991,992,987,991,996,997,992,996,1001,1002,997,1001,1006,1007,1002,1006,1011,1012,1007,1011,1016,1017,1012,1016,1021,1022,1023,1017,64,66,69,67,896,897,891,890,136,138,141,139,1031,1032,1023,1022,27,33,28,20,772,771,775,776,605,604,612,613,20,28,21,13,776,775,778,779,96,104,105,97,89,613,612,619,620,13,21,14,5,779,778,781,782,89,97,90,81,620,619,628,629,5,14,6,1,782,781,784,785,81,90,82,77,629,628,638,639,1,6,7,2,86,76,79,87,77,82,83,78,10,0,3,11,2,7,15,8,87,79,85,94,78,83,91,84,11,3,9,18,8,15,22,16,94,85,93,101,84,91,98,92,18,9,17,25,16,22,29,23,101,93,100,109,92,98,106,99,25,17,24,32,23,29,34,30,109, +100,108,115,99,106,112,107,32,24,31,37,30,34,40,35,115,108,114,119,107,112,116,113,37,31,36,43,35,40,46,41,119,114,118,123,113,116,120,117,43,36,42,49,41,46,52,47,123,118,122,127,117,120,124,121,49,42,48,55,47,52,56,53,127,122,126,131,121,124,128,125,55,48,54,59,53,56,60,57,915,916,913,912,125,128,132,129,1045,1046,1043,1042,57,60,63,61,912,913,906,905,129,132,135,133,1042,1043,1040,1039,61,63,66,64,905,906,897,896,133,135,138,136,1039,1040,1032,1031,943,944,928,930,282,278,281,283,803,804,788,792,210,206,209,211,470,473,480,481,692,695,702,703,175,168,161,170,481,480,489,490,703,702,709,710,170,161,154,163,490,489,499,500,239,230,222,232,710,709,716,717,163,154,146,156,500,499,512,513,232,222,218,228,717,716,723,724,156,146,142,152,143,148,149,144,228,218,221,229,219,224,225,220,152,142,145,153,144,149,157,150,229,221,227,236,220,225,233,226,153,145,151,160,150,157,164,158,236,227,235,243,226,233,240,234,160,151,159,167,158,164,171,165,243,235,242,251,234,240,248,241,167,159,166,174,165,171,176,172,251,242,250,257,241,248,254,249,174,166,173,179,172,176,182,177,257,250,256,261,249,254,258,255,179,173,178,185,177,182,188,183,261,256,260,265,255,258,262,259,185,178,184,191,183,188,194,189,265,260,264,269,259,262,266,263,191,184,190,197,189,194,198,195,269,264,268,273,263,266,270,267,197,190,196,201,971,972,964,963,273,268,272,276,831,832,824,823,201,196,200,204,963,964,956,955,276,272,275,279,823,824,816,815,204,200,203,207,955,956,944,943,279,275,278,282,815,816,804,803,207,203,206,210,1549,1552,1553,1548,790,796,809,800,919,918,922,923,796,808,821,809,924,919,923,937,808,820,829,821,938,924,937,950,820,828,837,829,951,938,950,958,828,836,842,837,959,951,958,966,836,841,847,842,967,959,966,974,841,846,852,847,975,967,974,980,846,851,857,852,981,975,980,985,851,856,862,857,986,981,985,990,856,861,867,862,991,986,990,995,861,866,872,867,996,991,995,1000,866,871,877,872,1001,996,1000,1005,871,876,882,877,1006,1001,1005,1010,876,881,887,882,1011,1006,1010,1015,881,886,893,887,1016,1011,1015,1020,1570,1572,1573,1571,1548, +1544,1545,1549,1544,1540,1541,1545,1540,1537,1536,1541,1564,1566,1567,1565,1566,1568,1569,1567,1568,1570,1571,1569,797,798,799,791,790,800,801,931,932,933,922,918,929,934,899,900,901,893,886,892,902,1026,1021,1016,1020,1027,1028,1029,928,929,918,921,930,892,891,898,1030,1022,1021,929,928,942,802,792,791,1048,1049,1050,1051,1108,1109,1107,1106,1104,1105,1103,1102,1100,1101,1099,1098,1098,1099,1097,1096,1096,1097,1095,1094,1094,1095,1093,1092,1092,1093,1091,1090,1090,1091,1089,1088,1088,1089,1087,1086,1086,1087,1085,1084,1084,1085,1083,1082,1082,1083,1081,1080,1080,1081,1079,1078,1078,1079,1077,1076,1076,1077,1075,1074,1074,1075,1073,1072,1072,1073,1071,1070,1070,1071,1069,1068,1068,1069,1067,1066,1066,1067,1065,1064,1064,1065,1063,1062,1062,1063,1061,1060,1060,1061,1059,1058,1056,1057,1055,1054,1052,1053,1049,1048,1054,1055,1053,1052,1058,1059,1057,1056,1106,1107,1105,1104,1102,1103,1101,1100,246,247,237,230,239,478,473,472,479,1470,1471,1466,1467,1472,630,622,613,620,631,621,605,613,622,623,505,487,495,506,506,495,510,518,486,507,508,496,496,508,519,509,518,510,521,527,509,519,528,520,527,521,530,535,535,530,538,543,520,528,536,529,529,536,544,537,543,538,546,551,551,546,554,559,537,544,552,545,545,552,560,553,559,554,562,567,553,560,568,561,567,562,570,575,561,568,576,569,575,570,578,583,569,576,584,577,583,578,586,591,577,584,592,585,591,586,594,599,585,592,600,593,599,594,602,607,593,600,608,601,607,602,610,615,601,608,616,609,615,610,618,624,609,616,625,617,624,618,627,634,617,625,635,626,634,627,637,647,626,635,648,636,647,637,650,656,636,648,657,649,656,650,659,664,649,657,665,658,664,659,667,672,658,665,673,666,672,667,675,680,666,673,681,674,680,675,683,688,674,681,689,682,688,683,684,691,682,689,690,685,691,684,676,687,685,690,686,677,687,676,668,679,677,686,678,669,679,668,660,671,669,678,670,661,671,660,652,663,661,670,662,653,663,652,641,655,655,641,632,646,653,662,654,642,642,654,644,633,623,645,646,632,643,621,633,644,632,633,621,623,1633,1632,1634,1635,1695,1694,1696,1697,495,487,486,496,1578,1582,1583, +1579,1644,1645,1641,1640,510,509,520,521,1574,1575,1576,1577,1636,1637,1638,1639,530,529,537,538,1581,1580,1584,1585,1643,1642,1646,1647,538,537,545,546,1585,1584,1586,1587,1647,1646,1648,1649,546,545,553,554,1587,1586,1588,1589,1649,1648,1650,1651,554,553,561,562,1589,1588,1590,1591,1651,1650,1652,1653,562,561,569,570,1591,1590,1592,1593,1653,1652,1654,1655,570,569,577,578,1593,1592,1594,1595,1655,1654,1656,1657,578,577,585,586,1595,1594,1596,1597,1657,1656,1658,1659,586,585,593,594,1597,1596,1598,1599,1659,1658,1660,1661,594,593,601,602,1599,1598,1600,1601,1661,1660,1662,1663,602,601,609,610,1601,1600,1602,1603,1663,1662,1664,1665,610,609,617,618,1603,1602,1604,1605,1665,1664,1666,1667,618,617,626,627,1605,1604,1606,1607,1667,1666,1668,1669,627,626,636,637,1607,1606,1608,1609,1669,1668,1670,1671,637,636,649,650,1609,1608,1610,1611,1671,1670,1672,1673,650,649,658,659,1611,1610,1612,1613,1673,1672,1674,1675,659,658,666,667,1613,1612,1614,1615,1675,1674,1676,1677,667,666,674,675,1615,1614,1616,1617,1677,1676,1678,1679,675,674,682,683,1617,1616,1618,1619,1679,1678,1680,1681,683,682,685,684,1619,1618,1620,1621,1681,1680,1682,1683,684,685,677,676,1621,1620,1622,1623,1683,1682,1684,1685,676,677,669,668,1623,1622,1624,1625,1685,1684,1686,1687,660,661,653,652,1627,1626,1628,1629,1689,1688,1690,1691,641,642,633,632,1631,1630,1632,1633,1693,1692,1694,1695,652,653,642,641,1629,1628,1630,1631,1691,1690,1692,1693,668,669,661,660,1625,1624,1626,1627,1687,1686,1688,1689,495,496,509,510,1578,1579,1575,1574,1640,1641,1637,1636,521,520,529,530,1577,1576,1580,1581,1639,1638,1642,1643,247,246,252,253,1475,1476,1471,1470,110,111,105,104,1494,1493,1496,1497 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 363536144, "Model::HiFi_Xylophone1", "Null" { + Version: 232 + Properties70: { + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 363538464, "Model::Frame", "Null" { + Version: 232 + Properties70: { + P: "RotationPivot", "Vector3D", "Vector", "",3.814697265625e-006,41.661837392844,-14.5002459569288 + P: "ScalingPivot", "Vector3D", "Vector", "",3.814697265625e-006,41.661837392844,-14.5002459569288 + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: Y + Culling: "CullingOff" + } + Model: 363550064, "Model::Wave", "Null" { + Version: 232 + Properties70: { + P: "RotationPivot", "Vector3D", "Vector", "",-4.39795767187518e-015,84.4647528022276,4.56259961274829 + P: "ScalingPivot", "Vector3D", "Vector", "",-4.39795767187518e-015,84.4647528022276,4.56259961274829 + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: Y + Culling: "CullingOff" + } + Model: 363517584, "Model::transform2", "Null" { + Version: 232 + Properties70: { + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Visibility", "Visibility", "", "A",0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 363503664, "Model::transform1", "Null" { + Version: 232 + Properties70: { + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Visibility", "Visibility", "", "A",0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 363501344, "Model::Wave", "Mesh" { + Version: 232 + Properties70: { + P: "RotationPivot", "Vector3D", "Vector", "",1.1444091796875e-005,41.6618365049362,-25.8935875892639 + P: "ScalingPivot", "Vector3D", "Vector", "",1.1444091796875e-005,41.6618365049362,-25.8935875892639 + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: T + Culling: "CullingOff" + } + Material: 1611742192, "Material::Steel", "" { + Version: 102 + ShadingModel: "unknown" + MultiLayer: 0 + Properties70: { + P: "Maya", "Compound", "", "" + P: "Maya|TypeId", "int", "Integer", "",1166017 + P: "Maya|TEX_global_diffuse_cube", "Vector3D", "Vector", "",0,0,0 + P: "Maya|TEX_global_specular_cube", "Vector3D", "Vector", "",0,0,0 + P: "Maya|TEX_brdf_lut", "Vector3D", "Vector", "",0,0,0 + P: "Maya|use_normal_map", "float", "", "",1 + P: "Maya|uv_offset", "Vector2D", "Vector2", "",0,0 + P: "Maya|uv_scale", "Vector2D", "Vector2", "",1,1 + P: "Maya|TEX_normal_map", "Vector3D", "Vector", "",0,0,0 + P: "Maya|use_color_map", "float", "", "",1 + P: "Maya|TEX_color_map", "Vector3D", "Vector", "",0,0,0 + P: "Maya|base_color", "Vector3D", "Vector", "",1,1,1 + P: "Maya|use_metallic_map", "float", "", "",1 + P: "Maya|TEX_metallic_map", "Vector3D", "Vector", "",0,0,0 + P: "Maya|metallic", "float", "", "",1 + P: "Maya|use_roughness_map", "float", "", "",1 + P: "Maya|TEX_roughness_map", "Vector3D", "Vector", "",0,0,0 + P: "Maya|roughness", "float", "", "",0.5 + P: "Maya|use_emissive_map", "float", "", "",0 + P: "Maya|TEX_emissive_map", "Vector3D", "Vector", "",0,0,0 + P: "Maya|emissive", "Vector3D", "Vector", "",0,0,0 + P: "Maya|emissive_intensity", "float", "", "",0 + P: "Maya|use_ao_map", "float", "", "",1 + P: "Maya|TEX_ao_map", "Vector3D", "Vector", "",0,0,0 + } + } + Video: 1971809008, "Video::file6", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Metallic.png" + } + UseMipMap: 0 + Filename: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Metallic.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_Metallic.png" + } + Video: 1971833408, "Video::file7", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Roughness.png" + } + UseMipMap: 0 + Filename: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Roughness.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_Roughness.png" + } + Video: 1971825008, "Video::file4", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_BaseColor.png" + } + UseMipMap: 0 + Filename: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_BaseColor.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_BaseColor.png" + } + Video: 1971829008, "Video::file5", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Normal.png" + } + UseMipMap: 0 + Filename: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Normal.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_Normal.png" + } + Texture: 1982231296, "Texture::file6", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file6" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::file6" + FileName: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Metallic.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_Metallic.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1982230816, "Texture::file8", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file8" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "" + FileName: "" + RelativeFilename: "" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1982230336, "Texture::file2", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file2" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "" + FileName: "" + RelativeFilename: "" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1971096816, "Texture::file1", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file1" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "" + FileName: "" + RelativeFilename: "" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1531689904, "Texture::file7", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file7" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::file7" + FileName: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Roughness.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_Roughness.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1612282368, "Texture::file3", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file3" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "" + FileName: "" + RelativeFilename: "" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1612282848, "Texture::file4", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file4" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::file4" + FileName: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_BaseColor.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_BaseColor.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 1612283328, "Texture::file5", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::file5" + Properties70: { + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::file5" + FileName: "F:/Dropbox/Dropbox/_High Fidelity/xylophone/xylophoneFrameWithWave_Steel_Normal.png" + RelativeFilename: "xylophoneFrameWithWave_Steel_Normal.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Implementation: 1981166160, "Implementation::Steel_Implementation", "" { + Version: 100 + Properties70: { + P: "ShaderLanguage", "KString", "", "", "SFX" + P: "ShaderLanguageVersion", "KString", "", "", "28" + P: "RenderAPI", "KString", "", "", "SFX_PBS_SHADER" + P: "RootBindingName", "KString", "", "", "root" + P: "ShaderGraph", "Blob", "", "",32006 { + BinaryData: "U0ZCX1dJTiA9IHsgIC8qClZlcnNpb249MjgKR3JvdXBWZXJzaW9uPS0xLjAKQWR2YW5jZWQ9MApIZWxwSUQ9MApQYXJlbnRNYXRlcmlhbD1wcmVzZXRzL1N0YW5kYXJkCk51bWJlck9mTm9kZXM9MzIKI05UPTIwMTg5IDAKCVBDPTMKCW5hbWU9MSB2PTUwMDAgTWV0YWxsaWNfTWFwX1N3aXRjaAoJcG9zeD0xIHY9MjAwMyAxMDIwLjAKCXBvc3k9MSB2PTIwMDMgMjQwLjAKCWdyb3VwPS0xCglJU0M9NAoJCVNWVD01MDIyIDIwMDMgMSAwIDAgCgkJU1ZUPTUwMjIgMjAwMyAyIDEgMCAKCQlTRFY9MS4wCgkJU1ZUPTUwMjIgMjAwMyAzIDAgMSAKCQlTQ1M9cgoJCVNWVD01MDIyIDIwMDMgNCAwIDAgCglPU0M9MQoJCVNWVD01MDIyIDIwMDMgNSAKCQlDQz0xCgkJCUM9MCAwIDUgNSA1IDYgMAoJCQlDUEM9MAojTlQ9MjAxODkgMAoJUEM9MwoJbmFtZT0xIHY9NTAwMCBFbWlzc2l2ZV9NYXBfU3dpdGNoCglwb3N4PTEgdj0yMDAzIDc0MC4wCglwb3N5PTEgdj0yMDAzIDc4MC4wCglncm91cD0tMQoJSVNDPTQKCQlTVlQ9NTAyMiAyMDAzIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAxIDAgCgkJU0RWPTEuMAoJCVNWVD01MDIyIDMwMDIgMyAwIDEgCgkJU0NTPXJnYgoJCVNWVD01MDIyIDMwMDIgNCAwIDAgCglPU0M9MQoJCVNWVD01MDIyIDMwMDIgNSAKCQlDQz0xCgkJCUM9MSAwIDUgMTAgMCAxIDAKCQkJQ1BDPTAKI05UPTIwMTg5IDAKCVBDPTMKCW5hbWU9MSB2PTUwMDAgQ29sb3JfTWFwX1N3aXRjaAoJcG9zeD0xIHY9MjAwMyAxMDIwLjAKCXBvc3k9MSB2PTIwMDMgLTM0MC4wCglncm91cD0tMQoJSVNDPTQKCQlTVlQ9NTAyMiAyMDAzIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAxIDAgCgkJU0RWPTEuMAoJCVNWVD01MDIyIDMwMDIgMyAwIDEgCgkJU0NTPXJnYgoJCVNWVD01MDIyIDMwMDIgNCAwIDAgCglPU0M9MQoJCVNWVD01MDIyIDMwMDIgNSAKCQlDQz0xCgkJCUM9MiAwIDUgNSAxIDIgMAoJCQlDUEM9MAojTlQ9MjAxODkgMAoJUEM9MwoJbmFtZT0xIHY9NTAwMCBOb3JtYWxfTWFwX1N3aXRjaAoJcG9zeD0xIHY9MjAwMyAxMDIwLjAKCXBvc3k9MSB2PTIwMDMgLTYwLjAKCWdyb3VwPS0xCglJU0M9NAoJCVNWVD01MDIyIDIwMDMgMSAwIDAgCgkJU1ZUPTUwMjIgMjAwMyAyIDEgMCAKCQlTRFY9MS4wCgkJU1ZUPTUwMjIgMzAwMiAzIDAgMCAKCQlTVlQ9NTAyMiAzMDAyIDQgMCAwIAoJT1NDPTEKCQlTVlQ9NTAyMiAzMDAyIDUgCgkJQ0M9MQoJCQlDPTMgMCA1IDUgNCA1IDAKCQkJQ1BDPTAKI05UPTIwMTg5IDAKCVBDPTMKCW5hbWU9MSB2PTUwMDAgUm91Z2huZXNzX01hcF9Td2l0Y2gKCXBvc3g9MSB2PTIwMDMgMTAyMC4wCglwb3N5PTEgdj0yMDAzIDU0MC4wCglncm91cD0tMQoJSVNDPTQKCQlTVlQ9NTAyMiAyMDAzIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAxIDAgCgkJU0RWPTEuMAoJCVNWVD01MDIyIDIwMDMgMyAwIDEgCgkJU0NTPXIKCQlTVlQ9NTAyMiAyMDAzIDQgMCAwIAoJT1NDPTEKCQlTVlQ9NTAyMiAyMDAzIDUgCgkJQ0M9MQoJCQlDPTQgMCA1IDUgNiA3IDAKCQkJQ1BDPTAKI05UPTIwMTc2IDAKCVBDPTQKCXBvc3g9MSB2PTIwMDMgMTM2MC4wCglwb3N5PTEgdj0yMDAzIDI2MC4wCglwcmVzZXRfcGF0aD0xIHY9NTAwMCBwcmVzZXRzL1N0YW5kYXJkCglub3JtYWxzcGFjZT0yIGU9MCB2PTUwMTIgMQoJZ3JvdXA9LTEKCUlTQz0xMwoJCVNWVD01MDIyIDMwMDIgMSAwIDAgCgkJU1ZUPTUwMjIgMzAwMiAyIDAgMCAKCQlTVlQ9NTAyMiAyMDAzIDMgMCAwIAoJCVNWVD01MDIyIDIwMDMgNCAwIDAgCgkJU1ZUPTUwMjIgMzAwMiA1IDAgMCAKCQlTVlQ9NTAyMiAyMDAzIDYgMCAwIAoJCVNWVD01MDIyIDIwMDMgNyAwIDAgCgkJU1ZUPTUwMjIgMzAwMiA4IDAgMCAKCQlTVlQ9NTAyMiAyMDAzIDkgMCAwIAoJCVNWVD01MDIyIDIwMDMgMTAgMCAwIAoJCVNWVD01MDIyIDIwMDMgMTEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMTQgMCAwIAoJCVNWVD01MDIyIDIwMDMgMTUgMCAwIAoJT1NDPTAKI05UPTIwMTg5IDAKCVBDPTMKCW5hbWU9MSB2PTUwMDAgQW9fTWFwX1N3dGljaAoJcG9zeD0xIHY9MjAwMyAxMDIwLjAKCXBvc3k9MSB2PTIwMDMgMTEwMC4wCglncm91cD0tMQoJSVNDPTQKCQlTVlQ9NTAyMiAyMDAzIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAxIDAgCgkJU0RWPTEuMAoJCVNWVD01MDIyIDIwMDMgMyAwIDEgCgkJU0NTPXIKCQlTVlQ9NTAyMiAyMDAzIDQgMSAwIAoJCVNEVj0xLjAKCU9TQz0xCgkJU1ZUPTUwMjIgMjAwMyA1IAoJCUNDPTEKCQkJQz02IDAgNSA1IDggOSAwCgkJCUNQQz0wCiNOVD0yMDE3OCAwCglQQz0yCglwb3N4PTEgdj0yMDAzIC0yNjAuMAoJcG9zeT0xIHY9MjAwMyA0MjAuMAoJZ3JvdXA9LTEKCUlTQz0wCglPU0M9MQoJCVNWVD01MDIyIDMwMDEgMSAKCQlDQz0xCgkJCUM9NyAwIDEgMjggMSAyIDAKCQkJQ1BDPTAKI05UPTIwMTc3IDAKCVBDPTYKCW5hbWU9MSB2PTUwMDAgcm91Z2huZXNzX21hcAoJcG9zeD0xIHY9MjAwMyA3MDAuMAoJcG9zeT0xIHY9MjAwMyA1NDAuMAoJdGV4dHVyZXBhdGg9MiBlPTEgdj01MDAwIEY6L0Ryb3Bib3gvRHJvcGJveC9fSGlnaCBGaWRlbGl0eS94eWxvcGhvbmUveHlsb3Bob25lRnJhbWVXaXRoV2F2ZV9TdGVlbF9Sb3VnaG5lc3MucG5nCgllbmNvZGluZz0yIGU9MCB2PTUwMTIgMAoJdWlvcmRlcj0yIGU9MCB2PTIwMDIgNAoJZ3JvdXA9LTEKCUlTQz0yCgkJU1ZUPTUw", + "MjIgMzAwMSAxIDAgMCAKCQlTVlQ9NTAyMiAyMDAzIDIgMCAwIAoJT1NDPTEKCQlTVlQ9NTAyMiAzMDAzIDMgCgkJQ0M9MQoJCQlDPTggMCAzIDQgMiAzIDAKCQkJQ1BDPTAKI05UPTIwMTc3IDAKCVBDPTQKCW5hbWU9MSB2PTUwMDAgZW1pc3NpdmVfbWFwCglwb3N4PTEgdj0yMDAzIDQyMC4wCglwb3N5PTEgdj0yMDAzIDc4MC4wCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiA1Cglncm91cD0tMQoJSVNDPTIKCQlTVlQ9NTAyMiAzMDAxIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAwIDAgCglPU0M9MQoJCVNWVD01MDIyIDMwMDMgMyAKCQlDQz0xCgkJCUM9OSAwIDMgMSAyIDMgMAoJCQlDUEM9MAojTlQ9MjAxODYgMAoJUEM9MgoJcG9zeD0xIHY9MjAwMyAxMDIwLjAKCXBvc3k9MSB2PTIwMDMgODQwLjAKCWdyb3VwPS0xCglJU0M9MgoJCVNWVD01MDIyIDMwMDIgMSAwIDAgCgkJU1ZUPTUwMjIgMjAwMyAyIDAgMCAKCU9TQz0xCgkJU1ZUPTUwMjIgMzAwMiAzIAoJCUNDPTEKCQkJQz0xMCAwIDMgNSA3IDggMAoJCQlDUEM9MAojTlQ9MjAxODUgMAoJUEM9NwoJbmFtZT0xIHY9NTAwMCB1c2VfY29sb3JfbWFwCglwb3N4PTEgdj0yMDAzIDcwMC4wCglwb3N5PTEgdj0yMDAzIC00MDAuMAoJdHlwZT0yIGU9MCB2PTUwMTIgMAoJZGVmYXVsdHNjYWxhcj0yIGU9MCB2PTIwMDMgMS4wCgl1aXR5cGU9MiBlPTAgdj01MDEyIDEKCXVpb3JkZXI9MiBlPTAgdj0yMDAyIDEwCglncm91cD0tMQoJSVNDPTAKCU9TQz0xCgkJU1ZUPTUwMjIgMjAwMyAxIAoJCUNDPTEKCQkJQz0xMSAwIDEgMiAwIDEgMAoJCQlDUEM9MAojTlQ9MjAxNzcgMAoJUEM9NQoJbmFtZT0xIHY9NTAwMCBjb2xvcl9tYXAKCXBvc3g9MSB2PTIwMDMgNzAwLjAKCXBvc3k9MSB2PTIwMDMgLTM0MC4wCgl0ZXh0dXJlcGF0aD0yIGU9MSB2PTUwMDAgRjovRHJvcGJveC9Ecm9wYm94L19IaWdoIEZpZGVsaXR5L3h5bG9waG9uZS94eWxvcGhvbmVGcmFtZVdpdGhXYXZlX1N0ZWVsX0Jhc2VDb2xvci5wbmcKCXVpb3JkZXI9MiBlPTAgdj0yMDAyIDEKCWdyb3VwPS0xCglJU0M9MgoJCVNWVD01MDIyIDMwMDEgMSAwIDAgCgkJU1ZUPTUwMjIgMjAwMyAyIDAgMCAKCU9TQz0xCgkJU1ZUPTUwMjIgMzAwMyAzIAoJCUNDPTEKCQkJQz0xMiAwIDMgMiAyIDMgMAoJCQlDUEM9MAojTlQ9MjAxODUgMAoJUEM9NwoJbmFtZT0xIHY9NTAwMCBiYXNlX2NvbG9yCglwb3N4PTEgdj0yMDAzIDcwMC4wCglwb3N5PTEgdj0yMDAzIC0yNDAuMAoJdHlwZT0yIGU9MCB2PTUwMTIgMgoJZGVmYXVsdHZlY3RocmVlPTIgZT0wIHY9MzAwMiAxLjAsMS4wLDEuMAoJZGVmYXVsdHZlY3Rvcj0yIGU9MCB2PTMwMDMgMC41LDAuNSwwLjUsMC4wCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiAyMAoJZ3JvdXA9LTEKCUlTQz0wCglPU0M9MQoJCVNWVD01MDIyIDMwMDIgMSAKCQlDQz0xCgkJCUM9MTMgMCAxIDIgMyA0IDAKCQkJQ1BDPTAKI05UPTIwMTg1IDAKCVBDPTcKCW5hbWU9MSB2PTUwMDAgdXNlX25vcm1hbF9tYXAKCXBvc3g9MSB2PTIwMDMgNzAwLjAKCXBvc3k9MSB2PTIwMDMgLTEyMC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAwCglkZWZhdWx0c2NhbGFyPTIgZT0wIHY9MjAwMyAxLjAKCXVpdHlwZT0yIGU9MCB2PTUwMTIgMQoJdWlvcmRlcj0yIGU9MCB2PTIwMDIgMTEKCWdyb3VwPS0xCglJU0M9MAoJT1NDPTEKCQlTVlQ9NTAyMiAyMDAzIDEgCgkJQ0M9MQoJCQlDPTE0IDAgMSAzIDAgMSAwCgkJCUNQQz0wCiNOVD0yMDE5NCAwCglQQz0yCglwb3N4PTEgdj0yMDAzIDY4MC4wCglwb3N5PTEgdj0yMDAzIDYwLjAKCWdyb3VwPS0xCglJU0M9MAoJT1NDPTEKCQlTVlQ9NTAyMiAzMDAyIDEgCgkJQ0M9MQoJCQlDPTE1IDAgMSAzIDMgNCAwCgkJCUNQQz0wCiNOVD0yMDE5NSAwCglQQz0yCglwb3N4PTEgdj0yMDAzIDc0MC4wCglwb3N5PTEgdj0yMDAzIC02MC4wCglncm91cD0tMQoJSVNDPTEKCQlTVlQ9NTAyMiAzMDAyIDEgMCAxIAoJCVNDUz1yZ2IKCU9TQz0xCgkJU1ZUPTUwMjIgMzAwMiAyIAoJCUNDPTEKCQkJQz0xNiAwIDIgMyAyIDMgMAoJCQlDUEM9MAojTlQ9MjAxNzcgMAoJUEM9NgoJbmFtZT0xIHY9NTAwMCBub3JtYWxfbWFwCglwb3N4PTEgdj0yMDAzIDQ0MC4wCglwb3N5PTEgdj0yMDAzIC02MC4wCgl0ZXh0dXJlcGF0aD0yIGU9MSB2PTUwMDAgRjovRHJvcGJveC9Ecm9wYm94L19IaWdoIEZpZGVsaXR5L3h5bG9waG9uZS94eWxvcGhvbmVGcmFtZVdpdGhXYXZlX1N0ZWVsX05vcm1hbC5wbmcKCWVuY29kaW5nPTIgZT0wIHY9NTAxMiAyCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiAyCglncm91cD0tMQoJSVNDPTIKCQlTVlQ9NTAyMiAzMDAxIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAwIDAgCglPU0M9MQoJCVNWVD01MDIyIDMwMDMgMyAKCQlDQz0xCgkJCUM9MTcgMCAzIDE2IDAgMSAwCgkJCUNQQz0wCiNOVD0yMDE3NyAwCglQQz03CgluYW1lPTEgdj01MDAwIG1ldGFsbGljX21hcAoJcG9zeD0xIHY9MjAwMyA3MDAuMAoJcG9zeT0xIHY9MjAwMyAyNDAuMAoJdGV4dHVyZXBhdGg9MiBlPTEgdj01MDAwIEY6L0Ryb3Bib3gvRHJvcGJveC9fSGlnaCBGaWRlbGl0eS94eWxvcGhvbmUveHlsb3Bob25lRnJhbWVXaXRoV2F2ZV9TdGVlbF9NZXRhbGxpYy5wbmcKCWVuY29kaW5nPTIgZT0wIHY9NTAxMiAwCglmaWx0ZXI9MiBlPTAgdj01MDEyIDEKCXVpb3JkZXI9MiBlPTAgdj0yMDAyIDMKCWdyb3VwPS0xCglJU0M9MgoJCVNWVD01MDIy", + "IDMwMDEgMSAwIDAgCgkJU1ZUPTUwMjIgMjAwMyAyIDAgMCAKCU9TQz0xCgkJU1ZUPTUwMjIgMzAwMyAzIAoJCUNDPTEKCQkJQz0xOCAwIDMgMCAyIDMgMAoJCQlDUEM9MAojTlQ9MjAxODUgMAoJUEM9NwoJbmFtZT0xIHY9NTAwMCB1c2VfbWV0YWxsaWNfbWFwCglwb3N4PTEgdj0yMDAzIDcwMC4wCglwb3N5PTEgdj0yMDAzIDE4MC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAwCglkZWZhdWx0c2NhbGFyPTIgZT0wIHY9MjAwMyAxLjAKCXVpdHlwZT0yIGU9MCB2PTUwMTIgMQoJdWlvcmRlcj0yIGU9MCB2PTIwMDIgMTIKCWdyb3VwPS0xCglJU0M9MAoJT1NDPTEKCQlTVlQ9NTAyMiAyMDAzIDEgCgkJQ0M9MQoJCQlDPTE5IDAgMSAwIDAgMSAwCgkJCUNQQz0wCiNOVD0yMDE4NSAwCglQQz02CgluYW1lPTEgdj01MDAwIG1ldGFsbGljCglwb3N4PTEgdj0yMDAzIDcwMC4wCglwb3N5PTEgdj0yMDAzIDM0MC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAwCglkZWZhdWx0c2NhbGFyPTIgZT0wIHY9MjAwMyAxLjAKCXVpb3JkZXI9MiBlPTAgdj0yMDAyIDIxCglncm91cD0tMQoJSVNDPTAKCU9TQz0xCgkJU1ZUPTUwMjIgMjAwMyAxIAoJCUNDPTEKCQkJQz0yMCAwIDEgMCAzIDQgMAoJCQlDUEM9MAojTlQ9MjAxODUgMAoJUEM9NwoJbmFtZT0xIHY9NTAwMCB1c2Vfcm91Z2huZXNzX21hcAoJcG9zeD0xIHY9MjAwMyA3MDAuMAoJcG9zeT0xIHY9MjAwMyA0ODAuMAoJdHlwZT0yIGU9MCB2PTUwMTIgMAoJZGVmYXVsdHNjYWxhcj0yIGU9MCB2PTIwMDMgMS4wCgl1aXR5cGU9MiBlPTAgdj01MDEyIDEKCXVpb3JkZXI9MiBlPTAgdj0yMDAyIDEzCglncm91cD0tMQoJSVNDPTAKCU9TQz0xCgkJU1ZUPTUwMjIgMjAwMyAxIAoJCUNDPTEKCQkJQz0yMSAwIDEgNCAwIDEgMAoJCQlDUEM9MAojTlQ9MjAxODUgMAoJUEM9NgoJbmFtZT0xIHY9NTAwMCByb3VnaG5lc3MKCXBvc3g9MSB2PTIwMDMgNzAwLjAKCXBvc3k9MSB2PTIwMDMgNjQwLjAKCXR5cGU9MiBlPTAgdj01MDEyIDAKCWRlZmF1bHRzY2FsYXI9MiBlPTAgdj0yMDAzIDAuNQoJdWlvcmRlcj0yIGU9MCB2PTIwMDIgMjIKCWdyb3VwPS0xCglJU0M9MAoJT1NDPTEKCQlTVlQ9NTAyMiAyMDAzIDEgCgkJQ0M9MQoJCQlDPTIyIDAgMSA0IDMgNCAwCgkJCUNQQz0wCiNOVD0yMDE4NSAwCglQQz01CgluYW1lPTEgdj01MDAwIGVtaXNzaXZlCglwb3N4PTEgdj0yMDAzIDQyMC4wCglwb3N5PTEgdj0yMDAzIDg4MC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAyCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiAyMwoJZ3JvdXA9LTEKCUlTQz0wCglPU0M9MQoJCVNWVD01MDIyIDMwMDIgMSAKCQlDQz0xCgkJCUM9MjMgMCAxIDEgMyA0IDAKCQkJQ1BDPTAKI05UPTIwMTg1IDAKCVBDPTYKCW5hbWU9MSB2PTUwMDAgdXNlX2VtaXNzaXZlX21hcAoJcG9zeD0xIHY9MjAwMyA0MjAuMAoJcG9zeT0xIHY9MjAwMyA3MjAuMAoJdHlwZT0yIGU9MCB2PTUwMTIgMAoJdWl0eXBlPTIgZT0wIHY9NTAxMiAxCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiAxNAoJZ3JvdXA9LTEKCUlTQz0wCglPU0M9MQoJCVNWVD01MDIyIDIwMDMgMSAKCQlDQz0xCgkJCUM9MjQgMCAxIDEgMCAxIDAKCQkJQ1BDPTAKI05UPTIwMTg1IDAKCVBDPTcKCW5hbWU9MSB2PTUwMDAgdXNlX2FvX21hcAoJcG9zeD0xIHY9MjAwMyA3MDAuMAoJcG9zeT0xIHY9MjAwMyAxMTAwLjAKCXR5cGU9MiBlPTAgdj01MDEyIDAKCWRlZmF1bHRzY2FsYXI9MiBlPTAgdj0yMDAzIDEuMAoJdWl0eXBlPTIgZT0wIHY9NTAxMiAxCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiAxNQoJZ3JvdXA9LTEKCUlTQz0wCglPU0M9MQoJCVNWVD01MDIyIDIwMDMgMSAKCQlDQz0xCgkJCUM9MjUgMCAxIDYgMCAxIDAKCQkJQ1BDPTAKI05UPTIwMTc3IDAKCVBDPTcKCW5hbWU9MSB2PTUwMDAgYW9fbWFwCglwb3N4PTEgdj0yMDAzIDcwMC4wCglwb3N5PTEgdj0yMDAzIDExNjAuMAoJdGV4dHVyZXBhdGg9MiBlPTEgdj01MDAwIEY6L0Ryb3Bib3gvRHJvcGJveC9fSGlnaCBGaWRlbGl0eS94eWxvcGhvbmUvCgllbmNvZGluZz0yIGU9MCB2PTUwMTIgMAoJZmlsdGVyPTIgZT0wIHY9NTAxMiAxCgl1aW9yZGVyPTIgZT0wIHY9MjAwMiA2Cglncm91cD0tMQoJSVNDPTIKCQlTVlQ9NTAyMiAzMDAxIDEgMCAwIAoJCVNWVD01MDIyIDIwMDMgMiAwIDAgCglPU0M9MQoJCVNWVD01MDIyIDMwMDMgMyAKCQlDQz0xCgkJCUM9MjYgMCAzIDYgMiAzIDAKCQkJQ1BDPTAKI05UPTIwMTg1IDAKCVBDPTYKCW5hbWU9MSB2PTUwMDAgZW1pc3NpdmVfaW50ZW5zaXR5Cglwb3N4PTEgdj0yMDAzIDc0MC4wCglwb3N5PTEgdj0yMDAzIDkyMC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAwCgltYXhyYW5nZT0yIGU9MCB2PTIwMDMgMTAuMAoJdWlvcmRlcj0yIGU9MCB2PTIwMDIgNTMKCWdyb3VwPS0xCglJU0M9MAoJT1NDPTEKCQlTVlQ9NTAyMiAyMDAzIDEgCgkJQ0M9MQoJCQlDPTI3IDAgMSAxMCAxIDIgMAoJCQlDUEM9MAojTlQ9MjAxODYgMAoJUEM9MgoJcG9zeD0xIHY9MjAwMyAtNjAuMAoJcG9zeT0xIHY9MjAwMyA0MDAuMAoJZ3JvdXA9LTEKCUlTQz0yCgkJU1ZUPTUwMjIgMzAwMSAxIDAgMCAKCQlTVlQ9NTAyMiAzMDAxIDIgMCAwIAoJT1NDPTEKCQlTVlQ9NTAyMiAzMDAxIDMgCgkJQ0M9MQoJCQlDPTI4IDAgMyAyOSAxIDIgMAoJCQlDUEM9MAojTlQ9MjAxODcgMAoJUEM9MgoJcG9zeD0xIHY9MjAwMyAxMjAuMAoJcG9zeT0xIHY9MjAwMyA0MDAuMAoJ", + "Z3JvdXA9LTEKCUlTQz0yCgkJU1ZUPTUwMjIgMzAwMSAxIDAgMCAKCQlTVlQ9NTAyMiAzMDAxIDIgMCAwIAoJT1NDPTEKCQlTVlQ9NTAyMiAzMDAxIDMgCgkJQ0M9NgoJCQlDPTI5IDAgMyAxMiAwIDEgMAoJCQlDUEM9MAoJCQlDPTI5IDAgMyAxNyAwIDEgMAoJCQlDUEM9MAoJCQlDPTI5IDAgMyAxOCAwIDEgMAoJCQlDUEM9MAoJCQlDPTI5IDAgMyA4IDAgMSAwCgkJCUNQQz0wCgkJCUM9MjkgMCAzIDkgMCAxIDAKCQkJQ1BDPTAKCQkJQz0yOSAwIDMgMjYgMCAxIDAKCQkJQ1BDPTAKI05UPTIwMTg1IDAKCVBDPTcKCW5hbWU9MSB2PTUwMDAgdXZfb2Zmc2V0Cglwb3N4PTEgdj0yMDAzIC02MC4wCglwb3N5PTEgdj0yMDAzIDM0MC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAxCgltaW5yYW5nZT0yIGU9MCB2PTIwMDMgLTFlKzAwOC4wCgltYXhyYW5nZT0yIGU9MCB2PTIwMDMgMWUrMDA4LjAKCXVpb3JkZXI9MiBlPTAgdj0yMDAyIDYwCglncm91cD0tMQoJSVNDPTAKCU9TQz0xCgkJU1ZUPTUwMjIgMzAwMSAxIAoJCUNDPTEKCQkJQz0zMCAwIDEgMjkgMCAxIDAKCQkJQ1BDPTAKI05UPTIwMTg1IDAKCVBDPTkKCW5hbWU9MSB2PTUwMDAgdXZfc2NhbGUKCXBvc3g9MSB2PTIwMDMgLTI0MC4wCglwb3N5PTEgdj0yMDAzIDM0MC4wCgl0eXBlPTIgZT0wIHY9NTAxMiAxCglkZWZhdWx0dmVjdHdvPTIgZT0wIHY9MzAwMSAxLjAsMS4wCglkZWZhdWx0dmVjdG9yPTIgZT0wIHY9MzAwMyAxLjAsMS4wLDAuMCwwLjAKCW1pbnJhbmdlPTIgZT0wIHY9MjAwMyAtMWUrMDA4LjAKCW1heHJhbmdlPTIgZT0wIHY9MjAwMyAxZSswMDguMAoJdWlvcmRlcj0yIGU9MCB2PTIwMDIgNjEKCWdyb3VwPS0xCglJU0M9MAoJT1NDPTEKCQlTVlQ9NTAyMiAzMDAxIDEgCgkJQ0M9MQoJCQlDPTMxIDAgMSAyOCAwIDEgMAoJCQlDUEM9MAoKICovIH0gCmNvbm5lY3Rpb25zID0gWwoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJhY2E2OTBjYi02MzA1LTRhMmYtYmYzZC02OTE4M2E0OTNkYjMiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjYiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIzIiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiQ0VEN0JCRjMtMEI0OC00MzM1LUI5MzMtMDk1QTQxQ0EwMjk0IiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIzIiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxMiIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjRDQkI0NDgwLTc5RTgtNENFNy1BQzBGLThCMDlCQUYxMjM5MCIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMyIgCgkJfSAKCQlzZWxlY3QgPSBbIAoJCQkicmdiIiAKCQkJXSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTMiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICIxZWU5YWYxZi02NWYyLTQ3MzktYWQyOC01ZWE2YTBlNjhmYzMiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTMiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjMwIiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiMWVlOWFmMWYtNjVmMi00NzM5LWFkMjgtNWVhNmEwZTY4ZmMzIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjE4IiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIzMCIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjFlZTlhZjFmLTY1ZjItNDczOS1hZDI4LTVlYTZhMGU2OGZjMyIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxOSIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMzAiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICIxZWU5YWYxZi02NWYyLTQ3MzktYWQyOC01ZWE2YTBlNjhmYzMiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjkiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjMwIiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiMWVlOWFmMWYtNjVmMi00NzM5LWFkMjgtNWVhNmEwZTY4ZmMzIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjEwIiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNl", + "X2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIzMCIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjFlZTlhZjFmLTY1ZjItNDczOS1hZDI4LTVlYTZhMGU2OGZjMyIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyNyIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMzAiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJmNzI1OTdjNC03NDg3LTQxOWEtYWZmYi1kZjY5MGU2NTgyZTEiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMzAiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjMxIiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiMDgwNmRiMGQtMmM0YS00M2NhLTk5Y2MtZjVhMmYwMzZhOGU4IiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjMwIiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyOSIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gImM1ODIzYzc1LTRhZTUtNGM3MS1iMDcwLTMxNWZhNGQwM2U4ZSIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyOSIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMzIiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICIyNDJkMTY0OC1hNjI2LTQ0NWItOTUzNC1iY2NlYzA5NDExMmYiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjkiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI4IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiRjJGNzRFNTgtNDAyRC00NzJCLTg3REQtMzMxRTAwREI0MTZDIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIzIiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxNCIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gImIxYzg2NDA4LWFhY2ItNDQ2Ni1iNzU0LWRkY2YzN2EzYTJjOCIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiNiIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjQiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJDRUQ3QkJGMy0wQjQ4LTQzMzUtQjkzMy0wOTVBNDFDQTAyOTQiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjQiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjE1IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiNENCQjQ0ODAtNzlFOC00Q0U3LUFDMEYtOEIwOUJBRjEyMzkwIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI0IiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxNyIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gImY3MjU5N2M0LTc0ODctNDE5YS1hZmZiLWRmNjkwZTY1ODJlMSIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxNyIgCgkJfSAKCQlzZWxlY3QgPSBbIAoJCQkicmdiIiAKCQkJXSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTgiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJGMkY3NEU1OC00MDJELTQ3MkItODdERC0zMzFFMDBEQjQxNkMiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjQiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjE2IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiYWQ1ZTA1MmYtZDMxNi00YTBmLThiNzktNTNjMzgyMDRkNjFiIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI2IiAKCQl9IAoJCXNvdXJj", + "ZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMSIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIkNFRDdCQkYzLTBCNDgtNDMzNS1COTMzLTA5NUE0MUNBMDI5NCIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMSIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjAiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICI0Q0JCNDQ4MC03OUU4LTRDRTctQUMwRi04QjA5QkFGMTIzOTAiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjEiIAoJCX0gCgkJc2VsZWN0ID0gWyAKCQkJInIiIAoJCQldIAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxOSIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIkYyRjc0RTU4LTQwMkQtNDcyQi04N0RELTMzMUUwMERCNDE2QyIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMSIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjEiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICIzNmJhNDZkMi1mNmVhLTRlNjAtYTQyOC1mZGMxN2M3NWJjNjIiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjYiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI1IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiQ0VEN0JCRjMtMEI0OC00MzM1LUI5MzMtMDk1QTQxQ0EwMjk0IiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI1IiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyMiIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjRDQkI0NDgwLTc5RTgtNENFNy1BQzBGLThCMDlCQUYxMjM5MCIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiNSIgCgkJfSAKCQlzZWxlY3QgPSBbIAoJCQkiciIgCgkJCV0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI5IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiRjJGNzRFNTgtNDAyRC00NzJCLTg3REQtMzMxRTAwREI0MTZDIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI1IiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyMyIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjExNjRhNWVmLTQ1NjMtNDc5NS1iM2I1LTQyODI1ZDZkZjAzNyIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiNiIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTEiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJjNTgyM2M3NS00YWU1LTRjNzEtYjA3MC0zMTVmYTRkMDNlOGUiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTEiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIyIiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiQ0VEN0JCRjMtMEI0OC00MzM1LUI5MzMtMDk1QTQxQ0EwMjk0IiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIyIiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyNSIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjRDQkI0NDgwLTc5RTgtNENFNy1BQzBGLThCMDlCQUYxMjM5MCIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMiIgCgkJfSAKCQlzZWxlY3QgPSBbIAoJCQkicmdiIiAKCQkJXSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTAiIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJGMkY3NEU1OC00MDJELTQ3MkItODdERC0zMzFFMDBEQjQx", + "NkMiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjIiIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjI0IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiMjQyZDE2NDgtYTYyNi00NDViLTk1MzQtYmNjZWMwOTQxMTJmIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjExIiAKCQl9IAoJCXNvdXJjZSA9IHsgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyOCIgCgkJfSAKCX0gCgl7IAoJCWRlc3RpbmF0aW9uID0geyAKCQkJY29ubmVjdG9yX2lkID0gIjU5ZmQxY2Y0LWY3MzYtNDcwZC04NTEwLTFkZDdjMDE2NjM5ZSIgCgkJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiNiIgCgkJfSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjciIAoJCX0gCgl9IAoJeyAKCQlkZXN0aW5hdGlvbiA9IHsgCgkJCWNvbm5lY3Rvcl9pZCA9ICJDRUQ3QkJGMy0wQjQ4LTQzMzUtQjkzMy0wOTVBNDFDQTAyOTQiIAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjciIAoJCX0gCgkJc291cmNlID0geyAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjI2IiAKCQl9IAoJfSAKCXsgCgkJZGVzdGluYXRpb24gPSB7IAoJCQljb25uZWN0b3JfaWQgPSAiNENCQjQ0ODAtNzlFOC00Q0U3LUFDMEYtOEIwOUJBRjEyMzkwIiAKCQkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI3IiAKCQl9IAoJCXNlbGVjdCA9IFsgCgkJCSJyIiAKCQkJXSAKCQlzb3VyY2UgPSB7IAoJCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjciIAoJCX0gCgl9IApdCmNvbnN0YW50cyA9IFsKCXsgCgkJY29ubmVjdG9yX2lkID0gIjM5QkM3NjE5LTI3NjgtNDgwQi1BQ0ZELTYzRkE2NkVGNjkwNSIgCgkJaWQgPSAiMWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIzIiAKCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjMiIAoJCXZhbHVlID0gWyAKCQkJMS4wCgkJXSAKCX0gCgl7IAoJCWNvbm5lY3Rvcl9pZCA9ICIzOUJDNzYxOS0yNzY4LTQ4MEItQUNGRC02M0ZBNjZFRjY5MDUiIAoJCWlkID0gIjFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiNCIgCgkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI0IiAKCQl2YWx1ZSA9IFsgCgkJCTEuMAoJCV0gCgl9IAoJeyAKCQljb25uZWN0b3JfaWQgPSAiMzlCQzc2MTktMjc2OC00ODBCLUFDRkQtNjNGQTY2RUY2OTA1IiAKCQlpZCA9ICIxYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjEiIAoJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMSIgCgkJdmFsdWUgPSBbIAoJCQkxLjAKCQldIAoJfSAKCXsgCgkJY29ubmVjdG9yX2lkID0gIjM5QkM3NjE5LTI3NjgtNDgwQi1BQ0ZELTYzRkE2NkVGNjkwNSIgCgkJaWQgPSAiMWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI1IiAKCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjUiIAoJCXZhbHVlID0gWyAKCQkJMS4wCgkJXSAKCX0gCgl7IAoJCWNvbm5lY3Rvcl9pZCA9ICIzOUJDNzYxOS0yNzY4LTQ4MEItQUNGRC02M0ZBNjZFRjY5MDUiIAoJCWlkID0gIjFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMiIgCgkJaW5zdGFuY2VfaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIyIiAKCQl2YWx1ZSA9IFsgCgkJCTEuMAoJCV0gCgl9IAoJeyAKCQljb25uZWN0b3JfaWQgPSAiMzlCQzc2MTktMjc2OC00ODBCLUFDRkQtNjNGQTY2RUY2OTA1IiAKCQlpZCA9ICIxYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjciIAoJCWluc3RhbmNlX2lkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiNyIgCgkJdmFsdWUgPSBbIAoJCQkxLjAKCQldIAoJfSAKCXsgCgkJY29ubmVjdG9yX2lkID0gIkYyRjc0RTU4LTQwMkQtNDcyQi04N0RELTMzMUUwMERCNDE2QyIgCgkJaWQgPSAiM2JiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI3IiAKCQlpbnN0YW5jZV9pZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjciIAoJCXZhbHVlID0gWyAKCQkJMS4wCgkJXSAKCX0gCl0Kbm9kZXMgPSBbCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjYiIAoJCW9wdGlvbnMgPSBbIAoJCQkiMmIxMzY0NDctNjc2ZS00OTQzLTk5N2ItMDRhMjhhZTY4NDk3IgoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQkxMzYwIAoJCQkyNjAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJT", + "dGFuZGFyZCBCYXNlIiAKCQl0eXBlID0gImNvcmUvc3RpbmdyYXlfcmVuZGVyZXIvb3V0cHV0X25vZGVzL3N0YW5kYXJkX2Jhc2UiIAoJfSAKCXsgCgkJY29udGVudF9zaXplID0gWyAKCQkJMTYwIAoJCQkwIAoJCV0gCgkJZXhwb3J0ID0geyAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMyIgCgkJb3B0aW9ucyA9IFsgCgkJCSI5QTg0MjgyQi1GMUEyLTQ2RDQtOUZDNC01QTc2RkM5QjMwREQiCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTEwMjAgCgkJCS0zNDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJDb2xvciBNYXAgU3dpdGNoIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL2lmIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJCW1hdGVyaWFsX3ZhcmlhYmxlID0geyAKCQkJCWRpc3BsYXlfbmFtZSA9ICJVc2UgQ29sb3IgTWFwIiAKCQkJCW5hbWUgPSAidXNlX2NvbG9yX21hcCIgCgkJCQl1aSA9IHsgCgkJCQkJbWF4ID0gMSAKCQkJCQltaW4gPSAwLjAgCgkJCQkJc3RlcCA9IDEgCgkJCQkJb3JkZXIgPSAxMCAKCQkJCQl1aV90eXBlID0gImNoZWNrYm94IiAKCQkJCX0gCgkJCQl0eXBlID0gImZsb2F0IiAKCQkJCXZhbHVlID0gMS4wIAoJCQl9IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjEyIiAKCQlvcHRpb25zID0gWyAKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNzAwIAoJCQktNDAwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVXNlIENvbG9yIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjEzIiAKCQlvcHRpb25zID0gWyAKCQkJIjFlMDY3NDY0LTEyZDgtNDgyNi05YjcyLWNmZDU3NjUwMDNlMyIKCQkJImZiM2Y3MDliLWE1NGEtNGU5My1hYzlmLWU5ZmM3NmZiOGJjZCIKCQkJIjVkZDU5YjNkLTE3NjItNGExNC05OTMwLTc1MDAyMzBlZjNkYiIKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNzAwIAoJCQktMzQwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCQl0ZXh0dXJlX21hcCA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiQ29sb3IgTWFwIiAKCQkJCXNsb3RfbmFtZSA9ICJjb2xvcl9tYXAiIAoJCQkJdWkgPSB7IAoJCQkJCW9yZGVyID0gMSAKCQkJCX0gCgkJCX0gCgkJfSAKCQl0aXRsZSA9ICJDb2xvciBNYXAiIAoJCXR5cGUgPSAiY29yZS9zaGFkZXJfbm9kZXMvc2FtcGxlX3RleHR1cmUiIAoJfSAKCXsgCgkJY29udGVudF9zaXplID0gWyAKCQkJMTYwIAoJCQkwIAoJCV0gCgkJZXhwb3J0ID0geyAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIzMCIgCgkJb3B0aW9ucyA9IFsgCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTEyMCAKCQkJNDAwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiQWRkIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL2FkZCIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiVXYgT2Zmc2V0IiAKCQkJCW5hbWUgPSAidXZfb2Zmc2V0IiAKCQkJCXVpID0geyAKCQkJCQltYXggPSBbIDFlKzAwOC4wIDFlKzAwOC4wIF0gCgkJCQkJbWluID0gWyAtMWUrMDA4LjAgLTFlKzAwOC4wIF0gCgkJCQkJc3RlcCA9IFsgMC4wMSAwLjAxIF0gCgkJCQkJb3JkZXIgPSA2MCAKCQkJCX0gCgkJCQl0eXBlID0gImZsb2F0MiIgCgkJCQl2YWx1ZSA9IFswLjAgMC4wXSAKCQkJfSAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIzMSIgCgkJb3B0aW9ucyA9IFsgCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCS02MCAKCQkJMzQwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVXYgT2Zmc2V0IiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL21hdGVyaWFsX3ZhcmlhYmxlIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjkiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQktNjAgCgkJCTQwMCAKCQldIAoJCXNhbXBsZXJzID0geyAKCQl9IAoJCXRpdGxlID0gIk11bHRpcGx5IiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL211bCIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiVXYgU2NhbGUiIAoJCQkJbmFtZSA9ICJ1dl9zY2FsZSIgCgkJCQl1aSA9IHsgCgkJCQkJbWF4ID0gWyAxZSswMDguMCAxZSswMDguMCBdIAoJCQkJCW1pbiA9IFsgLTFlKzAwOC4wIC0xZSswMDguMCBdIAoJCQkJCXN0ZXAgPSBbIDAuMDEgMC4wMSBdIAoJCQkJCW9yZGVyID0gNjEgCgkJCQl9IAoJCQkJdHlw", + "ZSA9ICJmbG9hdDIiIAoJCQkJdmFsdWUgPSBbMS4wIDEuMF0gCgkJCX0gCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMzIiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQktMjQwIAoJCQkzNDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJVdiBTY2FsZSIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI4IiAKCQlvcHRpb25zID0gWyAKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJLTI2MCAKCQkJNDIwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVGV4Y29vcmQwIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL3RleHR1cmVfY29vcmRpbmF0ZTAiIAoJfSAKCXsgCgkJY29udGVudF9zaXplID0gWyAKCQkJMTYwIAoJCQkwIAoJCV0gCgkJZXhwb3J0ID0geyAKCQkJbWF0ZXJpYWxfdmFyaWFibGUgPSB7IAoJCQkJZGlzcGxheV9uYW1lID0gIkJhc2UgQ29sb3IiIAoJCQkJbmFtZSA9ICJiYXNlX2NvbG9yIiAKCQkJCXVpID0geyAKCQkJCQltYXggPSBbIDEuMCAxLjAgMS4wIF0gCgkJCQkJbWluID0gWyAwLjAgMC4wIDAuMCBdIAoJCQkJCXN0ZXAgPSBbIDAuMDEgMC4wMSAwLjAxIF0gCgkJCQkJb3JkZXIgPSAyMCAKCQkJCQl1aV90eXBlID0gImNvbG9yIiAKCQkJCX0gCgkJCQl0eXBlID0gImZsb2F0MyIgCgkJCQl2YWx1ZSA9IFsxLjAgMS4wIDEuMF0gCgkJCX0gCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTQiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk3MDAgCgkJCS0yNDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJCYXNlIENvbG9yIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL21hdGVyaWFsX3ZhcmlhYmxlIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjQiIAoJCW9wdGlvbnMgPSBbIAoJCQkiOUE4NDI4MkItRjFBMi00NkQ0LTlGQzQtNUE3NkZDOUIzMEREIgoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQkxMDIwIAoJCQktNjAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJOb3JtYWwgTWFwIFN3aXRjaCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9pZiIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiVXNlIE5vcm1hbCBNYXAiIAoJCQkJbmFtZSA9ICJ1c2Vfbm9ybWFsX21hcCIgCgkJCQl1aSA9IHsgCgkJCQkJbWF4ID0gMSAKCQkJCQltaW4gPSAwLjAgCgkJCQkJc3RlcCA9IDEgCgkJCQkJb3JkZXIgPSAxMSAKCQkJCQl1aV90eXBlID0gImNoZWNrYm94IiAKCQkJCX0gCgkJCQl0eXBlID0gImZsb2F0IiAKCQkJCXZhbHVlID0gMS4wIAoJCQl9IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjE1IiAKCQlvcHRpb25zID0gWyAKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNzAwIAoJCQktMTIwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVXNlIE5vcm1hbCBNYXAiIAoJCXR5cGUgPSAiY29yZS9zaGFkZXJfbm9kZXMvbWF0ZXJpYWxfdmFyaWFibGUiIAoJfSAKCXsgCgkJY29udGVudF9zaXplID0gWyAKCQkJMTYwIAoJCQkwIAoJCV0gCgkJZXhwb3J0ID0geyAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIxNyIgCgkJb3B0aW9ucyA9IFsgCgkJCSIwYTBmYjVhZC0xNDVkLTQyMjktYWJkNC01YjM2NTYyNjA3YjMiCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTc0MCAKCQkJLTYwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVGFuZ2VudCBUbyBXb3JsZCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy90YW5nZW50X3RvX3dvcmxkIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTgiIAoJCW9wdGlvbnMgPSBbIAoJCQkiMWUwNjc0NjQtMTJkOC00ODI2LTliNzItY2ZkNTc2NTAwM2UzIgoJCQkiOTBlMjA4MjYtODY4OS00MmZhLThlMjQtZjQ4NGVjNjRjNWMzIgoJCQkiNWRkNTliM2QtMTc2Mi00YTE0LTk5MzAtNzUwMDIzMGVmM2RiIgoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk0NDAgCgkJCS02MCAKCQldIAoJCXNhbXBsZXJzID0geyAKCQkJdGV4dHVyZV9tYXAgPSB7IAoJCQkJZGlzcGxheV9uYW1lID0gIk5vcm1hbCBNYXAiIAoJCQkJc2xvdF9uYW1lID0gIm5vcm1hbF9tYXAiIAoJCQkJdWkgPSB7IAoJCQkJCW9yZGVyID0gMiAKCQkJCX0gCgkJCX0gCgkJfSAKCQl0aXRsZSA9ICJOb3JtYWwgTWFwIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL3NhbXBsZV90ZXh0dXJlIiAK", + "CX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTYiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk2ODAgCgkJCTYwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiV29ybGQgTm9ybWFsIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL3dvcmxkX3NwYWNlX25vcm1hbCIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmIxIiAKCQlvcHRpb25zID0gWyAKCQkJIjlBODQyODJCLUYxQTItNDZENC05RkM0LTVBNzZGQzlCMzBERCIKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJMTAyMCAKCQkJMjQwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiTWV0YWxsaWMgTWFwIFN3aXRjaCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9pZiIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiVXNlIE1ldGFsbGljIE1hcCIgCgkJCQluYW1lID0gInVzZV9tZXRhbGxpY19tYXAiIAoJCQkJdWkgPSB7IAoJCQkJCW1heCA9IDEgCgkJCQkJbWluID0gMC4wIAoJCQkJCXN0ZXAgPSAxIAoJCQkJCW9yZGVyID0gMTIgCgkJCQkJdWlfdHlwZSA9ICJjaGVja2JveCIgCgkJCQl9IAoJCQkJdHlwZSA9ICJmbG9hdCIgCgkJCQl2YWx1ZSA9IDEuMCAKCQkJfSAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyMCIgCgkJb3B0aW9ucyA9IFsgCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTcwMCAKCQkJMTgwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVXNlIE1ldGFsbGljIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjE5IiAKCQlvcHRpb25zID0gWyAKCQkJImY2NjlhM2E2LTAzNzYtNDE4Ny04NDBlLTgwMDAwZTI5MzlkNSIKCQkJImU5NGU1M2U2LTQ5YjYtNDE5NC1hNzQ3LThmMDY0YTU5MzJlMCIKCQkJIjVkZDU5YjNkLTE3NjItNGExNC05OTMwLTc1MDAyMzBlZjNkYiIKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNzAwIAoJCQkyNDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJCXRleHR1cmVfbWFwID0geyAKCQkJCWRpc3BsYXlfbmFtZSA9ICJNZXRhbGxpYyBNYXAiIAoJCQkJc2xvdF9uYW1lID0gIm1ldGFsbGljX21hcCIgCgkJCQl1aSA9IHsgCgkJCQkJb3JkZXIgPSAzIAoJCQkJfSAKCQkJfSAKCQl9IAoJCXRpdGxlID0gIk1ldGFsbGljIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9zYW1wbGVfdGV4dHVyZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiTWV0YWxsaWMiIAoJCQkJbmFtZSA9ICJtZXRhbGxpYyIgCgkJCQl1aSA9IHsgCgkJCQkJbWF4ID0gMS4wIAoJCQkJCW1pbiA9IDAuMCAKCQkJCQlzdGVwID0gMC4wMSAKCQkJCQlvcmRlciA9IDIxIAoJCQkJfSAKCQkJCXR5cGUgPSAiZmxvYXQiIAoJCQkJdmFsdWUgPSAxLjAgCgkJCX0gCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjEiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk3MDAgCgkJCTM0MCAKCQldIAoJCXNhbXBsZXJzID0geyAKCQl9IAoJCXRpdGxlID0gIk1ldGFsbGljIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL21hdGVyaWFsX3ZhcmlhYmxlIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiYjUiIAoJCW9wdGlvbnMgPSBbIAoJCQkiOUE4NDI4MkItRjFBMi00NkQ0LTlGQzQtNUE3NkZDOUIzMEREIgoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQkxMDIwIAoJCQk1NDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJSb3VnaG5lc3MgTWFwIFN3aXRjaCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9pZiIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiVXNlIFJvdWdobmVzcyBNYXAiIAoJCQkJbmFtZSA9ICJ1c2Vfcm91Z2huZXNzX21hcCIgCgkJCQl1aSA9IHsgCgkJCQkJbWF4ID0gMSAKCQkJCQltaW4gPSAwLjAgCgkJCQkJc3RlcCA9IDEgCgkJCQkJb3JkZXIgPSAxMyAKCQkJCQl1aV90eXBlID0gImNoZWNrYm94IiAKCQkJCX0gCgkJCQl0eXBlID0gImZsb2F0IiAKCQkJCXZhbHVlID0gMS4wIAoJCQl9IAoJCX0gCgkJaWQg", + "PSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjIyIiAKCQlvcHRpb25zID0gWyAKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNzAwIAoJCQk0ODAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJVc2UgUm91Z2huZXNzIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI5IiAKCQlvcHRpb25zID0gWyAKCQkJIjFlMDY3NDY0LTEyZDgtNDgyNi05YjcyLWNmZDU3NjUwMDNlMyIKCQkJImU5NGU1M2U2LTQ5YjYtNDE5NC1hNzQ3LThmMDY0YTU5MzJlMCIKCQkJIjVkZDU5YjNkLTE3NjItNGExNC05OTMwLTc1MDAyMzBlZjNkYiIKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNzAwIAoJCQk1NDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJCXRleHR1cmVfbWFwID0geyAKCQkJCWRpc3BsYXlfbmFtZSA9ICJSb3VnaG5lc3MgTWFwIiAKCQkJCXNsb3RfbmFtZSA9ICJyb3VnaG5lc3NfbWFwIiAKCQkJCXVpID0geyAKCQkJCQlvcmRlciA9IDQgCgkJCQl9IAoJCQl9IAoJCX0gCgkJdGl0bGUgPSAiUm91Z2huZXNzIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9zYW1wbGVfdGV4dHVyZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiUm91Z2huZXNzIiAKCQkJCW5hbWUgPSAicm91Z2huZXNzIiAKCQkJCXVpID0geyAKCQkJCQltYXggPSAxLjAgCgkJCQkJbWluID0gMC4wIAoJCQkJCXN0ZXAgPSAwLjAxIAoJCQkJCW9yZGVyID0gMjIgCgkJCQl9IAoJCQkJdHlwZSA9ICJmbG9hdCIgCgkJCQl2YWx1ZSA9IDAuNSAKCQkJfSAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyMyIgCgkJb3B0aW9ucyA9IFsgCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTcwMCAKCQkJNjQwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiUm91Z2huZXNzIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL21hdGVyaWFsX3ZhcmlhYmxlIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMTEiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQkxMDIwIAoJCQk4NDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJNdWx0aXBseSIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tdWwiIAoJfSAKCXsgCgkJY29udGVudF9zaXplID0gWyAKCQkJMTYwIAoJCQkwIAoJCV0gCgkJZXhwb3J0ID0geyAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWJiMiIgCgkJb3B0aW9ucyA9IFsgCgkJCSI5QTg0MjgyQi1GMUEyLTQ2RDQtOUZDNC01QTc2RkM5QjMwREQiCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTc0MCAKCQkJNzgwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiRW1pc3NpdmUgTWFwIFN3aXRjaCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9pZiIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiVXNlIEVtaXNzaXZlIE1hcCIgCgkJCQluYW1lID0gInVzZV9lbWlzc2l2ZV9tYXAiIAoJCQkJdWkgPSB7IAoJCQkJCW1heCA9IDEgCgkJCQkJbWluID0gMC4wIAoJCQkJCXN0ZXAgPSAxIAoJCQkJCW9yZGVyID0gMTQgCgkJCQkJdWlfdHlwZSA9ICJjaGVja2JveCIgCgkJCQl9IAoJCQkJdHlwZSA9ICJmbG9hdCIgCgkJCQl2YWx1ZSA9IDAuMCAKCQkJfSAKCQl9IAoJCWlkID0gImFiYmFhYmJhLWFiYmEtYWJiYS1hYmJhLWFiYmFhYmJhYWIyNSIgCgkJb3B0aW9ucyA9IFsgCgkJXSAKCQlwb3NpdGlvbiA9IFsgCgkJCTQyMCAKCQkJNzIwIAoJCV0gCgkJc2FtcGxlcnMgPSB7IAoJCX0gCgkJdGl0bGUgPSAiVXNlIEVtaXNzaXZlIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjEwIiAKCQlvcHRpb25zID0gWyAKCQkJIjFlMDY3NDY0LTEyZDgtNDgyNi05YjcyLWNmZDU3NjUwMDNlMyIKCQkJImZiM2Y3MDliLWE1NGEtNGU5My1hYzlmLWU5ZmM3NmZiOGJjZCIKCQkJIjVkZDU5YjNkLTE3NjItNGExNC05OTMwLTc1MDAyMzBlZjNkYiIKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNDIwIAoJCQk3ODAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJCXRleHR1cmVfbWFwID0geyAKCQkJCWRpc3BsYXlfbmFtZSA9ICJFbWlzc2l2ZSBNYXAiIAoJCQkJc2xvdF9uYW1lID0gImVtaXNzaXZlX21hcCIgCgkJCQl1aSA9IHsgCgkJCQkJb3JkZXIgPSA1IAoJCQkJfSAK", + "CQkJfSAKCQl9IAoJCXRpdGxlID0gIkVtaXNzaXZlIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9zYW1wbGVfdGV4dHVyZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiRW1pc3NpdmUiIAoJCQkJbmFtZSA9ICJlbWlzc2l2ZSIgCgkJCQl1aSA9IHsgCgkJCQkJbWF4ID0gWyAxLjAgMS4wIDEuMCBdIAoJCQkJCW1pbiA9IFsgMC4wIDAuMCAwLjAgXSAKCQkJCQlzdGVwID0gWyAwLjAxIDAuMDEgMC4wMSBdIAoJCQkJCW9yZGVyID0gMjMgCgkJCQkJdWlfdHlwZSA9ICJjb2xvciIgCgkJCQl9IAoJCQkJdHlwZSA9ICJmbG9hdDMiIAoJCQkJdmFsdWUgPSBbMC4wIDAuMCAwLjBdIAoJCQl9IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYjI0IiAKCQlvcHRpb25zID0gWyAKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJNDIwIAoJCQk4ODAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJFbWlzc2l2ZSIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCQltYXRlcmlhbF92YXJpYWJsZSA9IHsgCgkJCQlkaXNwbGF5X25hbWUgPSAiRW1pc3NpdmUgSW50ZW5zaXR5IiAKCQkJCW5hbWUgPSAiZW1pc3NpdmVfaW50ZW5zaXR5IiAKCQkJCXVpID0geyAKCQkJCQltYXggPSAxMC4wIAoJCQkJCW1pbiA9IDAuMCAKCQkJCQlzdGVwID0gMC4wMSAKCQkJCQlvcmRlciA9IDUzIAoJCQkJfSAKCQkJCXR5cGUgPSAiZmxvYXQiIAoJCQkJdmFsdWUgPSAwLjAgCgkJCX0gCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjgiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk3NDAgCgkJCTkyMCAKCQldIAoJCXNhbXBsZXJzID0geyAKCQl9IAoJCXRpdGxlID0gIkVtaXNzaXZlIEludGVuc2l0eSIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9tYXRlcmlhbF92YXJpYWJsZSIgCgl9IAoJeyAKCQljb250ZW50X3NpemUgPSBbIAoJCQkxNjAgCgkJCTAgCgkJXSAKCQlleHBvcnQgPSB7IAoJCX0gCgkJaWQgPSAiYWJiYWFiYmEtYWJiYS1hYmJhLWFiYmEtYWJiYWFiYmFhYmI3IiAKCQlvcHRpb25zID0gWyAKCQkJIjlBODQyODJCLUYxQTItNDZENC05RkM0LTVBNzZGQzlCMzBERCIKCQldIAoJCXBvc2l0aW9uID0gWyAKCQkJMTAyMCAKCQkJMTEwMCAKCQldIAoJCXNhbXBsZXJzID0geyAKCQl9IAoJCXRpdGxlID0gIkFvIE1hcCBTd3RpY2giIAoJCXR5cGUgPSAiY29yZS9zaGFkZXJfbm9kZXMvaWYiIAoJfSAKCXsgCgkJY29udGVudF9zaXplID0gWyAKCQkJMTYwIAoJCQkwIAoJCV0gCgkJZXhwb3J0ID0geyAKCQkJbWF0ZXJpYWxfdmFyaWFibGUgPSB7IAoJCQkJZGlzcGxheV9uYW1lID0gIlVzZSBBbyBNYXAiIAoJCQkJbmFtZSA9ICJ1c2VfYW9fbWFwIiAKCQkJCXVpID0geyAKCQkJCQltYXggPSAxIAoJCQkJCW1pbiA9IDAuMCAKCQkJCQlzdGVwID0gMSAKCQkJCQlvcmRlciA9IDE1IAoJCQkJCXVpX3R5cGUgPSAiY2hlY2tib3giIAoJCQkJfSAKCQkJCXR5cGUgPSAiZmxvYXQiIAoJCQkJdmFsdWUgPSAxLjAgCgkJCX0gCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjYiIAoJCW9wdGlvbnMgPSBbIAoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk3MDAgCgkJCTExMDAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJfSAKCQl0aXRsZSA9ICJVc2UgQW8gTWFwIiAKCQl0eXBlID0gImNvcmUvc2hhZGVyX25vZGVzL21hdGVyaWFsX3ZhcmlhYmxlIiAKCX0gCgl7IAoJCWNvbnRlbnRfc2l6ZSA9IFsgCgkJCTE2MCAKCQkJMCAKCQldIAoJCWV4cG9ydCA9IHsgCgkJfSAKCQlpZCA9ICJhYmJhYWJiYS1hYmJhLWFiYmEtYWJiYS1hYmJhYWJiYWFiMjciIAoJCW9wdGlvbnMgPSBbIAoJCQkiZjY2OWEzYTYtMDM3Ni00MTg3LTg0MGUtODAwMDBlMjkzOWQ1IgoJCQkiZTk0ZTUzZTYtNDliNi00MTk0LWE3NDctOGYwNjRhNTkzMmUwIgoJCQkiNWRkNTliM2QtMTc2Mi00YTE0LTk5MzAtNzUwMDIzMGVmM2RiIgoJCV0gCgkJcG9zaXRpb24gPSBbIAoJCQk3MDAgCgkJCTExNjAgCgkJXSAKCQlzYW1wbGVycyA9IHsgCgkJCXRleHR1cmVfbWFwID0geyAKCQkJCWRpc3BsYXlfbmFtZSA9ICJBbyBNYXAiIAoJCQkJc2xvdF9uYW1lID0gImFvX21hcCIgCgkJCQl1aSA9IHsgCgkJCQkJb3JkZXIgPSA2IAoJCQkJfSAKCQkJfSAKCQl9IAoJCXRpdGxlID0gIkFvIE1hcCIgCgkJdHlwZSA9ICJjb3JlL3NoYWRlcl9ub2Rlcy9zYW1wbGVfdGV4dHVyZSIgCgl9IApdCnZlcnNpb24gPSAzCgA=" + } + } + } + BindingTable: 994552656, "BindingTable::root 2", "" { + Version: 100 + Properties70: { + P: "TargetName", "KString", "", "", "root" + P: "TargetType", "KString", "", "", "shader" + } + Entry: "Maya|use_metallic_map", "FbxPropertyEntry", "use_metallic_map", "FbxSemanticEntry" + Entry: "Maya|base_color", "FbxPropertyEntry", "base_color", "FbxSemanticEntry" + Entry: "Maya|use_ao_map", "FbxPropertyEntry", "use_ao_map", "FbxSemanticEntry" + Entry: "Maya|TEX_emissive_map", "FbxPropertyEntry", "TEX_emissive_map", "FbxSemanticEntry" + Entry: "Maya|TEX_metallic_map", "FbxPropertyEntry", "TEX_metallic_map", "FbxSemanticEntry" + Entry: "Maya|TEX_ao_map", "FbxPropertyEntry", "TEX_ao_map", "FbxSemanticEntry" + Entry: "Maya|uv_offset", "FbxPropertyEntry", "uv_offset", "FbxSemanticEntry" + Entry: "Maya|emissive_intensity", "FbxPropertyEntry", "emissive_intensity", "FbxSemanticEntry" + Entry: "Maya|metallic", "FbxPropertyEntry", "metallic", "FbxSemanticEntry" + Entry: "Maya|TEX_global_specular_cube", "FbxPropertyEntry", "TEX_global_specular_cube", "FbxSemanticEntry" + Entry: "Maya|use_roughness_map", "FbxPropertyEntry", "use_roughness_map", "FbxSemanticEntry" + Entry: "Maya|use_normal_map", "FbxPropertyEntry", "use_normal_map", "FbxSemanticEntry" + Entry: "Maya|use_color_map", "FbxPropertyEntry", "use_color_map", "FbxSemanticEntry" + Entry: "Maya|emissive", "FbxPropertyEntry", "emissive", "FbxSemanticEntry" + Entry: "Maya|use_emissive_map", "FbxPropertyEntry", "use_emissive_map", "FbxSemanticEntry" + Entry: "Maya|uv_scale", "FbxPropertyEntry", "uv_scale", "FbxSemanticEntry" + Entry: "Maya|TEX_global_diffuse_cube", "FbxPropertyEntry", "TEX_global_diffuse_cube", "FbxSemanticEntry" + Entry: "Maya|TEX_roughness_map", "FbxPropertyEntry", "TEX_roughness_map", "FbxSemanticEntry" + Entry: "Maya|roughness", "FbxPropertyEntry", "roughness", "FbxSemanticEntry" + Entry: "Maya|TEX_brdf_lut", "FbxPropertyEntry", "TEX_brdf_lut", "FbxSemanticEntry" + Entry: "Maya|TEX_color_map", "FbxPropertyEntry", "TEX_color_map", "FbxSemanticEntry" + Entry: "Maya|TEX_normal_map", "FbxPropertyEntry", "TEX_normal_map", "FbxSemanticEntry" + } + AnimationStack: 1971005888, "AnimStack::Take 001", "" { + Properties70: { + P: "LocalStart", "KTime", "Time", "",1924423250 + P: "LocalStop", "KTime", "Time", "",230930790000 + P: "ReferenceStart", "KTime", "Time", "",1924423250 + P: "ReferenceStop", "KTime", "Time", "",230930790000 + } + } + AnimationLayer: 362989216, "AnimLayer::BaseLayer", "" { + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::HiFi_Xylophone1, Model::RootNode + C: "OO",363536144,0 + + ;Model::Wave, Model::RootNode + C: "OO",363501344,0 + + ;AnimLayer::BaseLayer, AnimStack::Take 001 + C: "OO",362989216,1971005888 + + ;NodeAttribute::, Model::HiFi_Xylophone1 + C: "OO",1611246784,363536144 + + ;Model::Frame, Model::HiFi_Xylophone1 + C: "OO",363538464,363536144 + + ;NodeAttribute::, Model::Frame + C: "OO",1611245728,363538464 + + ;Model::Wave, Model::Frame + C: "OO",363550064,363538464 + + ;Model::transform1, Model::Frame + C: "OO",363503664,363538464 + + ;NodeAttribute::, Model::Wave + C: "OO",1611246608,363550064 + + ;Model::transform2, Model::Wave + C: "OO",363517584,363550064 + + ;NodeAttribute::, Model::transform2 + C: "OO",1611246256,363517584 + + ;NodeAttribute::, Model::transform1 + C: "OO",1611247136,363503664 + + ;Texture::file1, Material::Steel + C: "OP",1971096816,1611742192, "Maya|TEX_global_diffuse_cube" + + ;Texture::file2, Material::Steel + C: "OP",1982230336,1611742192, "Maya|TEX_global_specular_cube" + + ;Texture::file3, Material::Steel + C: "OP",1612282368,1611742192, "Maya|TEX_brdf_lut" + + ;Texture::file5, Material::Steel + C: "OP",1612283328,1611742192, "Maya|TEX_normal_map" + + ;Texture::file4, Material::Steel + C: "OP",1612282848,1611742192, "Maya|TEX_color_map" + + ;Texture::file6, Material::Steel + C: "OP",1982231296,1611742192, "Maya|TEX_metallic_map" + + ;Texture::file7, Material::Steel + C: "OP",1531689904,1611742192, "Maya|TEX_roughness_map" + + ;Texture::file8, Material::Steel + C: "OP",1982230816,1611742192, "Maya|TEX_ao_map" + + ;Material::Steel, Implementation::Steel_Implementation + C: "OO",1611742192,1981166160 + + ;BindingTable::root 2, Implementation::Steel_Implementation + C: "OO",994552656,1981166160 + + ;Video::file6, Texture::file6 + C: "OO",1971809008,1982231296 + + ;Video::file7, Texture::file7 + C: "OO",1971833408,1531689904 + + ;Video::file4, Texture::file4 + C: "OO",1971825008,1612282848 + + ;Video::file5, Texture::file5 + C: "OO",1971829008,1612283328 + + ;Geometry::, Model::Wave + C: "OO",1983184160,363501344 + + ;Material::Steel, Model::Wave + C: "OO",1611742192,363501344 +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "Take 001" + Take: "Take 001" { + FileName: "Take_001.tak" + LocalTime: 1924423250,230930790000 + ReferenceTime: 1924423250,230930790000 + } +} diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_BaseColor.png b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_BaseColor.png new file mode 100644 index 0000000000..b40708b99d Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_BaseColor.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Metallic.png b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Metallic.png new file mode 100644 index 0000000000..7c14baf4fc Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Metallic.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Normal.png b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Normal.png new file mode 100644 index 0000000000..e4359d0d76 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Normal.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Roughness.png b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Roughness.png new file mode 100644 index 0000000000..b8fd8f8aac Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylophoneFrameWithWave_Steel_Roughness.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneKey.js b/unpublishedScripts/marketplace/xylophone/xylophoneKey.js new file mode 100644 index 0000000000..afba7e8075 --- /dev/null +++ b/unpublishedScripts/marketplace/xylophone/xylophoneKey.js @@ -0,0 +1,64 @@ +// +// xylophoneKey.js +// +// Created by Patrick Gosch on 03/28/2017 +// Copyright 2017 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 +// + +(function() { + Script.include(Script.resolvePath("pUtils.js")); + var TIMEOUT = 150; + var TEXGRAY = Script.resolvePath("xylotex_bar_gray.png"); + var TEXBLACK = Script.resolvePath("xylotex_bar_black.png"); + var _this; + + function XylophoneKey() { + _this = this; + } + + XylophoneKey.prototype = { + sound: null, + isWaiting: false, + homePos: null, + injector: null, + + preload: function(entityID) { + _this.entityID = entityID; + var soundURL = Script.resolvePath(JSON.parse(Entities.getEntityProperties(_this.entityID, ["userData"]).userData).soundFile); + _this.sound = SoundCache.getSound(soundURL); + Entities.editEntity(_this.entityID, {dimensions: {x: 0.15182036161422729, y: 0.049085158854722977, z: 0.39702033996582031}}); + }, + + collisionWithEntity: function(thisEntity, otherEntity, collision) { + if (collision.type === 0) { + _this.hit(); + } + }, + + clickDownOnEntity: function() { + _this.hit(); + }, + + hit: function() { + if (!_this.isWaiting) { + _this.isWaiting = true; + _this.homePos = Entities.getEntityProperties(_this.entityID, ["position"]).position; + _this.injector = Audio.playSound(_this.sound, {position: _this.homePos, volume: 1}); + editEntityTextures(_this.entityID, "file5", TEXGRAY); + _this.timeout(); + } + }, + + timeout: function() { + Script.setTimeout(function() { + editEntityTextures(_this.entityID, "file5", TEXBLACK); + _this.isWaiting = false; + }, TIMEOUT); + }; + + return new XylophoneKey(); + +}); diff --git a/unpublishedScripts/marketplace/xylophone/xylophoneRezzer.js b/unpublishedScripts/marketplace/xylophone/xylophoneRezzer.js new file mode 100644 index 0000000000..6416f81037 --- /dev/null +++ b/unpublishedScripts/marketplace/xylophone/xylophoneRezzer.js @@ -0,0 +1,102 @@ +// +// xylophoneRezzer.js +// +// Created by Patrick Gosch on 03/28/2017 +// Copyright 2017 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 +// + +var soundFiles = ["C4.wav", "D4.wav", "E4.wav", "F4.wav", "G4.wav", "A4.wav", "B4.wav", "C5.wav"]; +var keyModelURL = Script.resolvePath("xyloKey_2_a_e.fbx"); +var keyScriptURL = Script.resolvePath("xylophoneKey.js"); +var TEXBLACK = Script.resolvePath("xylotex_bar_black.png"); +var malletModelURL = Script.resolvePath("Mallet3-2pc.fbx"); +var malletModelColliderURL = Script.resolvePath("Mallet3-2bpc_phys.obj"); +var center = MyAvatar.position; +var fwd = {x:0, y:0, z:-1}; + +var xyloFramePos = Vec3.sum(center, Vec3.multiply(fwd, 0.8)); +var xyloFrameID = Entities.addEntity( { + name: "Xylophone", + type: "Model", + modelURL: Script.resolvePath("xylophoneFrameWithWave.fbx"), + position: xyloFramePos, + rotation: Quat.fromVec3Radians({x:0, y:Math.PI, z:0}), + shapeType: "static-mesh" +}); + +center.y += (0.45); // key Y offset from frame +var keyPos, keyRot, ud, td, keyID; +for (var i = 1; i <= soundFiles.length; i++) { + + keyRot = Quat.fromVec3Radians({x:0, y:(0.9 - (i*0.2)), z:0}); + keyPos = Vec3.sum(center, Vec3.multiplyQbyV(keyRot, fwd)); + + ud = { + soundFile: soundFiles[i-1] + }; + + td = { + "file4": Script.resolvePath("xylotex_bar" + i + ".png"), + "file5": TEXBLACK + }; + + keyID = Entities.addEntity( { + name: ("XyloKey" + i), + type: "Model", + modelURL: keyModelURL, + position: keyPos, + rotation: keyRot, + shapeType: "static-mesh", + script: keyScriptURL, + textures: JSON.stringify(td), + userData: JSON.stringify(ud), + parentID: xyloFrameID + } ); +} + +// if rezzed on/above something, wait until after model has loaded so you can read its dimensions then move object on to that surface. +var pickRay = {origin: center, direction: {x:0, y:-1, z:0}}; +var intersection = Entities.findRayIntersection(pickRay, true); +if (intersection.intersects && (intersection.distance < 10)) { + var surfaceY = intersection.intersection.y; + Script.setTimeout( function() { + // should add loop to check for fbx loaded instead of delay + var xyloDimensions = Entities.getEntityProperties(xyloFrameID, ["dimensions"]).dimensions; + xyloFramePos.y = surfaceY + (xyloDimensions.y/2); + Entities.editEntity(xyloFrameID, {position: xyloFramePos}); + rezMallets(); + }, 2000); +} else { + print("No surface detected."); + rezMallets(); +} + +function rezMallets() { + var malletProps = { + name: "Xylophone Mallet", + type: "Model", + modelURL: malletModelURL, + compoundShapeURL: malletModelColliderURL, + collidesWith: "static,dynamic,kinematic,", + collisionMask: 7, + collisionsWillMove: 1, + dynamic: 1, + damping: 1, + angularDamping: 1, + shapeType: "compound", + userData: "{\"grabbableKey\":{\"grabbable\":true}}", + dimensions: {"x": 0.057845603674650192, "y": 0.057845607399940491, "z": 0.30429631471633911} // not being set from fbx for some reason. + }; + + malletProps.position = Vec3.sum(xyloFramePos, {x: 0.1, y: 0.55, z: 0}); + malletProps.rotation = Quat.fromVec3Radians({x:0, y:Math.PI - 0.1, z:0}); + Entities.addEntity(malletProps); + + malletProps.position = Vec3.sum(xyloFramePos, {x: -0.1, y: 0.55, z: 0}); + malletProps.rotation = Quat.fromVec3Radians({x:0, y:Math.PI + 0.1, z:0}); + Entities.addEntity(malletProps); + Script.stop(); +} \ No newline at end of file diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar1.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar1.png new file mode 100644 index 0000000000..2651d86f95 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar1.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar2.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar2.png new file mode 100644 index 0000000000..606c193c98 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar2.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar3.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar3.png new file mode 100644 index 0000000000..2d94465b48 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar3.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar4.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar4.png new file mode 100644 index 0000000000..b6408ba30b Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar4.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar5.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar5.png new file mode 100644 index 0000000000..e860df384e Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar5.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar6.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar6.png new file mode 100644 index 0000000000..5eee08be3d Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar6.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar7.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar7.png new file mode 100644 index 0000000000..fe196d1db3 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar7.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar8.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar8.png new file mode 100644 index 0000000000..0548162878 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar8.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar_black.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar_black.png new file mode 100644 index 0000000000..ea9ccdb5c0 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar_black.png differ diff --git a/unpublishedScripts/marketplace/xylophone/xylotex_bar_gray.png b/unpublishedScripts/marketplace/xylophone/xylotex_bar_gray.png new file mode 100644 index 0000000000..bc886c1d46 Binary files /dev/null and b/unpublishedScripts/marketplace/xylophone/xylotex_bar_gray.png differ