Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Hifi Test Account 2013-08-07 12:08:43 -07:00
commit edf4579d0e
11 changed files with 270 additions and 156 deletions

View file

@ -36,6 +36,7 @@ bool includeBorderTracer = true;
bool includeMovingBug = true;
bool includeBlinkingVoxel = false;
bool includeDanceFloor = true;
bool buildStreet = false;
const int ANIMATION_LISTEN_PORT = 40107;
@ -616,6 +617,61 @@ static void sendBillboard() {
}
}
bool roadInitialized = false;
const int ROAD_WIDTH_METERS = 3.0f;
const int BRICKS_ACROSS_ROAD = 32;
const float ROAD_BRICK_SIZE = 0.125f/TREE_SCALE; //(ROAD_WIDTH_METERS / TREE_SCALE) / BRICKS_ACROSS_ROAD; // in voxel units
const int ROAD_LENGTH = 1.0f / ROAD_BRICK_SIZE; // in bricks
const int ROAD_WIDTH = BRICKS_ACROSS_ROAD; // in bricks
glm::vec3 roadPosition(0.5f - (ROAD_BRICK_SIZE * BRICKS_ACROSS_ROAD), 0.0f, 0.0f);
const int BRICKS_PER_PACKET = 32; // guessing
const int PACKETS_PER_ROAD = VOXELS_PER_PACKET / (ROAD_LENGTH * ROAD_WIDTH);
void doBuildStreet() {
if (roadInitialized) {
return;
}
PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully!
static VoxelDetail details[BRICKS_PER_PACKET];
unsigned char* bufferOut;
int sizeOut;
for (int z = 0; z < ROAD_LENGTH; z++) {
for (int x = 0; x < ROAD_WIDTH; x++) {
int nthVoxel = ((z * ROAD_WIDTH) + x);
int item = nthVoxel % BRICKS_PER_PACKET;
glm::vec3 brick = roadPosition + glm::vec3(x * ROAD_BRICK_SIZE, 0, z * ROAD_BRICK_SIZE);
details[item].s = ROAD_BRICK_SIZE;
details[item].x = brick.x;
details[item].y = brick.y;
details[item].z = brick.z;
unsigned char randomTone = randIntInRange(118,138);
details[item].red = randomTone;
details[item].green = randomTone;
details[item].blue = randomTone;
if (item == BRICKS_PER_PACKET - 1) {
if (createVoxelEditMessage(message, 0, BRICKS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){
::packetsSent++;
::bytesSent += sizeOut;
if (true || ::shouldShowPacketsPerSecond) {
printf("building road sending packet of size=%d\n", sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
}
}
}
roadInitialized = true;
}
double start = 0;
@ -645,6 +701,10 @@ void* animateVoxels(void* args) {
sendDanceFloor();
}
if (::buildStreet) {
doBuildStreet();
}
uint64_t end = usecTimestampNow();
uint64_t elapsedSeconds = (end - ::start) / 1000000;
if (::shouldShowPacketsPerSecond) {
@ -688,6 +748,9 @@ int main(int argc, const char * argv[])
const char* NO_DANCE_FLOOR = "--NoDanceFloor";
::includeDanceFloor = !cmdOptionExists(argc, argv, NO_DANCE_FLOOR);
const char* BUILD_STREET = "--BuildStreet";
::buildStreet = cmdOptionExists(argc, argv, BUILD_STREET);
// Handle Local Domain testing with the --local command line
const char* showPPS = "--showPPS";
::shouldShowPacketsPerSecond = cmdOptionExists(argc, argv, showPPS);
@ -700,6 +763,11 @@ int main(int argc, const char * argv[])
nodeList->setDomainIPToLocalhost();
}
const char* domainIP = getCmdOption(argc, argv, "--domain");
if (domainIP) {
NodeList::getInstance()->setDomainIP(domainIP);
}
nodeList->linkedDataCreateCallback = NULL; // do we need a callback?
nodeList->startSilentNodeRemovalThread();

View file

@ -77,8 +77,10 @@ static char STAR_CACHE_FILE[] = "cachedStars.txt";
static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored
const glm::vec3 START_LOCATION(4.f, 0.f, 5.f); // Where one's own node begins in the world
// (will be overwritten if avatar data file is found)
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found)
// this is basically in the center of the ground plane. Slightly adjusted. This was asked for by
// Grayson as he's building a street around here for demo dinner 2
const glm::vec3 START_LOCATION(0.485f * TREE_SCALE, 0.f, 0.5f * TREE_SCALE);
const int IDLE_SIMULATE_MSECS = 16; // How often should call simulate and other stuff
// in the idle loop? (60 FPS is default)
@ -2327,13 +2329,13 @@ void Application::renderFollowIndicator() {
if (leader != NULL) {
glColor3f(1.f, 0.f, 0.f);
glVertex3f(avatar->getPosition().x,
avatar->getPosition().y,
avatar->getPosition().z);
glVertex3f((avatar->getHead().getPosition().x + avatar->getPosition().x) / 2.f,
(avatar->getHead().getPosition().y + avatar->getPosition().y) / 2.f,
(avatar->getHead().getPosition().z + avatar->getPosition().z) / 2.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(leader->getPosition().x,
leader->getPosition().y,
leader->getPosition().z);
glVertex3f((leader->getHead().getPosition().x + leader->getPosition().x) / 2.f,
(leader->getHead().getPosition().y + leader->getPosition().y) / 2.f,
(leader->getHead().getPosition().z + leader->getPosition().z) / 2.f);
}
}
}
@ -2341,13 +2343,13 @@ void Application::renderFollowIndicator() {
if (_myAvatar.getLeadingAvatar() != NULL) {
glColor3f(1.f, 0.f, 0.f);
glVertex3f(_myAvatar.getPosition().x,
_myAvatar.getPosition().y,
_myAvatar.getPosition().z);
glVertex3f((_myAvatar.getHead().getPosition().x + _myAvatar.getPosition().x) / 2.f,
(_myAvatar.getHead().getPosition().y + _myAvatar.getPosition().y) / 2.f,
(_myAvatar.getHead().getPosition().z + _myAvatar.getPosition().z) / 2.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(_myAvatar.getLeadingAvatar()->getPosition().x,
_myAvatar.getLeadingAvatar()->getPosition().y,
_myAvatar.getLeadingAvatar()->getPosition().z);
glVertex3f((_myAvatar.getLeadingAvatar()->getHead().getPosition().x + _myAvatar.getLeadingAvatar()->getPosition().x) / 2.f,
(_myAvatar.getLeadingAvatar()->getHead().getPosition().y + _myAvatar.getLeadingAvatar()->getPosition().y) / 2.f,
(_myAvatar.getLeadingAvatar()->getHead().getPosition().z + _myAvatar.getLeadingAvatar()->getPosition().z) / 2.f);
}
glEnd();
@ -2538,7 +2540,7 @@ void Application::update(float deltaTime) {
}
// Leap finger-sensing device
LeapManager::enableFakeFingers(_simulateLeapHand->isChecked() || _testRaveGlove->isChecked());
LeapManager::enableFakeFingers(_simulateLeapHand->isChecked());
_myAvatar.getHand().setRaveGloveActive(_testRaveGlove->isChecked());
LeapManager::nextFrame(_myAvatar);
@ -2741,7 +2743,7 @@ void Application::updateAvatar(float deltaTime) {
// If I'm in paint mode, send a voxel out to VOXEL server nodes.
if (_paintOn) {
glm::vec3 avatarPos = _myAvatar.getPosition();
// For some reason, we don't want to flip X and Z here.
@ -2752,7 +2754,7 @@ void Application::updateAvatar(float deltaTime) {
if (_paintingVoxel.x >= 0.0 && _paintingVoxel.x <= 1.0 &&
_paintingVoxel.y >= 0.0 && _paintingVoxel.y <= 1.0 &&
_paintingVoxel.z >= 0.0 && _paintingVoxel.z <= 1.0) {
PACKET_TYPE message = (_destructiveAddVoxel->isChecked() ?
PACKET_TYPE_SET_VOXEL_DESTRUCTIVE : PACKET_TYPE_SET_VOXEL);
sendVoxelEditMessage(message, _paintingVoxel);
@ -3052,7 +3054,7 @@ void Application::displaySide(Camera& whichCamera) {
glDisable(GL_FOG);
glDisable(GL_NORMALIZE);
renderGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE, _audio.getCollisionSoundMagnitude());
//renderGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE, _audio.getCollisionSoundMagnitude());
}
// Draw voxels
if (_renderVoxels->isChecked()) {
@ -3106,14 +3108,16 @@ void Application::displaySide(Camera& whichCamera) {
}
// Render my own Avatar
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_myAvatar.getHead().setLookAtPosition(_myCamera.getPosition());
}
_myAvatar.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked());
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_myAvatar.getHead().setLookAtPosition(_myCamera.getPosition());
}
_myAvatar.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked());
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
if (_renderLookatIndicatorOn->isChecked() && _isLookingAtOtherAvatar) {
renderLookatIndicator(_lookatOtherPosition, whichCamera);
if (_renderLookatIndicatorOn->isChecked() && _isLookingAtOtherAvatar) {
renderLookatIndicator(_lookatOtherPosition, whichCamera);
}
}
}
@ -3960,24 +3964,27 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
uint16_t nodeID = voxelServer->getNodeID();
VoxelPositionSize jurisditionDetails;
voxelDetailsForCode(_voxelSceneStats.getJurisdictionRoot(), jurisditionDetails);
// see if this is the first we've heard of this node...
if (_voxelServerJurisdictions.find(nodeID) == _voxelServerJurisdictions.end()) {
printf("stats from new voxel server... v[%f, %f, %f, %f]\n",
jurisditionDetails.x, jurisditionDetails.y, jurisditionDetails.z, jurisditionDetails.s);
// quick fix for crash... why would voxelServer be NULL?
if (voxelServer) {
uint16_t nodeID = voxelServer->getNodeID();
// Add the jurisditionDetails object to the list of "fade outs"
VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
fade.voxelDetails = jurisditionDetails;
_voxelFades.push_back(fade);
VoxelPositionSize jurisditionDetails;
voxelDetailsForCode(_voxelSceneStats.getJurisdictionRoot(), jurisditionDetails);
// see if this is the first we've heard of this node...
if (_voxelServerJurisdictions.find(nodeID) == _voxelServerJurisdictions.end()) {
printf("stats from new voxel server... v[%f, %f, %f, %f]\n",
jurisditionDetails.x, jurisditionDetails.y, jurisditionDetails.z, jurisditionDetails.s);
// Add the jurisditionDetails object to the list of "fade outs"
VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
fade.voxelDetails = jurisditionDetails;
_voxelFades.push_back(fade);
}
// store jurisdiction details for later use
_voxelServerJurisdictions[nodeID] = jurisditionDetails;
}
// store jurisdiction details for later use
_voxelServerJurisdictions[nodeID] = jurisditionDetails;
return statsMessageLength;
}
@ -4061,9 +4068,11 @@ void* Application::networkReceive(void* args) {
break;
case PACKET_TYPE_AVATAR_VOXEL_URL:
processAvatarVoxelURLMessage(app->_incomingPacket, bytesReceived);
getInstance()->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
break;
case PACKET_TYPE_AVATAR_FACE_VIDEO:
processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived);
getInstance()->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
break;
default:
NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived);

View file

@ -24,7 +24,7 @@ BendyLine::BendyLine(){
_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);
_baseDirection = glm::vec3(0.0f, 1.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);

View file

@ -159,14 +159,17 @@ const float METERS_PER_MM = 1.0f / 1000.0f;
void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float midFaceDepth,
float aspectRatio, const RotatedRect& faceRect, bool sending, const JointVector& joints) {
if (!_enabled) {
return; // was queued before we shut down; ignore
}
if (!color.empty()) {
IplImage colorImage = color;
glPixelStorei(GL_UNPACK_ROW_LENGTH, colorImage.widthStep / 3);
if (_colorTextureID == 0) {
glGenTextures(1, &_colorTextureID);
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _textureSize.width = colorImage.width, _textureSize.height = colorImage.height,
0, format, GL_UNSIGNED_BYTE, colorImage.imageData);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _textureSize.width = colorImage.width,
_textureSize.height = colorImage.height, 0, format, GL_UNSIGNED_BYTE, colorImage.imageData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else {
@ -192,8 +195,8 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float midF
} else {
glBindTexture(GL_TEXTURE_2D, _depthTextureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _textureSize.width, _textureSize.height, GL_LUMINANCE,
GL_UNSIGNED_BYTE, depthImage.imageData);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _textureSize.width = depthImage.width,
_textureSize.height = depthImage.height, GL_LUMINANCE, GL_UNSIGNED_BYTE, depthImage.imageData);
}
} else if (_depthTextureID != 0) {
glDeleteTextures(1, &_depthTextureID);
@ -406,6 +409,10 @@ void FrameGrabber::shutdown() {
destroyCodecs();
_initialized = false;
// send an empty video message to indicate that we're no longer sending
QMetaObject::invokeMethod(Application::getInstance(), "sendAvatarFaceVideoMessage",
Q_ARG(int, ++_frameCount), Q_ARG(QByteArray, QByteArray()));
thread()->quit();
}

View file

@ -308,6 +308,7 @@ void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
} else {
_head.setPitch(pitchFromTouch);
_head.getFace().clearFrame();
return;
}
if (webcam->isActive()) {
@ -913,12 +914,17 @@ void Avatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMovem
}
// If there's a leap-interaction hand visible, use that as the endpoint
if (!getHand().isRaveGloveActive()) {
for (size_t i = 0; i < getHand().getPalms().size(); ++i) {
PalmData& palm = getHand().getPalms()[i];
if (palm.isActive()) {
glm::vec3 rightMostHand;
bool anyHandsFound = false;
for (size_t i = 0; i < getHand().getPalms().size(); ++i) {
PalmData& palm = getHand().getPalms()[i];
if (palm.isActive()) {
if (!anyHandsFound
|| palm.getRawPosition().x > rightMostHand.x) {
_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = palm.getPosition();
rightMostHand = palm.getRawPosition();
}
anyHandsFound = true;
}
}
}//if (_isMine)
@ -1159,12 +1165,33 @@ void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) {
glPopMatrix();
}
if (Application::getInstance()->getAvatar()->getHand().isRaveGloveActive()) {
_hand.setRaveLights(RAVE_LIGHTS_AVATAR);
}
// render a simple round on the ground projected down from the avatar's position
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), _scale * 0.1f, 0.2f);
// render body
renderBody(lookingInMirror, renderAvatarBalls);
// render sphere when far away
if (!isMyAvatar()) {
const float MAX_ANGLE = 10.f;
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
glm::vec3 delta = _height * (_head.getCameraOrientation() * IDENTITY_UP) / 2.f;
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
if (angle < MAX_ANGLE) {
glColor4f(0.5f, 0.8f, 0.8f, 1.f - angle / MAX_ANGLE);
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z);
glScalef(_height / 2.f, _height / 2.f, _height / 2.f);
glutSolidSphere(1.2f + _head.getAverageLoudness() * .0005f, 20, 20);
glPopMatrix();
}
}
// if this is my avatar, then render my interactions with the other avatar
if (isMyAvatar()) {
_avatarTouch.render(Application::getInstance()->getCamera()->getPosition());
@ -1225,16 +1252,6 @@ void Avatar::renderScreenTint(ScreenTintLayer layer, Camera& whichCamera) {
if (layer == SCREEN_TINT_BEFORE_AVATARS) {
if (_hand.isRaveGloveActive()) {
_hand.renderRaveGloveStage();
// Set some mood lighting
GLfloat ambient_color[] = { 0.0, 0.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
GLfloat diffuse_color[] = { 0.4, 0.0, 0.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
GLfloat specular_color[] = { 0.0, 0.0, 0.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
glMateriali(GL_FRONT, GL_SHININESS, 0);
}
}
else if (layer == SCREEN_TINT_BEFORE_AVATARS) {
@ -1410,13 +1427,9 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
float alpha = getBallRenderAlpha(b, lookingInMirror);
// When in rave glove mode, don't show the arms at all.
if (_hand.isRaveGloveActive()) {
if (b == BODY_BALL_LEFT_ELBOW
|| b == BODY_BALL_LEFT_WRIST
|| b == BODY_BALL_LEFT_FINGERTIPS
|| b == BODY_BALL_RIGHT_ELBOW
|| b == BODY_BALL_RIGHT_WRIST
// When we have leap hands, hide part of the arms.
if (_hand.getNumPalms() > 0) {
if (b == BODY_BALL_LEFT_FINGERTIPS
|| b == BODY_BALL_RIGHT_FINGERTIPS) {
continue;
}

View file

@ -78,7 +78,7 @@ void Hand::calculateGeometry() {
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
FingerData& finger = palm.getFingers()[f];
if (finger.isActive()) {
const float standardBallRadius = 0.01f;
const float standardBallRadius = 0.005f;
_leapFingerTipBalls.resize(_leapFingerTipBalls.size() + 1);
HandBall& ball = _leapFingerTipBalls.back();
ball.rotation = _baseOrientation;
@ -99,7 +99,7 @@ void Hand::calculateGeometry() {
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
FingerData& finger = palm.getFingers()[f];
if (finger.isActive()) {
const float standardBallRadius = 0.01f;
const float standardBallRadius = 0.005f;
_leapFingerRootBalls.resize(_leapFingerRootBalls.size() + 1);
HandBall& ball = _leapFingerRootBalls.back();
ball.rotation = _baseOrientation;
@ -139,12 +139,23 @@ void Hand::render(bool lookingInMirror) {
calculateGeometry();
if (_isRaveGloveActive) {
// Disable raveGloveStage while we work on the network glove features
// renderRaveGloveStage();
if ( SHOW_LEAP_HAND ) {
if (!isRaveGloveActive()) {
renderLeapFingerTrails();
}
if (isRaveGloveActive()) {
// Use mood lighting for the hand itself
setRaveLights(RAVE_LIGHTS_AVATAR);
}
renderLeapHands();
}
if (_isRaveGloveActive) {
if (_raveGloveInitialized) {
updateRaveGloveEmitters(); // do this after calculateGeometry
// Use normal lighting for the particles
setRaveLights(RAVE_LIGHTS_PARTICLES);
_raveGloveParticleSystem.render();
}
}
@ -152,86 +163,78 @@ void Hand::render(bool lookingInMirror) {
glEnable(GL_DEPTH_TEST);
glEnable(GL_RESCALE_NORMAL);
if ( SHOW_LEAP_HAND ) {
//renderLeapHands();
if (!isRaveGloveActive()) {
renderLeapFingerTrails();
renderLeapHandSpheres();
}
}
void Hand::setRaveLights(RaveLightsSetting setting) {
if (setting == RAVE_LIGHTS_AVATAR) {
// Set some mood lighting
GLfloat ambient_color[] = { 0.0, 0.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
GLfloat diffuse_color[] = { 0.4, 0.0, 0.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
GLfloat specular_color[] = { 0.0, 0.0, 0.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
glMateriali(GL_FRONT, GL_SHININESS, 0);
}
else if (setting == RAVE_LIGHTS_PARTICLES) {
// particles use a brighter light setting
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
glMateriali(GL_FRONT, GL_SHININESS, 96);
}
}
void Hand::renderRaveGloveStage() {
if (_owningAvatar && _owningAvatar->isMyAvatar()) {
Head& head = _owningAvatar->getHead();
glm::quat headOrientation = head.getOrientation();
glm::vec3 headPosition = head.getPosition();
float scale = 100.0f;
glm::vec3 vc = headOrientation * glm::vec3( 0.0f, 0.0f, -30.0f) + headPosition;
glm::vec3 v0 = headOrientation * (glm::vec3(-1.0f, -1.0f, 0.0f) * scale) + vc;
glm::vec3 v1 = headOrientation * (glm::vec3( 1.0f, -1.0f, 0.0f) * scale) + vc;
glm::vec3 v2 = headOrientation * (glm::vec3( 1.0f, 1.0f, 0.0f) * scale) + vc;
glm::vec3 v3 = headOrientation * (glm::vec3(-1.0f, 1.0f, 0.0f) * scale) + vc;
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBegin(GL_TRIANGLE_FAN);
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glVertex3fv((float*)&vc);
glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
glVertex3fv((float*)&v0);
glVertex3fv((float*)&v1);
glVertex3fv((float*)&v2);
glVertex3fv((float*)&v3);
glVertex3fv((float*)&v0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
}
}
void Hand::renderLeapHands() {
for (size_t i = 0; i < getNumPalms(); ++i) {
PalmData& hand = getPalms()[i];
if (hand.isActive()) {
renderLeapHand(hand);
}
}
}
void Hand::renderLeapHand(PalmData& hand) {
// Draw a simple fullscreen triangle fan, darkest in the center.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
const float palmThickness = 0.002f;
glColor4f(0.5f, 0.5f, 0.5f, 1.0);
glm::vec3 tip = hand.getPosition();
glm::vec3 root = hand.getPosition() + hand.getNormal() * palmThickness;
Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03);
for (size_t f = 0; f < hand.getNumFingers(); ++f) {
FingerData& finger = hand.getFingers()[f];
if (finger.isActive()) {
glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.5);
glm::vec3 tip = finger.getTipPosition();
glm::vec3 root = finger.getRootPosition();
Avatar::renderJointConnectingCone(root, tip, 0.001, 0.003);
}
}
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBegin(GL_TRIANGLE_FAN);
// Dark center vertex
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
// Lighter outer vertices
glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void Hand::renderLeapHands() {
void Hand::renderLeapHandSpheres() {
const float alpha = 1.0f;
//const glm::vec3 handColor = _ballColor;
const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color
glPushMatrix();
// Draw the leap balls
for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) {
float alpha = 1.0f;
if (alpha > 0.0f) {
glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, alpha);
glColor4f(handColor.r, handColor.g, handColor.b, alpha);
glPushMatrix();
glTranslatef(_leapFingerTipBalls[i].position.x, _leapFingerTipBalls[i].position.y, _leapFingerTipBalls[i].position.z);
@ -247,7 +250,7 @@ void Hand::renderLeapHandSpheres() {
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
FingerData& finger = palm.getFingers()[f];
if (finger.isActive()) {
glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.5);
glColor4f(handColor.r, handColor.g, handColor.b, 0.5);
glm::vec3 tip = finger.getTipPosition();
glm::vec3 root = finger.getRootPosition();
Avatar::renderJointConnectingCone(root, tip, 0.001, 0.003);
@ -261,7 +264,7 @@ void Hand::renderLeapHandSpheres() {
PalmData& palm = getPalms()[i];
if (palm.isActive()) {
const float palmThickness = 0.002f;
glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, 0.25);
glColor4f(handColor.r, handColor.g, handColor.b, 0.25);
glm::vec3 tip = palm.getPosition();
glm::vec3 root = palm.getPosition() + palm.getNormal() * palmThickness;
Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03);

View file

@ -20,6 +20,11 @@
#include <SharedUtil.h>
#include <vector>
enum RaveLightsSetting {
RAVE_LIGHTS_AVATAR = 0,
RAVE_LIGHTS_PARTICLES
};
class Avatar;
class ProgramObject;
@ -42,6 +47,7 @@ public:
void simulate(float deltaTime, bool isMine);
void render(bool lookingInMirror);
void renderRaveGloveStage();
void setRaveLights(RaveLightsSetting setting);
void setBallColor (glm::vec3 ballColor ) { _ballColor = ballColor; }
void updateRaveGloveParticles(float deltaTime);
@ -75,9 +81,7 @@ private:
void activateNewRaveGloveMode();
void renderLeapHandSpheres();
void renderLeapHands();
void renderLeapHand(PalmData& hand);
void renderLeapFingerTrails();
void calculateGeometry();
};

View file

@ -30,10 +30,12 @@ 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 = 7.0f;
const float HAIR_TORQUE_FORCE = 0.1f;
const float HAIR_GRAVITY_FORCE = 0.02f;
const float HAIR_SPRING_FORCE = 15.0f;
const float HAIR_TORQUE_FORCE = 0.2f;
const float HAIR_GRAVITY_FORCE = 0.001f;
const float HAIR_DRAG = 10.0f;
const float HAIR_LENGTH = 0.09f;
const float HAIR_THICKNESS = 0.03f;
const float NOSE_LENGTH = 0.025;
@ -75,7 +77,7 @@ Head::Head(Avatar* owningAvatar) :
_bodyRotation(0.0f, 0.0f, 0.0f),
_renderLookatVectors(false),
_mohawkTriangleFan(NULL),
_mohawkColors(NULL),
_mohawkColors(NULL),
_saccade(0.0f, 0.0f, 0.0f),
_saccadeTarget(0.0f, 0.0f, 0.0f),
_leftEyeBlink(0.0f),
@ -129,7 +131,6 @@ void Head::reset() {
}
void Head::resetHairPhysics() {
//glm::vec3 up = getUpDirection();
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
@ -333,10 +334,17 @@ void Head::setScale (float scale) {
delete[] _mohawkTriangleFan;
delete[] _mohawkColors;
createMohawk();
if (USING_PHYSICAL_MOHAWK) {
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
resetHairPhysics();
_hairTuft[t].setLength (_scale * HAIR_LENGTH );
_hairTuft[t].setThickness(_scale * HAIR_THICKNESS);
}
}
}
void Head::createMohawk() {
uint16_t nodeId = UNKNOWN_NODE_ID;
if (_owningAvatar->getOwningNode()) {
@ -724,19 +732,21 @@ void Head::renderEyeBalls() {
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
glColor3f(0.0f, 0.0f, 0.0f);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
glBegin(GL_LINES);
glColor4f(0.2f, 0.2f, 0.2f, 1.f);
glVertex3f(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z);
glColor4f(1.0f, 1.0f, 1.0f, 0.f);
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
glEnd();
glBegin(GL_LINE_STRIP);
glColor4f(0.2f, 0.2f, 0.2f, 1.f);
glVertex3f(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z);
glColor4f(1.0f, 1.0f, 1.0f, 0.f);
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
glEnd();
}
void Head::updateHairPhysics(float deltaTime) {
glm::quat orientation = getOrientation();
glm::vec3 up = orientation * IDENTITY_UP;
glm::vec3 front = orientation * IDENTITY_FRONT;

View file

@ -114,7 +114,7 @@ private:
float _returnSpringScale; //strength of return springs
glm::vec3 _bodyRotation;
bool _renderLookatVectors;
BendyLine _hairTuft[NUM_HAIR_TUFTS];
BendyLine _hairTuft[NUM_HAIR_TUFTS];
glm::vec3* _mohawkTriangleFan;
glm::vec3* _mohawkColors;
glm::vec3 _saccade;

View file

@ -639,14 +639,14 @@ void NodeList::removeHook(NodeListHook* hook) {
void NodeList::notifyHooksOfAddedNode(Node* node) {
for (int i = 0; i < _hooks.size(); i++) {
printf("NodeList::notifyHooksOfAddedNode() i=%d\n", i);
//printf("NodeList::notifyHooksOfAddedNode() i=%d\n", i);
_hooks[i]->nodeAdded(node);
}
}
void NodeList::notifyHooksOfKilledNode(Node* node) {
for (int i = 0; i < _hooks.size(); i++) {
printf("NodeList::notifyHooksOfKilledNode() i=%d\n", i);
//printf("NodeList::notifyHooksOfKilledNode() i=%d\n", i);
_hooks[i]->nodeKilled(node);
}
}

View file

@ -215,7 +215,6 @@ bool createVoxelEditMessage(unsigned char command, short int sequence,
bool success = true; // assume the best
int messageSize = MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE; // just a guess for now
int actualMessageSize = 3;
unsigned char* messageBuffer = new unsigned char[messageSize];
int numBytesPacketHeader = populateTypeAndVersion(messageBuffer, command);
@ -223,6 +222,7 @@ bool createVoxelEditMessage(unsigned char command, short int sequence,
*sequenceAt = sequence;
unsigned char* copyAt = &messageBuffer[numBytesPacketHeader + sizeof(sequence)];
int actualMessageSize = numBytesPacketHeader + sizeof(sequence);
for (int i = 0; i < voxelCount && success; i++) {
// get the coded voxel
@ -232,7 +232,7 @@ bool createVoxelEditMessage(unsigned char command, short int sequence,
int lengthOfVoxelData = bytesRequiredForCodeLength(*voxelData)+SIZE_OF_COLOR_DATA;
// make sure we have room to copy this voxel
if (actualMessageSize+lengthOfVoxelData > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) {
if (actualMessageSize + lengthOfVoxelData > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) {
success = false;
} else {
// add it to our message