This commit is contained in:
atlante45 2013-08-05 15:26:43 -07:00
commit 55e34558cb
11 changed files with 273 additions and 163 deletions

View file

@ -2254,7 +2254,7 @@ Avatar* Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar* avatar = (Avatar *) node->getLinkedData();
glm::vec3 headPosition = avatar->getHead().getPosition();
if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS)) {
if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS * avatar->getScale())) {
eyePosition = avatar->getHead().getEyePosition();
_lookatIndicatorScale = avatar->getScale();
_lookatOtherPosition = headPosition;
@ -2266,6 +2266,16 @@ Avatar* Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3
return NULL;
}
bool Application::isLookingAtMyAvatar(Avatar* avatar) {
glm::vec3 theirLookat = avatar->getHead().getLookAtPosition();
glm::vec3 myHeadPosition = _myAvatar.getHead().getPosition();
if (pointInSphere(theirLookat, myHeadPosition, HEAD_SPHERE_RADIUS * _myAvatar.getScale())) {
return true;
}
return false;
}
void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera) {
const float DISTANCE_FROM_HEAD_SPHERE = 0.1f * _lookatIndicatorScale;
@ -3015,6 +3025,9 @@ void Application::displaySide(Camera& whichCamera) {
if (!avatar->isInitialized()) {
avatar->init();
}
if (isLookingAtMyAvatar(avatar)) {
avatar->getHead().setLookAtPosition(_myCamera.getPosition());
}
avatar->render(false, _renderAvatarBalls->isChecked());
avatar->setDisplayingLookatVectors(_renderLookatOn->isChecked());
}

View file

@ -213,6 +213,7 @@ private:
void update(float deltaTime);
Avatar* isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
glm::vec3& eyePosition, uint16_t& nodeID);
bool isLookingAtMyAvatar(Avatar* avatar);
void renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera);
void updateAvatar(float deltaTime);

119
interface/src/BendyLine.cpp Normal file
View file

@ -0,0 +1,119 @@
//
// BendyLine.cpp
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
#include "BendyLine.h"
#include "Util.h"
#include "world.h"
const float DEFAULT_BENDY_LINE_SPRING_FORCE = 10.0f;
const float DEFAULT_BENDY_LINE_TORQUE_FORCE = 0.1f;
const float DEFAULT_BENDY_LINE_DRAG = 10.0f;
const float DEFAULT_BENDY_LINE_LENGTH = 0.09f;
const float DEFAULT_BENDY_LINE_THICKNESS = 0.03f;
BendyLine::BendyLine(){
_springForce = DEFAULT_BENDY_LINE_SPRING_FORCE;
_torqueForce = DEFAULT_BENDY_LINE_TORQUE_FORCE;
_drag = DEFAULT_BENDY_LINE_DRAG;
_length = DEFAULT_BENDY_LINE_LENGTH;
_thickness = DEFAULT_BENDY_LINE_THICKNESS;
_gravityForce = glm::vec3(0.0f, 0.0f, 0.0f);
_basePosition = glm::vec3(0.0f, 0.0f, 0.0f);
_baseDirection = glm::vec3(0.0f, 0.0f, 0.0f);
_midPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_endPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
_endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
}
void BendyLine::reset() {
_midPosition = _basePosition + _baseDirection * _length * ONE_HALF;
_endPosition = _midPosition + _baseDirection * _length * ONE_HALF;
_midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
_endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
}
void BendyLine::update(float deltaTime) {
glm::vec3 midAxis = _midPosition - _basePosition;
glm::vec3 endAxis = _endPosition - _midPosition;
float midLength = glm::length(midAxis);
float endLength = glm::length(endAxis);
glm::vec3 midDirection;
glm::vec3 endDirection;
if (midLength > 0.0f) {
midDirection = midAxis / midLength;
} else {
midDirection = _baseDirection;
}
if (endLength > 0.0f) {
endDirection = endAxis / endLength;
} else {
endDirection = _baseDirection;
}
// add spring force
float midForce = midLength - _length * ONE_HALF;
float endForce = endLength - _length * ONE_HALF;
_midVelocity -= midDirection * midForce * _springForce * deltaTime;
_endVelocity -= endDirection * endForce * _springForce * deltaTime;
// add gravity force
_midVelocity += _gravityForce;
_endVelocity += _gravityForce;
// add torque force
_midVelocity += _baseDirection * _torqueForce * deltaTime;
_endVelocity += midDirection * _torqueForce * deltaTime;
// add drag force
float momentum = 1.0f - (_drag * deltaTime);
if (momentum < 0.0f) {
_midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
_endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
} else {
_midVelocity *= momentum;
_endVelocity *= momentum;
}
// update position by velocity
_midPosition += _midVelocity;
_endPosition += _endVelocity;
// clamp lengths
glm::vec3 newMidVector = _midPosition - _basePosition;
glm::vec3 newEndVector = _endPosition - _midPosition;
float newMidLength = glm::length(newMidVector);
float newEndLength = glm::length(newEndVector);
glm::vec3 newMidDirection;
glm::vec3 newEndDirection;
if (newMidLength > 0.0f) {
newMidDirection = newMidVector/newMidLength;
} else {
newMidDirection = _baseDirection;
}
if (newEndLength > 0.0f) {
newEndDirection = newEndVector/newEndLength;
} else {
newEndDirection = _baseDirection;
}
_endPosition = _midPosition + newEndDirection * _length * ONE_HALF;
_midPosition = _basePosition + newMidDirection * _length * ONE_HALF;
}

