From 359c14e3191333e8d4300b56c64cf529d3b2175f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 23 Apr 2014 11:48:42 -0700 Subject: [PATCH 01/11] cleanup: remove unused Avatar::_mode The mode, if it is required, should probably eventually live in AvatarDAta since it will be determined by whatever engine is running the avatar (script or interface) and then broadcast to the rest of the world. When we need it we'll add it back in the right place. --- interface/src/avatar/Avatar.cpp | 13 ++----------- interface/src/avatar/Avatar.h | 8 -------- interface/src/avatar/MyAvatar.cpp | 10 +--------- interface/src/avatar/MyAvatar.h | 1 - 4 files changed, 3 insertions(+), 29 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index fe685b89f8..5173caa051 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -47,7 +47,6 @@ Avatar::Avatar() : AvatarData(), _skeletonModel(this), _bodyYawDelta(0.0f), - _mode(AVATAR_MODE_STANDING), _velocity(0.0f, 0.0f, 0.0f), _thrust(0.0f, 0.0f, 0.0f), _leanScale(0.5f), @@ -138,19 +137,11 @@ void Avatar::simulate(float deltaTime) { head->simulate(deltaTime, false, _shouldRenderBillboard); } - // use speed and angular velocity to determine walking vs. standing - float speed = glm::length(_velocity); - if (speed + fabs(_bodyYawDelta) > 0.2) { - _mode = AVATAR_MODE_WALKING; - } else { - _mode = AVATAR_MODE_INTERACTING; - } - // update position by velocity, and subtract the change added earlier for gravity _position += _velocity * deltaTime; // Zero thrust out now that we've added it to velocity in this frame - _thrust = glm::vec3(0, 0, 0); + _thrust = glm::vec3(0.0f); // update animation for display name fade in/out if ( _displayNameTargetAlpha != _displayNameAlpha) { @@ -166,7 +157,7 @@ void Avatar::simulate(float deltaTime) { // Fading in _displayNameAlpha = 1 - (1 - _displayNameAlpha) * coef; } - _displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01? _displayNameTargetAlpha : _displayNameAlpha; + _displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01f ? _displayNameTargetAlpha : _displayNameAlpha; } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index ecf1be4899..39cc174e69 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -46,13 +46,6 @@ enum DriveKeys { MAX_DRIVE_KEYS }; -enum AvatarMode { - AVATAR_MODE_STANDING = 0, - AVATAR_MODE_WALKING, - AVATAR_MODE_INTERACTING, - NUM_AVATAR_MODES -}; - enum ScreenTintLayer { SCREEN_TINT_BEFORE_LANDSCAPE = 0, SCREEN_TINT_BEFORE_AVATARS, @@ -164,7 +157,6 @@ signals: protected: SkeletonModel _skeletonModel; float _bodyYawDelta; - AvatarMode _mode; glm::vec3 _velocity; glm::vec3 _thrust; float _leanScale; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e1d7463aa3..de0c507272 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -269,17 +269,9 @@ void MyAvatar::simulate(float deltaTime) { // update the euler angles setOrientation(orientation); - const float WALKING_SPEED_THRESHOLD = 0.2f; - // use speed and angular velocity to determine walking vs. standing - float speed = glm::length(_velocity); - if (speed + fabs(_bodyYawDelta) > WALKING_SPEED_THRESHOLD) { - _mode = AVATAR_MODE_WALKING; - } else { - _mode = AVATAR_MODE_INTERACTING; - } - // update moving flag based on speed const float MOVING_SPEED_THRESHOLD = 0.01f; + float speed = glm::length(_velocity); _moving = speed > MOVING_SPEED_THRESHOLD; // If a move target is set, update position explicitly diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 71c74f7c91..f6c83c7ac4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -54,7 +54,6 @@ public: void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; } // getters - AvatarMode getMode() const { return _mode; } float getLeanScale() const { return _leanScale; } float getElapsedTimeStopped() const { return _elapsedTimeStopped; } float getElapsedTimeMoving() const { return _elapsedTimeMoving; } From 37a5d9130f6ae6050cdfc47adb15083f0f2c7664 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 23 Apr 2014 11:55:28 -0700 Subject: [PATCH 02/11] move _thrust from Avatar to MyAvatar --- interface/src/avatar/Avatar.cpp | 4 ---- interface/src/avatar/Avatar.h | 1 - interface/src/avatar/MyAvatar.cpp | 3 ++- interface/src/avatar/MyAvatar.h | 1 + 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5173caa051..2df1fd2302 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -48,7 +48,6 @@ Avatar::Avatar() : _skeletonModel(this), _bodyYawDelta(0.0f), _velocity(0.0f, 0.0f, 0.0f), - _thrust(0.0f, 0.0f, 0.0f), _leanScale(0.5f), _scale(1.0f), _worldUpDirection(DEFAULT_UP_DIRECTION), @@ -140,9 +139,6 @@ void Avatar::simulate(float deltaTime) { // update position by velocity, and subtract the change added earlier for gravity _position += _velocity * deltaTime; - // Zero thrust out now that we've added it to velocity in this frame - _thrust = glm::vec3(0.0f); - // update animation for display name fade in/out if ( _displayNameTargetAlpha != _displayNameAlpha) { // the alpha function is diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 39cc174e69..805a60d425 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -158,7 +158,6 @@ protected: SkeletonModel _skeletonModel; float _bodyYawDelta; glm::vec3 _velocity; - glm::vec3 _thrust; float _leanScale; float _scale; glm::vec3 _worldUpDirection; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index de0c507272..33a1127a64 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -59,6 +59,7 @@ MyAvatar::MyAvatar() : _elapsedTimeSinceCollision(0.0f), _lastCollisionPosition(0, 0, 0), _speedBrakes(false), + _thrust(0.0f), _isThrustOn(false), _thrustMultiplier(1.0f), _moveTarget(0,0,0), @@ -316,7 +317,7 @@ void MyAvatar::simulate(float deltaTime) { head->simulate(deltaTime, true); // Zero thrust out now that we've added it to velocity in this frame - _thrust = glm::vec3(0.0f); + _thrust *= glm::vec3(0.0f); // now that we're done stepping the avatar forward in time, compute new collisions if (_collisionFlags != 0) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f6c83c7ac4..5cdb13682f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -122,6 +122,7 @@ private: float _elapsedTimeSinceCollision; glm::vec3 _lastCollisionPosition; bool _speedBrakes; + glm::vec3 _thrust; bool _isThrustOn; float _thrustMultiplier; glm::vec3 _moveTarget; From 39c193a679c56dd565d9307ac51c9a3bcfe9f962 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 23 Apr 2014 12:15:15 -0700 Subject: [PATCH 03/11] remove unused getElapsedTime*() methods --- interface/src/avatar/MyAvatar.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 5cdb13682f..592e1172af 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -55,8 +55,6 @@ public: // getters float getLeanScale() const { return _leanScale; } - float getElapsedTimeStopped() const { return _elapsedTimeStopped; } - float getElapsedTimeMoving() const { return _elapsedTimeMoving; } const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } glm::vec3 getGravity() const { return _gravity; } @@ -117,14 +115,17 @@ private: float _driveKeys[MAX_DRIVE_KEYS]; glm::vec3 _gravity; float _distanceToNearestAvatar; // How close is the nearest avatar? + + // motion stuff float _elapsedTimeMoving; // Timers to drive camera transitions when moving float _elapsedTimeStopped; float _elapsedTimeSinceCollision; glm::vec3 _lastCollisionPosition; bool _speedBrakes; - glm::vec3 _thrust; + glm::vec3 _thrust; // final acceleration for the current frame bool _isThrustOn; float _thrustMultiplier; + glm::vec3 _moveTarget; glm::vec3 _lastBodyPenetration; int _moveTargetStepCounter; From 203dac054ad734ff630eb7b974f408473d4332af Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 23 Apr 2014 12:19:48 -0700 Subject: [PATCH 04/11] remove unused MoveTarget stuff from MyAvatar --- interface/src/avatar/MyAvatar.cpp | 22 ---------------------- interface/src/avatar/MyAvatar.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 33a1127a64..77698ea823 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -62,9 +62,7 @@ MyAvatar::MyAvatar() : _thrust(0.0f), _isThrustOn(false), _thrustMultiplier(1.0f), - _moveTarget(0,0,0), _lastBodyPenetration(0.0f), - _moveTargetStepCounter(0), _lookAtTargetAvatar(), _shouldRender(true), _billboardValid(false), @@ -98,11 +96,6 @@ void MyAvatar::reset() { setOrientation(glm::quat(glm::vec3(0.0f))); } -void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) { - _moveTarget = moveTarget; - _moveTargetStepCounter = 0; -} - void MyAvatar::update(float deltaTime) { Head* head = getHead(); head->relaxLean(deltaTime); @@ -275,21 +268,6 @@ void MyAvatar::simulate(float deltaTime) { float speed = glm::length(_velocity); _moving = speed > MOVING_SPEED_THRESHOLD; - // If a move target is set, update position explicitly - const float MOVE_FINISHED_TOLERANCE = 0.1f; - const float MOVE_SPEED_FACTOR = 2.0f; - const int MOVE_TARGET_MAX_STEPS = 250; - if ((glm::length(_moveTarget) > EPSILON) && (_moveTargetStepCounter < MOVE_TARGET_MAX_STEPS)) { - if (glm::length(_position - _moveTarget) > MOVE_FINISHED_TOLERANCE) { - _position += (_moveTarget - _position) * (deltaTime * MOVE_SPEED_FACTOR); - _moveTargetStepCounter++; - } else { - // Move completed - _moveTarget = glm::vec3(0,0,0); - _moveTargetStepCounter = 0; - } - } - updateChatCircle(deltaTime); _position += _velocity * deltaTime; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 592e1172af..ab6181120e 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -126,9 +126,7 @@ private: bool _isThrustOn; float _thrustMultiplier; - glm::vec3 _moveTarget; glm::vec3 _lastBodyPenetration; - int _moveTargetStepCounter; QWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; bool _shouldRender; From 96ca53740008bf025f7781de87d12a9c86035c6e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 23 Apr 2014 13:44:25 -0700 Subject: [PATCH 05/11] removing unused motion-state timers --- interface/src/avatar/MyAvatar.cpp | 15 --------------- interface/src/avatar/MyAvatar.h | 3 --- 2 files changed, 18 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 77698ea823..1de9b74c89 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -54,9 +54,6 @@ MyAvatar::MyAvatar() : _shouldJump(false), _gravity(0.0f, -1.0f, 0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), - _elapsedTimeMoving(0.0f), - _elapsedTimeStopped(0.0f), - _elapsedTimeSinceCollision(0.0f), _lastCollisionPosition(0, 0, 0), _speedBrakes(false), _thrust(0.0f), @@ -139,17 +136,6 @@ void MyAvatar::simulate(float deltaTime) { glm::quat orientation = getOrientation(); - // Update movement timers - _elapsedTimeSinceCollision += deltaTime; - const float VELOCITY_MOVEMENT_TIMER_THRESHOLD = 0.2f; - if (glm::length(_velocity) < VELOCITY_MOVEMENT_TIMER_THRESHOLD) { - _elapsedTimeMoving = 0.0f; - _elapsedTimeStopped += deltaTime; - } else { - _elapsedTimeStopped = 0.0f; - _elapsedTimeMoving += deltaTime; - } - if (_scale != _targetScale) { float scale = (1.0f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale; setScale(scale); @@ -798,7 +784,6 @@ void MyAvatar::applyHardCollision(const glm::vec3& penetration, float elasticity // cancel out the velocity component in the direction of penetration float penetrationLength = glm::length(penetration); if (penetrationLength > EPSILON) { - _elapsedTimeSinceCollision = 0.0f; glm::vec3 direction = penetration / penetrationLength; _velocity -= glm::dot(_velocity, direction) * direction * (1.0f + elasticity); _velocity *= glm::clamp(1.0f - damping, 0.0f, 1.0f); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ab6181120e..b713f1c223 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -117,9 +117,6 @@ private: float _distanceToNearestAvatar; // How close is the nearest avatar? // motion stuff - float _elapsedTimeMoving; // Timers to drive camera transitions when moving - float _elapsedTimeStopped; - float _elapsedTimeSinceCollision; glm::vec3 _lastCollisionPosition; bool _speedBrakes; glm::vec3 _thrust; // final acceleration for the current frame From 10265a4a3e0d48fdccd66eb23059bdd1f2896905 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 23 Apr 2014 14:37:24 -0700 Subject: [PATCH 06/11] temp disable of screen flash for avatar collisions --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 1de9b74c89..17ff79c443 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -820,7 +820,7 @@ void MyAvatar::updateCollisionSound(const glm::vec3 &penetration, float deltaTim std::min(COLLISION_LOUDNESS * velocityTowardCollision, 1.0f), frequency * (1.0f + velocityTangentToCollision / velocityTowardCollision), std::min(velocityTangentToCollision / velocityTowardCollision * NOISE_SCALING, 1.0f), - 1.0f - DURATION_SCALING * powf(frequency, 0.5f) / velocityTowardCollision, true); + 1.0f - DURATION_SCALING * powf(frequency, 0.5f) / velocityTowardCollision, false); } } From f07a418a2708a19dc69c9583aa9c7cd2123c3453 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Apr 2014 11:07:49 -0700 Subject: [PATCH 07/11] namechange CollisionFlags --> CollisionGroups --- interface/src/Menu.cpp | 10 +++++----- interface/src/avatar/Avatar.cpp | 16 ++++++++-------- interface/src/avatar/Avatar.h | 4 ++-- interface/src/avatar/MyAvatar.cpp | 18 +++++++----------- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 84b17fddca..74df3e4f63 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -505,7 +505,7 @@ void Menu::loadSettings(QSettings* settings) { // MyAvatar caches some menu options, so we have to update them whenever we load settings. // TODO: cache more settings in MyAvatar that are checked with very high frequency. MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - myAvatar->updateCollisionFlags(); + myAvatar->updateCollisionGroups(); if (lockedSettings) { Application::getInstance()->unlockSettings(); @@ -1368,13 +1368,13 @@ void Menu::addAvatarCollisionSubMenu(QMenu* overMenu) { Application* appInstance = Application::getInstance(); QObject* avatar = appInstance->getAvatar(); addCheckableActionToQMenuAndActionHash(subMenu, MenuOption::CollideWithEnvironment, - 0, false, avatar, SLOT(updateCollisionFlags())); + 0, false, avatar, SLOT(updateCollisionGroups())); addCheckableActionToQMenuAndActionHash(subMenu, MenuOption::CollideWithAvatars, - 0, true, avatar, SLOT(updateCollisionFlags())); + 0, true, avatar, SLOT(updateCollisionGroups())); addCheckableActionToQMenuAndActionHash(subMenu, MenuOption::CollideWithVoxels, - 0, false, avatar, SLOT(updateCollisionFlags())); + 0, false, avatar, SLOT(updateCollisionGroups())); addCheckableActionToQMenuAndActionHash(subMenu, MenuOption::CollideWithParticles, - 0, true, avatar, SLOT(updateCollisionFlags())); + 0, true, avatar, SLOT(updateCollisionGroups())); } QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2df1fd2302..b060c3421a 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -54,7 +54,7 @@ Avatar::Avatar() : _mouseRayOrigin(0.0f, 0.0f, 0.0f), _mouseRayDirection(0.0f, 0.0f, 0.0f), _moving(false), - _collisionFlags(0), + _collisionGroups(0), _initialized(false), _shouldRenderBillboard(true) { @@ -550,7 +550,7 @@ bool Avatar::findCollisions(const QVector& shapes, CollisionList& } bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) { - if (_collisionFlags & COLLISION_GROUP_PARTICLES) { + if (_collisionGroups & COLLISION_GROUP_PARTICLES) { return false; } bool collided = false; @@ -740,19 +740,19 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, glEnd(); } -void Avatar::updateCollisionFlags() { - _collisionFlags = 0; +void Avatar::updateCollisionGroups() { + _collisionGroups = 0; if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithEnvironment)) { - _collisionFlags |= COLLISION_GROUP_ENVIRONMENT; + _collisionGroups |= COLLISION_GROUP_ENVIRONMENT; } if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) { - _collisionFlags |= COLLISION_GROUP_AVATARS; + _collisionGroups |= COLLISION_GROUP_AVATARS; } if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithVoxels)) { - _collisionFlags |= COLLISION_GROUP_VOXELS; + _collisionGroups |= COLLISION_GROUP_VOXELS; } if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithParticles)) { - _collisionFlags |= COLLISION_GROUP_PARTICLES; + _collisionGroups |= COLLISION_GROUP_PARTICLES; } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 805a60d425..6106b9f39c 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -149,7 +149,7 @@ public: void updateShapePositions(); public slots: - void updateCollisionFlags(); + void updateCollisionGroups(); signals: void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision); @@ -166,7 +166,7 @@ protected: float _stringLength; bool _moving; ///< set when position is changing - uint32_t _collisionFlags; + uint32_t _collisionGroups; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 17ff79c443..9f70f41631 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -284,7 +284,7 @@ void MyAvatar::simulate(float deltaTime) { _thrust *= glm::vec3(0.0f); // now that we're done stepping the avatar forward in time, compute new collisions - if (_collisionFlags != 0) { + if (_collisionGroups != 0) { Camera* myCamera = Application::getInstance()->getCamera(); float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE; @@ -292,15 +292,15 @@ void MyAvatar::simulate(float deltaTime) { radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.0f)); radius *= COLLISION_RADIUS_SCALAR; } - if (_collisionFlags) { + if (_collisionGroups) { updateShapePositions(); - if (_collisionFlags & COLLISION_GROUP_ENVIRONMENT) { + if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) { updateCollisionWithEnvironment(deltaTime, radius); } - if (_collisionFlags & COLLISION_GROUP_VOXELS) { + if (_collisionGroups & COLLISION_GROUP_VOXELS) { updateCollisionWithVoxels(deltaTime, radius); } - if (_collisionFlags & COLLISION_GROUP_AVATARS) { + if (_collisionGroups & COLLISION_GROUP_AVATARS) { updateCollisionWithAvatars(deltaTime); } } @@ -408,17 +408,13 @@ void MyAvatar::renderDebugBodyPoints() { glTranslatef(position.x, position.y, position.z); glutSolidSphere(0.15, 10, 10); glPopMatrix(); - - } // virtual void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { - // don't render if we've been asked to disable local rendering - if (!_shouldRender) { - return; // exit early + if (_shouldRender) { + Avatar::render(cameraPosition, renderMode); } - Avatar::render(cameraPosition, renderMode); } void MyAvatar::renderHeadMouse() const { From 73d0674565038eb80c2782ab01db9a2937cd8d0a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Apr 2014 11:19:08 -0700 Subject: [PATCH 08/11] expose MyAvatar.collisionGroups to JS --- interface/src/avatar/Avatar.h | 6 +++++- libraries/shared/src/CollisionInfo.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 6106b9f39c..a1ff817b02 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -63,6 +63,7 @@ class Texture; class Avatar : public AvatarData { Q_OBJECT + Q_PROPERTY(quint32 collisionGroups READ getCollisionGroups WRITE setCollisionGroups) public: Avatar(); @@ -148,6 +149,9 @@ public: virtual float getBoundingRadius() const; void updateShapePositions(); + quint32 getCollisionGroups() const { return _collisionGroups; } + void setCollisionGroups(quint32 collisionGroups) { _collisionGroups = (collisionGroups & VALID_COLLISION_GROUPS); } + public slots: void updateCollisionGroups(); @@ -166,7 +170,7 @@ protected: float _stringLength; bool _moving; ///< set when position is changing - uint32_t _collisionGroups; + quint32 _collisionGroups; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/libraries/shared/src/CollisionInfo.h b/libraries/shared/src/CollisionInfo.h index 7db965fe64..510728daa6 100644 --- a/libraries/shared/src/CollisionInfo.h +++ b/libraries/shared/src/CollisionInfo.h @@ -27,6 +27,7 @@ const quint32 COLLISION_GROUP_ENVIRONMENT = 1U << 0; const quint32 COLLISION_GROUP_AVATARS = 1U << 1; const quint32 COLLISION_GROUP_VOXELS = 1U << 2; const quint32 COLLISION_GROUP_PARTICLES = 1U << 3; +const quint32 VALID_COLLISION_GROUPS = 0x0f; // CollisionInfo contains details about the collision between two things: BodyA and BodyB. // The assumption is that the context that analyzes the collision knows about BodyA but From 0a7a5031ee05b6ca657cc82109e0abd5f9c11c78 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Apr 2014 14:17:10 -0700 Subject: [PATCH 09/11] expose COLLISION_GOUP_* constants to JS --- libraries/script-engine/src/ScriptEngine.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 2e92567fe7..b923427307 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -230,8 +231,13 @@ void ScriptEngine::init() { registerGlobalObject("Voxels", &_voxelsScriptingInterface); - QScriptValue treeScaleValue = _engine.newVariant(QVariant(TREE_SCALE)); - _engine.globalObject().setProperty("TREE_SCALE", treeScaleValue); + // constants + QScriptValue globalObject = _engine.globalObject(); + globalObject.setProperty("TREE_SCALE", _engine.newVariant(QVariant(TREE_SCALE))); + globalObject.setProperty("COLLISION_GROUP_ENVIRONMENT", _engine.newVariant(QVariant(COLLISION_GROUP_ENVIRONMENT))); + globalObject.setProperty("COLLISION_GROUP_AVATARS", _engine.newVariant(QVariant(COLLISION_GROUP_AVATARS))); + globalObject.setProperty("COLLISION_GROUP_VOXELS", _engine.newVariant(QVariant(COLLISION_GROUP_VOXELS))); + globalObject.setProperty("COLLISION_GROUP_PARTICLES", _engine.newVariant(QVariant(COLLISION_GROUP_PARTICLES))); // let the VoxelPacketSender know how frequently we plan to call it _voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(SCRIPT_DATA_CALLBACK_USECS); @@ -561,4 +567,4 @@ void ScriptEngine::include(const QString& includeFile) { qDebug() << "Uncaught exception at (" << includeFile << ") line" << line << ":" << result.toString(); emit errorMessage("Uncaught exception at (" + includeFile + ") line" + QString::number(line) + ":" + result.toString()); } -} \ No newline at end of file +} From 0b5c1b0a9a0d82fbd4fa2e0d685c15ad1bf24de8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Apr 2014 15:43:03 -0700 Subject: [PATCH 10/11] add MyAvatar::_motionBehaviors (for obeyGravity) Also reconcile Menu checkable set vs script-set collision groups. --- interface/src/Application.cpp | 2 +- interface/src/Menu.cpp | 6 +++--- interface/src/Menu.h | 2 +- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/MyAvatar.cpp | 26 ++++++++++++++++++++++++-- interface/src/avatar/MyAvatar.h | 11 +++++++++++ 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3ae4720351..e9c208bace 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -861,7 +861,7 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_G: if (isShifted) { - Menu::getInstance()->triggerOption(MenuOption::Gravity); + Menu::getInstance()->triggerOption(MenuOption::ObeyGravity); } break; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 74df3e4f63..4aeb4dd203 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -186,9 +186,9 @@ Menu::Menu() : QAction::PreferencesRole); addDisabledActionAndSeparator(editMenu, "Physics"); - addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, false); - - + QObject* avatar = appInstance->getAvatar(); + addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ObeyGravity, Qt::SHIFT | Qt::Key_G, true, + avatar, SLOT(updateMotionBehaviorFlags())); addAvatarCollisionSubMenu(editMenu); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index a1e6cded2a..8b2368d22f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -313,7 +313,7 @@ namespace MenuOption { const QString GoTo = "Go To..."; const QString GoToDomain = "Go To Domain..."; const QString GoToLocation = "Go To Location..."; - const QString Gravity = "Use Gravity"; + const QString ObeyGravity = "Obey Gravity"; const QString HandsCollideWithSelf = "Collide With Self"; const QString HeadMouse = "Head Mouse"; const QString IncreaseAvatarSize = "Increase Avatar Size"; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index a1ff817b02..bcf3487e09 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -150,7 +150,7 @@ public: void updateShapePositions(); quint32 getCollisionGroups() const { return _collisionGroups; } - void setCollisionGroups(quint32 collisionGroups) { _collisionGroups = (collisionGroups & VALID_COLLISION_GROUPS); } + virtual void setCollisionGroups(quint32 collisionGroups) { _collisionGroups = (collisionGroups & VALID_COLLISION_GROUPS); } public slots: void updateCollisionGroups(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9f70f41631..467b1f2613 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -59,6 +59,7 @@ MyAvatar::MyAvatar() : _thrust(0.0f), _isThrustOn(false), _thrustMultiplier(1.0f), + _motionBehaviors(0), _lastBodyPenetration(0.0f), _lookAtTargetAvatar(), _shouldRender(true), @@ -123,7 +124,7 @@ void MyAvatar::update(float deltaTime) { head->setAudioLoudness(audio->getLastInputLoudness()); head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness()); - if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) { + if (_motionBehaviors & AVATAR_MOTION_OBEY_GRAVITY) { setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition())); } else { setGravity(glm::vec3(0.0f, 0.0f, 0.0f)); @@ -1134,7 +1135,28 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { setPosition(newPosition); emit transformChanged(); } - +} + +void MyAvatar::updateMotionBehaviors() { + _motionBehaviors = 0; + if (Menu::getInstance()->isOptionChecked(MenuOption::ObeyGravity)) { + _motionBehaviors |= AVATAR_MOTION_OBEY_GRAVITY; + } +} + +void MyAvatar::setCollisionGroups(quint32 collisionGroups) { + Avatar::setCollisionGroups(collisionGroups & VALID_COLLISION_GROUPS); + Menu* menu = Menu::getInstance(); + menu->setIsOptionChecked(MenuOption::CollideWithEnvironment, (bool)(_collisionGroups & COLLISION_GROUP_ENVIRONMENT)); + menu->setIsOptionChecked(MenuOption::CollideWithAvatars, (bool)(_collisionGroups & COLLISION_GROUP_AVATARS)); + menu->setIsOptionChecked(MenuOption::CollideWithVoxels, (bool)(_collisionGroups & COLLISION_GROUP_VOXELS)); + menu->setIsOptionChecked(MenuOption::CollideWithParticles, (bool)(_collisionGroups & COLLISION_GROUP_PARTICLES)); +} + +void MyAvatar::setMotionBehaviors(quint32 flags) { + _motionBehaviors = flags; + Menu* menu = Menu::getInstance(); + menu->setIsOptionChecked(MenuOption::ObeyGravity, (bool)(_motionBehaviors & AVATAR_MOTION_OBEY_GRAVITY)); } void MyAvatar::applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index b713f1c223..9b6b13568f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -25,9 +25,12 @@ enum AvatarHandState NUM_HAND_STATES }; +const quint32 AVATAR_MOTION_OBEY_GRAVITY = 1U << 0; + class MyAvatar : public Avatar { Q_OBJECT Q_PROPERTY(bool shouldRenderLocally READ getShouldRenderLocally WRITE setShouldRenderLocally) + Q_PROPERTY(quint32 motionBehaviors READ getMotionBehaviors WRITE setMotionBehaviors) public: MyAvatar(); @@ -88,6 +91,10 @@ public: virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + virtual void setCollisionGroups(quint32 collisionGroups); + void setMotionBehaviors(quint32 flags); + quint32 getMotionBehaviors() const { return _motionBehaviors; } + void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration); public slots: @@ -104,6 +111,8 @@ public slots: glm::vec3 getThrust() { return _thrust; }; void setThrust(glm::vec3 newThrust) { _thrust = newThrust; } + void updateMotionBehaviors(); + signals: void transformChanged(); @@ -123,6 +132,8 @@ private: bool _isThrustOn; float _thrustMultiplier; + quint32 _motionBehaviors; + glm::vec3 _lastBodyPenetration; QWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; From afb12bcd70f1a388822ca4d54c4d3dfd5d339e71 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Apr 2014 19:12:23 -0700 Subject: [PATCH 11/11] add swissArmyJetpack.js --- examples/swissArmyJetpack.js | 142 +++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 examples/swissArmyJetpack.js diff --git a/examples/swissArmyJetpack.js b/examples/swissArmyJetpack.js new file mode 100644 index 0000000000..9bb5bea267 --- /dev/null +++ b/examples/swissArmyJetpack.js @@ -0,0 +1,142 @@ +// +// swissArmyJetpack.js +// examples +// +// Created by Andrew Meadows 2014.04.24 +// Copyright 2014 High Fidelity, Inc. +// +// This is a work in progress. It will eventually be able to move the avatar around, +// toggle collision groups, modify avatar movement options, and other stuff (maybe trigger animations). +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var numberOfButtons = 3; + +var enabledColors = new Array(); +enabledColors[0] = { red: 255, green: 0, blue: 0}; +enabledColors[1] = { red: 0, green: 255, blue: 0}; +enabledColors[2] = { red: 0, green: 0, blue: 255}; + +var disabledColors = new Array(); +disabledColors[0] = { red: 90, green: 75, blue: 75}; +disabledColors[1] = { red: 75, green: 90, blue: 75}; +disabledColors[2] = { red: 75, green: 90, blue: 90}; + +var buttons = new Array(); +var labels = new Array(); + +var labelContents = new Array(); +labelContents[0] = "Collide with Avatars"; +labelContents[1] = "Collide with Voxels"; +labelContents[2] = "Collide with Particles"; +var groupBits = 0; + +var buttonStates = new Array(); + +var disabledOffsetT = 0; +var enabledOffsetT = 55; + +var buttonX = 50; +var buttonY = 200; +var buttonWidth = 30; +var buttonHeight = 54; +var textX = buttonX + buttonWidth + 10; + +for (i = 0; i < numberOfButtons; i++) { + var offsetS = 12 + var offsetT = disabledOffsetT; + + buttons[i] = Overlays.addOverlay("image", { + //x: buttonX + (buttonWidth * i), + x: buttonX, + y: buttonY + (buttonHeight * i), + width: buttonWidth, + height: buttonHeight, + subImage: { x: offsetS, y: offsetT, width: buttonWidth, height: buttonHeight }, + imageURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/testing-swatches.svg", + color: disabledColors[i], + alpha: 1, + }); + + labels[i] = Overlays.addOverlay("text", { + x: textX, + y: buttonY + (buttonHeight * i) + 12, + width: 150, + height: 50, + color: { red: 0, green: 0, blue: 0}, + textColor: { red: 255, green: 0, blue: 0}, + topMargin: 4, + leftMargin: 4, + text: labelContents[i] + }); + + buttonStates[i] = false; +} + +function updateButton(i, enabled) { + var offsetY = disabledOffsetT; + var buttonColor = disabledColors[i]; + groupBits + if (enabled) { + offsetY = enabledOffsetT; + buttonColor = enabledColors[i]; + if (i == 0) { + groupBits |= COLLISION_GROUP_AVATARS; + } else if (i == 1) { + groupBits |= COLLISION_GROUP_VOXELS; + } else if (i == 2) { + groupBits |= COLLISION_GROUP_PARTICLES; + } + } else { + if (i == 0) { + groupBits &= ~COLLISION_GROUP_AVATARS; + } else if (i == 1) { + groupBits &= ~COLLISION_GROUP_VOXELS; + } else if (i == 2) { + groupBits &= ~COLLISION_GROUP_PARTICLES; + } + } + MyAvatar.collisionGroups = groupBits; + + Overlays.editOverlay(buttons[i], { subImage: { y: offsetY } } ); + Overlays.editOverlay(buttons[i], { color: buttonColor } ); + buttonStates[i] = enabled; +} + +// When our script shuts down, we should clean up all of our overlays +function scriptEnding() { + for (i = 0; i < numberOfButtons; i++) { + print("adebug deleting overlay " + i); + Overlays.deleteOverlay(buttons[i]); + Overlays.deleteOverlay(labels[i]); + } +} +Script.scriptEnding.connect(scriptEnding); + + +// Our update() function is called at approximately 60fps, and we will use it to animate our various overlays +function update(deltaTime) { + if (groupBits != MyAvatar.collisionGroups) { + groupBits = MyAvatar.collisionGroups; + updateButton(0, groupBits & COLLISION_GROUP_AVATARS); + updateButton(1, groupBits & COLLISION_GROUP_VOXELS); + updateButton(2, groupBits & COLLISION_GROUP_PARTICLES); + } +} +Script.update.connect(update); + + +// we also handle click detection in our mousePressEvent() +function mousePressEvent(event) { + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + for (i = 0; i < numberOfButtons; i++) { + if (clickedOverlay == buttons[i]) { + var enabled = !(buttonStates[i]); + updateButton(i, enabled); + } + } +} +Controller.mousePressEvent.connect(mousePressEvent); +