diff --git a/interface/src/Balls.cpp b/interface/src/Balls.cpp deleted file mode 100644 index 693b38462b..0000000000 --- a/interface/src/Balls.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// -// Balls.cpp -// hifi -// -// Created by Philip on 4/25/13. -// -// A cloud of spring-mass spheres to simulate the avatar body/skin. Each ball -// connects to as many as 4 neighbors, and executes motion according to a damped -// spring, while responding physically to other avatars. -// - -#include - -#include - -#include "Balls.h" -#include "InterfaceConfig.h" -#include "Util.h" -#include "world.h" - -const float INITIAL_AREA = 0.2f; -const float BALL_RADIUS = 0.016f; -const glm::vec3 INITIAL_COLOR(0.62f, 0.74f, 0.91f); - -Balls::Balls(int numberOfBalls) { - _numberOfBalls = numberOfBalls; - _balls = new Ball[_numberOfBalls]; - for (unsigned int i = 0; i < _numberOfBalls; ++i) { - _balls[i].position = randVector() * INITIAL_AREA; - _balls[i].targetPosition = _balls[i].position; - _balls[i].velocity = glm::vec3(0, 0, 0); - _balls[i].radius = BALL_RADIUS; - for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) { - _balls[i].links[j] = 0; - } - } - _color = INITIAL_COLOR; - _origin = glm::vec3(0, 0, 0); -} - -Balls::~Balls() { - delete[] _balls; -} - -void Balls::moveOrigin(const glm::vec3& newOrigin) { - glm::vec3 delta = newOrigin - _origin; - if (glm::length(delta) > EPSILON) { - _origin = newOrigin; - for (unsigned int i = 0; i < _numberOfBalls; ++i) { - _balls[i].targetPosition += delta; - } - } -} - -const bool RENDER_SPRINGS = false; - -void Balls::render() { - - // Render Balls NOTE: This needs to become something other that GlutSpheres! - glColor3fv(&_color.x); - for (unsigned int i = 0; i < _numberOfBalls; ++i) { - glPushMatrix(); - glTranslatef(_balls[i].position.x, _balls[i].position.y, _balls[i].position.z); - glutSolidSphere(_balls[i].radius, 8, 8); - glPopMatrix(); - } - - // Render springs - if (RENDER_SPRINGS) { - glColor3f(0.74, 0.91, 0.62); - for (unsigned int i = 0; i < _numberOfBalls; ++i) { - glBegin(GL_LINES); - for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) { - if(_balls[i].links[j] > 0) { - glVertex3f(_balls[i].position.x, - _balls[i].position.y, - _balls[i].position.z); - glVertex3f(_balls[_balls[i].links[j]-1].position.x, - _balls[_balls[i].links[j]-1].position.y, - _balls[_balls[i].links[j]-1].position.z); - } - } - glEnd(); - } - } - -} - -const float CONSTANT_VELOCITY_DAMPING = 1.0f; -const float NOISE_SCALE = 0.06; -const float SPRING_FORCE = 30.0; -const float ORIGIN_DISTANCE = 0.1; -const float SPRING_DAMPING = 1.0; - -void Balls::simulate(float deltaTime) { - for (unsigned int i = 0; i < _numberOfBalls; ++i) { - - // Move particles - _balls[i].position += _balls[i].velocity * deltaTime; - _balls[i].targetPosition += _balls[i].velocity * deltaTime; - - // Drag: decay velocity - _balls[i].velocity *= (1.f - CONSTANT_VELOCITY_DAMPING * deltaTime); - - // Add noise - _balls[i].velocity += randVector() * NOISE_SCALE; - - // spring force to origin - float separation = glm::distance(_balls[i].position, - _origin); - - _balls[i].velocity += - glm::normalize(_balls[i].position - _origin) - * deltaTime - * - SPRING_FORCE * - (ORIGIN_DISTANCE - separation); - - // Approach target position -// for (unsigned int i = 0; i < _numberOfBalls; ++i) { -// _balls[i].position += randFloat() * deltaTime * (_balls[i].targetPosition - _balls[i].position); -// } - - // Spring Force - - /* - for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) { - if(_balls[i].links[j] > 0) { - float separation = glm::distance(_balls[i].position, - _balls[_balls[i].links[j]-1].position); - _balls[i].velocity += glm::normalize(_balls[i].position - - _balls[_balls[i].links[j]-1].position) * - deltaTime * - SPRING_FORCE * - (_balls[i].springLength[j] - separation); - - //_balls[i].velocity *= (1.f - SPRING_DAMPING*deltaTime); - - } - } */ - - - - - } -} - diff --git a/interface/src/Balls.h b/interface/src/Balls.h deleted file mode 100644 index eefa71828a..0000000000 --- a/interface/src/Balls.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// Balls.h -// hifi -// -// Created by Philip on 4/25/13. -// -// - -#ifndef hifi_Balls_h -#define hifi_Balls_h - -const int NUMBER_SPRINGS = 4; - -class Balls { -public: - Balls(int numberOfBalls); - ~Balls(); - - void simulate(float deltaTime); - void render(); - - void setColor(const glm::vec3& c) { _color = c; }; - void moveOrigin(const glm::vec3& newOrigin); - -private: - struct Ball { - glm::vec3 position, targetPosition, velocity; - int links[NUMBER_SPRINGS]; - float springLength[NUMBER_SPRINGS]; - float radius; - } *_balls; - int _numberOfBalls; - glm::vec3 _origin; - glm::vec3 _color; -}; - -#endif diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ec0c19cb7a..5a9a689775 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -118,18 +118,12 @@ Avatar::Avatar(Node* owningNode) : _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight(); _pelvisToHeadLength = _skeleton.getPelvisToHeadLength(); - if (BALLS_ON) { - _balls = new Balls(100); - } else { - _balls = NULL; - } } Avatar::~Avatar() { _headData = NULL; _handData = NULL; - delete _balls; } void Avatar::deleteOrDeleteLater() { @@ -180,18 +174,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // copy velocity so we can use it later for acceleration glm::vec3 oldVelocity = getVelocity(); - // update balls - if (_balls) { - _balls->moveOrigin(_position); - glm::vec3 lookAt = _head.getLookAtPosition(); - if (glm::length(lookAt) > EPSILON) { - _balls->moveOrigin(lookAt); - } else { - _balls->moveOrigin(_position); - } - _balls->simulate(deltaTime); - } - // update torso rotation based on head lean _skeleton.joint[AVATAR_JOINT_TORSO].rotation = glm::quat(glm::radians(glm::vec3( _head.getLeanForward(), 0.0f, _head.getLeanSideways()))); @@ -288,13 +270,7 @@ void Avatar::render(bool forceRenderHead) { } } - // Render the balls - if (_balls) { - glPushMatrix(); - _balls->render(); - glPopMatrix(); - } - + if (!_chatMessage.empty()) { int width = 0; int lastWidth = 0; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index c23e30f60b..b0448563cf 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -15,7 +15,6 @@ #include -#include "Balls.h" #include "Hand.h" #include "Head.h" #include "InterfaceConfig.h" @@ -214,7 +213,6 @@ protected: float _pelvisToHeadLength; float _scale; float _height; - Balls* _balls; glm::vec3 _worldUpDirection; glm::vec3 _mouseRayOrigin; glm::vec3 _mouseRayDirection; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 136d59bc37..20f034989b 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -52,6 +52,8 @@ Hand::Hand(Avatar* owningAvatar) : _pitchUpdate(0), _grabDelta(0, 0, 0), _grabDeltaVelocity(0, 0, 0), + _grabStartRotation(0, 0, 0, 1), + _grabCurrentRotation(0, 0, 0, 1), _throwInjector(QUrl("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw")), _catchInjector(QUrl("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw")) { @@ -227,7 +229,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f } glm::vec3 Hand::getAndResetGrabDelta() { - const float HAND_GRAB_SCALE_DISTANCE = 5.f; + const float HAND_GRAB_SCALE_DISTANCE = 2.f; glm::vec3 delta = _grabDelta * _owningAvatar->getScale() * HAND_GRAB_SCALE_DISTANCE; _grabDelta = glm::vec3(0,0,0); glm::quat avatarRotation = _owningAvatar->getOrientation(); @@ -242,6 +244,11 @@ glm::vec3 Hand::getAndResetGrabDeltaVelocity() { return avatarRotation * -delta; } +glm::quat Hand::getAndResetGrabRotation() { + glm::quat diff = _grabCurrentRotation * glm::inverse(_grabStartRotation); + _grabStartRotation = _grabCurrentRotation; + return diff; +} void Hand::simulate(float deltaTime, bool isMine) { @@ -275,10 +282,16 @@ void Hand::simulate(float deltaTime, bool isMine) { if (palm.getControllerButtons() & BUTTON_4) { _grabDelta += palm.getRawVelocity() * deltaTime; + _grabCurrentRotation = palm.getRawRotation(); } if ((palm.getLastControllerButtons() & BUTTON_4) && !(palm.getControllerButtons() & BUTTON_4)) { + // Just ending grab, capture velocity _grabDeltaVelocity = palm.getRawVelocity(); } + if (!(palm.getLastControllerButtons() & BUTTON_4) && (palm.getControllerButtons() & BUTTON_4)) { + // Just starting grab, capture starting rotation + _grabStartRotation = palm.getRawRotation(); + } if (palm.getControllerButtons() & BUTTON_1) { if (glm::length(fingerTipPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) { diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 884d710381..e938135a29 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -21,7 +21,6 @@ #include #include -#include "Balls.h" #include "InterfaceConfig.h" #include "ParticleSystem.h" #include "world.h" @@ -65,6 +64,7 @@ public: // Get the drag distance to move glm::vec3 getAndResetGrabDelta(); glm::vec3 getAndResetGrabDeltaVelocity(); + glm::quat getAndResetGrabRotation(); private: // disallow copies of the Hand, copy of owning Avatar is disallowed too @@ -111,6 +111,8 @@ private: glm::vec3 _grabDelta; glm::vec3 _grabDeltaVelocity; + glm::quat _grabStartRotation; + glm::quat _grabCurrentRotation; AudioInjector _throwInjector; AudioInjector _catchInjector; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6c2bc78090..0efa8b09cf 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -111,18 +111,6 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { // calculate speed _speed = glm::length(_velocity); - // update balls - if (_balls) { - _balls->moveOrigin(_position); - glm::vec3 lookAt = _head.getLookAtPosition(); - if (glm::length(lookAt) > EPSILON) { - _balls->moveOrigin(lookAt); - } else { - _balls->moveOrigin(_position); - } - _balls->simulate(deltaTime); - } - // update torso rotation based on head lean _skeleton.joint[AVATAR_JOINT_TORSO].rotation = glm::quat(glm::radians(glm::vec3( _head.getLeanForward(), 0.0f, _head.getLeanSideways()))); @@ -270,14 +258,21 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { } updateChatCircle(deltaTime); - - // Get any position or velocity update from Grab controller + + // Get any position, velocity, or rotation update from Grab Drag controller glm::vec3 moveFromGrab = _hand.getAndResetGrabDelta(); if (glm::length(moveFromGrab) > EPSILON) { _position += moveFromGrab; _velocity = glm::vec3(0, 0, 0); } _velocity += _hand.getAndResetGrabDeltaVelocity(); + glm::quat deltaRotation = _hand.getAndResetGrabRotation(); + const float GRAB_CONTROLLER_TURN_SCALING = 0.5f; + glm::vec3 euler = safeEulerAngles(deltaRotation) * GRAB_CONTROLLER_TURN_SCALING; + // Adjust body yaw by yaw from controller + setOrientation(glm::angleAxis(-euler.y, glm::vec3(0, 1, 0)) * getOrientation()); + // Adjust head pitch from controller + getHead().setMousePitch(getHead().getMousePitch() - euler.x); _position += _velocity * deltaTime; @@ -455,17 +450,9 @@ void MyAvatar::render(bool forceRenderHead) { // render body renderBody(forceRenderHead); - - // Render the balls - if (_balls) { - glPushMatrix(); - _balls->render(); - glPopMatrix(); - } //renderDebugBodyPoints(); - if (!_chatMessage.empty()) { int width = 0; int lastWidth = 0;