52
interface/src/BendyLine.h Normal file
View file

@ -0,0 +1,52 @@
//
// BendyLine.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef hifi_bendyLine_h
#define hifi_bendyLine_h
#include <SharedUtil.h>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
class BendyLine {
public:
BendyLine();
void update(float deltaTime);
void reset();
void setLength (float length ) { _length = length; }
void setThickness (float thickness ) { _thickness = thickness; }
void setSpringForce (float springForce ) { _springForce = springForce; }
void setTorqueForce (float torqueForce ) { _torqueForce = torqueForce; }
void setDrag (float drag ) { _drag = drag; }
void setBasePosition (glm::vec3 basePosition ) { _basePosition = basePosition; }
void setBaseDirection(glm::vec3 baseDirection) { _baseDirection = baseDirection;}
void setGravityForce (glm::vec3 gravityForce ) { _gravityForce = gravityForce; }
glm::vec3 getBasePosition() { return _basePosition; }
glm::vec3 getMidPosition () { return _midPosition; }
glm::vec3 getEndPosition () { return _endPosition; }
float getThickness () { return _thickness; }
private:
float _springForce;
float _torqueForce;
float _drag;
float _length;
float _thickness;
glm::vec3 _gravityForce;
glm::vec3 _basePosition;
glm::vec3 _baseDirection;
glm::vec3 _midPosition;
glm::vec3 _endPosition;
glm::vec3 _midVelocity;
glm::vec3 _endVelocity;
};
#endif

View file

