From 3742c169b531e133d9c3462ecaf8b3f438c1be2b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 22 Oct 2015 12:03:19 -0700 Subject: [PATCH 01/21] Make handler generators more readable --- libraries/script-engine/src/ScriptEngine.cpp | 47 +++++++++----------- libraries/script-engine/src/ScriptEngine.h | 2 +- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 76590f266b..a317f2a82c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -508,26 +508,29 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& // Connect up ALL the handlers to the global entities object's signals. // (We could go signal by signal, or even handler by handler, but I don't think the efficiency is worth the complexity.) auto entities = DependencyManager::get(); - connect(entities.data(), &EntityScriptingInterface::deletingEntity, this, - [=](const EntityItemID& entityID) { - _registeredHandlers.remove(entityID); - }); - + connect(entities.data(), &EntityScriptingInterface::deletingEntity, this, [this](const EntityItemID& entityID) { + _registeredHandlers.remove(entityID); + }); + // Two common cases of event handler, differing only in argument signature. - auto makeSingleEntityHandler = [=](const QString& eventName) -> std::function { - return [=](const EntityItemID& entityItemID) -> void { - generalHandler(entityItemID, eventName, [=]() -> QScriptValueList { - return QScriptValueList() << entityItemID.toScriptValue(this); - }); + auto makeSingleEntityHandler = [&](QString eventName) { + return [this, eventName](const EntityItemID& entityItemID) { + forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this) }); }; }; - auto makeMouseHandler = [=](const QString& eventName) -> std::function { - return [=](const EntityItemID& entityItemID, const MouseEvent& event) -> void { - generalHandler(entityItemID, eventName, [=]() -> QScriptValueList { - return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this); - }); + auto makeMouseHandler = [&](QString eventName) { + return [this, eventName](const EntityItemID& entityItemID, const MouseEvent& event) { + forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) }); }; }; + + auto makeCollisionHandler = [&](QString eventName) { + return [this, eventName](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { + forwardHandlerCall(idA, eventName, { idA.toScriptValue(this), idB.toScriptValue(this), + collisionToScriptValue(this, collision) }); + }; + }; + connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity")); connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity")); @@ -543,12 +546,7 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, makeMouseHandler("hoverOverEntity")); connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, makeMouseHandler("hoverLeaveEntity")); - connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, - [=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { - generalHandler(idA, "collisionWithEntity", [=]() { - return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision); - }); - }); + connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, makeCollisionHandler("collisionWithEntity")); } if (!_registeredHandlers.contains(entityID)) { _registeredHandlers[entityID] = RegisteredEventHandlers(); @@ -899,9 +897,9 @@ void ScriptEngine::load(const QString& loadFile) { } // Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args -void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function argGenerator) { +void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) { if (QThread::currentThread() != thread()) { - qDebug() << "*** ERROR *** ScriptEngine::generalHandler() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]"; + qDebug() << "*** ERROR *** ScriptEngine::forwardHandlerCall() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]"; assert(false); return; } @@ -915,9 +913,8 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e } QScriptValueList handlersForEvent = handlersOnEntity[eventName]; if (!handlersForEvent.isEmpty()) { - QScriptValueList args = argGenerator(); for (int i = 0; i < handlersForEvent.count(); ++i) { - handlersForEvent[i].call(QScriptValue(), args); + handlersForEvent[i].call(QScriptValue(), eventHanderArgs); } } } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 1d3986143a..c2f9d966f1 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -193,7 +193,7 @@ private: ArrayBufferClass* _arrayBufferClass; QHash _registeredHandlers; - void generalHandler(const EntityItemID& entityID, const QString& eventName, std::function argGenerator); + void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs); Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success); static QSet _allKnownScriptEngines; From c8c9118d4d0f671ea7f7cc4ed9dc64bdb4eaae30 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 23 Oct 2015 15:40:56 -0700 Subject: [PATCH 02/21] Improve script engine error logging + some cleanup --- libraries/script-engine/src/ScriptEngine.cpp | 74 ++++++++++++++------ libraries/script-engine/src/ScriptEngine.h | 5 +- libraries/shared/src/LogHandler.cpp | 2 +- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index a317f2a82c..cbe9449551 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -556,7 +556,7 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& } -QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) { +QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fileName, int lineNumber) { if (_stoppingAllScripts) { return QScriptValue(); // bail early } @@ -565,27 +565,30 @@ QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileN QScriptValue result; #ifdef THREAD_DEBUGGING qDebug() << "*** WARNING *** ScriptEngine::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " - "program:" << program << " fileName:" << fileName << "lineNumber:" << lineNumber; + "sourceCode:" << sourceCode << " fileName:" << fileName << "lineNumber:" << lineNumber; #endif QMetaObject::invokeMethod(this, "evaluate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QScriptValue, result), - Q_ARG(const QString&, program), + Q_ARG(const QString&, sourceCode), Q_ARG(const QString&, fileName), Q_ARG(int, lineNumber)); return result; } + + // Check synthax + const QScriptProgram program(sourceCode, fileName, lineNumber); + if (!checkSynthax(program)) { + return QScriptValue(); + } - _evaluatesPending++; - QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber); - if (hasUncaughtException()) { - int line = uncaughtExceptionLineNumber(); - qCDebug(scriptengine) << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString(); - } - _evaluatesPending--; + ++_evaluatesPending; + const auto result = QScriptEngine::evaluate(program); + --_evaluatesPending; + + const auto hadUncaughtException = checkExceptions(this, program.fileName()); if (_wantSignals) { - emit evaluationFinished(result, hasUncaughtException()); + emit evaluationFinished(result, hadUncaughtException); } - clearExceptions(); return result; } @@ -603,7 +606,7 @@ void ScriptEngine::run() { emit runningStateChanged(); } - QScriptValue result = evaluate(_scriptContents); + QScriptValue result = evaluate(_scriptContents, _fileNameString); QElapsedTimer startTime; startTime.start(); @@ -644,15 +647,6 @@ void ScriptEngine::run() { qint64 now = usecTimestampNow(); float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND; - if (hasUncaughtException()) { - int line = uncaughtExceptionLineNumber(); - qCDebug(scriptengine) << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << uncaughtException().toString(); - if (_wantSignals) { - emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + uncaughtException().toString()); - } - clearExceptions(); - } - if (!_isFinished) { if (_wantSignals) { emit update(deltaTime); @@ -660,6 +654,7 @@ void ScriptEngine::run() { } lastUpdate = now; + checkExceptions(this, _fileNameString); } stopAllTimers(); // make sure all our timers are stopped if the script is ending @@ -896,6 +891,38 @@ void ScriptEngine::load(const QString& loadFile) { } } + +bool ScriptEngine::checkSynthax(const QScriptProgram& program) { + const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); + if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { + const auto error = syntaxCheck.errorMessage(); + const auto line = QString::number(syntaxCheck.errorLineNumber()); + const auto column = QString::number(syntaxCheck.errorColumnNumber()); + const auto message = QString("[SyntaxError] %1 in %2:%3(%4)").arg(error, program.fileName(), line, column); + qCWarning(scriptengine) << qPrintable(message); + return false; + } + return true; +} + +bool ScriptEngine::checkExceptions(QScriptEngine* engine, const QString& fileName) { + if (engine->hasUncaughtException()) { + const auto backtrace = engine->uncaughtExceptionBacktrace(); + const auto exception = engine->uncaughtException().toString(); + const auto line = QString::number(engine->uncaughtExceptionLineNumber()); + engine->clearExceptions(); + + auto message = QString("[UncaughtException] %1 in %2:%3").arg(exception, fileName, line); + if (!backtrace.empty()) { + static const auto lineSeparator = "\n "; + message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator)); + } + qCWarning(scriptengine) << qPrintable(message); + return false; + } + return true; +} + // Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) { if (QThread::currentThread() != thread()) { @@ -1015,7 +1042,8 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch(); } - QScriptValue entityScriptConstructor = evaluate(contents); + auto fileName = QString("(EntityID:%1, %2)").arg(entityID.toString(), isURL ? scriptOrURL : "EmbededEntityScript"); + QScriptValue entityScriptConstructor = evaluate(contents, fileName); QScriptValue entityScriptObject = entityScriptConstructor.construct(); EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified }; _entityScripts[entityID] = newDetails; diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index c2f9d966f1..8fda876a31 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -88,7 +88,7 @@ public: Q_INVOKABLE void registerValue(const QString& valueName, QScriptValue value); /// evaluate some code in the context of the ScriptEngine and return the result - Q_INVOKABLE QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1); // this is also used by the script tool widget + Q_INVOKABLE QScriptValue evaluate(const QString& program, const QString& fileName, int lineNumber = 1); // this is also used by the script tool widget /// if the script engine is not already running, this will download the URL and start the process of seting it up /// to run... NOTE - this is used by Application currently to load the url. We don't really want it to be exposed @@ -182,6 +182,9 @@ private: QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot); void stopTimer(QTimer* timer); + static bool checkSynthax(const QScriptProgram& program); + static bool checkExceptions(QScriptEngine* engine, const QString& fileName); + AbstractControllerScriptingInterface* _controllerScriptingInterface; QString _fileNameString; Quat _quatLibrary; diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 22ea12c1b3..cc3519e43e 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -135,7 +135,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont prefixString.append(QString(" [%1]").arg(_targetName)); } - QString logMessage = QString("%1 %2").arg(prefixString, message); + QString logMessage = QString("%1 %2").arg(prefixString, message.split("\n").join("\n" + prefixString + " ")); fprintf(stdout, "%s\n", qPrintable(logMessage)); return logMessage; } From 13b7fa6b5df805497795725556f06cf0b9294731 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 26 Oct 2015 10:49:41 -0700 Subject: [PATCH 03/21] Typo --- libraries/script-engine/src/ScriptEngine.cpp | 6 +++--- libraries/script-engine/src/ScriptEngine.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index cbe9449551..2c725bdf70 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -575,9 +575,9 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi return result; } - // Check synthax + // Check syntax const QScriptProgram program(sourceCode, fileName, lineNumber); - if (!checkSynthax(program)) { + if (!checkSyntax(program)) { return QScriptValue(); } @@ -892,7 +892,7 @@ void ScriptEngine::load(const QString& loadFile) { } -bool ScriptEngine::checkSynthax(const QScriptProgram& program) { +bool ScriptEngine::checkSyntax(const QScriptProgram& program) { const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { const auto error = syntaxCheck.errorMessage(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 8fda876a31..db10ecef40 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -182,7 +182,7 @@ private: QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot); void stopTimer(QTimer* timer); - static bool checkSynthax(const QScriptProgram& program); + static bool checkSyntax(const QScriptProgram& program); static bool checkExceptions(QScriptEngine* engine, const QString& fileName); AbstractControllerScriptingInterface* _controllerScriptingInterface; From 3e43a3c345b0f06f7789dbf57bb8885e260aba87 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 26 Oct 2015 11:33:13 -0700 Subject: [PATCH 04/21] Some more script checks --- libraries/script-engine/src/ScriptEngine.cpp | 26 +++++++------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 2c725bdf70..0411c507ab 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -79,7 +79,6 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { QScriptValue inputControllerToScriptValue(QScriptEngine *engine, AbstractInputController* const &in) { return engine->newQObject(in); } - void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputController* &out) { out = qobject_cast(object.toQObject()); } @@ -95,9 +94,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam _wantSignals(wantSignals), _controllerScriptingInterface(controllerScriptingInterface), _fileNameString(fileNameString), - _quatLibrary(), - _vec3Library(), - _uuidLibrary(), _isUserLoaded(false), _isReloading(false), _arrayBufferClass(new ArrayBufferClass(this)) @@ -654,7 +650,9 @@ void ScriptEngine::run() { } lastUpdate = now; - checkExceptions(this, _fileNameString); + if (!checkExceptions(this, _fileNameString)) { + stop(); + } } stopAllTimers(); // make sure all our timers are stopped if the script is ending @@ -891,7 +889,6 @@ void ScriptEngine::load(const QString& loadFile) { } } - bool ScriptEngine::checkSyntax(const QScriptProgram& program) { const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { @@ -1005,14 +1002,10 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co auto scriptCache = DependencyManager::get(); bool isFileUrl = isURL && scriptOrURL.startsWith("file://"); + auto fileName = QString("(EntityID:%1, %2)").arg(entityID.toString(), isURL ? scriptOrURL : "EmbededEntityScript"); - // first check the syntax of the script contents - QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents); - if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { - qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID; - qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":" - << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber(); - qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; + QScriptProgram program(contents, fileName); + if (!checkSyntax(program)) { if (!isFileUrl) { scriptCache->addScriptToBadScriptList(scriptOrURL); } @@ -1027,9 +1020,9 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co QScriptValue testConstructor = sandbox.evaluate(contents); if (!testConstructor.isFunction()) { - qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID; - qCDebug(scriptengine) << " NOT CONSTRUCTOR"; - qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; + qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID << "\n" + " NOT CONSTRUCTOR\n" + " SCRIPT:" << scriptOrURL; if (!isFileUrl) { scriptCache->addScriptToBadScriptList(scriptOrURL); } @@ -1042,7 +1035,6 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch(); } - auto fileName = QString("(EntityID:%1, %2)").arg(entityID.toString(), isURL ? scriptOrURL : "EmbededEntityScript"); QScriptValue entityScriptConstructor = evaluate(contents, fileName); QScriptValue entityScriptObject = entityScriptConstructor.construct(); EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified }; From 1bebdc8e7022890310e87e73e29521ed2b4df53c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 26 Oct 2015 11:33:36 -0700 Subject: [PATCH 05/21] Fix scripts syntax errors --- examples/libraries/entityCameraTool.js | 10 +++++----- examples/libraries/soundArray.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index d304a6382e..88e01b29fe 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -564,12 +564,12 @@ CameraTool = function(cameraManager) { var ORIENTATION_OVERLAY_SIZE = 26; var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2; - var ORIENTATION_OVERLAY_CUBE_SIZE = 10.5, + var ORIENTATION_OVERLAY_CUBE_SIZE = 10.5; - var ORIENTATION_OVERLAY_OFFSET = { - x: 30, - y: 30, - } + var ORIENTATION_OVERLAY_OFFSET = { + x: 30, + y: 30, + } var UI_WIDTH = 70; var UI_HEIGHT = 70; diff --git a/examples/libraries/soundArray.js b/examples/libraries/soundArray.js index 813621fb4b..f59c88a723 100644 --- a/examples/libraries/soundArray.js +++ b/examples/libraries/soundArray.js @@ -6,7 +6,7 @@ SoundArray = function(audioOptions, autoUpdateAudioPosition) { this.audioOptions = audioOptions !== undefined ? audioOptions : {}; this.autoUpdateAudioPosition = autoUpdateAudioPosition !== undefined ? autoUpdateAudioPosition : false; if (this.audioOptions.position === undefined) { - this.audioOptions.position = Vec3.sum(MyAvatar.position, { x: 0, y: 1, z: 0}), + this.audioOptions.position = Vec3.sum(MyAvatar.position, { x: 0, y: 1, z: 0}); } if (this.audioOptions.volume === undefined) { this.audioOptions.volume = 1.0; From ea56f965a48ddc368f2e38ccf9b10dd2364baee4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 26 Oct 2015 12:27:48 -0700 Subject: [PATCH 06/21] Lambda conversion fix for windows --- libraries/script-engine/src/ScriptEngine.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 0411c507ab..bcfeef1acb 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -509,18 +509,22 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& }); // Two common cases of event handler, differing only in argument signature. - auto makeSingleEntityHandler = [&](QString eventName) { + using SingleEntityHandler = std::function; + auto makeSingleEntityHandler = [this](QString eventName) -> SingleEntityHandler { return [this, eventName](const EntityItemID& entityItemID) { forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this) }); }; }; - auto makeMouseHandler = [&](QString eventName) { + + using MouseHandler = std::function; + auto makeMouseHandler = [this](QString eventName) -> MouseHandler { return [this, eventName](const EntityItemID& entityItemID, const MouseEvent& event) { forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) }); }; }; - auto makeCollisionHandler = [&](QString eventName) { + using CollisionHandler = std::function; + auto makeCollisionHandler = [this](QString eventName) -> CollisionHandler { return [this, eventName](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { forwardHandlerCall(idA, eventName, { idA.toScriptValue(this), idB.toScriptValue(this), collisionToScriptValue(this, collision) }); From a53a576aa32901ab4d5af7e4fa45cab99f30f1e9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 26 Oct 2015 12:33:42 -0700 Subject: [PATCH 07/21] checkExceptions after testing entity scripts in the sandbox --- libraries/script-engine/src/ScriptEngine.cpp | 23 +++++++++++--------- libraries/script-engine/src/ScriptEngine.h | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index bcfeef1acb..986613c20b 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -585,7 +585,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi const auto result = QScriptEngine::evaluate(program); --_evaluatesPending; - const auto hadUncaughtException = checkExceptions(this, program.fileName()); + const auto hadUncaughtException = checkExceptions(*this, program.fileName()); if (_wantSignals) { emit evaluationFinished(result, hadUncaughtException); } @@ -654,7 +654,7 @@ void ScriptEngine::run() { } lastUpdate = now; - if (!checkExceptions(this, _fileNameString)) { + if (!checkExceptions(*this, _fileNameString)) { stop(); } } @@ -906,12 +906,12 @@ bool ScriptEngine::checkSyntax(const QScriptProgram& program) { return true; } -bool ScriptEngine::checkExceptions(QScriptEngine* engine, const QString& fileName) { - if (engine->hasUncaughtException()) { - const auto backtrace = engine->uncaughtExceptionBacktrace(); - const auto exception = engine->uncaughtException().toString(); - const auto line = QString::number(engine->uncaughtExceptionLineNumber()); - engine->clearExceptions(); +bool ScriptEngine::checkExceptions(QScriptEngine& engine, const QString& fileName) { + if (engine.hasUncaughtException()) { + const auto backtrace = engine.uncaughtExceptionBacktrace(); + const auto exception = engine.uncaughtException().toString(); + const auto line = QString::number(engine.uncaughtExceptionLineNumber()); + engine.clearExceptions(); auto message = QString("[UncaughtException] %1 in %2:%3").arg(exception, fileName, line); if (!backtrace.empty()) { @@ -1021,8 +1021,11 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } QScriptEngine sandbox; - QScriptValue testConstructor = sandbox.evaluate(contents); - + QScriptValue testConstructor = sandbox.evaluate(program); + if (!checkExceptions(sandbox, program.fileName())) { + return; + } + if (!testConstructor.isFunction()) { qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID << "\n" " NOT CONSTRUCTOR\n" diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index db10ecef40..ddd957e163 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -183,7 +183,7 @@ private: void stopTimer(QTimer* timer); static bool checkSyntax(const QScriptProgram& program); - static bool checkExceptions(QScriptEngine* engine, const QString& fileName); + static bool checkExceptions(QScriptEngine& engine, const QString& fileName); AbstractControllerScriptingInterface* _controllerScriptingInterface; QString _fileNameString; From ffe73348fb9157186005b9e93e8ef24cb96a5a99 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 27 Oct 2015 12:10:45 -0700 Subject: [PATCH 08/21] Move check functions to cpp only --- libraries/script-engine/src/ScriptEngine.cpp | 62 ++++++++++---------- libraries/script-engine/src/ScriptEngine.h | 3 - 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 986613c20b..92bc3da595 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -83,6 +83,37 @@ void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputCon out = qobject_cast(object.toQObject()); } +bool checkSyntax(const QScriptProgram& program) { + const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); + if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { + const auto error = syntaxCheck.errorMessage(); + const auto line = QString::number(syntaxCheck.errorLineNumber()); + const auto column = QString::number(syntaxCheck.errorColumnNumber()); + const auto message = QString("[SyntaxError] %1 in %2:%3(%4)").arg(error, program.fileName(), line, column); + qCWarning(scriptengine) << qPrintable(message); + return false; + } + return true; +} + +bool checkExceptions(QScriptEngine& engine, const QString& fileName) { + if (engine.hasUncaughtException()) { + const auto backtrace = engine.uncaughtExceptionBacktrace(); + const auto exception = engine.uncaughtException().toString(); + const auto line = QString::number(engine.uncaughtExceptionLineNumber()); + engine.clearExceptions(); + + auto message = QString("[UncaughtException] %1 in %2:%3").arg(exception, fileName, line); + if (!backtrace.empty()) { + static const auto lineSeparator = "\n "; + message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator)); + } + qCWarning(scriptengine) << qPrintable(message); + return false; + } + return true; +} + ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString, AbstractControllerScriptingInterface* controllerScriptingInterface, bool wantSignals) : @@ -893,37 +924,6 @@ void ScriptEngine::load(const QString& loadFile) { } } -bool ScriptEngine::checkSyntax(const QScriptProgram& program) { - const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); - if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { - const auto error = syntaxCheck.errorMessage(); - const auto line = QString::number(syntaxCheck.errorLineNumber()); - const auto column = QString::number(syntaxCheck.errorColumnNumber()); - const auto message = QString("[SyntaxError] %1 in %2:%3(%4)").arg(error, program.fileName(), line, column); - qCWarning(scriptengine) << qPrintable(message); - return false; - } - return true; -} - -bool ScriptEngine::checkExceptions(QScriptEngine& engine, const QString& fileName) { - if (engine.hasUncaughtException()) { - const auto backtrace = engine.uncaughtExceptionBacktrace(); - const auto exception = engine.uncaughtException().toString(); - const auto line = QString::number(engine.uncaughtExceptionLineNumber()); - engine.clearExceptions(); - - auto message = QString("[UncaughtException] %1 in %2:%3").arg(exception, fileName, line); - if (!backtrace.empty()) { - static const auto lineSeparator = "\n "; - message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator)); - } - qCWarning(scriptengine) << qPrintable(message); - return false; - } - return true; -} - // Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) { if (QThread::currentThread() != thread()) { diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index ddd957e163..89d651930b 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -181,9 +181,6 @@ private: QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot); void stopTimer(QTimer* timer); - - static bool checkSyntax(const QScriptProgram& program); - static bool checkExceptions(QScriptEngine& engine, const QString& fileName); AbstractControllerScriptingInterface* _controllerScriptingInterface; QString _fileNameString; From c0138bd189542116b323c1e75c75f68b7afea8c1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 27 Oct 2015 12:39:40 -0700 Subject: [PATCH 09/21] Rename check functions and make them static --- libraries/script-engine/src/ScriptEngine.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 92bc3da595..1d6bf32fcc 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -83,7 +83,7 @@ void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputCon out = qobject_cast(object.toQObject()); } -bool checkSyntax(const QScriptProgram& program) { +static bool hasCorrectSyntax(const QScriptProgram& program) { const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { const auto error = syntaxCheck.errorMessage(); @@ -96,7 +96,7 @@ bool checkSyntax(const QScriptProgram& program) { return true; } -bool checkExceptions(QScriptEngine& engine, const QString& fileName) { +static bool hadUncauchtExceptions(QScriptEngine& engine, const QString& fileName) { if (engine.hasUncaughtException()) { const auto backtrace = engine.uncaughtExceptionBacktrace(); const auto exception = engine.uncaughtException().toString(); @@ -109,9 +109,9 @@ bool checkExceptions(QScriptEngine& engine, const QString& fileName) { message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator)); } qCWarning(scriptengine) << qPrintable(message); - return false; + return true; } - return true; + return false; } ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString, @@ -608,7 +608,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi // Check syntax const QScriptProgram program(sourceCode, fileName, lineNumber); - if (!checkSyntax(program)) { + if (!hasCorrectSyntax(program)) { return QScriptValue(); } @@ -616,7 +616,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi const auto result = QScriptEngine::evaluate(program); --_evaluatesPending; - const auto hadUncaughtException = checkExceptions(*this, program.fileName()); + const auto hadUncaughtException = hadUncauchtExceptions(*this, program.fileName()); if (_wantSignals) { emit evaluationFinished(result, hadUncaughtException); } @@ -685,7 +685,7 @@ void ScriptEngine::run() { } lastUpdate = now; - if (!checkExceptions(*this, _fileNameString)) { + if (hadUncauchtExceptions(*this, _fileNameString)) { stop(); } } @@ -1009,7 +1009,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co auto fileName = QString("(EntityID:%1, %2)").arg(entityID.toString(), isURL ? scriptOrURL : "EmbededEntityScript"); QScriptProgram program(contents, fileName); - if (!checkSyntax(program)) { + if (!hasCorrectSyntax(program)) { if (!isFileUrl) { scriptCache->addScriptToBadScriptList(scriptOrURL); } @@ -1022,7 +1022,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co QScriptEngine sandbox; QScriptValue testConstructor = sandbox.evaluate(program); - if (!checkExceptions(sandbox, program.fileName())) { + if (hadUncauchtExceptions(sandbox, program.fileName())) { return; } From a1f1e504319c49734dcd51cd06277cd747fff87b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 21 Oct 2015 17:37:26 -0700 Subject: [PATCH 10/21] split CharacterController btw phys and interface --- interface/src/Application.cpp | 5 +- interface/src/avatar/MyAvatar.cpp | 109 +++++++++----- interface/src/avatar/MyAvatar.h | 43 ++++-- .../src/avatar/MyAvatarController.cpp | 137 ++++++++++++------ interface/src/avatar/MyAvatarController.h | 106 ++++++++++++++ libraries/physics/src/CharacterController.cpp | 52 +++++++ libraries/physics/src/CharacterController.h | 60 ++++++++ .../physics/src/DynamicCharacterController.h | 95 ------------ libraries/physics/src/PhysicsEngine.cpp | 43 +++--- libraries/physics/src/PhysicsEngine.h | 7 +- 10 files changed, 437 insertions(+), 220 deletions(-) rename libraries/physics/src/DynamicCharacterController.cpp => interface/src/avatar/MyAvatarController.cpp (81%) create mode 100644 interface/src/avatar/MyAvatarController.h create mode 100644 libraries/physics/src/CharacterController.cpp create mode 100644 libraries/physics/src/CharacterController.h delete mode 100644 libraries/physics/src/DynamicCharacterController.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1b6be53876..79339b03de 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2756,7 +2756,6 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("physics"); - myAvatar->relayDriveKeysToCharacterController(); static VectorOfMotionStates motionStates; _entitySimulation.getObjectsToDelete(motionStates); @@ -2783,6 +2782,8 @@ void Application::update(float deltaTime) { avatarManager->getObjectsToChange(motionStates); _physicsEngine->changeObjects(motionStates); + myAvatar->prepareForPhysicsSimulation(); + _entities.getTree()->withWriteLock([&] { _physicsEngine->stepSimulation(); }); @@ -2807,6 +2808,8 @@ void Application::update(float deltaTime) { // and will simulate entity motion (the EntityTree has been given an EntitySimulation). _entities.update(); // update the models... } + + myAvatar->harvestResultsFromPhysicsSimulation(); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5920543dca..e52e56cd89 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -109,8 +109,13 @@ MyAvatar::MyAvatar(RigPointer rig) : _goToOrientation(), _rig(rig), _prevShouldDrawHead(true), - _audioListenerMode(FROM_HEAD), - _hmdAtRestDetector(glm::vec3(0), glm::quat()) + _audioListenerMode(FROM_HEAD) +#ifdef OLD_HMD_TRACKER + ,_hmdAtRestDetector(glm::vec3(0), glm::quat()) +#else + ,_avatarOffsetFromHMD(0.0f) + ,_hmdVelocity(0.0f) +#endif // OLD_HMD_TRACKER { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -154,7 +159,10 @@ void MyAvatar::reset(bool andReload) { } // Reset dynamic state. - _wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false; + _wasPushing = _isPushing = _isBraking = _billboardValid = false; +#ifdef OLD_HMD_TRACKER + _isFollowingHMD = false; +#endif // OLD_HMD_TRACKER _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); @@ -302,9 +310,10 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } +#ifdef OLD_HMD_TRACKER // returns true if pos is OUTSIDE of the vertical capsule // where the middle cylinder length is defined by capsuleLen and the radius by capsuleRad. -static bool capsuleCheck(const glm::vec3& pos, float capsuleLen, float capsuleRad) { +static bool pointIsOutsideCapsule(const glm::vec3& pos, float capsuleLen, float capsuleRad) { const float halfCapsuleLen = capsuleLen / 2.0f; if (fabs(pos.y) <= halfCapsuleLen) { // cylinder check for middle capsule @@ -320,12 +329,18 @@ static bool capsuleCheck(const glm::vec3& pos, float capsuleLen, float capsuleRa return false; } } +#endif // OLD_HMD_TRACKER // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD // as it moves through the world. void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { + // update the sensorMatrices based on the new hmd pose + _hmdSensorMatrix = hmdSensorMatrix; + _hmdSensorPosition = extractTranslation(hmdSensorMatrix); + _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); +#ifdef OLD_HMD_TRACKER // calc deltaTime auto now = usecTimestampNow(); auto deltaUsecs = now - _lastUpdateFromHMDTime; @@ -334,11 +349,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { const float BIGGEST_DELTA_TIME_SECS = 0.25f; float deltaTime = glm::clamp((float)actualDeltaTime, 0.0f, BIGGEST_DELTA_TIME_SECS); - // update the sensorMatrices based on the new hmd pose - _hmdSensorMatrix = hmdSensorMatrix; - _hmdSensorPosition = extractTranslation(hmdSensorMatrix); - _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); - bool hmdIsAtRest = _hmdAtRestDetector.update(deltaTime, _hmdSensorPosition, _hmdSensorOrientation); // It can be more accurate/smooth to use velocity rather than position, @@ -360,58 +370,57 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { bool justStartedMoving = (_lastIsMoving != isMoving) && isMoving; _lastIsMoving = isMoving; - if (shouldBeginStraighteningLean() || hmdIsAtRest || justStartedMoving) { - beginStraighteningLean(); + if (shouldFollowHMD() || hmdIsAtRest || justStartedMoving) { + beginFollowingHMD(); } - processStraighteningLean(deltaTime); + followHMD(deltaTime); +#endif // OLD_HMD_TRACKER } -void MyAvatar::beginStraighteningLean() { +#ifdef OLD_HMD_TRACKER +void MyAvatar::beginFollowingHMD() { // begin homing toward derived body position. - if (!_straighteningLean) { - _straighteningLean = true; - _straighteningLeanAlpha = 0.0f; + if (!_isFollowingHMD) { + _isFollowingHMD = true; + _followHMDAlpha = 0.0f; } } -bool MyAvatar::shouldBeginStraighteningLean() const { - // define a vertical capsule - const float STRAIGHTENING_LEAN_CAPSULE_RADIUS = 0.2f; // meters - const float STRAIGHTENING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. - - // detect if the derived body position is outside of a capsule around the _bodySensorMatrix - auto newBodySensorMatrix = deriveBodyFromHMDSensor(); - glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - bool isBodyPosOutsideCapsule = capsuleCheck(diff, STRAIGHTENING_LEAN_CAPSULE_LENGTH, STRAIGHTENING_LEAN_CAPSULE_RADIUS); - - if (isBodyPosOutsideCapsule) { - return true; - } else { - return false; +bool MyAvatar::shouldFollowHMD() const { + if (!_isFollowingHMD) { + // define a vertical capsule + const float FOLLOW_HMD_CAPSULE_RADIUS = 0.2f; // meters + const float FOLLOW_HMD_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. + + // detect if the derived body position is outside of a capsule around the _bodySensorMatrix + auto newBodySensorMatrix = deriveBodyFromHMDSensor(); + glm::vec3 localPoint = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); + return pointIsOutsideCapsule(localPoint, FOLLOW_HMD_CAPSULE_LENGTH, FOLLOW_HMD_CAPSULE_RADIUS); } + return false; } -void MyAvatar::processStraighteningLean(float deltaTime) { - if (_straighteningLean) { +void MyAvatar::followHMD(float deltaTime) { + if (_isFollowingHMD) { - const float STRAIGHTENING_LEAN_DURATION = 0.5f; // seconds + const float FOLLOW_HMD_DURATION = 0.5f; // seconds auto newBodySensorMatrix = deriveBodyFromHMDSensor(); auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix; glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); - _straighteningLeanAlpha += (1.0f / STRAIGHTENING_LEAN_DURATION) * deltaTime; + _followHMDAlpha += (1.0f / FOLLOW_HMD_DURATION) * deltaTime; - if (_straighteningLeanAlpha >= 1.0f) { - _straighteningLean = false; + if (_followHMDAlpha >= 1.0f) { + _isFollowingHMD = false; nextAttitude(worldBodyPos, worldBodyRot); _bodySensorMatrix = newBodySensorMatrix; } else { // interp position toward the desired pos - glm::vec3 pos = lerp(getPosition(), worldBodyPos, _straighteningLeanAlpha); - glm::quat rot = glm::normalize(safeMix(getOrientation(), worldBodyRot, _straighteningLeanAlpha)); + glm::vec3 pos = lerp(getPosition(), worldBodyPos, _followHMDAlpha); + glm::quat rot = glm::normalize(safeMix(getOrientation(), worldBodyRot, _followHMDAlpha)); nextAttitude(pos, rot); // interp sensor matrix toward desired @@ -419,12 +428,17 @@ void MyAvatar::processStraighteningLean(float deltaTime) { glm::quat nextBodyRot = glm::normalize(glm::quat_cast(newBodySensorMatrix)); glm::vec3 prevBodyPos = extractTranslation(_bodySensorMatrix); glm::quat prevBodyRot = glm::normalize(glm::quat_cast(_bodySensorMatrix)); - pos = lerp(prevBodyPos, nextBodyPos, _straighteningLeanAlpha); - rot = glm::normalize(safeMix(prevBodyRot, nextBodyRot, _straighteningLeanAlpha)); + pos = lerp(prevBodyPos, nextBodyPos, _followHMDAlpha); + rot = glm::normalize(safeMix(prevBodyRot, nextBodyRot, _followHMDAlpha)); _bodySensorMatrix = createMatFromQuatAndPos(rot, pos); } } } +#else +void MyAvatar::harvestHMDOffset(glm::vec3 offset) { + +} +#endif // USE_OLD // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. @@ -1274,6 +1288,21 @@ void MyAvatar::rebuildSkeletonBody() { _characterController.setLocalBoundingBox(corner, scale); } +void MyAvatar::prepareForPhysicsSimulation() { + relayDriveKeysToCharacterController(); + _characterController.setTargetVelocity(getTargetVelocity()); + _characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation()); + //_characterController.setHMDVelocity(hmdVelocity); +} + +void MyAvatar::harvestResultsFromPhysicsSimulation() { + glm::vec3 position = getPosition(); + glm::quat orientation = getOrientation(); + _characterController.getAvatarPositionAndOrientation(position, orientation); + nextAttitude(position, orientation); + setVelocity(_characterController.getLinearVelocity()); +} + QString MyAvatar::getScriptedMotorFrame() const { QString frame = "avatar"; if (_scriptedMotorFrame == SCRIPTED_MOTOR_CAMERA_FRAME) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7347419fee..f3f55f4a7a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -12,12 +12,16 @@ #ifndef hifi_MyAvatar_h #define hifi_MyAvatar_h +#include + #include -#include #include #include "Avatar.h" -#include "AtRestDetector.h" +//#include "AtRestDetector.h" +#include "MyAvatarController.h" + +//#define OLD_HMD_TRACKER class ModelItemID; @@ -154,8 +158,10 @@ public: virtual void setAttachmentData(const QVector& attachmentData) override; - DynamicCharacterController* getCharacterController() { return &_characterController; } + MyAvatarController* getCharacterController() { return &_characterController; } + void prepareForPhysicsSimulation(); + void harvestResultsFromPhysicsSimulation(); const QString& getCollisionSoundURL() {return _collisionSoundURL; } void setCollisionSoundURL(const QString& url); @@ -262,9 +268,13 @@ private: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } - void beginStraighteningLean(); - bool shouldBeginStraighteningLean() const; - void processStraighteningLean(float deltaTime); +#ifdef OLD_HMD_TRACKER + void beginFollowingHMD(); + bool shouldFollowHMD() const; + void followHMD(float deltaTime); +#else + void harvestHMDOffset(glm::vec3 offset); +#endif bool cameraInsideHead() const; @@ -295,7 +305,7 @@ private: quint32 _motionBehaviors; QString _collisionSoundURL; - DynamicCharacterController _characterController; + MyAvatarController _characterController; AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; @@ -348,21 +358,26 @@ private: RigPointer _rig; bool _prevShouldDrawHead; - bool _enableDebugDrawBindPose = false; - bool _enableDebugDrawAnimPose = false; - AnimSkeleton::ConstPointer _debugDrawSkeleton = nullptr; + bool _enableDebugDrawBindPose { false }; + bool _enableDebugDrawAnimPose { false }; + AnimSkeleton::ConstPointer _debugDrawSkeleton { nullptr }; AudioListenerMode _audioListenerMode; glm::vec3 _customListenPosition; glm::quat _customListenOrientation; - bool _straighteningLean = false; - float _straighteningLeanAlpha = 0.0f; +#ifdef OLD_HMD_TRACKER + bool _isFollowingHMD { false }; + float _followHMDAlpha{0.0f}; - quint64 _lastUpdateFromHMDTime = usecTimestampNow(); + quint64 _lastUpdateFromHMDTime{usecTimestampNow()}; AtRestDetector _hmdAtRestDetector; glm::vec3 _lastPosition; - bool _lastIsMoving = false; + bool _lastIsMoving { false }; +#else + glm::vec3 _avatarOffsetFromHMD; + glm::vec3 _hmdVelocity; +#endif // OLD_HMD_TRACKER }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/libraries/physics/src/DynamicCharacterController.cpp b/interface/src/avatar/MyAvatarController.cpp similarity index 81% rename from libraries/physics/src/DynamicCharacterController.cpp rename to interface/src/avatar/MyAvatarController.cpp index 604326168c..931c8b9b08 100644 --- a/libraries/physics/src/DynamicCharacterController.cpp +++ b/interface/src/avatar/MyAvatarController.cpp @@ -1,13 +1,27 @@ +// +// MyAvatar.h +// interface/src/avatar +// +// Created by AndrewMeadows 2015.10.21 +// Copyright 2015 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 "MyAvatarController.h" + #include #include #include #include +#include +#include +#include #include -#include "BulletUtil.h" -#include "DynamicCharacterController.h" -#include "PhysicsLogging.h" +#include "MyAvatar.h" const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); const float DEFAULT_GRAVITY = -5.0f; @@ -15,11 +29,6 @@ const float JUMP_SPEED = 3.5f; const float MAX_FALL_HEIGHT = 20.0f; -const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; -const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; -const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; -const uint32_t PENDING_FLAG_JUMP = 1U << 3; - // TODO: improve walking up steps // TODO: make avatars able to walk up and down steps/slopes // TODO: make avatars stand on steep slope @@ -41,19 +50,19 @@ protected: btRigidBody* _me; }; -DynamicCharacterController::DynamicCharacterController(AvatarData* avatarData) { +MyAvatarController::MyAvatarController(MyAvatar* avatar) { _halfHeight = 1.0f; _shape = nullptr; - _rigidBody = nullptr; - assert(avatarData); - _avatarData = avatarData; + assert(avatar); + _avatar = avatar; _enabled = false; _floorDistance = MAX_FALL_HEIGHT; - _walkVelocity.setValue(0.0f,0.0f,0.0f); + _walkVelocity.setValue(0.0f, 0.0f, 0.0f); + _hmdVelocity.setValue(0.0f, 0.0f, 0.0f); _jumpSpeed = JUMP_SPEED; _isOnGround = false; _isJumping = false; @@ -61,21 +70,16 @@ DynamicCharacterController::DynamicCharacterController(AvatarData* avatarData) { _isHovering = true; _isPushingUp = false; _jumpToHoverStart = 0; + _lastStepDuration = 0.0f; _pendingFlags = PENDING_FLAG_UPDATE_SHAPE; updateShapeIfNecessary(); } -DynamicCharacterController::~DynamicCharacterController() { +MyAvatarController::~MyAvatarController() { } -// virtual -void DynamicCharacterController::setWalkDirection(const btVector3& walkDirection) { - // do nothing -- walkVelocity is upated in preSimulation() - //_walkVelocity = walkDirection; -} - -void DynamicCharacterController::preStep(btCollisionWorld* collisionWorld) { +void MyAvatarController::preStep(btCollisionWorld* collisionWorld) { // trace a ray straight down to see if we're standing on the ground const btTransform& xform = _rigidBody->getWorldTransform(); @@ -96,7 +100,7 @@ void DynamicCharacterController::preStep(btCollisionWorld* collisionWorld) { } } -void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { +void MyAvatarController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { btVector3 actualVelocity = _rigidBody->getLinearVelocity(); btScalar actualSpeed = actualVelocity.length(); @@ -160,7 +164,7 @@ void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScala } } -void DynamicCharacterController::jump() { +void MyAvatarController::jump() { // check for case where user is holding down "jump" key... // we'll eventually tansition to "hover" if (!_isJumping) { @@ -178,12 +182,12 @@ void DynamicCharacterController::jump() { } } -bool DynamicCharacterController::onGround() const { +bool MyAvatarController::onGround() const { const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; return _floorDistance < FLOOR_PROXIMITY_THRESHOLD; } -void DynamicCharacterController::setHovering(bool hover) { +void MyAvatarController::setHovering(bool hover) { if (hover != _isHovering) { _isHovering = hover; _isJumping = false; @@ -198,7 +202,7 @@ void DynamicCharacterController::setHovering(bool hover) { } } -void DynamicCharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { +void MyAvatarController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { _boxScale = scale; float x = _boxScale.x; @@ -231,15 +235,17 @@ void DynamicCharacterController::setLocalBoundingBox(const glm::vec3& corner, co _shapeLocalOffset = corner + 0.5f * _boxScale; } -bool DynamicCharacterController::needsRemoval() const { +/* moved to base class +bool MyAvatarController::needsRemoval() const { return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); } -bool DynamicCharacterController::needsAddition() const { +bool MyAvatarController::needsAddition() const { return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); } +*/ -void DynamicCharacterController::setEnabled(bool enabled) { +void MyAvatarController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. @@ -257,7 +263,8 @@ void DynamicCharacterController::setEnabled(bool enabled) { } } -void DynamicCharacterController::setDynamicsWorld(btDynamicsWorld* world) { +/* moved to base class +void MyAvatarController::setDynamicsWorld(btDynamicsWorld* world) { if (_dynamicsWorld != world) { if (_dynamicsWorld) { if (_rigidBody) { @@ -284,9 +291,9 @@ void DynamicCharacterController::setDynamicsWorld(btDynamicsWorld* world) { } else { _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; } -} +}*/ -void DynamicCharacterController::updateShapeIfNecessary() { +void MyAvatarController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { // make sure there is NO pending removal from simulation at this point // (don't want to delete _rigidBody out from under the simulation) @@ -321,8 +328,8 @@ void DynamicCharacterController::updateShapeIfNecessary() { _rigidBody = new btRigidBody(mass, nullptr, _shape, inertia); _rigidBody->setSleepingThresholds(0.0f, 0.0f); _rigidBody->setAngularFactor(0.0f); - _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), - glmToBullet(_avatarData->getPosition()))); + _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatar->getOrientation()), + glmToBullet(_avatar->getPosition()))); if (_isHovering) { _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); } else { @@ -335,7 +342,7 @@ void DynamicCharacterController::updateShapeIfNecessary() { } } -void DynamicCharacterController::updateUpAxis(const glm::quat& rotation) { +void MyAvatarController::updateUpAxis(const glm::quat& rotation) { btVector3 oldUp = _currentUp; _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); if (!_isHovering) { @@ -346,24 +353,57 @@ void DynamicCharacterController::updateUpAxis(const glm::quat& rotation) { } } -void DynamicCharacterController::preSimulation(btScalar timeStep) { - if (_enabled && _dynamicsWorld) { - glm::quat rotation = _avatarData->getOrientation(); +void MyAvatarController::setAvatarPositionAndOrientation( + const glm::vec3& position, + const glm::quat& orientation) { + // TODO: update gravity if up has changed + updateUpAxis(orientation); + btQuaternion bodyOrientation = glmToBullet(orientation); + btVector3 bodyPosition = glmToBullet(position + orientation * _shapeLocalOffset); + _avatarBodyTransform = btTransform(bodyOrientation, bodyPosition); +} + +void MyAvatarController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { + if (_enabled && _rigidBody) { + const btTransform& avatarTransform = _rigidBody->getWorldTransform(); + rotation = bulletToGLM(avatarTransform.getRotation()); + position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset; + } +} + +void MyAvatarController::setTargetVelocity(const glm::vec3& velocity) { + //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); + _walkVelocity = glmToBullet(velocity); +} + +void MyAvatarController::setHMDVelocity(const glm::vec3& velocity) { + _hmdVelocity = glmToBullet(velocity); +} + +glm::vec3 MyAvatarController::getLinearVelocity() const { + glm::vec3 velocity(0.0f); + if (_rigidBody) { + velocity = bulletToGLM(_rigidBody->getLinearVelocity()); + } + return velocity; +} + +void MyAvatarController::preSimulation() { + if (_enabled && _dynamicsWorld) { + /* + glm::quat rotation = _avatarData->getOrientation(); // TODO: update gravity if up has changed updateUpAxis(rotation); - glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; _rigidBody->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); + */ - // the rotation is dictated by AvatarData - btTransform xform = _rigidBody->getWorldTransform(); - xform.setRotation(glmToBullet(rotation)); - _rigidBody->setWorldTransform(xform); + _rigidBody->setWorldTransform(_avatarBodyTransform); // scan for distant floor // rayStart is at center of bottom sphere - btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp; + btVector3 rayStart = _avatarBodyTransform.getOrigin() - _halfHeight * _currentUp; // rayEnd is straight down MAX_FALL_HEIGHT btScalar rayLength = _radius + MAX_FALL_HEIGHT; @@ -388,8 +428,6 @@ void DynamicCharacterController::preSimulation(btScalar timeStep) { setHovering(true); } - _walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); - if (_pendingFlags & PENDING_FLAG_JUMP) { _pendingFlags &= ~ PENDING_FLAG_JUMP; if (onGround()) { @@ -402,7 +440,9 @@ void DynamicCharacterController::preSimulation(btScalar timeStep) { } } -void DynamicCharacterController::postSimulation() { +void MyAvatarController::postSimulation() { + /* + _lastStepDuration += timeStep; if (_enabled && _rigidBody) { const btTransform& avatarTransform = _rigidBody->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); @@ -410,5 +450,8 @@ void DynamicCharacterController::postSimulation() { _avatarData->nextAttitude(position - rotation * _shapeLocalOffset, rotation); _avatarData->setVelocity(bulletToGLM(_rigidBody->getLinearVelocity())); + _avatarData->applySimulationTime(_lastStepDuration); } + _lastStepDuration = 0.0f; + */ } diff --git a/interface/src/avatar/MyAvatarController.h b/interface/src/avatar/MyAvatarController.h new file mode 100644 index 0000000000..a973905653 --- /dev/null +++ b/interface/src/avatar/MyAvatarController.h @@ -0,0 +1,106 @@ +// +// MyAvatar.h +// interface/src/avatar +// +// Created by AndrewMeadows 2015.10.21 +// Copyright 2015 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_MyAvatarController_h +#define hifi_MyAvatarController_h + +#include +#include + +#include +#include + +class btCollisionShape; +class MyAvatar; + +class MyAvatarController : public CharacterController { +public: + MyAvatarController(MyAvatar* avatar); + ~MyAvatarController (); + + // TODO: implement these when needed + virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } + virtual void reset(btCollisionWorld* collisionWorld) override { } + virtual void warp(const btVector3& origin) override { } + virtual void debugDraw(btIDebugDraw* debugDrawer) override { } + virtual void setUpInterpolate(bool value) override { } + + // overrides from btCharacterControllerInterface + virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override { + preStep(collisionWorld); + playerStep(collisionWorld, deltaTime); + } + virtual void preStep(btCollisionWorld* collisionWorld) override; + virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt) override; + virtual bool canJump() const override { assert(false); return false; } // never call this + virtual void jump() override; // call this every frame the jump button is pressed + virtual bool onGround() const override; + + // overrides from CharacterController + virtual void preSimulation() override; + virtual void postSimulation() override; + virtual void incrementSimulationTime(btScalar timeStep) override { _lastStepDuration += timeStep; } + + bool isHovering() const { return _isHovering; } + void setHovering(bool enabled); + + void setEnabled(bool enabled); + bool isEnabled() const { return _enabled && _dynamicsWorld; } + + void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); + + virtual void updateShapeIfNecessary() override; + + void setAvatarPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation); + void getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const; + + void setTargetVelocity(const glm::vec3& velocity); + void setHMDVelocity(const glm::vec3& velocity); + + glm::vec3 getLinearVelocity() const; + +protected: + void updateUpAxis(const glm::quat& rotation); + +protected: + btVector3 _currentUp; + btVector3 _walkVelocity; + btVector3 _hmdVelocity; + btTransform _avatarBodyTransform; + + glm::vec3 _shapeLocalOffset; + glm::vec3 _boxScale; // used to compute capsule shape + + quint64 _jumpToHoverStart; + + btCollisionShape* _shape { nullptr }; + MyAvatar* _avatar { nullptr }; + + btScalar _halfHeight; + btScalar _radius; + + btScalar _floorDistance; + + btScalar _gravity; + + btScalar _jumpSpeed; + btScalar _lastStepDuration; + + bool _enabled; + bool _isOnGround; + bool _isJumping; + bool _isFalling; + bool _isHovering; + bool _isPushingUp; +}; + +#endif // hifi_MyAvatarController_h diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp new file mode 100644 index 0000000000..9ba22cf2db --- /dev/null +++ b/libraries/physics/src/CharacterController.cpp @@ -0,0 +1,52 @@ +// +// CharacterControllerInterface.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.10.21 +// Copyright 2015 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 "CharacterController.h" + +#include "PhysicsCollisionGroups.h" + +bool CharacterController::needsRemoval() const { + return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); +} + +bool CharacterController::needsAddition() const { + return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); +} + +void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { + if (_dynamicsWorld != world) { + if (_dynamicsWorld) { + if (_rigidBody) { + _dynamicsWorld->removeRigidBody(_rigidBody); + _dynamicsWorld->removeAction(this); + } + _dynamicsWorld = nullptr; + } + if (world && _rigidBody) { + _dynamicsWorld = world; + _pendingFlags &= ~ PENDING_FLAG_JUMP; + _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); + _dynamicsWorld->addAction(this); + //reset(_dynamicsWorld); + } + } + if (_dynamicsWorld) { + if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { + // shouldn't fall in here, but if we do make sure both ADD and REMOVE bits are still set + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_REMOVE_FROM_SIMULATION; + } else { + _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; + } + } else { + _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; + } +} + diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h new file mode 100644 index 0000000000..cff257a790 --- /dev/null +++ b/libraries/physics/src/CharacterController.h @@ -0,0 +1,60 @@ +// +// CharacterControllerInterface.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.10.21 +// Copyright 2015 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_CharacterControllerInterface_h +#define hifi_CharacterControllerInterface_h + +#include +#include +#include +#include + +const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; +const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; +const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; +const uint32_t PENDING_FLAG_JUMP = 1U << 3; + + +class btRigidBody; +class btCollisionWorld; +class btDynamicsWorld; + +class CharacterController : public btCharacterControllerInterface { +public: + bool needsRemoval() const; + bool needsAddition() const; + void setDynamicsWorld(btDynamicsWorld* world); + btCollisionObject* getCollisionObject() { return _rigidBody; } + + virtual void updateShapeIfNecessary() = 0; + virtual void preSimulation() = 0; + virtual void incrementSimulationTime(btScalar stepTime) = 0; + virtual void postSimulation() = 0; + + virtual void setWalkDirection(const btVector3 &walkDirection) { assert(false); } + + /* these from btCharacterControllerInterface remain to be overridden + virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) = 0; + virtual void reset() = 0; + virtual void warp(const btVector3 &origin) = 0; + virtual void preStep(btCollisionWorld *collisionWorld) = 0; + virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) = 0; + virtual bool canJump() const = 0; + virtual void jump() = 0; + virtual bool onGround() const = 0; + */ +protected: + btDynamicsWorld* _dynamicsWorld { nullptr }; + btRigidBody* _rigidBody { nullptr }; + uint32_t _pendingFlags { 0 }; +}; + +#endif // hifi_CharacterControllerInterface_h diff --git a/libraries/physics/src/DynamicCharacterController.h b/libraries/physics/src/DynamicCharacterController.h deleted file mode 100644 index d26c69c5a5..0000000000 --- a/libraries/physics/src/DynamicCharacterController.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef hifi_DynamicCharacterController_h -#define hifi_DynamicCharacterController_h - -#include -#include - -#include - -class btCollisionShape; -class btRigidBody; -class btCollisionWorld; - -const int NUM_CHARACTER_CONTROLLER_RAYS = 2; - -class DynamicCharacterController : public btCharacterControllerInterface -{ -protected: - btScalar _halfHeight; - btScalar _radius; - btCollisionShape* _shape; - btRigidBody* _rigidBody; - - btVector3 _currentUp; - - btScalar _floorDistance; - - btVector3 _walkVelocity; - btScalar _gravity; - - glm::vec3 _shapeLocalOffset; - glm::vec3 _boxScale; // used to compute capsule shape - AvatarData* _avatarData = nullptr; - - bool _enabled; - bool _isOnGround; - bool _isJumping; - bool _isFalling; - bool _isHovering; - bool _isPushingUp; - quint64 _jumpToHoverStart; - uint32_t _pendingFlags; - - btDynamicsWorld* _dynamicsWorld = nullptr; - - btScalar _jumpSpeed; - -public: - DynamicCharacterController(AvatarData* avatarData); - ~DynamicCharacterController (); - - virtual void setWalkDirection(const btVector3& walkDirection); - virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) { assert(false); } - - // TODO: implement these when needed - virtual void reset(btCollisionWorld* collisionWorld) { } - virtual void warp(const btVector3& origin) { } - virtual void debugDraw(btIDebugDraw* debugDrawer) { } - virtual void setUpInterpolate(bool value) { } - - btCollisionObject* getCollisionObject() { return _rigidBody; } - - ///btActionInterface interface - virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) { - preStep(collisionWorld); - playerStep(collisionWorld, deltaTime); - } - - virtual void preStep(btCollisionWorld* collisionWorld); - virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt); - - virtual bool canJump() const { assert(false); return false; } // never call this - virtual void jump(); // call this every frame the jump button is pressed - virtual bool onGround() const; - bool isHovering() const { return _isHovering; } - void setHovering(bool enabled); - - bool needsRemoval() const; - bool needsAddition() const; - void setEnabled(bool enabled); - bool isEnabled() const { return _enabled && _dynamicsWorld; } - - void setDynamicsWorld(btDynamicsWorld* world); - - void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); - bool needsShapeUpdate() const; - void updateShapeIfNecessary(); - - void preSimulation(btScalar timeStep); - void postSimulation(); - -protected: - void updateUpAxis(const glm::quat& rotation); -}; - -#endif // hifi_DynamicCharacterController_h diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 75273e62ba..a6b8dbe959 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -11,6 +11,7 @@ #include +#include "CharacterController.h" #include "ObjectMotionState.h" #include "PhysicsEngine.h" #include "PhysicsHelpers.h" @@ -23,7 +24,7 @@ uint32_t PhysicsEngine::getNumSubsteps() { PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : _originOffset(offset), - _characterController(nullptr) { + _myAvatarController(nullptr) { // build table of masks with their group as the key _collisionMasks.insert(btHashInt((int)COLLISION_GROUP_DEFAULT), COLLISION_MASK_DEFAULT); _collisionMasks.insert(btHashInt((int)COLLISION_GROUP_STATIC), COLLISION_MASK_STATIC); @@ -38,8 +39,8 @@ PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : } PhysicsEngine::~PhysicsEngine() { - if (_characterController) { - _characterController->setDynamicsWorld(nullptr); + if (_myAvatarController) { + _myAvatarController->setDynamicsWorld(nullptr); } delete _collisionConfig; delete _collisionDispatcher; @@ -239,16 +240,18 @@ void PhysicsEngine::stepSimulation() { _clock.reset(); float timeStep = btMin(dt, MAX_TIMESTEP); - // TODO: move character->preSimulation() into relayIncomingChanges - if (_characterController) { - if (_characterController->needsRemoval()) { - _characterController->setDynamicsWorld(nullptr); + if (_myAvatarController) { + // ADEBUG TODO: move this stuff outside and in front of stepSimulation, because + // the updateShapeIfNecessary() call needs info from MyAvatar and should + // be done on the main thread during the pre-simulation stuff + if (_myAvatarController->needsRemoval()) { + _myAvatarController->setDynamicsWorld(nullptr); } - _characterController->updateShapeIfNecessary(); - if (_characterController->needsAddition()) { - _characterController->setDynamicsWorld(_dynamicsWorld); + _myAvatarController->updateShapeIfNecessary(); + if (_myAvatarController->needsAddition()) { + _myAvatarController->setDynamicsWorld(_dynamicsWorld); } - _characterController->preSimulation(timeStep); + _myAvatarController->preSimulation(); } int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, PHYSICS_ENGINE_MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); @@ -257,8 +260,8 @@ void PhysicsEngine::stepSimulation() { _numSubsteps += (uint32_t)numSubsteps; ObjectMotionState::setWorldSimulationStep(_numSubsteps); - if (_characterController) { - _characterController->postSimulation(); + if (_myAvatarController) { + _myAvatarController->postSimulation(); } updateContactMap(); _hasOutgoingChanges = true; @@ -268,7 +271,7 @@ void PhysicsEngine::stepSimulation() { void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) { BT_PROFILE("ownershipInfection"); - const btCollisionObject* characterObject = _characterController ? _characterController->getCollisionObject() : nullptr; + const btCollisionObject* characterObject = _myAvatarController ? _myAvatarController->getCollisionObject() : nullptr; ObjectMotionState* motionStateA = static_cast(objectA->getUserPointer()); ObjectMotionState* motionStateB = static_cast(objectB->getUserPointer()); @@ -431,15 +434,15 @@ void PhysicsEngine::bump(ObjectMotionState* motionState) { } } -void PhysicsEngine::setCharacterController(DynamicCharacterController* character) { - if (_characterController != character) { - if (_characterController) { +void PhysicsEngine::setCharacterController(CharacterController* character) { + if (_myAvatarController != character) { + if (_myAvatarController) { // remove the character from the DynamicsWorld immediately - _characterController->setDynamicsWorld(nullptr); - _characterController = nullptr; + _myAvatarController->setDynamicsWorld(nullptr); + _myAvatarController = nullptr; } // the character will be added to the DynamicsWorld later - _characterController = character; + _myAvatarController = character; } } diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 0a317652da..e7b5fd79d4 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -21,13 +21,14 @@ #include "BulletUtil.h" #include "ContactInfo.h" -#include "DynamicCharacterController.h" #include "ObjectMotionState.h" #include "ThreadSafeDynamicsWorld.h" #include "ObjectAction.h" const float HALF_SIMULATION_EXTENT = 512.0f; // meters +class CharacterController; + // simple class for keeping track of contacts class ContactKey { public: @@ -87,7 +88,7 @@ public: void removeRigidBody(btRigidBody* body); - void setCharacterController(DynamicCharacterController* character); + void setCharacterController(CharacterController* character); void dumpNextStats() { _dumpNextStats = true; } @@ -117,7 +118,7 @@ private: uint32_t _lastNumSubstepsAtUpdateInternal = 0; /// character collisions - DynamicCharacterController* _characterController = NULL; + CharacterController* _myAvatarController; bool _dumpNextStats = false; bool _hasOutgoingChanges = false; From 5f278f90246004dc0bbafe69d3e2082766bae4c6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 09:44:22 -0700 Subject: [PATCH 11/21] name change --- interface/src/avatar/MyAvatar.h | 6 +-- ...ntroller.cpp => MyCharacterController.cpp} | 44 +++++++++---------- ...arController.h => MyCharacterController.h} | 14 +++--- 3 files changed, 32 insertions(+), 32 deletions(-) rename interface/src/avatar/{MyAvatarController.cpp => MyCharacterController.cpp} (91%) rename interface/src/avatar/{MyAvatarController.h => MyCharacterController.h} (91%) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f3f55f4a7a..2f2b8ca3b5 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -19,7 +19,7 @@ #include "Avatar.h" //#include "AtRestDetector.h" -#include "MyAvatarController.h" +#include "MyCharacterController.h" //#define OLD_HMD_TRACKER @@ -158,7 +158,7 @@ public: virtual void setAttachmentData(const QVector& attachmentData) override; - MyAvatarController* getCharacterController() { return &_characterController; } + MyCharacterController* getCharacterController() { return &_characterController; } void prepareForPhysicsSimulation(); void harvestResultsFromPhysicsSimulation(); @@ -305,7 +305,7 @@ private: quint32 _motionBehaviors; QString _collisionSoundURL; - MyAvatarController _characterController; + MyCharacterController _characterController; AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; diff --git a/interface/src/avatar/MyAvatarController.cpp b/interface/src/avatar/MyCharacterController.cpp similarity index 91% rename from interface/src/avatar/MyAvatarController.cpp rename to interface/src/avatar/MyCharacterController.cpp index 931c8b9b08..05d6c57bb8 100644 --- a/interface/src/avatar/MyAvatarController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "MyAvatarController.h" +#include "MyCharacterController.h" #include #include @@ -50,7 +50,7 @@ protected: btRigidBody* _me; }; -MyAvatarController::MyAvatarController(MyAvatar* avatar) { +MyCharacterController::MyCharacterController(MyAvatar* avatar) { _halfHeight = 1.0f; _shape = nullptr; @@ -76,10 +76,10 @@ MyAvatarController::MyAvatarController(MyAvatar* avatar) { updateShapeIfNecessary(); } -MyAvatarController::~MyAvatarController() { +MyCharacterController::~MyCharacterController() { } -void MyAvatarController::preStep(btCollisionWorld* collisionWorld) { +void MyCharacterController::preStep(btCollisionWorld* collisionWorld) { // trace a ray straight down to see if we're standing on the ground const btTransform& xform = _rigidBody->getWorldTransform(); @@ -100,7 +100,7 @@ void MyAvatarController::preStep(btCollisionWorld* collisionWorld) { } } -void MyAvatarController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { +void MyCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { btVector3 actualVelocity = _rigidBody->getLinearVelocity(); btScalar actualSpeed = actualVelocity.length(); @@ -164,7 +164,7 @@ void MyAvatarController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { } } -void MyAvatarController::jump() { +void MyCharacterController::jump() { // check for case where user is holding down "jump" key... // we'll eventually tansition to "hover" if (!_isJumping) { @@ -182,12 +182,12 @@ void MyAvatarController::jump() { } } -bool MyAvatarController::onGround() const { +bool MyCharacterController::onGround() const { const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; return _floorDistance < FLOOR_PROXIMITY_THRESHOLD; } -void MyAvatarController::setHovering(bool hover) { +void MyCharacterController::setHovering(bool hover) { if (hover != _isHovering) { _isHovering = hover; _isJumping = false; @@ -202,7 +202,7 @@ void MyAvatarController::setHovering(bool hover) { } } -void MyAvatarController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { +void MyCharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { _boxScale = scale; float x = _boxScale.x; @@ -236,16 +236,16 @@ void MyAvatarController::setLocalBoundingBox(const glm::vec3& corner, const glm: } /* moved to base class -bool MyAvatarController::needsRemoval() const { +bool MyCharacterController::needsRemoval() const { return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); } -bool MyAvatarController::needsAddition() const { +bool MyCharacterController::needsAddition() const { return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); } */ -void MyAvatarController::setEnabled(bool enabled) { +void MyCharacterController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. @@ -264,7 +264,7 @@ void MyAvatarController::setEnabled(bool enabled) { } /* moved to base class -void MyAvatarController::setDynamicsWorld(btDynamicsWorld* world) { +void MyCharacterController::setDynamicsWorld(btDynamicsWorld* world) { if (_dynamicsWorld != world) { if (_dynamicsWorld) { if (_rigidBody) { @@ -293,7 +293,7 @@ void MyAvatarController::setDynamicsWorld(btDynamicsWorld* world) { } }*/ -void MyAvatarController::updateShapeIfNecessary() { +void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { // make sure there is NO pending removal from simulation at this point // (don't want to delete _rigidBody out from under the simulation) @@ -342,7 +342,7 @@ void MyAvatarController::updateShapeIfNecessary() { } } -void MyAvatarController::updateUpAxis(const glm::quat& rotation) { +void MyCharacterController::updateUpAxis(const glm::quat& rotation) { btVector3 oldUp = _currentUp; _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); if (!_isHovering) { @@ -353,7 +353,7 @@ void MyAvatarController::updateUpAxis(const glm::quat& rotation) { } } -void MyAvatarController::setAvatarPositionAndOrientation( +void MyCharacterController::setAvatarPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation) { // TODO: update gravity if up has changed @@ -364,7 +364,7 @@ void MyAvatarController::setAvatarPositionAndOrientation( _avatarBodyTransform = btTransform(bodyOrientation, bodyPosition); } -void MyAvatarController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { +void MyCharacterController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { if (_enabled && _rigidBody) { const btTransform& avatarTransform = _rigidBody->getWorldTransform(); rotation = bulletToGLM(avatarTransform.getRotation()); @@ -372,16 +372,16 @@ void MyAvatarController::getAvatarPositionAndOrientation(glm::vec3& position, gl } } -void MyAvatarController::setTargetVelocity(const glm::vec3& velocity) { +void MyCharacterController::setTargetVelocity(const glm::vec3& velocity) { //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); _walkVelocity = glmToBullet(velocity); } -void MyAvatarController::setHMDVelocity(const glm::vec3& velocity) { +void MyCharacterController::setHMDVelocity(const glm::vec3& velocity) { _hmdVelocity = glmToBullet(velocity); } -glm::vec3 MyAvatarController::getLinearVelocity() const { +glm::vec3 MyCharacterController::getLinearVelocity() const { glm::vec3 velocity(0.0f); if (_rigidBody) { velocity = bulletToGLM(_rigidBody->getLinearVelocity()); @@ -389,7 +389,7 @@ glm::vec3 MyAvatarController::getLinearVelocity() const { return velocity; } -void MyAvatarController::preSimulation() { +void MyCharacterController::preSimulation() { if (_enabled && _dynamicsWorld) { /* glm::quat rotation = _avatarData->getOrientation(); @@ -440,7 +440,7 @@ void MyAvatarController::preSimulation() { } } -void MyAvatarController::postSimulation() { +void MyCharacterController::postSimulation() { /* _lastStepDuration += timeStep; if (_enabled && _rigidBody) { diff --git a/interface/src/avatar/MyAvatarController.h b/interface/src/avatar/MyCharacterController.h similarity index 91% rename from interface/src/avatar/MyAvatarController.h rename to interface/src/avatar/MyCharacterController.h index a973905653..2533ec2680 100644 --- a/interface/src/avatar/MyAvatarController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -1,5 +1,5 @@ // -// MyAvatar.h +// MyCharacterController.h // interface/src/avatar // // Created by AndrewMeadows 2015.10.21 @@ -10,8 +10,8 @@ // -#ifndef hifi_MyAvatarController_h -#define hifi_MyAvatarController_h +#ifndef hifi_MyCharacterController_h +#define hifi_MyCharacterController_h #include #include @@ -22,10 +22,10 @@ class btCollisionShape; class MyAvatar; -class MyAvatarController : public CharacterController { +class MyCharacterController : public CharacterController { public: - MyAvatarController(MyAvatar* avatar); - ~MyAvatarController (); + MyCharacterController(MyAvatar* avatar); + ~MyCharacterController (); // TODO: implement these when needed virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } @@ -103,4 +103,4 @@ protected: bool _isPushingUp; }; -#endif // hifi_MyAvatarController_h +#endif // hifi_MyCharacterController_h From 5e59e9595b1f2bded6021189ca44355acf0f6fb5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 09:45:47 -0700 Subject: [PATCH 12/21] fix typo in comments --- interface/src/avatar/MyCharacterController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 05d6c57bb8..4c77384e88 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -1,5 +1,5 @@ // -// MyAvatar.h +// MyCharacterController.h // interface/src/avatar // // Created by AndrewMeadows 2015.10.21 From 355ebe923dd94b879cf9cbc0c1400768fe1eb551 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 09:51:36 -0700 Subject: [PATCH 13/21] cleanup and comments --- .../src/avatar/MyCharacterController.cpp | 63 +------------------ 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 4c77384e88..0ae4b240a2 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -235,16 +235,6 @@ void MyCharacterController::setLocalBoundingBox(const glm::vec3& corner, const g _shapeLocalOffset = corner + 0.5f * _boxScale; } -/* moved to base class -bool MyCharacterController::needsRemoval() const { - return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); -} - -bool MyCharacterController::needsAddition() const { - return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); -} -*/ - void MyCharacterController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { @@ -263,36 +253,6 @@ void MyCharacterController::setEnabled(bool enabled) { } } -/* moved to base class -void MyCharacterController::setDynamicsWorld(btDynamicsWorld* world) { - if (_dynamicsWorld != world) { - if (_dynamicsWorld) { - if (_rigidBody) { - _dynamicsWorld->removeRigidBody(_rigidBody); - _dynamicsWorld->removeAction(this); - } - _dynamicsWorld = nullptr; - } - if (world && _rigidBody) { - _dynamicsWorld = world; - _pendingFlags &= ~ PENDING_FLAG_JUMP; - _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); - _dynamicsWorld->addAction(this); - //reset(_dynamicsWorld); - } - } - if (_dynamicsWorld) { - if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { - // shouldn't fall in here, but if we do make sure both ADD and REMOVE bits are still set - _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_REMOVE_FROM_SIMULATION; - } else { - _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; - } - } else { - _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; - } -}*/ - void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { // make sure there is NO pending removal from simulation at this point @@ -391,14 +351,7 @@ glm::vec3 MyCharacterController::getLinearVelocity() const { void MyCharacterController::preSimulation() { if (_enabled && _dynamicsWorld) { - /* - glm::quat rotation = _avatarData->getOrientation(); - // TODO: update gravity if up has changed - updateUpAxis(rotation); - glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; - _rigidBody->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); - */ - + // slam body to where it is supposed to be _rigidBody->setWorldTransform(_avatarBodyTransform); // scan for distant floor @@ -441,17 +394,5 @@ void MyCharacterController::preSimulation() { } void MyCharacterController::postSimulation() { - /* - _lastStepDuration += timeStep; - if (_enabled && _rigidBody) { - const btTransform& avatarTransform = _rigidBody->getWorldTransform(); - glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); - glm::vec3 position = bulletToGLM(avatarTransform.getOrigin()); - - _avatarData->nextAttitude(position - rotation * _shapeLocalOffset, rotation); - _avatarData->setVelocity(bulletToGLM(_rigidBody->getLinearVelocity())); - _avatarData->applySimulationTime(_lastStepDuration); - } - _lastStepDuration = 0.0f; - */ + // postSimulation() exists for symmetry and just in case we need to do something here later } From 24c2f538a42bb34780b5a9310e44fdf59c504b35 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 10:52:49 -0700 Subject: [PATCH 14/21] keep MyAvatar RigidBody on shape changes --- .../src/avatar/MyCharacterController.cpp | 27 +++++++++---------- interface/src/avatar/MyCharacterController.h | 1 - 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 0ae4b240a2..3e9755c6ca 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -52,7 +52,6 @@ protected: MyCharacterController::MyCharacterController(MyAvatar* avatar) { _halfHeight = 1.0f; - _shape = nullptr; assert(avatar); _avatar = avatar; @@ -255,15 +254,7 @@ void MyCharacterController::setEnabled(bool enabled) { void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { - // make sure there is NO pending removal from simulation at this point - // (don't want to delete _rigidBody out from under the simulation) - assert(!(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION)); _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; - // delete shape and RigidBody - delete _rigidBody; - _rigidBody = nullptr; - delete _shape; - _shape = nullptr; // compute new dimensions from avatar's bounding box float x = _boxScale.x; @@ -277,15 +268,23 @@ void MyCharacterController::updateShapeIfNecessary() { // NOTE: _shapeLocalOffset is already computed if (_radius > 0.0f) { - // create new shape - _shape = new btCapsuleShape(_radius, 2.0f * _halfHeight); - // HACK: use some simple mass property defaults for now float mass = 100.0f; btVector3 inertia(30.0f, 8.0f, 30.0f); - // create new body - _rigidBody = new btRigidBody(mass, nullptr, _shape, inertia); + // create RigidBody if it doesn't exist + if (!_rigidBody) { + btCollisionShape* shape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _rigidBody = new btRigidBody(mass, nullptr, shape, inertia); + } else { + btCollisionShape* shape = _rigidBody->getCollisionShape(); + if (shape) { + delete shape; + } + shape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _rigidBody->setCollisionShape(shape); + } + _rigidBody->setSleepingThresholds(0.0f, 0.0f); _rigidBody->setAngularFactor(0.0f); _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatar->getOrientation()), diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 2533ec2680..5ee9f50f7e 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -82,7 +82,6 @@ protected: quint64 _jumpToHoverStart; - btCollisionShape* _shape { nullptr }; MyAvatar* _avatar { nullptr }; btScalar _halfHeight; From 43aac813daab023eeb5003ed3d0db072f104cf7d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 11:46:55 -0700 Subject: [PATCH 15/21] more prep for shifting avatar during HMD motion --- interface/src/avatar/MyAvatar.cpp | 17 +++++++++++------ interface/src/avatar/MyAvatar.h | 5 ++--- interface/src/avatar/MyCharacterController.cpp | 13 ++++++++++++- interface/src/avatar/MyCharacterController.h | 3 ++- libraries/physics/src/CharacterController.h | 1 - 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e52e56cd89..cfcd7a69f9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -114,7 +114,6 @@ MyAvatar::MyAvatar(RigPointer rig) : ,_hmdAtRestDetector(glm::vec3(0), glm::quat()) #else ,_avatarOffsetFromHMD(0.0f) - ,_hmdVelocity(0.0f) #endif // OLD_HMD_TRACKER { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { @@ -375,9 +374,16 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } followHMD(deltaTime); +#else + // TODO adebug BOOKMARK -- this is where we need to add the new code for HMD_TRACKER #endif // OLD_HMD_TRACKER } +glm::vec3 MyAvatar::getHMDCorrectionVelocity() const { + // TODO: impelement this + return Vectors::ZERO; +} + #ifdef OLD_HMD_TRACKER void MyAvatar::beginFollowingHMD() { // begin homing toward derived body position. @@ -433,10 +439,6 @@ void MyAvatar::followHMD(float deltaTime) { _bodySensorMatrix = createMatFromQuatAndPos(rot, pos); } } -} -#else -void MyAvatar::harvestHMDOffset(glm::vec3 offset) { - } #endif // USE_OLD @@ -1292,7 +1294,7 @@ void MyAvatar::prepareForPhysicsSimulation() { relayDriveKeysToCharacterController(); _characterController.setTargetVelocity(getTargetVelocity()); _characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation()); - //_characterController.setHMDVelocity(hmdVelocity); + _characterController.setHMDVelocity(getHMDCorrectionVelocity()); } void MyAvatar::harvestResultsFromPhysicsSimulation() { @@ -1301,6 +1303,9 @@ void MyAvatar::harvestResultsFromPhysicsSimulation() { _characterController.getAvatarPositionAndOrientation(position, orientation); nextAttitude(position, orientation); setVelocity(_characterController.getLinearVelocity()); + + // adebug TODO: harvest HMD shift here + //glm::vec3 hmdShift = _characterController.getHMDShift(); } QString MyAvatar::getScriptedMotorFrame() const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2f2b8ca3b5..36c73d672d 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -76,6 +76,8 @@ public: // as it moves through the world. void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); + glm::vec3 getHMDCorrectionVelocity() const; + // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. // This is so the correct camera can be used for rendering. @@ -272,8 +274,6 @@ private: void beginFollowingHMD(); bool shouldFollowHMD() const; void followHMD(float deltaTime); -#else - void harvestHMDOffset(glm::vec3 offset); #endif bool cameraInsideHead() const; @@ -376,7 +376,6 @@ private: bool _lastIsMoving { false }; #else glm::vec3 _avatarOffsetFromHMD; - glm::vec3 _hmdVelocity; #endif // OLD_HMD_TRACKER }; diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 3e9755c6ca..ad2ca32b05 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -161,6 +160,17 @@ void MyCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) _rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection); } } + + // Rather than add _hmdVelocity to the velocity of the RigidBody, we explicitly teleport + // the RigidBody forward according to the formula: distance = rate * time + if (_hmdVelocity.length2() > 0.0f) { + btTransform bodyTransform = _rigidBody->getWorldTransform(); + bodyTransform.setOrigin(bodyTransform.getOrigin() + dt * _hmdVelocity); + _rigidBody->setWorldTransform(bodyTransform); + } + // MyAvatar will ask us how far we stepped for HMD motion, which will depend on how + // much time has accumulated in _lastStepDuration. + _lastStepDuration += dt; } void MyCharacterController::jump() { @@ -390,6 +400,7 @@ void MyCharacterController::preSimulation() { } } } + _lastStepDuration = 0.0f; } void MyCharacterController::postSimulation() { diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 5ee9f50f7e..de711c84f4 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -48,7 +49,6 @@ public: // overrides from CharacterController virtual void preSimulation() override; virtual void postSimulation() override; - virtual void incrementSimulationTime(btScalar timeStep) override { _lastStepDuration += timeStep; } bool isHovering() const { return _isHovering; } void setHovering(bool enabled); @@ -65,6 +65,7 @@ public: void setTargetVelocity(const glm::vec3& velocity); void setHMDVelocity(const glm::vec3& velocity); + glm::vec3 getHMDShift() const { return _lastStepDuration * bulletToGLM(_hmdVelocity); } glm::vec3 getLinearVelocity() const; diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index cff257a790..e9e6f1328e 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -36,7 +36,6 @@ public: virtual void updateShapeIfNecessary() = 0; virtual void preSimulation() = 0; - virtual void incrementSimulationTime(btScalar stepTime) = 0; virtual void postSimulation() = 0; virtual void setWalkDirection(const btVector3 &walkDirection) { assert(false); } From 8b285fd2287a3a6a02567208303f6f3e34693580 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 27 Oct 2015 13:51:40 -0700 Subject: [PATCH 16/21] recover follow HMD behavior --- interface/src/avatar/MyAvatar.cpp | 18 ++---------------- interface/src/avatar/MyAvatar.h | 9 +-------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cfcd7a69f9..acde1dc599 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -109,12 +109,8 @@ MyAvatar::MyAvatar(RigPointer rig) : _goToOrientation(), _rig(rig), _prevShouldDrawHead(true), - _audioListenerMode(FROM_HEAD) -#ifdef OLD_HMD_TRACKER - ,_hmdAtRestDetector(glm::vec3(0), glm::quat()) -#else - ,_avatarOffsetFromHMD(0.0f) -#endif // OLD_HMD_TRACKER + _audioListenerMode(FROM_HEAD), + _hmdAtRestDetector(glm::vec3(0), glm::quat()) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -159,9 +155,7 @@ void MyAvatar::reset(bool andReload) { // Reset dynamic state. _wasPushing = _isPushing = _isBraking = _billboardValid = false; -#ifdef OLD_HMD_TRACKER _isFollowingHMD = false; -#endif // OLD_HMD_TRACKER _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); @@ -309,7 +303,6 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } -#ifdef OLD_HMD_TRACKER // returns true if pos is OUTSIDE of the vertical capsule // where the middle cylinder length is defined by capsuleLen and the radius by capsuleRad. static bool pointIsOutsideCapsule(const glm::vec3& pos, float capsuleLen, float capsuleRad) { @@ -328,7 +321,6 @@ static bool pointIsOutsideCapsule(const glm::vec3& pos, float capsuleLen, float return false; } } -#endif // OLD_HMD_TRACKER // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD @@ -339,7 +331,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorPosition = extractTranslation(hmdSensorMatrix); _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); -#ifdef OLD_HMD_TRACKER // calc deltaTime auto now = usecTimestampNow(); auto deltaUsecs = now - _lastUpdateFromHMDTime; @@ -374,9 +365,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } followHMD(deltaTime); -#else - // TODO adebug BOOKMARK -- this is where we need to add the new code for HMD_TRACKER -#endif // OLD_HMD_TRACKER } glm::vec3 MyAvatar::getHMDCorrectionVelocity() const { @@ -384,7 +372,6 @@ glm::vec3 MyAvatar::getHMDCorrectionVelocity() const { return Vectors::ZERO; } -#ifdef OLD_HMD_TRACKER void MyAvatar::beginFollowingHMD() { // begin homing toward derived body position. if (!_isFollowingHMD) { @@ -440,7 +427,6 @@ void MyAvatar::followHMD(float deltaTime) { } } } -#endif // USE_OLD // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 36c73d672d..9e66472328 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -18,10 +18,9 @@ #include #include "Avatar.h" -//#include "AtRestDetector.h" +#include "AtRestDetector.h" #include "MyCharacterController.h" -//#define OLD_HMD_TRACKER class ModelItemID; @@ -270,11 +269,9 @@ private: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } -#ifdef OLD_HMD_TRACKER void beginFollowingHMD(); bool shouldFollowHMD() const; void followHMD(float deltaTime); -#endif bool cameraInsideHead() const; @@ -366,7 +363,6 @@ private: glm::vec3 _customListenPosition; glm::quat _customListenOrientation; -#ifdef OLD_HMD_TRACKER bool _isFollowingHMD { false }; float _followHMDAlpha{0.0f}; @@ -374,9 +370,6 @@ private: AtRestDetector _hmdAtRestDetector; glm::vec3 _lastPosition; bool _lastIsMoving { false }; -#else - glm::vec3 _avatarOffsetFromHMD; -#endif // OLD_HMD_TRACKER }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); From 32f88f3fb6a664d5e664db51415fd8ecc0dd007d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 27 Oct 2015 14:37:39 -0700 Subject: [PATCH 17/21] Fix for JSConcole --- interface/src/ui/JSConsole.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index b50f84d538..2d34ba5608 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -106,8 +106,11 @@ void JSConsole::executeCommand(const QString& command) { QScriptValue JSConsole::executeCommandInWatcher(const QString& command) { QScriptValue result; + static const QString filename = "JSConcole"; QMetaObject::invokeMethod(_scriptEngine, "evaluate", Qt::ConnectionType::BlockingQueuedConnection, - Q_RETURN_ARG(QScriptValue, result), Q_ARG(const QString&, command)); + Q_RETURN_ARG(QScriptValue, result), + Q_ARG(const QString&, command), + Q_ARG(const QString&, filename)); return result; } From e35596428c7e9445036131326122a5efc3d59cd4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 27 Oct 2015 14:43:18 -0700 Subject: [PATCH 18/21] cleanup comment --- interface/src/avatar/MyAvatar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index acde1dc599..f7fad2bd2b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1289,8 +1289,7 @@ void MyAvatar::harvestResultsFromPhysicsSimulation() { _characterController.getAvatarPositionAndOrientation(position, orientation); nextAttitude(position, orientation); setVelocity(_characterController.getLinearVelocity()); - - // adebug TODO: harvest HMD shift here + // TODO: harvest HMD shift here //glm::vec3 hmdShift = _characterController.getHMDShift(); } From c9cd3364005f29368c5412560adb86fea0fc381d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 27 Oct 2015 15:01:48 -0700 Subject: [PATCH 19/21] fix for bad contacts after changing avatar models --- libraries/physics/src/PhysicsEngine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a6b8dbe959..d6772f8d36 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -246,6 +246,11 @@ void PhysicsEngine::stepSimulation() { // be done on the main thread during the pre-simulation stuff if (_myAvatarController->needsRemoval()) { _myAvatarController->setDynamicsWorld(nullptr); + + // We must remove any existing contacts for the avatar so that any new contacts will have + // valid data. MyAvatar's RigidBody is the ONLY one in the simulation that does not yet + // have a MotionState so we pass nullptr to removeContacts(). + removeContacts(nullptr); } _myAvatarController->updateShapeIfNecessary(); if (_myAvatarController->needsAddition()) { From 5cbb2562cd1b72ea77d0f60703d34a0f0365a241 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 27 Oct 2015 11:04:50 -0700 Subject: [PATCH 20/21] Move GL utilities out to their own library --- interface/CMakeLists.txt | 3 +- interface/src/Application.cpp | 2 +- interface/src/ui/overlays/Web3DOverlay.cpp | 2 +- libraries/display-plugins/CMakeLists.txt | 2 +- .../src/display-plugins/DisplayPlugin.h | 4 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 2 +- .../src/display-plugins/OpenGLDisplayPlugin.h | 6 +-- .../oculus/OculusLegacyDisplayPlugin.cpp | 4 +- .../openvr/OpenVrDisplayPlugin.cpp | 2 +- .../stereo/InterleavedStereoDisplayPlugin.cpp | 2 +- .../stereo/SideBySideStereoDisplayPlugin.cpp | 2 +- libraries/entities-renderer/CMakeLists.txt | 2 +- .../src/RenderablePolyLineEntityItem.cpp | 2 +- .../src/RenderablePolyLineEntityItem.h | 3 +- .../src/RenderableWebEntityItem.cpp | 2 +- libraries/gl/CMakeLists.txt | 7 ++++ .../gpu/GPUConfig.h => gl/src/gl/Config.h} | 0 .../src => gl/src/gl}/GLEscrow.h | 0 .../{shared/src => gl/src/gl}/GLHelpers.cpp | 0 .../{shared/src => gl/src/gl}/GLHelpers.h | 0 .../src => gl/src/gl}/GlWindow.cpp | 7 ++-- .../src => gl/src/gl}/GlWindow.h | 0 .../src => gl/src/gl}/OffscreenGlCanvas.cpp | 9 +++-- .../src => gl/src/gl}/OffscreenGlCanvas.h | 0 .../src => gl/src/gl}/OffscreenQmlSurface.cpp | 5 +-- .../src => gl/src/gl}/OffscreenQmlSurface.h | 0 .../src => gl/src/gl}/OglplusHelpers.cpp | 0 .../src => gl/src/gl}/OglplusHelpers.h | 0 libraries/gpu/CMakeLists.txt | 2 +- libraries/gpu/src/gpu/GLBackend.h | 2 +- libraries/render-utils/src/GeometryCache.cpp | 40 +++++++++---------- libraries/ui/CMakeLists.txt | 2 +- libraries/ui/src/OffscreenUi.h | 2 +- tests/gpu-test/CMakeLists.txt | 2 +- tests/render-utils/CMakeLists.txt | 2 +- tests/shaders/CMakeLists.txt | 4 +- tests/shaders/src/main.cpp | 2 +- tests/ui/CMakeLists.txt | 2 +- 38 files changed, 66 insertions(+), 62 deletions(-) create mode 100644 libraries/gl/CMakeLists.txt rename libraries/{gpu/src/gpu/GPUConfig.h => gl/src/gl/Config.h} (100%) rename libraries/{render-utils/src => gl/src/gl}/GLEscrow.h (100%) rename libraries/{shared/src => gl/src/gl}/GLHelpers.cpp (100%) rename libraries/{shared/src => gl/src/gl}/GLHelpers.h (100%) rename libraries/{render-utils/src => gl/src/gl}/GlWindow.cpp (94%) rename libraries/{render-utils/src => gl/src/gl}/GlWindow.h (100%) rename libraries/{render-utils/src => gl/src/gl}/OffscreenGlCanvas.cpp (94%) rename libraries/{render-utils/src => gl/src/gl}/OffscreenGlCanvas.h (100%) rename libraries/{render-utils/src => gl/src/gl}/OffscreenQmlSurface.cpp (99%) rename libraries/{render-utils/src => gl/src/gl}/OffscreenQmlSurface.h (100%) rename libraries/{render-utils/src => gl/src/gl}/OglplusHelpers.cpp (100%) rename libraries/{render-utils/src => gl/src/gl}/OglplusHelpers.h (100%) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 00f6d2ecea..f9c92c59e7 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -96,7 +96,8 @@ else() endif() # link required hifi libraries -link_hifi_libraries(shared octree environment gpu procedural model render fbx networking model-networking entities avatars +link_hifi_libraries(shared octree environment gpu gl procedural model render + fbx networking model-networking entities avatars audio audio-client animation script-engine physics render-utils entities-renderer ui auto-updater plugins display-plugins input-plugins) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1b6be53876..b4d43ea1d7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -70,7 +70,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 0f2361410b..1088473a25 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -27,7 +27,7 @@ #include #include -#include +#include static const float DPI = 30.47f; static const float INCHES_TO_METERS = 1.0f / 39.3701f; diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index 504370796a..14aa03de44 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME display-plugins) setup_hifi_library(OpenGL) -link_hifi_libraries(shared plugins gpu render-utils) +link_hifi_libraries(shared plugins gpu gl) target_opengl() diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h index b4ae6be97f..b2176e0bd1 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -12,8 +12,8 @@ #include #include -#include "gpu/GPUConfig.h" -#include "GLMHelpers.h" +#include +#include #include #include diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 505dae824a..6f6117229a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 52715ebde7..44ab656f31 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -7,10 +7,10 @@ // #pragma once -#include - #include "DisplayPlugin.h" -#include "OglplusHelpers.h" + +#include +#include class GlWindow; class QOpenGLContext; diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp index 1ad61513d6..205444397f 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include "plugins/PluginContainer.h" diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp index faf5a7b781..245fd11ef7 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.cpp index 23bc176d65..6e14a158d4 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp index 1bdb02fd26..5ba113420d 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index bb90c04c95..7023d285ff 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME entities-renderer) AUTOSCRIBE_SHADER_LIB(gpu model render render-utils) setup_hifi_library(Widgets Network Script) -link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils) +link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils gl) target_bullet() diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 572b24e99f..7bec8f2b03 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -37,7 +37,7 @@ PolyLineEntityItem(entityItemID, properties) { gpu::PipelinePointer RenderablePolyLineEntityItem::_pipeline; gpu::Stream::FormatPointer RenderablePolyLineEntityItem::_format; gpu::TexturePointer RenderablePolyLineEntityItem::_texture; -GLint RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT; +int32_t RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT; void RenderablePolyLineEntityItem::createPipeline() { static const int NORMAL_OFFSET = 12; diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h index 59bf416d7a..2832053639 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h @@ -18,7 +18,6 @@ #include "RenderableEntityItem.h" #include #include -#include class RenderablePolyLineEntityItem : public PolyLineEntityItem { @@ -34,7 +33,7 @@ public: static gpu::PipelinePointer _pipeline; static gpu::Stream::FormatPointer _format; static gpu::TexturePointer _texture; - static GLint PAINTSTROKE_GPU_SLOT; + static int32_t PAINTSTROKE_GPU_SLOT; protected: void updateGeometry(); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 84707aca3b..29fac6cd84 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libraries/gl/CMakeLists.txt b/libraries/gl/CMakeLists.txt new file mode 100644 index 0000000000..f60e41739a --- /dev/null +++ b/libraries/gl/CMakeLists.txt @@ -0,0 +1,7 @@ +set(TARGET_NAME gl) +setup_hifi_library(OpenGL Qml Quick) +link_hifi_libraries(shared) + +target_glew() +target_opengl() +target_oglplus() \ No newline at end of file diff --git a/libraries/gpu/src/gpu/GPUConfig.h b/libraries/gl/src/gl/Config.h similarity index 100% rename from libraries/gpu/src/gpu/GPUConfig.h rename to libraries/gl/src/gl/Config.h diff --git a/libraries/render-utils/src/GLEscrow.h b/libraries/gl/src/gl/GLEscrow.h similarity index 100% rename from libraries/render-utils/src/GLEscrow.h rename to libraries/gl/src/gl/GLEscrow.h diff --git a/libraries/shared/src/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp similarity index 100% rename from libraries/shared/src/GLHelpers.cpp rename to libraries/gl/src/gl/GLHelpers.cpp diff --git a/libraries/shared/src/GLHelpers.h b/libraries/gl/src/gl/GLHelpers.h similarity index 100% rename from libraries/shared/src/GLHelpers.h rename to libraries/gl/src/gl/GLHelpers.h diff --git a/libraries/render-utils/src/GlWindow.cpp b/libraries/gl/src/gl/GlWindow.cpp similarity index 94% rename from libraries/render-utils/src/GlWindow.cpp rename to libraries/gl/src/gl/GlWindow.cpp index 248b9305e2..7e43b29e73 100644 --- a/libraries/render-utils/src/GlWindow.cpp +++ b/libraries/gl/src/gl/GlWindow.cpp @@ -8,9 +8,10 @@ #include "GlWindow.h" -#include -#include -#include +#include +#include + +#include "GLHelpers.h" GlWindow::GlWindow(QOpenGLContext* shareContext) : GlWindow(getDefaultOpenGlSurfaceFormat(), shareContext) { } diff --git a/libraries/render-utils/src/GlWindow.h b/libraries/gl/src/gl/GlWindow.h similarity index 100% rename from libraries/render-utils/src/GlWindow.h rename to libraries/gl/src/gl/GlWindow.h diff --git a/libraries/render-utils/src/OffscreenGlCanvas.cpp b/libraries/gl/src/gl/OffscreenGlCanvas.cpp similarity index 94% rename from libraries/render-utils/src/OffscreenGlCanvas.cpp rename to libraries/gl/src/gl/OffscreenGlCanvas.cpp index 07256e7731..e5c1ee4c4a 100644 --- a/libraries/render-utils/src/OffscreenGlCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGlCanvas.cpp @@ -12,10 +12,11 @@ #include "OffscreenGlCanvas.h" -#include -#include -#include -#include +#include +#include +#include + +#include "GLHelpers.h" OffscreenGlCanvas::OffscreenGlCanvas() : _context(new QOpenGLContext), _offscreenSurface(new QOffscreenSurface){ } diff --git a/libraries/render-utils/src/OffscreenGlCanvas.h b/libraries/gl/src/gl/OffscreenGlCanvas.h similarity index 100% rename from libraries/render-utils/src/OffscreenGlCanvas.h rename to libraries/gl/src/gl/OffscreenGlCanvas.h diff --git a/libraries/render-utils/src/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp similarity index 99% rename from libraries/render-utils/src/OffscreenQmlSurface.cpp rename to libraries/gl/src/gl/OffscreenQmlSurface.cpp index 6c68b60f42..3afd0c84a8 100644 --- a/libraries/render-utils/src/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -23,7 +23,6 @@ #include "GLEscrow.h" #include "OffscreenGlCanvas.h" -#include "AbstractViewStateInterface.h" // FIXME move to threaded rendering with Qt 5.5 // #define QML_THREADED @@ -207,9 +206,7 @@ private: qreal pixelRatio = 1.0; if (_renderControl && _renderControl->_renderWindow) { pixelRatio = _renderControl->_renderWindow->devicePixelRatio(); - } else { - pixelRatio = AbstractViewStateInterface::instance()->getDevicePixelRatio(); - } + } uvec2 newOffscreenSize = toGlm(newSize * pixelRatio); _textures.setSize(newOffscreenSize); diff --git a/libraries/render-utils/src/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h similarity index 100% rename from libraries/render-utils/src/OffscreenQmlSurface.h rename to libraries/gl/src/gl/OffscreenQmlSurface.h diff --git a/libraries/render-utils/src/OglplusHelpers.cpp b/libraries/gl/src/gl/OglplusHelpers.cpp similarity index 100% rename from libraries/render-utils/src/OglplusHelpers.cpp rename to libraries/gl/src/gl/OglplusHelpers.cpp diff --git a/libraries/render-utils/src/OglplusHelpers.h b/libraries/gl/src/gl/OglplusHelpers.h similarity index 100% rename from libraries/render-utils/src/OglplusHelpers.h rename to libraries/gl/src/gl/OglplusHelpers.h diff --git a/libraries/gpu/CMakeLists.txt b/libraries/gpu/CMakeLists.txt index 63da1d8f8a..29115af22f 100644 --- a/libraries/gpu/CMakeLists.txt +++ b/libraries/gpu/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME gpu) AUTOSCRIBE_SHADER_LIB(gpu) setup_hifi_library() -link_hifi_libraries(shared) +link_hifi_libraries(shared gl) target_glew() target_opengl() \ No newline at end of file diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 9cb988a431..6c359d81f1 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -18,7 +18,7 @@ #include #include -#include "GPUConfig.h" +#include #include "Context.h" diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 3fcd556dbb..eed52fccbc 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -19,8 +19,6 @@ #include #include -#include - #include "TextureCache.h" #include "RenderUtilsLogging.h" @@ -573,8 +571,8 @@ void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions if (!_gridBuffers.contains(key)) { auto verticesBuffer = std::make_shared(); - GLfloat* vertexData = new GLfloat[vertices * 2]; - GLfloat* vertex = vertexData; + float* vertexData = new float[vertices * 2]; + float* vertex = vertexData; for (int i = 0; i <= xDivisions; i++) { float x = (float)i / xDivisions; @@ -595,7 +593,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions *(vertex++) = y; } - verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Byte*) vertexData); + verticesBuffer->append(sizeof(float) * vertices * 2, (gpu::Byte*) vertexData); delete[] vertexData; _gridBuffers[key] = verticesBuffer; @@ -674,8 +672,8 @@ void GeometryCache::renderGrid(gpu::Batch& batch, int x, int y, int width, int h _alternateGridBuffers[key] = verticesBuffer; } - GLfloat* vertexData = new GLfloat[vertices * 2]; - GLfloat* vertex = vertexData; + float* vertexData = new float[vertices * 2]; + float* vertex = vertexData; int dx = width / cols; int dy = height / rows; @@ -702,7 +700,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, int x, int y, int width, int h tx += dx; } - verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Byte*) vertexData); + verticesBuffer->append(sizeof(float) * vertices * 2, (gpu::Byte*) vertexData); delete[] vertexData; } @@ -785,8 +783,8 @@ void GeometryCache::updateVertices(int id, const QVector& points, con ((int(color.z * 255.0f) & 0xFF) << 16) | ((int(color.w * 255.0f) & 0xFF) << 24); - GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; - GLfloat* vertex = vertexData; + float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX]; + float* vertex = vertexData; int* colorData = new int[details.vertices]; int* colorDataAt = colorData; @@ -798,7 +796,7 @@ void GeometryCache::updateVertices(int id, const QVector& points, con *(colorDataAt++) = compactColor; } - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; @@ -846,8 +844,8 @@ void GeometryCache::updateVertices(int id, const QVector& points, con ((int(color.z * 255.0f) & 0xFF) << 16) | ((int(color.w * 255.0f) & 0xFF) << 24); - GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; - GLfloat* vertex = vertexData; + float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX]; + float* vertex = vertexData; int* colorData = new int[details.vertices]; int* colorDataAt = colorData; @@ -860,7 +858,7 @@ void GeometryCache::updateVertices(int id, const QVector& points, con *(colorDataAt++) = compactColor; } - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; @@ -912,8 +910,8 @@ void GeometryCache::updateVertices(int id, const QVector& points, con ((int(color.z * 255.0f) & 0xFF) << 16) | ((int(color.w * 255.0f) & 0xFF) << 24); - GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; - GLfloat* vertex = vertexData; + float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX]; + float* vertex = vertexData; int* colorData = new int[details.vertices]; int* colorDataAt = colorData; @@ -930,7 +928,7 @@ void GeometryCache::updateVertices(int id, const QVector& points, con *(colorDataAt++) = compactColor; } - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; @@ -997,7 +995,7 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride); - GLfloat vertexBuffer[NUM_FLOATS]; // only vertices, no normals because we're a 2D quad + float vertexBuffer[NUM_FLOATS]; // only vertices, no normals because we're a 2D quad int vertexPoint = 0; // Triangle strip points @@ -1438,8 +1436,8 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, int* colorData = new int[details.vertices]; int* colorDataAt = colorData; - GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; - GLfloat* vertex = vertexData; + float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX]; + float* vertex = vertexData; glm::vec3 point = start; *(vertex++) = point.x; @@ -1465,7 +1463,7 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, *(vertex++) = end.z; *(colorDataAt++) = compactColor; - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; diff --git a/libraries/ui/CMakeLists.txt b/libraries/ui/CMakeLists.txt index d4cd1fc2bb..140ca87d0d 100644 --- a/libraries/ui/CMakeLists.txt +++ b/libraries/ui/CMakeLists.txt @@ -1,3 +1,3 @@ set(TARGET_NAME ui) setup_hifi_library(OpenGL Network Qml Quick Script XmlPatterns) -link_hifi_libraries(render-utils shared) +link_hifi_libraries(shared networking gl) diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 4c8b4a8304..be7f6b5e2e 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -12,7 +12,7 @@ #ifndef hifi_OffscreenUi_h #define hifi_OffscreenUi_h -#include "OffscreenQmlSurface.h" +#include #include #include diff --git a/tests/gpu-test/CMakeLists.txt b/tests/gpu-test/CMakeLists.txt index 0c183fc2f0..2c9ee23c47 100644 --- a/tests/gpu-test/CMakeLists.txt +++ b/tests/gpu-test/CMakeLists.txt @@ -3,5 +3,5 @@ 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) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") -link_hifi_libraries(networking gpu procedural shared fbx model model-networking animation script-engine render-utils ) +link_hifi_libraries(networking gl gpu procedural shared fbx model model-networking animation script-engine render-utils ) copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/render-utils/CMakeLists.txt b/tests/render-utils/CMakeLists.txt index b56297d05e..865db4dad5 100644 --- a/tests/render-utils/CMakeLists.txt +++ b/tests/render-utils/CMakeLists.txt @@ -6,6 +6,6 @@ setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(render-utils gpu shared) +link_hifi_libraries(render-utils gl gpu shared) copy_dlls_beside_windows_executable() diff --git a/tests/shaders/CMakeLists.txt b/tests/shaders/CMakeLists.txt index 42766c98e3..fd58a5911f 100644 --- a/tests/shaders/CMakeLists.txt +++ b/tests/shaders/CMakeLists.txt @@ -8,8 +8,8 @@ set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") #include_oglplus() # link in the shared libraries -link_hifi_libraries(shared octree environment gpu model render fbx networking entities - script-engine physics +link_hifi_libraries(shared octree environment gl gpu model render fbx networking entities + script-engine physics render-utils entities-renderer) include_directories("${PROJECT_BINARY_DIR}/../../libraries/gpu/") diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp index 8d12663935..3edff67d66 100644 --- a/tests/shaders/src/main.cpp +++ b/tests/shaders/src/main.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include "../model/Skybox_vert.h" #include "../model/Skybox_frag.h" diff --git a/tests/ui/CMakeLists.txt b/tests/ui/CMakeLists.txt index 6a2d8c394a..82fc23e680 100644 --- a/tests/ui/CMakeLists.txt +++ b/tests/ui/CMakeLists.txt @@ -11,6 +11,6 @@ if (WIN32) endif() # link in the shared libraries -link_hifi_libraries(ui render-utils gpu shared) +link_hifi_libraries(shared networking gl gpu ui) copy_dlls_beside_windows_executable() From afec2a9771cadd729f21aca42020fada86e898cd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 28 Oct 2015 09:42:55 -0700 Subject: [PATCH 21/21] fix whitespace --- interface/src/avatar/MyAvatar.h | 6 +++--- libraries/physics/src/CharacterController.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9e66472328..5f75b7cf14 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -164,7 +164,7 @@ public: void prepareForPhysicsSimulation(); void harvestResultsFromPhysicsSimulation(); - const QString& getCollisionSoundURL() {return _collisionSoundURL; } + const QString& getCollisionSoundURL() { return _collisionSoundURL; } void setCollisionSoundURL(const QString& url); void clearScriptableSettings(); @@ -364,9 +364,9 @@ private: glm::quat _customListenOrientation; bool _isFollowingHMD { false }; - float _followHMDAlpha{0.0f}; + float _followHMDAlpha { 0.0f }; - quint64 _lastUpdateFromHMDTime{usecTimestampNow()}; + quint64 _lastUpdateFromHMDTime { usecTimestampNow() }; AtRestDetector _hmdAtRestDetector; glm::vec3 _lastPosition; bool _lastIsMoving { false }; diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 9ba22cf2db..aadf9b16ea 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -32,7 +32,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { } if (world && _rigidBody) { _dynamicsWorld = world; - _pendingFlags &= ~ PENDING_FLAG_JUMP; + _pendingFlags &= ~PENDING_FLAG_JUMP; _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); _dynamicsWorld->addAction(this); //reset(_dynamicsWorld); @@ -46,7 +46,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; } } else { - _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; + _pendingFlags &= ~PENDING_FLAG_REMOVE_FROM_SIMULATION; } }