mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Hair draped for masks and driven by audio loudness
This commit is contained in:
parent
ad64ea62a1
commit
9be2b33971
4 changed files with 45 additions and 18 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue