working on lookat (eye contact)

This commit is contained in:
Jeffrey Ventrella 2013-05-14 17:30:41 -07:00
parent 7117e4a76c
commit f53b49c496
7 changed files with 193 additions and 162 deletions

View file

@ -293,7 +293,9 @@ bool Avatar::getIsNearInteractingOther() {
void Avatar::simulate(float deltaTime) { void Avatar::simulate(float deltaTime) {
//figure out if the mouse cursor is over any body spheres... //figure out if the mouse cursor is over any body spheres...
checkForMouseRayTouching(); if (_isMine) {
checkForMouseRayTouching();
}
// update balls // update balls
if (_balls) { _balls->simulate(deltaTime); } if (_balls) { _balls->simulate(deltaTime); }
@ -519,6 +521,9 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
} }
if (_interactingOther) { if (_interactingOther) {
_head.setLookatPosition( _interactingOther->getSpringyHeadPosition());
_avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourBodyPosition(_interactingOther->_position);
_avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
_avatarTouch.setYourHandState (_interactingOther->_handState); _avatarTouch.setYourHandState (_interactingOther->_handState);
@ -592,115 +597,6 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
} }
} }
void Avatar::updateHead(float deltaTime) {
/*
// Decay head back to center if turned on
if (_isMine && _returnHeadToCenter) {
// Decay back toward center
_headPitch *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime);
_headYaw *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime);
_headRoll *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime);
}
// For invensense gyro, decay only slightly when roughly centered
if (_isMine) {
const float RETURN_RANGE = 15.0;
const float RETURN_STRENGTH = 2.0;
if (fabs(_headPitch) < RETURN_RANGE) { _headPitch *= (1.0f - RETURN_STRENGTH * deltaTime); }
if (fabs(_headYaw) < RETURN_RANGE) { _headYaw *= (1.0f - RETURN_STRENGTH * deltaTime); }
if (fabs(_headRoll) < RETURN_RANGE) { _headRoll *= (1.0f - RETURN_STRENGTH * deltaTime); }
}
if (_head.noise) {
// Move toward new target
_headPitch += (_head.pitchTarget - _headPitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ;
_headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime);
_headRoll *= 1.f - (DECAY * deltaTime);
}
_head.leanForward *= (1.f - DECAY * 30 * deltaTime);
_head.leanSideways *= (1.f - DECAY * 30 * deltaTime);
// Update where the avatar's eyes are
//
// First, decide if we are making eye contact or not
if (randFloat() < 0.005) {
_head.eyeContact = !_head.eyeContact;
_head.eyeContact = 1;
if (!_head.eyeContact) {
// If we just stopped making eye contact,move the eyes markedly away
_head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5) * 10;
_head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5) * 5;
} else {
// If now making eye contact, turn head to look right at viewer
SetNewHeadTarget(0,0);
}
}
const float DEGREES_BETWEEN_VIEWER_EYES = 3;
const float DEGREES_TO_VIEWER_MOUTH = 7;
if (_head.eyeContact) {
// Should we pick a new eye contact target?
if (randFloat() < 0.01) {
// Choose where to look next
if (randFloat() < 0.1) {
_head.eyeContactTarget = MOUTH;
} else {
if (randFloat() < 0.5) _head.eyeContactTarget = LEFT_EYE; else _head.eyeContactTarget = RIGHT_EYE;
}
}
// Set eyeball pitch and yaw to make contact
float eye_target_yaw_adjust = 0;
float eye_target_pitch_adjust = 0;
if (_head.eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES;
if (_head.eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES;
if (_head.eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH;
_head.eyeballPitch[0] = _head.eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust;
_head.eyeballYaw[0] = _head.eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust;
}
if (_head.noise)
{
_headPitch += (randFloat() - 0.5) * 0.2 * _head.noiseEnvelope;
_headYaw += (randFloat() - 0.5) * 0.3 *_head.noiseEnvelope;
//PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope;
if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3];
if (!_head.eyeContact) {
if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5) * 20;
if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5) * 10;
}
if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _headPitch) < 1.0) && (fabs(_head.yawTarget - _headYaw) < 1.0)) {
SetNewHeadTarget((randFloat()-0.5) * 20.0, (randFloat()-0.5) * 45.0);
}
if (0) {
// Pick new target
_head.pitchTarget = (randFloat() - 0.5) * 45;
_head.yawTarget = (randFloat() - 0.5) * 22;
}
if (randFloat() < 0.01)
{
_head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3];
_head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5];
_head.eyebrowRoll [1] *=-1;
}
}
// Update audio trailing average for rendering facial animations
const float AUDIO_AVERAGING_SECS = 0.05;
_head.averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * _head.averageLoudness +
(deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness;
*/
}
float Avatar::getHeight() { float Avatar::getHeight() {
return _height; return _height;
} }

