Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 4 files). Show all
Unified · Split
| @@ -89,16 +89,8 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 88 unmodified lines | |||
| 89 | _isFinished(false), | 89 | _isFinished(false), |
| 90 | _isRunning(false), | 90 | _isRunning(false), |
| 91 | _isInitialized(false), | 91 | _isInitialized(false), |
| 92 | _isAvatar(false), | ||
| 93 | _avatarIdentityTimer(NULL), | ||
| 94 | _avatarBillboardTimer(NULL), | ||
| 95 | _timerFunctionMap(), | ||
| 96 | _isListeningToAudioStream(false), | ||
| 97 | _avatarSound(NULL), | ||
| 98 | _numAvatarSoundSentBytes(0), | ||
| 99 | _controllerScriptingInterface(controllerScriptingInterface), | 92 | _controllerScriptingInterface(controllerScriptingInterface), |
| 100 | _wantSignals(wantSignals), | 93 | _wantSignals(wantSignals), |
| 101 | _avatarData(NULL), | ||
| 102 | _fileNameString(fileNameString), | 94 | _fileNameString(fileNameString), |
| 103 | _quatLibrary(), | 95 | _quatLibrary(), |
| 104 | _vec3Library(), | 96 | _vec3Library(), |
| @@ -229,40 +221,6 @@ QString ScriptEngine::getFilename() const { · 124 unmodified lines | |||
| 229 | } | 221 | } |
| 230 | 222 | ||
| 231 | 223 | ||
| 232 | void ScriptEngine::setIsAvatar(bool isAvatar) { | ||
| 233 | _isAvatar = isAvatar; | ||
| 234 | |||
| 235 | if (_isAvatar && !_avatarIdentityTimer) { | ||
| 236 | // set up the avatar timers | ||
| 237 | _avatarIdentityTimer = new QTimer(this); | ||
| 238 | _avatarBillboardTimer = new QTimer(this); | ||
| 239 | |||
| 240 | // connect our slot | ||
| 241 | connect(_avatarIdentityTimer, &QTimer::timeout, this, &ScriptEngine::sendAvatarIdentityPacket); | ||
| 242 | connect(_avatarBillboardTimer, &QTimer::timeout, this, &ScriptEngine::sendAvatarBillboardPacket); | ||
| 243 | |||
| 244 | // start the timers | ||
| 245 | _avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); | ||
| 246 | _avatarBillboardTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS); | ||
| 247 | } | ||
| 248 | |||
| 249 | if (!_isAvatar) { | ||
| 250 | delete _avatarIdentityTimer; | ||
| 251 | _avatarIdentityTimer = NULL; | ||
| 252 | delete _avatarBillboardTimer; | ||
| 253 | _avatarBillboardTimer = NULL; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | |||
| 257 | void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectName) { | ||
| 258 | _avatarData = avatarData; | ||
| 259 | |||
| 260 | // remove the old Avatar property, if it exists | ||
| 261 | globalObject().setProperty(objectName, QScriptValue()); | ||
| 262 | |||
| 263 | // give the script engine the new Avatar script property | ||
| 264 | registerGlobalObject(objectName, _avatarData); | ||
| 265 | } | ||
| 266 | 224 | ||
| 267 | bool ScriptEngine::setScriptContents(const QString& scriptContents, const QString& fileNameString) { | 225 | bool ScriptEngine::setScriptContents(const QString& scriptContents, const QString& fileNameString) { |
| 268 | if (_isRunning) { | 226 | if (_isRunning) { |
| @@ -571,18 +529,6 @@ QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileN · 302 unmodified lines | |||
| 571 | return result; | 529 | return result; |
| 572 | } | 530 | } |
| 573 | 531 | ||
| 574 | void ScriptEngine::sendAvatarIdentityPacket() { | ||
| 575 | if (_isAvatar && _avatarData) { | ||
| 576 | _avatarData->sendIdentityPacket(); | ||
| 577 | } | ||
| 578 | } | ||
| 579 | |||
| 580 | void ScriptEngine::sendAvatarBillboardPacket() { | ||
| 581 | if (_isAvatar && _avatarData) { | ||
| 582 | _avatarData->sendBillboardPacket(); | ||
| 583 | } | ||
| 584 | } | ||
| 585 | |||
| 586 | void ScriptEngine::run() { | 532 | void ScriptEngine::run() { |
| 587 | // TODO: can we add a short circuit for _stoppingAllScripts here? What does it mean to not start running if | 533 | // TODO: can we add a short circuit for _stoppingAllScripts here? What does it mean to not start running if |
| 588 | // we're in the process of stopping? | 534 | // we're in the process of stopping? |
| @@ -634,107 +580,6 @@ void ScriptEngine::run() { · 45 unmodified lines | |||
| 634 | } | 580 | } |
| 635 | } | 581 | } |
| 636 | 582 | ||
| 637 | if (!_isFinished && _isAvatar && _avatarData) { | ||
| 638 | |||
| 639 | const int SCRIPT_AUDIO_BUFFER_SAMPLES = floor(((SCRIPT_DATA_CALLBACK_USECS * AudioConstants::SAMPLE_RATE) | ||
| 640 | / (1000 * 1000)) + 0.5); | ||
| 641 | const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t); | ||
| 642 | |||
| 643 | QByteArray avatarByteArray = _avatarData->toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); | ||
| 644 | _avatarData->doneEncoding(true); | ||
| 645 | auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size()); | ||
| 646 | |||
| 647 | avatarPacket->write(avatarByteArray); | ||
| 648 | |||
| 649 | nodeList->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer); | ||
| 650 | |||
| 651 | if (_isListeningToAudioStream || _avatarSound) { | ||
| 652 | // if we have an avatar audio stream then send it out to our audio-mixer | ||
| 653 | bool silentFrame = true; | ||
| 654 | |||
| 655 | int16_t numAvailableSamples = SCRIPT_AUDIO_BUFFER_SAMPLES; | ||
| 656 | const int16_t* nextSoundOutput = NULL; | ||
| 657 | |||
| 658 | if (_avatarSound) { | ||
| 659 | |||
| 660 | const QByteArray& soundByteArray = _avatarSound->getByteArray(); | ||
| 661 | nextSoundOutput = reinterpret_cast<const int16_t*>(soundByteArray.data() | ||
| 662 | + _numAvatarSoundSentBytes); | ||
| 663 | |||
| 664 | int numAvailableBytes = (soundByteArray.size() - _numAvatarSoundSentBytes) > SCRIPT_AUDIO_BUFFER_BYTES | ||
| 665 | ? SCRIPT_AUDIO_BUFFER_BYTES | ||
| 666 | : soundByteArray.size() - _numAvatarSoundSentBytes; | ||
| 667 | numAvailableSamples = numAvailableBytes / sizeof(int16_t); | ||
| 668 | |||
| 669 | |||
| 670 | // check if the all of the _numAvatarAudioBufferSamples to be sent are silence | ||
| 671 | for (int i = 0; i < numAvailableSamples; ++i) { | ||
| 672 | if (nextSoundOutput[i] != 0) { | ||
| 673 | silentFrame = false; | ||
| 674 | break; | ||
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 | _numAvatarSoundSentBytes += numAvailableBytes; | ||
| 679 | if (_numAvatarSoundSentBytes == soundByteArray.size()) { | ||
| 680 | // we're done with this sound object - so set our pointer back to NULL | ||
| 681 | // and our sent bytes back to zero | ||
| 682 | _avatarSound = NULL; | ||
| 683 | _numAvatarSoundSentBytes = 0; | ||
| 684 | } | ||
| 685 | } | ||
| 686 | |||
| 687 | auto audioPacket = NLPacket::create(silentFrame | ||
| 688 | ? PacketType::SilentAudioFrame | ||
| 689 | : PacketType::MicrophoneAudioNoEcho); | ||
| 690 | |||
| 691 | // seek past the sequence number, will be packed when destination node is known | ||
| 692 | audioPacket->seek(sizeof(quint16)); | ||
| 693 | |||
| 694 | if (silentFrame) { | ||
| 695 | if (!_isListeningToAudioStream) { | ||
| 696 | // if we have a silent frame and we're not listening then just send nothing and break out of here | ||
| 697 | break; | ||
| 698 | } | ||
| 699 | |||
| 700 | // write the number of silent samples so the audio-mixer can uphold timing | ||
| 701 | audioPacket->writePrimitive(SCRIPT_AUDIO_BUFFER_SAMPLES); | ||
| 702 | |||
| 703 | // use the orientation and position of this avatar for the source of this audio | ||
| 704 | audioPacket->writePrimitive(_avatarData->getPosition()); | ||
| 705 | glm::quat headOrientation = _avatarData->getHeadOrientation(); | ||
| 706 | audioPacket->writePrimitive(headOrientation); | ||
| 707 | |||
| 708 | } else if (nextSoundOutput) { | ||
| 709 | // assume scripted avatar audio is mono and set channel flag to zero | ||
| 710 | audioPacket->writePrimitive((quint8) 0); | ||
| 711 | |||
| 712 | // use the orientation and position of this avatar for the source of this audio | ||
| 713 | audioPacket->writePrimitive(_avatarData->getPosition()); | ||
| 714 | glm::quat headOrientation = _avatarData->getHeadOrientation(); | ||
| 715 | audioPacket->writePrimitive(headOrientation); | ||
| 716 | |||
| 717 | // write the raw audio data | ||
| 718 | audioPacket->write(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples * sizeof(int16_t)); | ||
| 719 | } | ||
| 720 | |||
| 721 | // write audio packet to AudioMixer nodes | ||
| 722 | auto nodeList = DependencyManager::get<NodeList>(); | ||
| 723 | nodeList->eachNode([this, &nodeList, &audioPacket](const SharedNodePointer& node){ | ||
| 724 | // only send to nodes of type AudioMixer | ||
| 725 | if (node->getType() == NodeType::AudioMixer) { | ||
| 726 | // pack sequence number | ||
| 727 | quint16 sequence = _outgoingScriptAudioSequenceNumbers[node->getUUID()]++; | ||
| 728 | audioPacket->seek(0); | ||
| 729 | audioPacket->writePrimitive(sequence); | ||
| 730 | |||
| 731 | // send audio packet | ||
| 732 | nodeList->sendUnreliablePacket(*audioPacket, *node); | ||
| 733 | } | ||
| 734 | }); | ||
| 735 | } | ||
| 736 | } | ||
| 737 | |||
| 738 | qint64 now = usecTimestampNow(); | 583 | qint64 now = usecTimestampNow(); |
| 739 | float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND; | 584 | float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND; |
| 740 | 585 | ||
| @@ -761,9 +606,6 @@ void ScriptEngine::run() { · 20 unmodified lines | |||
| 761 | emit scriptEnding(); | 606 | emit scriptEnding(); |
| 762 | } | 607 | } |
| 763 | 608 | ||
| 764 | // kill the avatar identity timer | ||
| 765 | delete _avatarIdentityTimer; | ||
| 766 | |||
| 767 | if (entityScriptingInterface->getEntityPacketSender()->serversExist()) { | 609 | if (entityScriptingInterface->getEntityPacketSender()->serversExist()) { |
| 768 | // release the queue of edit entity messages. | 610 | // release the queue of edit entity messages. |
| 769 | entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages(); | 611 | entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages(); |