mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 06:12:21 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
edf4579d0e
11 changed files with 270 additions and 156 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue