mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge branch 'master' of https://github.com/highfidelity/hifi into skin
This commit is contained in:
commit
3638a3b9c3
15 changed files with 198 additions and 124 deletions
38
cmake/externals/hifiAudioCodec/CMakeLists.txt
vendored
38
cmake/externals/hifiAudioCodec/CMakeLists.txt
vendored
|
@ -1,19 +1,31 @@
|
|||
include(ExternalProject)
|
||||
include(SelectLibraryConfigurations)
|
||||
|
||||
set(EXTERNAL_NAME HiFiAudioCodec)
|
||||
set(EXTERNAL_NAME hifiAudioCodec)
|
||||
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://s3.amazonaws.com/hifi-public/dependencies/codecSDK-1.zip
|
||||
URL_MD5 23ec3fe51eaa155ea159a4971856fc13
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
LOG_DOWNLOAD 1
|
||||
)
|
||||
if (WIN32 OR APPLE)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-1.zip
|
||||
URL_MD5 23ec3fe51eaa155ea159a4971856fc13
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
LOG_DOWNLOAD 1
|
||||
)
|
||||
elseif(NOT ANDROID)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-linux.zip
|
||||
URL_MD5 7d37914a18aa4de971d2f45dd3043bde
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
LOG_DOWNLOAD 1
|
||||
)
|
||||
endif()
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
@ -23,11 +35,9 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
|||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
|
||||
|
||||
if (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL)
|
||||
elseif(APPLE)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
|
||||
elseif(NOT ANDROID)
|
||||
# FIXME need to account for different architectures
|
||||
#set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux64/audio.so CACHE TYPE INTERNAL)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -43,4 +43,4 @@ macro(ADD_DEPENDENCY_EXTERNAL_PROJECTS)
|
|||
|
||||
endforeach()
|
||||
|
||||
endmacro()
|
||||
endmacro()
|
||||
|
|
|
@ -37,7 +37,7 @@ macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
|
|||
${CLIENT_PLUGIN_FULL_PATH}
|
||||
)
|
||||
# copy the client plugin binaries
|
||||
add_custom_command(TARGET ${DIR} POST_BUILD
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_FILE:${TARGET_NAME}>"
|
||||
${CLIENT_PLUGIN_FULL_PATH}
|
||||
|
@ -50,7 +50,7 @@ macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
|
|||
${SERVER_PLUGIN_FULL_PATH}
|
||||
)
|
||||
# copy the server plugin binaries
|
||||
add_custom_command(TARGET ${DIR} POST_BUILD
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_FILE:${TARGET_NAME}>"
|
||||
${SERVER_PLUGIN_FULL_PATH}
|
||||
|
|
|
@ -207,8 +207,10 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
|
|||
}
|
||||
|
||||
withWriteLock([&]{
|
||||
if (_previousSet) {
|
||||
if (_previousSet &&
|
||||
_positionalTarget != _previousPositionalTarget) { // don't average in a zero velocity if we get the same data
|
||||
glm::vec3 oneFrameVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep;
|
||||
|
||||
_measuredLinearVelocities[_measuredLinearVelocitiesIndex++] = oneFrameVelocity;
|
||||
if (_measuredLinearVelocitiesIndex >= AvatarActionHold::velocitySmoothFrames) {
|
||||
_measuredLinearVelocitiesIndex = 0;
|
||||
|
@ -228,9 +230,9 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
|
|||
// 3 -- ignore i of 0 1 2
|
||||
// 4 -- ignore i of 1 2 3
|
||||
// 5 -- ignore i of 2 3 4
|
||||
if ((i + 1) % 6 == _measuredLinearVelocitiesIndex ||
|
||||
(i + 2) % 6 == _measuredLinearVelocitiesIndex ||
|
||||
(i + 3) % 6 == _measuredLinearVelocitiesIndex) {
|
||||
if ((i + 1) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex ||
|
||||
(i + 2) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex ||
|
||||
(i + 3) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex) {
|
||||
continue;
|
||||
}
|
||||
measuredLinearVelocity += _measuredLinearVelocities[i];
|
||||
|
|
|
@ -862,6 +862,9 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) {
|
|||
static const float INT16_TO_FLOAT_SCALE_FACTOR = 1/32768.0f;
|
||||
|
||||
bool injectorsHaveData = false;
|
||||
|
||||
// lock the injector vector
|
||||
Lock lock(_injectorsMutex);
|
||||
|
||||
for (AudioInjector* injector : getActiveLocalAudioInjectors()) {
|
||||
if (injector->getLocalBuffer()) {
|
||||
|
@ -871,6 +874,7 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) {
|
|||
AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL;
|
||||
|
||||
// get one frame from the injector (mono or stereo)
|
||||
memset(_scratchBuffer, 0, sizeof(_scratchBuffer));
|
||||
if (0 < injector->getLocalBuffer()->readData((char*)_scratchBuffer, samplesToRead)) {
|
||||
|
||||
injectorsHaveData = true;
|
||||
|
@ -894,14 +898,14 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) {
|
|||
} else {
|
||||
|
||||
qDebug() << "injector has no more data, marking finished for removal";
|
||||
injector->finish();
|
||||
injector->finishLocalInjection();
|
||||
injectorsToRemove.append(injector);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
qDebug() << "injector has no local buffer, marking as finished for removal";
|
||||
injector->finish();
|
||||
injector->finishLocalInjection();
|
||||
injectorsToRemove.append(injector);
|
||||
}
|
||||
}
|
||||
|
@ -1003,6 +1007,7 @@ void AudioClient::setIsStereoInput(bool isStereoInput) {
|
|||
|
||||
|
||||
bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) {
|
||||
Lock lock(_injectorsMutex);
|
||||
if (injector->getLocalBuffer() && _audioInput ) {
|
||||
// just add it to the vector of active local injectors, if
|
||||
// not already there.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#include <QtCore/qsystemdetection.h>
|
||||
#include <QtCore/QByteArray>
|
||||
|
@ -83,6 +84,9 @@ public:
|
|||
using AudioPositionGetter = std::function<glm::vec3()>;
|
||||
using AudioOrientationGetter = std::function<glm::quat()>;
|
||||
|
||||
using Mutex = std::mutex;
|
||||
using Lock = std::unique_lock<Mutex>;
|
||||
|
||||
class AudioOutputIODevice : public QIODevice {
|
||||
public:
|
||||
AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream, AudioClient* audio) :
|
||||
|
@ -219,6 +223,7 @@ private:
|
|||
float azimuthForSource(const glm::vec3& relativePosition);
|
||||
float gainForSource(float distance, float volume);
|
||||
|
||||
Mutex _injectorsMutex;
|
||||
QByteArray firstInputFrame;
|
||||
QAudioInput* _audioInput;
|
||||
QAudioFormat _desiredInputFormat;
|
||||
|
|
|
@ -28,6 +28,15 @@
|
|||
|
||||
int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>();
|
||||
|
||||
AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs) {
|
||||
return static_cast<AudioInjectorState>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
|
||||
};
|
||||
|
||||
AudioInjectorState& operator|= (AudioInjectorState& lhs, AudioInjectorState rhs) {
|
||||
lhs = static_cast<AudioInjectorState>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
|
||||
return lhs;
|
||||
};
|
||||
|
||||
AudioInjector::AudioInjector(QObject* parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
@ -48,6 +57,10 @@ AudioInjector::AudioInjector(const QByteArray& audioData, const AudioInjectorOpt
|
|||
|
||||
}
|
||||
|
||||
bool AudioInjector::stateHas(AudioInjectorState state) const {
|
||||
return (_state & state) == state;
|
||||
}
|
||||
|
||||
void AudioInjector::setOptions(const AudioInjectorOptions& options) {
|
||||
// since options.stereo is computed from the audio stream,
|
||||
// we need to copy it from existing options just in case.
|
||||
|
@ -56,10 +69,25 @@ void AudioInjector::setOptions(const AudioInjectorOptions& options) {
|
|||
_options.stereo = currentlyStereo;
|
||||
}
|
||||
|
||||
void AudioInjector::finishNetworkInjection() {
|
||||
_state |= AudioInjectorState::NetworkInjectionFinished;
|
||||
|
||||
// if we are already finished with local
|
||||
// injection, then we are finished
|
||||
if(stateHas(AudioInjectorState::LocalInjectionFinished)) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioInjector::finishLocalInjection() {
|
||||
_state |= AudioInjectorState::LocalInjectionFinished;
|
||||
if(_options.localOnly || stateHas(AudioInjectorState::NetworkInjectionFinished)) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioInjector::finish() {
|
||||
bool shouldDelete = (_state == State::NotFinishedWithPendingDelete);
|
||||
_state = State::Finished;
|
||||
_state |= AudioInjectorState::Finished;
|
||||
|
||||
emit finished();
|
||||
|
||||
|
@ -69,7 +97,7 @@ void AudioInjector::finish() {
|
|||
_localBuffer = NULL;
|
||||
}
|
||||
|
||||
if (shouldDelete) {
|
||||
if (stateHas(AudioInjectorState::PendingDelete)) {
|
||||
// we've been asked to delete after finishing, trigger a deleteLater here
|
||||
deleteLater();
|
||||
}
|
||||
|
@ -121,23 +149,27 @@ void AudioInjector::restart() {
|
|||
_hasSentFirstFrame = false;
|
||||
|
||||
// check our state to decide if we need extra handling for the restart request
|
||||
if (_state == State::Finished) {
|
||||
if (stateHas(AudioInjectorState::Finished)) {
|
||||
// we finished playing, need to reset state so we can get going again
|
||||
_hasSetup = false;
|
||||
_shouldStop = false;
|
||||
_state = State::NotFinished;
|
||||
_state = AudioInjectorState::NotFinished;
|
||||
|
||||
// call inject audio to start injection over again
|
||||
setupInjection();
|
||||
|
||||
// if we're a local injector, just inject again
|
||||
if (_options.localOnly) {
|
||||
injectLocally();
|
||||
} else {
|
||||
// wake the AudioInjectorManager back up if it's stuck waiting
|
||||
if (!injectorManager->restartFinishedInjector(this)) {
|
||||
_state = State::Finished; // we're not playing, so reset the state used by isPlaying.
|
||||
// inject locally
|
||||
if(injectLocally()) {
|
||||
|
||||
// if not localOnly, wake the AudioInjectorManager back up if it is stuck waiting
|
||||
if (!_options.localOnly) {
|
||||
|
||||
if (!injectorManager->restartFinishedInjector(this)) {
|
||||
_state = AudioInjectorState::Finished; // we're not playing, so reset the state used by isPlaying.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_state = AudioInjectorState::Finished; // we failed to play, so we are finished again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +215,7 @@ static const int64_t NEXT_FRAME_DELTA_ERROR_OR_FINISHED = -1;
|
|||
static const int64_t NEXT_FRAME_DELTA_IMMEDIATELY = 0;
|
||||
|
||||
int64_t AudioInjector::injectNextFrame() {
|
||||
if (_state == AudioInjector::State::Finished) {
|
||||
if (stateHas(AudioInjectorState::NetworkInjectionFinished)) {
|
||||
qDebug() << "AudioInjector::injectNextFrame called but AudioInjector has finished and was not restarted. Returning.";
|
||||
return NEXT_FRAME_DELTA_ERROR_OR_FINISHED;
|
||||
}
|
||||
|
@ -234,8 +266,10 @@ int64_t AudioInjector::injectNextFrame() {
|
|||
// pack the stereo/mono type of the stream
|
||||
audioPacketStream << _options.stereo;
|
||||
|
||||
// pack the flag for loopback
|
||||
uchar loopbackFlag = (uchar)true;
|
||||
// pack the flag for loopback. Now, we don't loopback
|
||||
// and _always_ play locally, so loopbackFlag should be
|
||||
// false always.
|
||||
uchar loopbackFlag = (uchar)false;
|
||||
audioPacketStream << loopbackFlag;
|
||||
|
||||
// pack the position for injected audio
|
||||
|
@ -333,7 +367,7 @@ int64_t AudioInjector::injectNextFrame() {
|
|||
}
|
||||
|
||||
if (_currentSendOffset >= _audioData.size() && !_options.loop) {
|
||||
finish();
|
||||
finishNetworkInjection();
|
||||
return NEXT_FRAME_DELTA_ERROR_OR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -372,10 +406,10 @@ void AudioInjector::triggerDeleteAfterFinish() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (_state == State::Finished) {
|
||||
if (_state == AudioInjectorState::Finished) {
|
||||
stopAndDeleteLater();
|
||||
} else {
|
||||
_state = State::NotFinishedWithPendingDelete;
|
||||
_state |= AudioInjectorState::PendingDelete;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +455,7 @@ AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const
|
|||
AudioInjector* sound = playSound(buffer, options, localInterface);
|
||||
|
||||
if (sound) {
|
||||
sound->_state = AudioInjector::State::NotFinishedWithPendingDelete;
|
||||
sound->_state |= AudioInjectorState::PendingDelete;
|
||||
}
|
||||
|
||||
return sound;
|
||||
|
@ -438,21 +472,23 @@ AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInj
|
|||
// setup parameters required for injection
|
||||
injector->setupInjection();
|
||||
|
||||
if (options.localOnly) {
|
||||
if (injector->injectLocally()) {
|
||||
// local injection succeeded, return the pointer to injector
|
||||
return injector;
|
||||
} else {
|
||||
// unable to inject locally, return a nullptr
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// attempt to thread the new injector
|
||||
if (injectorManager->threadInjector(injector)) {
|
||||
return injector;
|
||||
} else {
|
||||
// we failed to thread the new injector (we are at the max number of injector threads)
|
||||
return nullptr;
|
||||
}
|
||||
// we always inject locally
|
||||
//
|
||||
if (!injector->injectLocally()) {
|
||||
// failed, so don't bother sending to server
|
||||
qDebug() << "AudioInjector::playSound failed to inject locally";
|
||||
return nullptr;
|
||||
}
|
||||
// if localOnly, we are done, just return injector.
|
||||
if (options.localOnly) {
|
||||
return injector;
|
||||
}
|
||||
|
||||
// send off to server for everyone else
|
||||
if (!injectorManager->threadInjector(injector)) {
|
||||
// we failed to thread the new injector (we are at the max number of injector threads)
|
||||
qDebug() << "AudioInjector::playSound failed to thread injector";
|
||||
}
|
||||
return injector;
|
||||
|
||||
}
|
||||
|
|
|
@ -32,24 +32,29 @@
|
|||
class AbstractAudioInterface;
|
||||
class AudioInjectorManager;
|
||||
|
||||
|
||||
enum class AudioInjectorState : uint8_t {
|
||||
NotFinished = 0,
|
||||
Finished = 1,
|
||||
PendingDelete = 2,
|
||||
LocalInjectionFinished = 4,
|
||||
NetworkInjectionFinished = 8
|
||||
};
|
||||
|
||||
AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs);
|
||||
AudioInjectorState& operator|= (AudioInjectorState& lhs, AudioInjectorState rhs);
|
||||
|
||||
// In order to make scripting cleaner for the AudioInjector, the script now holds on to the AudioInjector object
|
||||
// until it dies.
|
||||
|
||||
class AudioInjector : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class State : uint8_t {
|
||||
NotFinished,
|
||||
NotFinishedWithPendingDelete,
|
||||
Finished
|
||||
};
|
||||
|
||||
AudioInjector(QObject* parent);
|
||||
AudioInjector(const Sound& sound, const AudioInjectorOptions& injectorOptions);
|
||||
AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions);
|
||||
|
||||
bool isFinished() const { return _state == State::Finished; }
|
||||
bool isFinished() const { return (stateHas(AudioInjectorState::Finished)); }
|
||||
|
||||
int getCurrentSendOffset() const { return _currentSendOffset; }
|
||||
void setCurrentSendOffset(int currentSendOffset) { _currentSendOffset = currentSendOffset; }
|
||||
|
@ -63,6 +68,7 @@ public:
|
|||
bool isStereo() const { return _options.stereo; }
|
||||
void setLocalAudioInterface(AbstractAudioInterface* localAudioInterface) { _localAudioInterface = localAudioInterface; }
|
||||
|
||||
bool stateHas(AudioInjectorState state) const ;
|
||||
static AudioInjector* playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
||||
static AudioInjector* playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
||||
static AudioInjector* playSound(SharedSoundPointer sound, const float volume, const float stretchFactor, const glm::vec3 position);
|
||||
|
@ -78,8 +84,10 @@ public slots:
|
|||
void setOptions(const AudioInjectorOptions& options);
|
||||
|
||||
float getLoudness() const { return _loudness; }
|
||||
bool isPlaying() const { return _state == State::NotFinished || _state == State::NotFinishedWithPendingDelete; }
|
||||
bool isPlaying() const { return !stateHas(AudioInjectorState::Finished); }
|
||||
void finish();
|
||||
void finishLocalInjection();
|
||||
void finishNetworkInjection();
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
@ -92,7 +100,7 @@ private:
|
|||
|
||||
QByteArray _audioData;
|
||||
AudioInjectorOptions _options;
|
||||
State _state { State::NotFinished };
|
||||
AudioInjectorState _state { AudioInjectorState::NotFinished };
|
||||
bool _hasSentFirstFrame { false };
|
||||
bool _hasSetup { false };
|
||||
bool _shouldStop { false };
|
||||
|
@ -111,4 +119,5 @@ private:
|
|||
friend class AudioInjectorManager;
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_AudioInjector_h
|
||||
|
|
|
@ -36,7 +36,15 @@ OffscreenGLCanvas::~OffscreenGLCanvas() {
|
|||
delete _logger;
|
||||
_logger = nullptr;
|
||||
}
|
||||
|
||||
_context->doneCurrent();
|
||||
delete _context;
|
||||
_context = nullptr;
|
||||
|
||||
_offscreenSurface->destroy();
|
||||
delete _offscreenSurface;
|
||||
_offscreenSurface = nullptr;
|
||||
|
||||
}
|
||||
|
||||
bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) {
|
||||
|
|
|
@ -34,8 +34,8 @@ public:
|
|||
|
||||
protected:
|
||||
std::once_flag _reportOnce;
|
||||
QOpenGLContext* _context;
|
||||
QOffscreenSurface* _offscreenSurface;
|
||||
QOpenGLContext* _context{ nullptr };
|
||||
QOffscreenSurface* _offscreenSurface{ nullptr };
|
||||
QOpenGLDebugLogger* _logger{ nullptr };
|
||||
};
|
||||
|
||||
|
|
|
@ -28,16 +28,17 @@ QOpenGLContext* QOpenGLContextWrapper::currentContext() {
|
|||
return QOpenGLContext::currentContext();
|
||||
}
|
||||
|
||||
|
||||
QOpenGLContextWrapper::QOpenGLContextWrapper() :
|
||||
_context(new QOpenGLContext)
|
||||
{
|
||||
}
|
||||
|
||||
_ownContext(true), _context(new QOpenGLContext) { }
|
||||
|
||||
QOpenGLContextWrapper::QOpenGLContextWrapper(QOpenGLContext* context) :
|
||||
_context(context)
|
||||
{
|
||||
_context(context) { }
|
||||
|
||||
QOpenGLContextWrapper::~QOpenGLContextWrapper() {
|
||||
if (_ownContext) {
|
||||
delete _context;
|
||||
_context = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void QOpenGLContextWrapper::setFormat(const QSurfaceFormat& format) {
|
||||
|
|
|
@ -23,6 +23,7 @@ class QOpenGLContextWrapper {
|
|||
public:
|
||||
QOpenGLContextWrapper();
|
||||
QOpenGLContextWrapper(QOpenGLContext* context);
|
||||
virtual ~QOpenGLContextWrapper();
|
||||
void setFormat(const QSurfaceFormat& format);
|
||||
bool create();
|
||||
void swapBuffers(QSurface* surface);
|
||||
|
@ -40,6 +41,7 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
bool _ownContext { false };
|
||||
QOpenGLContext* _context { nullptr };
|
||||
};
|
||||
|
||||
|
|
|
@ -187,7 +187,11 @@ GLTexture::~GLTexture() {
|
|||
}
|
||||
}
|
||||
|
||||
Backend::decrementTextureGPUCount();
|
||||
if (_id) {
|
||||
glDeleteTextures(1, &_id);
|
||||
const_cast<GLuint&>(_id) = 0;
|
||||
Backend::decrementTextureGPUCount();
|
||||
}
|
||||
Backend::updateTextureGPUMemoryUsage(_size, 0);
|
||||
Backend::updateTextureGPUVirtualMemoryUsage(_virtualSize, 0);
|
||||
}
|
||||
|
|
|
@ -6,15 +6,11 @@
|
|||
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
set(TARGET_NAME hifiCodec)
|
||||
setup_hifi_client_server_plugin()
|
||||
|
||||
link_hifi_libraries(audio shared plugins)
|
||||
|
||||
add_dependency_external_projects(HiFiAudioCodec)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES})
|
||||
install_beside_console()
|
||||
endif()
|
||||
set(TARGET_NAME hifiCodec)
|
||||
setup_hifi_client_server_plugin()
|
||||
link_hifi_libraries(audio shared plugins)
|
||||
add_dependency_external_projects(hifiAudioCodec)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES})
|
||||
install_beside_console()
|
||||
|
||||
|
|
|
@ -202,8 +202,7 @@ CONTROLLER_STATE_MACHINE[STATE_NEAR_GRABBING] = {
|
|||
CONTROLLER_STATE_MACHINE[STATE_HOLD] = {
|
||||
name: "hold",
|
||||
enterMethod: "nearGrabbingEnter",
|
||||
updateMethod: "nearGrabbing",
|
||||
exitMethod: "holdExit"
|
||||
updateMethod: "nearGrabbing"
|
||||
};
|
||||
CONTROLLER_STATE_MACHINE[STATE_NEAR_TRIGGER] = {
|
||||
name: "trigger",
|
||||
|
@ -228,7 +227,7 @@ function colorPow(color, power) {
|
|||
return {
|
||||
red: Math.pow(color.red / 255.0, power) * 255,
|
||||
green: Math.pow(color.green / 255.0, power) * 255,
|
||||
blue: Math.pow(color.blue / 255.0, power) * 255,
|
||||
blue: Math.pow(color.blue / 255.0, power) * 255
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -271,14 +270,12 @@ function propsArePhysical(props) {
|
|||
return isPhysical;
|
||||
}
|
||||
|
||||
// currently disabled.
|
||||
var USE_ATTACH_POINT_SETTINGS = false;
|
||||
var USE_ATTACH_POINT_SETTINGS = true;
|
||||
|
||||
var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints";
|
||||
function getAttachPointSettings() {
|
||||
try {
|
||||
var str = Settings.getValue(ATTACH_POINT_SETTINGS);
|
||||
print("getAttachPointSettings = " + str);
|
||||
if (str === "false") {
|
||||
return {};
|
||||
} else {
|
||||
|
@ -291,7 +288,6 @@ function getAttachPointSettings() {
|
|||
}
|
||||
function setAttachPointSettings(attachPointSettings) {
|
||||
var str = JSON.stringify(attachPointSettings);
|
||||
print("setAttachPointSettings = " + str);
|
||||
Settings.setValue(ATTACH_POINT_SETTINGS, str);
|
||||
}
|
||||
function getAttachPointForHotspotFromSettings(hotspot, hand) {
|
||||
|
@ -765,9 +761,8 @@ function MyController(hand) {
|
|||
}
|
||||
};
|
||||
|
||||
var SEARCH_SPHERE_ALPHA = 0.5;
|
||||
this.searchSphereOn = function (location, size, color) {
|
||||
|
||||
|
||||
var rotation = Quat.lookAt(location, Camera.getPosition(), Vec3.UP);
|
||||
var brightColor = colorPow(color, 0.06);
|
||||
if (this.searchSphere === null) {
|
||||
|
@ -790,7 +785,7 @@ function MyController(hand) {
|
|||
position: location,
|
||||
rotation: rotation,
|
||||
innerColor: brightColor,
|
||||
outerColor: color,
|
||||
outerColor: color,
|
||||
innerAlpha: 1.0,
|
||||
outerAlpha: 0.0,
|
||||
outerRadius: size * 1.2,
|
||||
|
@ -1961,12 +1956,12 @@ function MyController(hand) {
|
|||
this.currentObjectRotation = grabbedProperties.rotation;
|
||||
this.currentVelocity = ZERO_VEC;
|
||||
this.currentAngularVelocity = ZERO_VEC;
|
||||
|
||||
this.prevDropDetected = false;
|
||||
};
|
||||
|
||||
this.nearGrabbing = function (deltaTime, timestamp) {
|
||||
|
||||
var dropDetected = this.dropGestureProcess(deltaTime);
|
||||
|
||||
if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
|
||||
this.callEntityMethodOnGrabbed("releaseGrab");
|
||||
this.setState(STATE_OFF, "trigger released");
|
||||
|
@ -1975,6 +1970,16 @@ function MyController(hand) {
|
|||
|
||||
if (this.state == STATE_HOLD) {
|
||||
|
||||
var dropDetected = this.dropGestureProcess(deltaTime);
|
||||
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
this.waitForTriggerRelease = false;
|
||||
}
|
||||
|
||||
if (dropDetected && this.prevDropDetected != dropDetected) {
|
||||
this.waitForTriggerRelease = true;
|
||||
}
|
||||
|
||||
// highlight the grabbed hotspot when the dropGesture is detected.
|
||||
if (dropDetected) {
|
||||
entityPropertiesCache.addEntity(this.grabbedHotspot.entityID);
|
||||
|
@ -1982,17 +1987,24 @@ function MyController(hand) {
|
|||
equipHotspotBuddy.highlightHotspot(this.grabbedHotspot);
|
||||
}
|
||||
|
||||
if (dropDetected && this.triggerSmoothedGrab()) {
|
||||
if (dropDetected && !this.waitForTriggerRelease && this.triggerSmoothedGrab()) {
|
||||
this.callEntityMethodOnGrabbed("releaseEquip");
|
||||
this.setState(STATE_OFF, "drop gesture detected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.thumbPressed()) {
|
||||
this.callEntityMethodOnGrabbed("releaseEquip");
|
||||
this.setState(STATE_OFF, "drop via thumb press");
|
||||
// store the offset attach points into preferences.
|
||||
if (USE_ATTACH_POINT_SETTINGS && this.grabbedHotspot && this.grabbedEntity) {
|
||||
var props = Entities.getEntityProperties(this.grabbedEntity, ["localPosition", "localRotation"]);
|
||||
if (props && props.localPosition && props.localRotation) {
|
||||
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand, props.localPosition, props.localRotation);
|
||||
}
|
||||
}
|
||||
|
||||
var grabbedEntity = this.grabbedEntity;
|
||||
this.release();
|
||||
this.grabbedEntity = grabbedEntity;
|
||||
this.setState(STATE_NEAR_GRABBING, "drop gesture detected");
|
||||
return;
|
||||
}
|
||||
this.prevDropDetected = dropDetected;
|
||||
}
|
||||
|
||||
this.heartBeat(this.grabbedEntity);
|
||||
|
@ -2088,22 +2100,6 @@ function MyController(hand) {
|
|||
}
|
||||
};
|
||||
|
||||
this.holdExit = function () {
|
||||
// store the offset attach points into preferences.
|
||||
if (USE_ATTACH_POINT_SETTINGS && this.grabbedHotspot && this.grabbedEntity) {
|
||||
entityPropertiesCache.addEntity(this.grabbedEntity);
|
||||
var props = entityPropertiesCache.getProps(this.grabbedEntity);
|
||||
var entityXform = new Xform(props.rotation, props.position);
|
||||
var avatarXform = new Xform(MyAvatar.orientation, MyAvatar.position);
|
||||
var handRot = (this.hand === RIGHT_HAND) ? MyAvatar.getRightPalmRotation() : MyAvatar.getLeftPalmRotation();
|
||||
var avatarHandPos = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition;
|
||||
var palmXform = new Xform(handRot, avatarXform.xformPoint(avatarHandPos));
|
||||
var offsetXform = Xform.mul(palmXform.inv(), entityXform);
|
||||
|
||||
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand, offsetXform.pos, offsetXform.rot);
|
||||
}
|
||||
};
|
||||
|
||||
this.nearTriggerEnter = function () {
|
||||
|
||||
this.clearEquipHaptics();
|
||||
|
|
Loading…
Reference in a new issue