more hair tweaks, don’t render in 1P, improved toy ball

This commit is contained in:
Philip Rosedale 2014-06-25 03:29:08 -07:00
parent 95a66a06af
commit 88c01266ab
4 changed files with 50 additions and 33 deletions

View file

@ -26,14 +26,21 @@ var RIGHT_TIP = 3;
var RIGHT_BUTTON_FWD = 11;
var RIGHT_BUTTON_3 = 9;
var BALL_RADIUS = 0.08;
var GRAVITY_STRENGTH = 0.5;
var HELD_COLOR = { red: 240, green: 0, blue: 0 };
var THROWN_COLOR = { red: 128, green: 0, blue: 0 };
var leftBallAlreadyInHand = false;
var rightBallAlreadyInHand = false;
var leftHandParticle;
var rightHandParticle;
var throwSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
var newSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
var catchSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw");
var targetRadius = 0.25;
var throwSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw");
var targetRadius = 1.0;
var wantDebugging = false;
@ -54,7 +61,7 @@ function getBallHoldPosition(whichSide) {
tipPosition = Controller.getSpatialControlPosition(RIGHT_TIP);
}
var BALL_FORWARD_OFFSET = 0.08; // put the ball a bit forward of fingers
var BALL_FORWARD_OFFSET = 0.15; // put the ball a bit forward of fingers
position = { x: BALL_FORWARD_OFFSET * normal.x,
y: BALL_FORWARD_OFFSET * normal.y,
z: BALL_FORWARD_OFFSET * normal.z };
@ -69,6 +76,7 @@ function getBallHoldPosition(whichSide) {
function checkControllerSide(whichSide) {
var BUTTON_FWD;
var BUTTON_3;
var TRIGGER;
var palmPosition;
var ballAlreadyInHand;
var handMessage;
@ -76,18 +84,20 @@ function checkControllerSide(whichSide) {
if (whichSide == LEFT_PALM) {
BUTTON_FWD = LEFT_BUTTON_FWD;
BUTTON_3 = LEFT_BUTTON_3;
TRIGGER = 0;
palmPosition = Controller.getSpatialControlPosition(LEFT_PALM);
ballAlreadyInHand = leftBallAlreadyInHand;
handMessage = "LEFT";
} else {
BUTTON_FWD = RIGHT_BUTTON_FWD;
BUTTON_3 = RIGHT_BUTTON_3;
TRIGGER = 1;
palmPosition = Controller.getSpatialControlPosition(RIGHT_PALM);
ballAlreadyInHand = rightBallAlreadyInHand;
handMessage = "RIGHT";
}
var grabButtonPressed = (Controller.isButtonPressed(BUTTON_FWD) || Controller.isButtonPressed(BUTTON_3));
var grabButtonPressed = (Controller.isButtonPressed(BUTTON_FWD) || Controller.isButtonPressed(BUTTON_3) || (Controller.getTriggerValue(TRIGGER) > 0.5));
// If I don't currently have a ball in my hand, then try to catch closest one
if (!ballAlreadyInHand && grabButtonPressed) {
@ -107,8 +117,11 @@ function checkControllerSide(whichSide) {
var ballPosition = getBallHoldPosition(whichSide);
var properties = { position: { x: ballPosition.x,
y: ballPosition.y,
z: ballPosition.z },
velocity : { x: 0, y: 0, z: 0}, inHand: true };
z: ballPosition.z },
color: HELD_COLOR,
velocity : { x: 0, y: 0, z: 0},
lifetime : 600,
inHand: true };
Particles.editParticle(closestParticle, properties);
var options = new AudioInjectionOptions();
@ -127,7 +140,7 @@ function checkControllerSide(whichSide) {
//}
// If '3' is pressed, and not holding a ball, make a new one
if (Controller.isButtonPressed(BUTTON_3) && !ballAlreadyInHand) {
if (grabButtonPressed && !ballAlreadyInHand) {
var ballPosition = getBallHoldPosition(whichSide);
var properties = { position: { x: ballPosition.x,
y: ballPosition.y,
@ -135,11 +148,11 @@ function checkControllerSide(whichSide) {
velocity: { x: 0, y: 0, z: 0},
gravity: { x: 0, y: 0, z: 0},
inHand: true,
radius: 0.05,
radius: BALL_RADIUS,
damping: 0.999,
color: { red: 255, green: 0, blue: 0 },
color: HELD_COLOR,
lifetime: 10 // 10 seconds - same as default, not needed but here as an example
lifetime: 600 // 10 seconds - same as default, not needed but here as an example
};
newParticle = Particles.addParticle(properties);
@ -155,7 +168,7 @@ function checkControllerSide(whichSide) {
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
Audio.playSound(newSound, options);
return; // exit early
}
@ -188,7 +201,9 @@ function checkControllerSide(whichSide) {
y: tipVelocity.y * THROWN_VELOCITY_SCALING,
z: tipVelocity.z * THROWN_VELOCITY_SCALING } ,
inHand: false,
gravity: { x: 0, y: -2, z: 0},
color: THROWN_COLOR,
lifetime: 10,
gravity: { x: 0, y: -GRAVITY_STRENGTH, z: 0},
};
Particles.editParticle(handParticle, properties);

View file

@ -379,22 +379,22 @@ void Avatar::renderBody(RenderMode renderMode, float glowLevel) {
renderHair();
}
const float HAIR_LENGTH = 0.4f;
const float HAIR_LENGTH = 0.2f;
const float HAIR_LINK_LENGTH = HAIR_LENGTH / HAIR_LINKS;
const float HAIR_DAMPING = 0.99f;
const float HEAD_RADIUS = 0.25f;
const float HEAD_RADIUS = 0.15f;
const float COLLISION_RELAXATION = 10.f;
const float CONSTRAINT_RELAXATION = 10.0f;
const float NOISE = 0.0f; // 0.1f;
const float NOISE_MAGNITUDE = 0.02f;
const glm::vec3 HAIR_GRAVITY(0.f, -0.05f, 0.f);
const glm::vec3 HAIR_GRAVITY(0.f, -0.005f, 0.f);
const float HAIR_ACCELERATION_COUPLING = 0.025f;
const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.15f;
const float HAIR_MAX_LINEAR_ACCELERATION = 5.f;
const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.10f;
const float HAIR_MAX_LINEAR_ACCELERATION = 4.f;
const float HAIR_THICKNESS = 0.025f;
const float HAIR_STIFFNESS = 0.002f;
const glm::vec3 HAIR_COLOR1(0.98f, 0.92f, 0.843f);
const glm::vec3 HAIR_COLOR2(0.545f, 0.533f, 0.47f);
const glm::vec3 WIND_DIRECTION(1.0f, -1.0f, 0.f);
const glm::vec3 WIND_DIRECTION(0.5f, -1.0f, 0.f);
const float MAX_WIND_STRENGTH = 0.01f;
void Avatar::renderHair() {
//
@ -447,18 +447,14 @@ void Avatar::simulateHair(float deltaTime) {
acceleration = acceleration * rotation;
glm::vec3 angularVelocity = getAngularVelocity() + getHead()->getAngularVelocity();
float windIntensity = randFloat() * 0.02f;
float windIntensity = randFloat() * MAX_WIND_STRENGTH;
for (int strand = 0; strand < HAIR_STRANDS; strand++) {
for (int link = 0; link < HAIR_LINKS; link++) {
int vertexIndex = strand * HAIR_LINKS + link;
if (vertexIndex % HAIR_LINKS == 0) {
// Base Joint - no integration
if (randFloat() < NOISE) {
// Move base of hair
_hairPosition[vertexIndex] += randVector() * NOISE_MAGNITUDE;
}
} else {
} else {
//
// Vertlet Integration
//
@ -477,6 +473,10 @@ void Avatar::simulateHair(float deltaTime) {
// Add linear acceleration of the avatar body
_hairPosition[vertexIndex] -= acceleration * HAIR_ACCELERATION_COUPLING * deltaTime;
// Add stiffness (product)
_hairPosition[vertexIndex] += (_hairOriginalPosition[vertexIndex] - _hairPosition[vertexIndex])
* powf(1.f - link / HAIR_LINKS, 2.f) * HAIR_STIFFNESS;
// Add some wind
glm::vec3 wind = WIND_DIRECTION * windIntensity;
_hairPosition[vertexIndex] += wind * deltaTime;
@ -529,17 +529,17 @@ void Avatar::simulateHair(float deltaTime) {
}
void Avatar::initializeHair() {
const float FACE_WIDTH = 0.25f * PI;
const float FACE_WIDTH = PI / 4.0f;
glm::vec3 thisVertex;
for (int strand = 0; strand < HAIR_STRANDS; strand++) {
float strandAngle = randFloat() * PI;
float azimuth = randFloat() * 2.f * PI;
float elevation;
if ((azimuth > FACE_WIDTH) || (azimuth < -FACE_WIDTH)) {
float azimuth = FACE_WIDTH / 2.0f + (randFloat() * (2.0 * PI - FACE_WIDTH));
float elevation = PI_OVER_TWO - (randFloat() * 0.75 * PI);
/*if ((azimuth > FACE_WIDTH) || (azimuth < -FACE_WIDTH)) {
elevation = randFloat() * PI_OVER_TWO;
} else {
elevation = (PI_OVER_TWO / 2.f) + randFloat() * (PI_OVER_TWO / 2.f);
}
}*/
glm::vec3 thisStrand(sinf(azimuth) * cosf(elevation), sinf(elevation), -cosf(azimuth) * cosf(elevation));
thisStrand *= HEAD_RADIUS + 0.01f;
@ -562,6 +562,7 @@ void Avatar::initializeHair() {
}
_hairPosition[vertexIndex] = thisVertex;
_hairLastPosition[vertexIndex] = _hairPosition[vertexIndex];
_hairOriginalPosition[vertexIndex] = _hairPosition[vertexIndex];
_hairQuadDelta[vertexIndex] = glm::vec3(cos(strandAngle) * HAIR_THICKNESS, 0.f, sin(strandAngle) * HAIR_THICKNESS);
_hairNormals[vertexIndex] = glm::normalize(randVector());

View file

@ -201,6 +201,7 @@ protected:
virtual void updateJointMappings();
glm::vec3 _hairPosition[HAIR_STRANDS * HAIR_LINKS];
glm::vec3 _hairOriginalPosition[HAIR_STRANDS * HAIR_LINKS];
glm::vec3 _hairLastPosition[HAIR_STRANDS * HAIR_LINKS];
glm::vec3 _hairQuadDelta[HAIR_STRANDS * HAIR_LINKS];
glm::vec3 _hairNormals[HAIR_STRANDS * HAIR_LINKS];

View file

@ -833,9 +833,9 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) {
// Render head so long as the camera isn't inside it
if (shouldRenderHead(Application::getInstance()->getCamera()->getPosition(), renderMode)) {
getHead()->render(1.0f, modelRenderMode);
renderHair();
}
getHand()->render(true, modelRenderMode);
renderHair();
}
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f;