Merge remote-tracking branch 'trunk/master'

This commit is contained in:
Andrew Meadows 2013-12-31 10:57:24 -08:00
commit 7c108ab489
7 changed files with 35 additions and 243 deletions

View file

@ -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 <glm/glm.hpp>
#include <SharedUtil.h>
#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);
}
} */
}
}

View file

@ -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

View file

@ -59,8 +59,8 @@ const float HEAD_RATE_MAX = 50.f;
const float SKIN_COLOR[] = {1.0, 0.84, 0.66};
const float DARK_SKIN_COLOR[] = {0.9, 0.78, 0.63};
const int NUM_BODY_CONE_SIDES = 9;
const float chatMessageScale = 0.0015;
const float chatMessageHeight = 0.4f;
const float CHAT_MESSAGE_SCALE = 0.0015;
const float CHAT_MESSAGE_HEIGHT = 0.1f;
void Avatar::sendAvatarURLsMessage(const QUrl& voxelURL) {
QByteArray message;
@ -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;
@ -303,7 +279,7 @@ void Avatar::render(bool forceRenderHead) {
}
glPushMatrix();
glm::vec3 chatPosition = getPosition() + getBodyUpDirection() * chatMessageHeight * _scale;
glm::vec3 chatPosition = getHead().getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale;
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation);
@ -313,7 +289,7 @@ void Avatar::render(bool forceRenderHead) {
glColor3f(0, 0.8, 0);
glRotatef(180, 0, 1, 0);
glRotatef(180, 0, 0, 1);
glScalef(_scale * chatMessageScale, _scale * chatMessageScale, 1.0f);
glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f);
glDisable(GL_LIGHTING);
glDepthMask(false);

View file

@ -15,7 +15,6 @@
#include <AvatarData.h>
#include "Balls.h"
#include "Hand.h"
#include "Head.h"
#include "InterfaceConfig.h"
@ -58,8 +57,8 @@ const float BODY_BALL_RADIUS_RIGHT_TOES = 0.025;
extern const bool usingBigSphereCollisionTest;
extern const float chatMessageScale;
extern const float chatMessageHeight;
extern const float CHAT_MESSAGE_SCALE;
extern const float CHAT_MESSAGE_HEIGHT;
enum AvatarBodyBallID {
BODY_BALL_NULL = -1,
@ -214,7 +213,6 @@ protected:
float _pelvisToHeadLength;
float _scale;
float _height;
Balls* _balls;
glm::vec3 _worldUpDirection;
glm::vec3 _mouseRayOrigin;
glm::vec3 _mouseRayDirection;

View file

@ -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)) {

View file

@ -21,7 +21,6 @@
#include <HandData.h>
#include <ParticleEditHandle.h>
#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;

View file

@ -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;
@ -474,7 +461,7 @@ void MyAvatar::render(bool forceRenderHead) {
}
glPushMatrix();
glm::vec3 chatPosition = getPosition() + getBodyUpDirection() * chatMessageHeight * _scale;
glm::vec3 chatPosition = getHead().getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale;
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation);
@ -484,7 +471,7 @@ void MyAvatar::render(bool forceRenderHead) {
glColor3f(0, 0.8, 0);
glRotatef(180, 0, 1, 0);
glRotatef(180, 0, 0, 1);
glScalef(_scale * chatMessageScale, _scale * chatMessageScale, 1.0f);
glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f);
glDisable(GL_LIGHTING);
glDepthMask(false);