View file

@ -195,9 +195,6 @@ private:
glm::vec3 _mouseRayDirection; glm::vec3 _mouseRayDirection;
glm::vec3 _cameraPosition; glm::vec3 _cameraPosition;
//AvatarJointID _jointTouched;
// private methods... // private methods...
void initializeSkeleton(); void initializeSkeleton();
void updateSkeleton(); void updateSkeleton();
@ -205,7 +202,6 @@ private:
void updateBodySprings( float deltaTime ); void updateBodySprings( float deltaTime );
void calculateBoneLengths(); void calculateBoneLengths();
void readSensors(); void readSensors();
void updateHead( float deltaTime );
void updateHandMovementAndTouching(float deltaTime); void updateHandMovementAndTouching(float deltaTime);
void updateAvatarCollisions(float deltaTime); void updateAvatarCollisions(float deltaTime);
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ); void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );

View file

@ -7,6 +7,7 @@
// //
#include "Head.h" #include "Head.h"
#include "Util.h"
#include <vector> #include <vector>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <lodepng.h> #include <lodepng.h>
@ -15,6 +16,8 @@ using namespace std;
const float HEAD_MOTION_DECAY = 0.1; const float HEAD_MOTION_DECAY = 0.1;
const bool TESTING_LOOKAT = false;
float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0};
float _mouthColor[] = {1, 0, 0}; float _mouthColor[] = {1, 0, 0};
@ -49,6 +52,7 @@ void Head::initialize() {
audioLoudness = 0.0; audioLoudness = 0.0;
skinColor = glm::vec3(0.0f, 0.0f, 0.0f); skinColor = glm::vec3(0.0f, 0.0f, 0.0f);
position = glm::vec3(0.0f, 0.0f, 0.0f); position = glm::vec3(0.0f, 0.0f, 0.0f);
lookatPosition = glm::vec3(0.0f, 0.0f, 0.0f);
yaw = 0.0f; yaw = 0.0f;
pitch = 0.0f; pitch = 0.0f;
roll = 0.0f; roll = 0.0f;
@ -219,11 +223,21 @@ void Head::simulate(float deltaTime, bool isMine) {
const float AUDIO_AVERAGING_SECS = 0.05; const float AUDIO_AVERAGING_SECS = 0.05;
averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * averageLoudness + averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * averageLoudness +
(deltaTime / AUDIO_AVERAGING_SECS) * audioLoudness; (deltaTime / AUDIO_AVERAGING_SECS) * audioLoudness;
} }
void Head::setLookatPosition(glm::vec3 l) {
lookatPosition = l;
}
void Head::render(bool lookingInMirror, float bodyYaw) { void Head::render(bool lookingInMirror, float bodyYaw) {
//float a = angleBetween( &position, &position);
int side = 0; int side = 0;
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@ -236,11 +250,11 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
glScalef(scale, scale, scale); glScalef(scale, scale, scale);
if (lookingInMirror) { if (lookingInMirror) {
glRotatef(bodyYaw - yaw, 0, 1, 0); glRotatef(bodyYaw - yaw, 0, 1, 0);
glRotatef(pitch, 1, 0, 0); glRotatef(pitch, 1, 0, 0);
glRotatef(-roll, 0, 0, 1); glRotatef(-roll, 0, 0, 1);
} else { } else {
glRotatef(bodyYaw + yaw, 0, 1, 0); glRotatef(bodyYaw + yaw, 0, 1, 0);
glRotatef(pitch, 1, 0, 0); glRotatef(pitch, 1, 0, 0);
glRotatef(roll, 0, 0, 1); glRotatef(roll, 0, 0, 1);
} }
@ -290,24 +304,37 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
// Mouth // Mouth
glPushMatrix(); glPushMatrix();
glTranslatef(0,-0.35,0.75); glTranslatef(0,-0.35,0.75);
glColor3f(0,0,0); glColor3f(0,0,0);
glRotatef(mouthPitch, 1, 0, 0); glRotatef(mouthPitch, 1, 0, 0);
glRotatef(mouthYaw, 0, 0, 1); glRotatef(mouthYaw, 0, 0, 1);
if (averageLoudness > 1.f) { if (averageLoudness > 1.f) {
glScalef(mouthWidth * (.7f + sqrt(averageLoudness) /60.f), glScalef(mouthWidth * (.7f + sqrt(averageLoudness) /60.f),
mouthHeight * (1.f + sqrt(averageLoudness) /30.f), 1); mouthHeight * (1.f + sqrt(averageLoudness) /30.f), 1);
} else { } else {
glScalef(mouthWidth, mouthHeight, 1); glScalef(mouthWidth, mouthHeight, 1);
} }
glutSolidCube(0.5); glutSolidCube(0.5);
glPopMatrix(); glPopMatrix();
glTranslatef(0, 1.0, 0); renderEyeBalls();
glPopMatrix();
if (TESTING_LOOKAT) {
//the irises are special - they have the ability to look at specific targets in the world (code still not finished yet)
renderIrises(bodyYaw + yaw);
}
}
void Head::renderEyeBalls() {
glTranslatef(0, 1.0, 0);
glTranslatef(-interPupilDistance/2.0,-0.68,0.7); glTranslatef(-interPupilDistance/2.0,-0.68,0.7);
// Right Eye // Right Eye
@ -322,30 +349,33 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
} }
glPopMatrix(); glPopMatrix();
// Right Pupil if (!TESTING_LOOKAT) {
if (sphere == NULL) { // Right Pupil
sphere = gluNewQuadric(); if (sphere == NULL) {
gluQuadricTexture(sphere, GL_TRUE); sphere = gluNewQuadric();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gluQuadricTexture(sphere, GL_TRUE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gluQuadricOrientation(sphere, GLU_OUTSIDE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]); gluQuadricOrientation(sphere, GLU_OUTSIDE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]);
}
glPushMatrix();
{
glRotatef(eyeballPitch[1], 1, 0, 0);
glRotatef(eyeballYaw[1] + yaw + pupilConverge, 0, 1, 0);
glTranslatef(0,0,.35);
glRotatef(-75,1,0,0);
glScalef(1.0, 0.4, 1.0);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, pupilSize, 15, 15);
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
} }
glPushMatrix();
{
glRotatef(eyeballPitch[1], 1, 0, 0);
glRotatef(eyeballYaw[1] + yaw + pupilConverge, 0, 1, 0);
glTranslatef(0,0,.35);
glRotatef(-75,1,0,0);
glScalef(1.0, 0.4, 1.0);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, pupilSize, 15, 15);
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
// Left Eye // Left Eye
glColor3fv(_eyeColor); glColor3fv(_eyeColor);
glTranslatef(interPupilDistance, 0, 0); glTranslatef(interPupilDistance, 0, 0);
@ -357,21 +387,111 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
glutSolidSphere(0.25, 30, 30); glutSolidSphere(0.25, 30, 30);
} }
glPopMatrix(); glPopMatrix();
// Left Pupil
if (!TESTING_LOOKAT) {
// Left Pupil
glPushMatrix();
{
glRotatef(eyeballPitch[0], 1, 0, 0);
glRotatef(eyeballYaw[0] + yaw - pupilConverge, 0, 1, 0);
glTranslatef(0, 0, .35);
glRotatef(-75, 1, 0, 0);
glScalef(1.0, 0.4, 1.0);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, pupilSize, 15, 15);
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
}
}
//---------------------------------------------------------
// the code below is still in the prototyping stages....
//---------------------------------------------------------
void Head::renderIrises(float yaw) {
Orientation orientation;
orientation.setToPitchYawRoll( pitch, yaw, roll);
// Render lines originating from the eyes and converging on the lookatPosition
float rightShift = scale * 0.22f;
float upShift = scale * 0.38f;
float frontShift = scale * 0.9f;
glm::vec3 leftEyePosition = position + orientation.getRight() * rightShift
+ orientation.getUp () * upShift
+ orientation.getFront() * frontShift;
glm::vec3 rightEyePosition = position - orientation.getRight() * rightShift
+ orientation.getUp () * upShift
+ orientation.getFront() * frontShift;
debugRenderLookatVectors(leftEyePosition, rightEyePosition, lookatPosition);
glColor3fv(_eyeColor);
if (sphere == NULL) {
sphere = gluNewQuadric();
gluQuadricTexture(sphere, GL_TRUE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluQuadricOrientation(sphere, GLU_OUTSIDE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]);
}
//render left iris
glPushMatrix(); glPushMatrix();
{ {
glRotatef(eyeballPitch[0], 1, 0, 0); glTranslatef(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z);
glRotatef(eyeballYaw[0] + yaw - pupilConverge, 0, 1, 0); glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - leftEyePosition);
glTranslatef(0, 0, .35);
glRotatef(-75, 1, 0, 0);
glScalef(1.0, 0.4, 1.0);
glEnable(GL_TEXTURE_2D); glPushMatrix();
gluSphere(sphere, pupilSize, 15, 15); glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight());
glDisable(GL_TEXTURE_2D); glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp());
glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z);
glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, 0.01, 15, 15);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
} }
glPopMatrix(); glPopMatrix();
//render right iris
glPushMatrix();
{
glTranslatef(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z);
glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - rightEyePosition);
glPushMatrix();
glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight());
glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp());
glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z);
glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, 0.01, 15, 15);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
glPopMatrix(); glPopMatrix();
} }
void Head::debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
glColor3f(0.0f, 0.0f, 0.0f);
glLineWidth(3.0);
glBegin(GL_LINE_STRIP);
glVertex3f(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z);
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z);
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
glEnd();
}

View file

@ -15,6 +15,7 @@
#include "world.h" #include "world.h"
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include "SerialInterface.h" #include "SerialInterface.h"
#include "Orientation.h"
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
@ -30,6 +31,7 @@ public:
void render(bool lookingInMirror, float bodyYaw); void render(bool lookingInMirror, float bodyYaw);
void setNewTarget(float, float); void setNewTarget(float, float);
void setSpringScale(float s) { returnSpringScale = s; } void setSpringScale(float s) { returnSpringScale = s; }
void setLookatPosition(glm::vec3 lookatPosition);
// Do you want head to try to return to center (depends on interface detected) // Do you want head to try to return to center (depends on interface detected)
void setReturnToCenter(bool r) { returnHeadToCenter = r; } void setReturnToCenter(bool r) { returnHeadToCenter = r; }
@ -43,6 +45,7 @@ public:
glm::vec3 skinColor; glm::vec3 skinColor;
glm::vec3 position; glm::vec3 position;
glm::vec3 rotation; glm::vec3 rotation;
glm::vec3 lookatPosition;
float yaw; float yaw;
float pitch; float pitch;
float roll; float roll;
@ -85,6 +88,12 @@ public:
// Strength of return springs // Strength of return springs
float returnSpringScale; float returnSpringScale;
private:
void renderEyeBalls();
void renderIrises(float yaw);
void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
}; };
#endif #endif

