Hair draped for masks and driven by audio loudness

This commit is contained in:
Philip Rosedale 2014-10-10 17:06:11 -07:00
parent ad64ea62a1
commit 9be2b33971
4 changed files with 45 additions and 18 deletions

View file

@ -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();
}

View file

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

View file

@ -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);
}
}

View file

@ -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);
}
}