@ -322,27 +322,48 @@ void ParticleSystem::updateParticle(int p, float deltaTime) {
// apply color modulation
if (myEmitter.particleAttributes[lifeStage ].modulationAmplitude > 0.0f) {
float modulation = 0.0f;
float redModulation = 0.0f;
float greenModulation = 0.0f;
float bueModulation = 0.0f;
float radian = _timer * myEmitter.particleAttributes[lifeStage ].modulationRate * PI_TIMES_TWO;
if (myEmitter.particleAttributes[lifeStage ].modulationStyle == COLOR_MODULATION_STYLE_LIGHNTESS_PULSE) {
if (sinf(radian) > 0.0f) {
modulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
redModulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
greenModulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
bueModulation = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
}
} else if (myEmitter.particleAttributes[lifeStage].modulationStyle == COLOR_MODULATION_STYLE_LIGHTNESS_WAVE) {
float a = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
modulation = a * ONE_HALF + sinf(radian) * a * ONE_HALF;
float amp = myEmitter.particleAttributes[lifeStage].modulationAmplitude;
float brightness = amp * ONE_HALF + sinf(radian) * amp * ONE_HALF;
redModulation = brightness;
greenModulation = brightness;
bueModulation = brightness;
} else if (myEmitter.particleAttributes[lifeStage].modulationStyle == COLOR_MODULATION_STYLE_RAINBOW_CYCLE) {
float amp = myEmitter.particleAttributes[lifeStage].modulationAmplitude * ONE_HALF;
redModulation = sinf(radian * RAINBOW_CYCLE_RED_RATE ) * amp;
greenModulation = sinf(radian * RAINBOW_CYCLE_GREEN_RATE) * amp;
bueModulation = sinf(radian * RAINBOW_CYCLE_BLUE_RATE ) * amp;
}
_particle[p].color.r += modulation;
_particle[p].color.g += modulation;
_particle[p].color.b += modulation;
_particle[p].color.a += modulation;
_particle[p].color.r += redModulation;
_particle[p].color.g += greenModulation;
_particle[p].color.b += bueModulation;
_particle[p].color.a = 1.0f;
if (_particle[p].color.r > 1.0f) {_particle[p].color.r = 1.0f;}
if (_particle[p].color.g > 1.0f) {_particle[p].color.g = 1.0f;}
if (_particle[p].color.b > 1.0f) {_particle[p].color.b = 1.0f;}
if (_particle[p].color.a > 1.0f) {_particle[p].color.a = 1.0f;}
}
if (_particle[p].color.r < 0.0f) {_particle[p].color.r = 0.0f;}
if (_particle[p].color.g < 0.0f) {_particle[p].color.g = 0.0f;}
if (_particle[p].color.b < 0.0f) {_particle[p].color.b = 0.0f;}
if (_particle[p].color.a < 0.0f) {_particle[p].color.a = 0.0f;}
}
// do this at the end...
_particle[p].age += deltaTime;

View file

@ -15,6 +15,10 @@ const int NULL_PARTICLE = -1;
const int MAX_EMITTERS = 100;
const int MAX_PARTICLES = 5000;
const float RAINBOW_CYCLE_RED_RATE = 0.5f;
const float RAINBOW_CYCLE_GREEN_RATE = 0.7f;
const float RAINBOW_CYCLE_BLUE_RATE = 1.0f;
enum ParticleRenderStyle
{
PARTICLE_RENDER_STYLE_SPHERE = 0,
@ -28,6 +32,7 @@ enum ColorModulationStyle
COLOR_MODULATION_STYLE_NULL = -1,
COLOR_MODULATION_STYLE_LIGHNTESS_PULSE,
COLOR_MODULATION_STYLE_LIGHTNESS_WAVE,
COLOR_MODULATION_STYLE_RAINBOW_CYCLE,
NUM_COLOR_MODULATION_STYLES
};

View file

@ -607,3 +607,12 @@ bool rayIntersectsSphere(glm::vec3& rayStarting, glm::vec3& rayNormalizedDirecti
}
return false;
}
bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius) {
glm::vec3 diff = point - sphereCenter;
double mag = sqrt(glm::dot(diff, diff));
if (mag <= sphereRadius) {
return true;
}
return false;
}

View file

@ -76,4 +76,6 @@ float loadSetting(QSettings* settings, const char* name, float defaultValue);
bool rayIntersectsSphere(glm::vec3& rayStarting, glm::vec3& rayNormalizedDirection, glm::vec3& sphereCenter, double sphereRadius);
bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius);
#endif

View file

@ -343,29 +343,6 @@ void Hand::updateRaveGloveParticles(float deltaTime) {
_raveGloveParticleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f));
_raveGloveInitialized = true;
} else {
_raveGloveClock += deltaTime;
// this rave glove effect oscillates though various colors and radii that are meant to show off some effects
if (_raveGloveMode == RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR) {
ParticleSystem::ParticleAttributes attributes;
float red = 0.5f + 0.5f * sinf(_raveGloveClock * 2.4f);
float green = 0.5f + 0.5f * cosf(_raveGloveClock * 2.7f);
float blue = 0.5f + 0.5f * sinf(_raveGloveClock * 3.0f);
float alpha = 1.0f;
attributes.color = glm::vec4(red, green, blue, alpha);
attributes.radius = 0.01f + 0.003f * sinf(_raveGloveClock * 50.0f);
attributes.modulationAmplitude = 0.0f;
for ( int f = 0; f< NUM_FINGERS; f ++ ) {
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes);
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes);
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes);
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_3, attributes);
}
}
_raveGloveParticleSystem.simulate(deltaTime);
}
}
@ -395,11 +372,15 @@ void Hand::setRaveGloveMode(int mode) {
_raveGloveParticleSystem.setParticleAttributesToDefault(&attributes);
attributes.radius = 0.02f;
attributes.gravity = 0.0f;
attributes.airFriction = 0.0f;
attributes.jitter = 0.0f;
attributes.bounce = 0.0f;
attributes.modulationAmplitude = 1.0;
attributes.modulationRate = 0.33;
attributes.modulationStyle = COLOR_MODULATION_STYLE_RAINBOW_CYCLE;
attributes.color = glm::vec4( 0.5f, 0.5f, 0.5f, 1.0f);
attributes.radius = 0.02f;
attributes.gravity = 0.0f;
attributes.airFriction = 0.0f;
attributes.jitter = 0.0f;
attributes.bounce = 0.0f;
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_0, attributes);
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_1, attributes);
_raveGloveParticleSystem.setParticleAttributes(_raveGloveEmitter[f], PARTICLE_LIFESTAGE_2, attributes);

View file