View file

@ -1059,6 +1059,7 @@ void display(void)
myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -myAvatar.getHeadPitch(), myAvatar.getHeadRoll()); myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -myAvatar.getHeadPitch(), myAvatar.getHeadRoll());
} else if (myCamera.getMode() == CAMERA_MODE_MIRROR) { } else if (myCamera.getMode() == CAMERA_MODE_MIRROR) {
myCamera.setTightness (100.0f);
myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition()); myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition());
myCamera.setTargetRotation(myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f); myCamera.setTargetRotation(myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f);
@ -1086,7 +1087,6 @@ void display(void)
glPopMatrix(); glPopMatrix();
*/ */
// Note: whichCamera is used to pick between the normal camera myCamera for our // Note: whichCamera is used to pick between the normal camera myCamera for our
// main camera, vs, an alternate camera. The alternate camera we support right now // main camera, vs, an alternate camera. The alternate camera we support right now
// is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism // is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism

View file

@ -25,6 +25,15 @@ void Orientation::setToIdentity() {
front = glm::vec3(IDENTITY_FRONT); front = glm::vec3(IDENTITY_FRONT);
} }
void Orientation::setToPitchYawRoll(float p, float y, float r) {
setToIdentity();
pitch(p);
yaw (y);
roll (r);
}
void Orientation::set(Orientation o) { void Orientation::set(Orientation o) {
quat = o.quat; quat = o.quat;

View file

@ -22,6 +22,7 @@ public:
Orientation(); Orientation();
void set(Orientation); void set(Orientation);
void setToPitchYawRoll(float p, float y, float r);
void setToIdentity(); void setToIdentity();
void pitch(float p); void pitch(float p);