mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
55e34558cb
11 changed files with 273 additions and 163 deletions
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
119
interface/src/BendyLine.cpp
Normal 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
52
interface/src/BendyLine.h
Normal 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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue