diff --git a/interface/src/Hair.cpp b/interface/src/Hair.cpp index 810833d750..227adb10a6 100644 --- a/interface/src/Hair.cpp +++ b/interface/src/Hair.cpp @@ -17,13 +17,13 @@ const float HAIR_DAMPING = 0.99f; const float CONSTRAINT_RELAXATION = 10.0f; -const float HAIR_ACCELERATION_COUPLING = 0.025f; -const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.01f; -const float HAIR_ANGULAR_ACCELERATION_COUPLING = 0.001f; +const float HAIR_ACCELERATION_COUPLING = 0.045f; +const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.020f; +const float HAIR_ANGULAR_ACCELERATION_COUPLING = 0.003f; const float HAIR_MAX_LINEAR_ACCELERATION = 4.0f; -const float HAIR_STIFFNESS = 0.005f; -const glm::vec3 HAIR_COLOR1(0.98f, 0.92f, 0.843f); -const glm::vec3 HAIR_COLOR2(0.545f, 0.533f, 0.47f); +const float HAIR_STIFFNESS = 0.00f; +const glm::vec3 HAIR_COLOR1(0.98f, 0.76f, 0.075f); +const glm::vec3 HAIR_COLOR2(0.912f, 0.184f, 0.101f); Hair::Hair(int strands, int links, @@ -38,7 +38,8 @@ Hair::Hair(int strands, _acceleration(0.0f), _angularVelocity(0.0f), _angularAcceleration(0.0f), - _gravity(0.0f) + _gravity(0.0f), + _loudness() { _hairPosition = new glm::vec3[_strands * _links]; _hairOriginalPosition = new glm::vec3[_strands * _links]; @@ -48,12 +49,15 @@ Hair::Hair(int strands, _hairColors = new glm::vec3[_strands * _links]; _hairIsMoveable = new int[_strands * _links]; _hairConstraints = new int[_strands * _links * HAIR_CONSTRAINTS]; // Hair can link to two others - const float FACE_WIDTH = PI / 4.0f; glm::vec3 thisVertex; for (int strand = 0; strand < _strands; strand++) { float strandAngle = randFloat() * PI; - float azimuth = FACE_WIDTH / 2.0f + (randFloat() * (2.0 * PI - FACE_WIDTH)); - float elevation = PI_OVER_TWO - (randFloat() * 0.75 * PI); + float azimuth; + float elevation = PI_OVER_TWO - (randFloat() * 0.10f * PI); + azimuth = PI_OVER_TWO; + if (randFloat() < 0.5f) { + azimuth *= -1.0f; + } glm::vec3 thisStrand(sinf(azimuth) * cosf(elevation), sinf(elevation), -cosf(azimuth) * cosf(elevation)); thisStrand *= _radius; @@ -77,7 +81,7 @@ Hair::Hair(int strands, _hairOriginalPosition[vertexIndex] = _hairLastPosition[vertexIndex] = _hairPosition[vertexIndex] = thisVertex; _hairQuadDelta[vertexIndex] = glm::vec3(cos(strandAngle) * _hairThickness, 0.f, sin(strandAngle) * _hairThickness); - _hairQuadDelta[vertexIndex] *= 1.f - ((float)link / _links); + _hairQuadDelta[vertexIndex] *= ((float)link / _links); _hairNormals[vertexIndex] = glm::normalize(randVector()); if (randFloat() < elevation / PI_OVER_TWO) { _hairColors[vertexIndex] = HAIR_COLOR1 * ((float)(link + 1) / (float)_links); @@ -114,9 +118,15 @@ void Hair::simulate(float deltaTime) { _hairPosition[vertexIndex] += glm::normalize(_hairPosition[vertexIndex]) * (_radius - glm::length(_hairPosition[vertexIndex])); } - + // Add random thing driven by loudness + const float LOUD_BASE = 0.0005f; + float loudnessFactor = (_loudness > 0.0f) ? logf(_loudness) / 2000.0f : 0.0f; + + _hairPosition[vertexIndex] += randVector() * (LOUD_BASE + loudnessFactor) * ((float)link / (float)_links); + // Add gravity - _hairPosition[vertexIndex] += _gravity * deltaTime; + const float SCALE_GRAVITY = 0.10f; + _hairPosition[vertexIndex] += _gravity * deltaTime * SCALE_GRAVITY; // Add linear acceleration _hairPosition[vertexIndex] -= acceleration * HAIR_ACCELERATION_COUPLING * deltaTime; @@ -179,11 +189,23 @@ void Hair::render() { // // Before calling this function, translate/rotate to the origin of the owning object // + float loudnessFactor = (_loudness > 0.0f) ? logf(_loudness) / 16.0f : 0.0f; + const int SPARKLE_EVERY = 5; + const float HAIR_SETBACK = 0.125f; + int sparkleIndex = random() % 5; + glPushMatrix(); + glTranslatef(0.f, 0.f, HAIR_SETBACK); glBegin(GL_QUADS); for (int strand = 0; strand < _strands; strand++) { for (int link = 0; link < _links - 1; link++) { int vertexIndex = strand * _links + link; - glColor3fv(&_hairColors[vertexIndex].x); + glm::vec3 thisColor = _hairColors[vertexIndex]; + if (sparkleIndex % SPARKLE_EVERY == 0) { + thisColor.x += (1.f - thisColor.x) * loudnessFactor; + thisColor.y += (1.f - thisColor.y) * loudnessFactor; + thisColor.z += (1.f - thisColor.z) * loudnessFactor; + } + glColor3fv(&thisColor.x); glNormal3fv(&_hairNormals[vertexIndex].x); glVertex3f(_hairPosition[vertexIndex].x - _hairQuadDelta[vertexIndex].x, _hairPosition[vertexIndex].y - _hairQuadDelta[vertexIndex].y, @@ -198,9 +220,11 @@ void Hair::render() { glVertex3f(_hairPosition[vertexIndex + 1].x - _hairQuadDelta[vertexIndex].x, _hairPosition[vertexIndex + 1].y - _hairQuadDelta[vertexIndex].y, _hairPosition[vertexIndex + 1].z - _hairQuadDelta[vertexIndex].z); + sparkleIndex++; } } glEnd(); + glPopMatrix(); } diff --git a/interface/src/Hair.h b/interface/src/Hair.h index f5180f639d..036d137cd3 100644 --- a/interface/src/Hair.h +++ b/interface/src/Hair.h @@ -23,11 +23,11 @@ const int HAIR_CONSTRAINTS = 2; -const int DEFAULT_HAIR_STRANDS = 50; +const int DEFAULT_HAIR_STRANDS = 20; const int DEFAULT_HAIR_LINKS = 10; const float DEFAULT_HAIR_RADIUS = 0.15f; -const float DEFAULT_HAIR_LINK_LENGTH = 0.03f; -const float DEFAULT_HAIR_THICKNESS = 0.015f; +const float DEFAULT_HAIR_LINK_LENGTH = 0.04f; +const float DEFAULT_HAIR_THICKNESS = 0.025f; class Hair { public: @@ -42,6 +42,7 @@ public: void setAngularVelocity(const glm::vec3& angularVelocity) { _angularVelocity = angularVelocity; } void setAngularAcceleration(const glm::vec3& angularAcceleration) { _angularAcceleration = angularAcceleration; } void setGravity(const glm::vec3& gravity) { _gravity = gravity; } + void setLoudness(const float loudness) { _loudness = loudness; } private: int _strands; @@ -61,7 +62,7 @@ private: glm::vec3 _angularVelocity; glm::vec3 _angularAcceleration; glm::vec3 _gravity; - + float _loudness; }; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0477f6e04e..c2076397af 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -192,6 +192,7 @@ void Avatar::simulate(float deltaTime) { _hair.setAngularVelocity((getAngularVelocity() + getHead()->getAngularVelocity()) * getHead()->getFinalOrientationInWorldFrame()); _hair.setAngularAcceleration(getAngularAcceleration() * getHead()->getFinalOrientationInWorldFrame()); _hair.setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()) * getHead()->getFinalOrientationInWorldFrame()); + _hair.setLoudness((float) getHeadData()->getAudioLoudness()); _hair.simulate(deltaTime); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 36035880fd..b674254466 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -218,6 +218,7 @@ void MyAvatar::simulate(float deltaTime) { _hair.setAngularVelocity((getAngularVelocity() + getHead()->getAngularVelocity()) * getHead()->getFinalOrientationInWorldFrame()); _hair.setAngularAcceleration(getAngularAcceleration() * getHead()->getFinalOrientationInWorldFrame()); _hair.setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()) * getHead()->getFinalOrientationInWorldFrame()); + _hair.setLoudness((float)getHeadData()->getAudioLoudness()); _hair.simulate(deltaTime); } }