@ -30,9 +30,9 @@ const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is
const float EYEBALL_RADIUS = 0.017;
const float EYELID_RADIUS = 0.019;
const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f };
const float HAIR_SPRING_FORCE = 10.0f;
const float HAIR_SPRING_FORCE = 7.0f;
const float HAIR_TORQUE_FORCE = 0.1f;
const float HAIR_GRAVITY_FORCE = 0.05f;
const float HAIR_GRAVITY_FORCE = 0.02f;
const float HAIR_DRAG = 10.0f;
const float HAIR_LENGTH = 0.09f;
const float HAIR_THICKNESS = 0.03f;
@ -90,7 +90,7 @@ Head::Head(Avatar* owningAvatar) :
_cameraFollowHeadRate(0.0f),
_face(this)
{
if (USING_PHYSICAL_MOHAWK) {
if (USING_PHYSICAL_MOHAWK) {
resetHairPhysics();
}
}
@ -105,7 +105,7 @@ void Head::init() {
_irisProgram->setUniformValue("texture", 0);
_eyePositionLocation = _irisProgram->uniformLocation("eyePosition");
QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_ARGB32);
glGenTextures(1, &_irisTextureID);
@ -127,20 +127,20 @@ void Head::reset() {
}
}
void Head::resetHairPhysics() {
glm::vec3 up = getUpDirection();
//glm::vec3 up = getUpDirection();
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
_hairTuft[t].length = _scale * HAIR_LENGTH;
_hairTuft[t].thickness = _scale * HAIR_THICKNESS;
_hairTuft[t].basePosition = _position + up * _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.9f;
_hairTuft[t].midPosition = _hairTuft[t].basePosition + up * _hairTuft[t].length * ONE_HALF;
_hairTuft[t].endPosition = _hairTuft[t].midPosition + up * _hairTuft[t].length * ONE_HALF;
_hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
_hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
_hairTuft[t].setSpringForce (HAIR_SPRING_FORCE);
_hairTuft[t].setTorqueForce (HAIR_TORQUE_FORCE);
_hairTuft[t].setGravityForce (HAIR_GRAVITY_FORCE * _gravity);
_hairTuft[t].setDrag (HAIR_DRAG);
_hairTuft[t].setLength (_scale * HAIR_LENGTH );
_hairTuft[t].setThickness (_scale * HAIR_THICKNESS);
_hairTuft[t].setBaseDirection(getUpDirection());
_hairTuft[t].reset();
}
}
}
@ -223,6 +223,7 @@ void Head::simulate(float deltaTime, bool isMine) {
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
if (USING_PHYSICAL_MOHAWK) {
updateHairPhysics(deltaTime);
}
// Update camera pitch and yaw independently from motion of head (for gyro-based interface)
@ -376,17 +377,17 @@ void Head::renderMohawk() {
if (USING_PHYSICAL_MOHAWK) {
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition;
glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition;
glm::vec3 viewVector = _hairTuft[t].basePosition - Application::getInstance()->getCamera()->getPosition();
glm::vec3 baseAxis = _hairTuft[t].getMidPosition() - _hairTuft[t].getBasePosition();
glm::vec3 midAxis = _hairTuft[t].getEndPosition() - _hairTuft[t].getMidPosition();
glm::vec3 viewVector = _hairTuft[t].getBasePosition() - Application::getInstance()->getCamera()->getPosition();
glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector));
glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector));
glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF;
glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF;
glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF;
glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF;
glm::vec3 base1 = _hairTuft[t].getBasePosition() - basePerpendicular * _hairTuft[t].getThickness() * ONE_HALF;
glm::vec3 base2 = _hairTuft[t].getBasePosition() + basePerpendicular * _hairTuft[t].getThickness() * ONE_HALF;
glm::vec3 mid1 = _hairTuft[t].getMidPosition() - midPerpendicular * _hairTuft[t].getThickness() * ONE_HALF * ONE_HALF;
glm::vec3 mid2 = _hairTuft[t].getMidPosition() + midPerpendicular * _hairTuft[t].getThickness() * ONE_HALF * ONE_HALF;
glColor3f(_mohawkColors[t].x, _mohawkColors[t].y, _mohawkColors[t].z);
@ -399,7 +400,7 @@ void Head::renderMohawk() {
glVertex3f(mid2.x, mid2.y, mid2.z );
glVertex3f(mid1.x, mid1.y, mid1.z );
glVertex3f(mid2.x, mid2.y, mid2.z );
glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z );
glVertex3f(_hairTuft[t].getEndPosition().x, _hairTuft[t].getEndPosition().y, _hairTuft[t].getEndPosition().z );
glEnd();
}
} else {
@ -735,100 +736,17 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi
glEnd();
}
void Head::updateHairPhysics(float deltaTime) {
glm::quat orientation = getOrientation();
glm::vec3 up = orientation * IDENTITY_UP;
glm::vec3 front = orientation * IDENTITY_FRONT;
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
float fraction = (float)t / (float)(NUM_HAIR_TUFTS - 1);
float angle = -20.0f + 40.0f * fraction;
float radian = angle * PI_OVER_180;
glm::vec3 baseDirection
= front * sinf(radian)
+ up * cosf(radian);
_hairTuft[t].basePosition = _position + _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.9f * baseDirection;
glm::vec3 midAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition;
glm::vec3 endAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition;
float midLength = glm::length(midAxis);
float endLength = glm::length(endAxis);
glm::vec3 midDirection;
glm::vec3 endDirection;
if (midLength > 0.0f) {
midDirection = midAxis / midLength;
} else {
midDirection = up;
}
if (endLength > 0.0f) {
endDirection = endAxis / endLength;
} else {
endDirection = up;
}
// add spring force
float midForce = midLength - _hairTuft[t].length * ONE_HALF;
float endForce = endLength - _hairTuft[t].length * ONE_HALF;
_hairTuft[t].midVelocity -= midDirection * midForce * HAIR_SPRING_FORCE * deltaTime;
_hairTuft[t].endVelocity -= endDirection * endForce * HAIR_SPRING_FORCE * deltaTime;
// add gravity force
glm::vec3 gravityForce = _gravity * HAIR_GRAVITY_FORCE * deltaTime;
_hairTuft[t].midVelocity += gravityForce;
_hairTuft[t].endVelocity += gravityForce;
// add torque force
_hairTuft[t].midVelocity += baseDirection * HAIR_TORQUE_FORCE * deltaTime;
_hairTuft[t].endVelocity += midDirection * HAIR_TORQUE_FORCE * deltaTime;
// add drag force
float momentum = 1.0f - (HAIR_DRAG * deltaTime);
if (momentum < 0.0f) {
_hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
_hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
} else {
_hairTuft[t].midVelocity *= momentum;
_hairTuft[t].endVelocity *= momentum;
}
// update position by velocity
_hairTuft[t].midPosition += _hairTuft[t].midVelocity;
_hairTuft[t].endPosition += _hairTuft[t].endVelocity;
// clamp lengths
glm::vec3 newMidVector = _hairTuft[t].midPosition - _hairTuft[t].basePosition;
glm::vec3 newEndVector = _hairTuft[t].endPosition - _hairTuft[t].midPosition;
float newMidLength = glm::length(newMidVector);
float newEndLength = glm::length(newEndVector);
glm::vec3 newMidDirection;
glm::vec3 newEndDirection;
if (newMidLength > 0.0f) {
newMidDirection = newMidVector/newMidLength;
} else {
newMidDirection = up;
}
if (newEndLength > 0.0f) {
newEndDirection = newEndVector/newEndLength;
} else {
newEndDirection = up;
}
_hairTuft[t].endPosition = _hairTuft[t].midPosition + newEndDirection * _hairTuft[t].length * ONE_HALF;
_hairTuft[t].midPosition = _hairTuft[t].basePosition + newMidDirection * _hairTuft[t].length * ONE_HALF;
glm::vec3 baseDirection = front * sinf(radian) + up * cosf(radian);
_hairTuft[t].setBasePosition (_position + _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.9f * baseDirection);
_hairTuft[t].setBaseDirection(baseDirection);
_hairTuft[t].update(deltaTime);
}
}

View file

@ -18,6 +18,7 @@
#include <VoxelConstants.h>
#include "Face.h"
#include "BendyLine.h"
#include "InterfaceConfig.h"
#include "SerialInterface.h"
#include "world.h"
@ -29,7 +30,7 @@ enum eyeContactTargets
MOUTH
};
const int NUM_HAIR_TUFTS = 4;
const int NUM_HAIR_TUFTS = 4;
class Avatar;
class ProgramObject;
@ -80,18 +81,6 @@ private:
Head(const Head&);
Head& operator= (const Head&);
struct HairTuft
{
float length;
float thickness;
glm::vec3 basePosition;
glm::vec3 midPosition;
glm::vec3 endPosition;
glm::vec3 midVelocity;
glm::vec3 endVelocity;
};
struct Nose
{
glm::vec3 top;
@ -123,7 +112,7 @@ private:
float _returnSpringScale; //strength of return springs
glm::vec3 _bodyRotation;
bool _renderLookatVectors;
HairTuft _hairTuft[NUM_HAIR_TUFTS];
BendyLine _hairTuft[NUM_HAIR_TUFTS];
glm::vec3* _mohawkTriangleFan;
glm::vec3* _mohawkColors;
glm::vec3 _saccade;