Merge branch 'master' of https://github.com/worklist/hifi into glow

This commit is contained in:
Andrzej Kapolka 2013-08-09 10:12:47 -07:00
commit 9189a206b8
12 changed files with 221 additions and 56 deletions

View file

@ -86,8 +86,8 @@ const float BUG_VOXEL_SIZE = 0.0625f / TREE_SCALE;
glm::vec3 bugPosition = glm::vec3(BUG_VOXEL_SIZE * 20.0, BUG_VOXEL_SIZE * 30.0, BUG_VOXEL_SIZE * 20.0);
glm::vec3 bugDirection = glm::vec3(0, 0, 1);
const int VOXELS_PER_BUG = 18;
glm::vec3 bugPathCenter = glm::vec3(BUG_VOXEL_SIZE * 150.0, BUG_VOXEL_SIZE * 30.0, BUG_VOXEL_SIZE * 150.0);
float bugPathRadius = BUG_VOXEL_SIZE * 140.0;
glm::vec3 bugPathCenter = glm::vec3(0.25f,0.15f,0.25f); // glm::vec3(BUG_VOXEL_SIZE * 150.0, BUG_VOXEL_SIZE * 30.0, BUG_VOXEL_SIZE * 150.0);
float bugPathRadius = 0.2f; //BUG_VOXEL_SIZE * 140.0;
float bugPathTheta = 0.0 * PI_OVER_180;
float bugRotation = 0.0 * PI_OVER_180;
float bugAngleDelta = 0.2 * PI_OVER_180;

View file

@ -32,9 +32,8 @@ int main(int argc, const char* argv[]) {
UDPSocket serverSocket(ASSIGNMENT_SERVER_PORT);
int numHeaderBytes = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_SEND_ASSIGNMENT);
unsigned char assignmentPacket[MAX_PACKET_SIZE_BYTES];
populateTypeAndVersion(assignmentPacket, PACKET_TYPE_SEND_ASSIGNMENT);
int numSendHeaderBytes = populateTypeAndVersion(assignmentPacket, PACKET_TYPE_SEND_ASSIGNMENT);
while (true) {
if (serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) {
@ -53,7 +52,7 @@ int main(int argc, const char* argv[]) {
qDebug() << "Sending assignment with URL" << scriptURL << "\n";
int scriptURLBytes = scriptURL.size();
memcpy(assignmentPacket + numHeaderBytes, scriptURL.toLocal8Bit().constData(), scriptURLBytes);
memcpy(assignmentPacket + numSendHeaderBytes, scriptURL.toLocal8Bit().constData(), scriptURLBytes);
// send the assignment
serverSocket.send((sockaddr*) &senderSocket, assignmentPacket, numHeaderBytes + scriptURLBytes);

View file

@ -943,7 +943,7 @@ void Application::mousePressEvent(QMouseEvent* event) {
maybeEditVoxelUnderCursor();
if (!_palette.isActive()) {
if (!_palette.isActive() && (!_isHoverVoxel || _isLookingAtOtherAvatar)) {
_pieMenu.mousePressEvent(_mouseX, _mouseY);
}
@ -952,7 +952,16 @@ void Application::mousePressEvent(QMouseEvent* event) {
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
_hoverVoxelOriginalColor[3] = 1;
_audio.startCollisionSound(1.0, HOVER_VOXEL_FREQUENCY * _hoverVoxel.s * TREE_SCALE, 0.0, HOVER_VOXEL_DECAY);
const float RED_CLICK_FREQUENCY = 1000.f;
const float GREEN_CLICK_FREQUENCY = 1250.f;
const float BLUE_CLICK_FREQUENCY = 1330.f;
const float MIDDLE_A_FREQUENCY = 440.f;
float frequency = MIDDLE_A_FREQUENCY +
(_hoverVoxel.red / 255.f * RED_CLICK_FREQUENCY +
_hoverVoxel.green / 255.f * GREEN_CLICK_FREQUENCY +
_hoverVoxel.blue / 255.f * BLUE_CLICK_FREQUENCY) / 3.f;
_audio.startCollisionSound(1.0, frequency, 0.0, HOVER_VOXEL_DECAY);
_isHoverVoxelSounding = true;
}

View file

@ -704,7 +704,7 @@ void Audio::addProceduralSounds(int16_t* inputBuffer,
float speed = glm::length(_lastVelocity);
float volume = VOLUME_BASELINE * (1.f - speed / MAX_AUDIBLE_VELOCITY);
int sample;
float sample;
//
// Travelling noise
@ -724,13 +724,16 @@ void Audio::addProceduralSounds(int16_t* inputBuffer,
if (_collisionSoundMagnitude > COLLISION_SOUND_CUTOFF_LEVEL) {
for (int i = 0; i < numSamples; i++) {
t = (float) _proceduralEffectSample + (float) i;
sample = sinf(t * _collisionSoundFrequency) +
sinf(t * _collisionSoundFrequency / DOWN_TWO_OCTAVES) +
sinf(t * _collisionSoundFrequency / DOWN_FOUR_OCTAVES * UP_MAJOR_FIFTH);
sample *= _collisionSoundMagnitude * COLLISION_SOUND_MAX_VOLUME;
inputBuffer[i] += sample;
outputLeft[i] += sample;
outputRight[i] += sample;
inputBuffer[i] += (int) sample;
outputLeft[i] += (int) sample;
outputRight[i] += (int) sample;
_collisionSoundMagnitude *= _collisionSoundDuration;
}
}

View file

@ -63,6 +63,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) :
_abandonedVBOSlots = 0;
_falseColorizeBySource = false;
_dataSourceID = UNKNOWN_NODE_ID;
_voxelServerCount = 0;
}
void VoxelSystem::nodeDeleted(VoxelNode* node) {
@ -389,14 +390,29 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
bool shouldRender = false; // assume we don't need to render it
// if it's colored, we might need to render it!
shouldRender = node->calculateShouldRender(Application::getInstance()->getViewFrustum());
node->setShouldRender(shouldRender);
// let children figure out their renderness
if (!node->isLeaf()) {
// As we check our children, see if any of them went from shouldRender to NOT shouldRender
// then we probably dropped LOD and if we don't have color, we want to average our children
// for a new color.
int childrenGotHiddenCount = 0;
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
if (node->getChildAtIndex(i)) {
voxelsUpdated += newTreeToArrays(node->getChildAtIndex(i));
VoxelNode* childNode = node->getChildAtIndex(i);
if (childNode) {
bool wasShouldRender = childNode->getShouldRender();
voxelsUpdated += newTreeToArrays(childNode);
bool isShouldRender = childNode->getShouldRender();
if (wasShouldRender && !isShouldRender) {
childrenGotHiddenCount++;
}
}
}
if (childrenGotHiddenCount > 0) {
node->setColorFromAverageOfChildren();
}
}
if (_writeRenderFullVBO) {
voxelsUpdated += updateNodeInArraysAsFullVBO(node);
@ -1538,6 +1554,7 @@ void VoxelSystem::nodeAdded(Node* node) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
uint16_t nodeID = node->getNodeID();
printf("VoxelSystem... voxel server %u added...\n", nodeID);
_voxelServerCount++;
}
}
@ -1545,8 +1562,11 @@ bool VoxelSystem::killSourceVoxelsOperation(VoxelNode* node, void* extraData) {
uint16_t killedNodeID = *(uint16_t*)extraData;
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
VoxelNode* childNode = node->getChildAtIndex(i);
if (childNode && childNode->getSourceID()== killedNodeID) {
node->safeDeepDeleteChildAtIndex(i);
if (childNode) {
uint16_t childNodeID = childNode->getSourceID();
if (childNodeID == killedNodeID) {
node->safeDeepDeleteChildAtIndex(i);
}
}
}
return true;
@ -1554,12 +1574,19 @@ bool VoxelSystem::killSourceVoxelsOperation(VoxelNode* node, void* extraData) {
void VoxelSystem::nodeKilled(Node* node) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
_voxelServerCount--;
uint16_t nodeID = node->getNodeID();
printf("VoxelSystem... voxel server %u removed...\n", nodeID);
// Kill any voxels from the local tree
_tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeID);
_tree->setDirtyBit();
if (_voxelServerCount > 0) {
// Kill any voxels from the local tree that match this nodeID
_tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeID);
_tree->setDirtyBit();
} else {
// Last server, take the easy way and kill all the local voxels!
_tree->eraseAllVoxels();
_voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this??
}
setupNewVoxelsForDrawing();
}
}

View file

@ -206,6 +206,8 @@ private:
bool _falseColorizeBySource;
int _dataSourceID;
int _voxelServerCount;
};
#endif

View file

@ -297,7 +297,6 @@ void Avatar::reset() {
// Update avatar head rotation with sensor data
void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
float pitchFromTouch) {
_head.setMousePitch(pitchFromTouch);
SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor();
Webcam* webcam = Application::getInstance()->getWebcam();
glm::vec3 estimatedPosition, estimatedRotation;
@ -307,11 +306,17 @@ void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
} else if (webcam->isActive()) {
estimatedRotation = webcam->getEstimatedRotation();
} else if (_leadingAvatar) {
_head.getFace().clearFrame();
return;
} else {
_head.setMousePitch(pitchFromTouch);
_head.setPitch(pitchFromTouch);
_head.getFace().clearFrame();
return;
}
_head.setMousePitch(pitchFromTouch);
if (webcam->isActive()) {
estimatedPosition = webcam->getEstimatedPosition();
@ -426,33 +431,47 @@ void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) {
_shouldJump = false;
}
// Add thrusts from leading avatar
const float FOLLOWING_RATE = 0.02f;
const float MIN_YAW = 5.0f;
const float MIN_PITCH = 1.0f;
const float PITCH_RATE = 0.1f;
const float MIN_YAW_BEFORE_PITCH = 30.0f;
if (_leadingAvatar != NULL) {
glm::vec3 toTarget = _leadingAvatar->getPosition() - _position;
if (.5f < up.x * toTarget.x + up.y * toTarget.y + up.z * toTarget.z) {
_thrust += _scale * THRUST_MAG_UP * deltaTime * up;
} else if (up.x * toTarget.x + up.y * toTarget.y + up.z * toTarget.z < -.5f) {
_thrust -= _scale * THRUST_MAG_UP * deltaTime * up;
}
if (glm::length(_position - _leadingAvatar->getPosition()) > _scale * _stringLength) {
_thrust += _scale * THRUST_MAG_FWD * deltaTime * front;
_position += toTarget * FOLLOWING_RATE;
} else {
toTarget = _leadingAvatar->getHead().getLookAtPosition() - _position;
getHead().setLookAtPosition(_leadingAvatar->getHead().getLookAtPosition());
toTarget = _leadingAvatar->getHead().getLookAtPosition() - _head.getPosition();
}
toTarget = glm::vec3(glm::dot(right, toTarget),
glm::dot(up , toTarget),
glm::dot(front, toTarget));
float yawAngle = angleBetween(front, glm::vec3(toTarget.x, 0.f, toTarget.z));
if (yawAngle < -10.f || 10.f < yawAngle){
if (right.x * toTarget.x + right.y * toTarget.y + right.z * toTarget.z > 0) {
_bodyYawDelta -= YAW_MAG * deltaTime;
float yawAngle = angleBetween(-IDENTITY_FRONT, glm::vec3(toTarget.x, 0.f, toTarget.z));
if (glm::abs(yawAngle) > MIN_YAW){
if (IDENTITY_RIGHT.x * toTarget.x + IDENTITY_RIGHT.y * toTarget.y + IDENTITY_RIGHT.z * toTarget.z > 0) {
_bodyYawDelta -= yawAngle;
} else {
_bodyYawDelta += YAW_MAG * deltaTime;
_bodyYawDelta += yawAngle;
}
}
float pitchAngle = glm::abs(90.0f - angleBetween(IDENTITY_UP, toTarget));
if (glm::abs(pitchAngle) > MIN_PITCH && yawAngle < MIN_YAW_BEFORE_PITCH){
if (IDENTITY_UP.x * toTarget.x + IDENTITY_UP.y * toTarget.y + IDENTITY_UP.z * toTarget.z > 0) {
_head.setMousePitch(_head.getMousePitch() + PITCH_RATE * pitchAngle);
} else {
_head.setMousePitch(_head.getMousePitch() - PITCH_RATE * pitchAngle);
}
_head.setPitch(_head.getMousePitch());
}
}
// Add thrusts from Transmitter
if (transmitter) {
transmitter->checkForLostTransmitter();
@ -533,7 +552,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCamer
follow(NULL);
}
// Ajust, scale, thrust and lookAt position when following an other avatar
// Ajust, scale, position and lookAt position when following an other avatar
if (isMyAvatar() && _leadingAvatar && _newScale != _leadingAvatar->getScale()) {
_newScale = _leadingAvatar->getScale();
}

View file

@ -27,8 +27,8 @@
#include "world.h"
static const float MAX_SCALE = 10.f;
static const float MIN_SCALE = .5f;
static const float MAX_SCALE = 1000.f;
static const float MIN_SCALE = .005f;
static const float SCALING_RATIO = .05f;
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
static const float RESCALING_TOLERANCE = .02f;

View file

@ -57,8 +57,9 @@ public:
void setCameraFollowsHead(bool cameraFollowsHead) { _cameraFollowsHead = cameraFollowsHead; }
void setMousePitch(float mousePitch) { _mousePitch = mousePitch; }
float getMousePitch() { return _mousePitch; }
void setMousePitch(float mousePitch) { _mousePitch = mousePitch; }
glm::quat getOrientation() const;
glm::quat getCameraOrientation () const;

View file

@ -31,7 +31,9 @@ public:
bool writeToFile(const char* filename);
bool readFromFile(const char* filename);
unsigned char* getRootOctalCode() const { return _rootOctalCode; }
unsigned char* getRootOctalCode() const { return _rootOctalCode; }
unsigned char* getEndNodeOctalCode(int index) const { return _endNodes[index]; }
int getEndNodeCount() const { return _endNodes.size(); }
private:
void clear();

View file

@ -9,6 +9,7 @@
#include <VoxelTree.h>
#include <SharedUtil.h>
#include <SceneUtils.h>
#include <JurisdictionMap.h>
VoxelTree myTree;
@ -56,19 +57,107 @@ void voxelTutorial(VoxelTree * tree) {
int main(int argc, const char * argv[])
{
const char* SAY_HELLO = "--sayHello";
if (cmdOptionExists(argc, argv, SAY_HELLO)) {
printf("I'm just saying hello...\n");
}
qInstallMessageHandler(sharedMessageHandler);
const char* DONT_CREATE_FILE = "--dontCreateSceneFile";
bool dontCreateFile = cmdOptionExists(argc, argv, DONT_CREATE_FILE);
// Handles taking and SVO and splitting it into multiple SVOs based on
// jurisdiction details
const char* SPLIT_SVO = "--splitSVO";
const char* splitSVOFile = getCmdOption(argc, argv, SPLIT_SVO);
const char* SPLIT_JURISDICTION_ROOT = "--splitJurisdictionRoot";
const char* SPLIT_JURISDICTION_ENDNODES = "--splitJurisdictionEndNodes";
const char* splitJurisdictionRoot = getCmdOption(argc, argv, SPLIT_JURISDICTION_ROOT);
const char* splitJurisdictionEndNodes = getCmdOption(argc, argv, SPLIT_JURISDICTION_ENDNODES);
if (splitSVOFile && splitJurisdictionRoot && splitJurisdictionEndNodes) {
char outputFileName[512];
printf("splitSVOFile: %s Jurisdictions Root: %s EndNodes: %s\n",
splitSVOFile, splitJurisdictionRoot, splitJurisdictionEndNodes);
VoxelTree rootSVO;
rootSVO.readFromSVOFile(splitSVOFile);
JurisdictionMap jurisdiction(splitJurisdictionRoot, splitJurisdictionEndNodes);
printf("Jurisdiction Root Octcode: ");
printOctalCode(jurisdiction.getRootOctalCode());
printf("Jurisdiction End Nodes: %d \n", jurisdiction.getEndNodeCount());
for (int i = 0; i < jurisdiction.getEndNodeCount(); i++) {
unsigned char* endNodeCode = jurisdiction.getEndNodeOctalCode(i);
printf("End Node: %d ", i);
printOctalCode(endNodeCode);
// get the endNode details
VoxelPositionSize endNodeDetails;
voxelDetailsForCode(endNodeCode, endNodeDetails);
// Now, create a split SVO for the EndNode.
// copy the EndNode into a temporary tree
VoxelTree endNodeTree;
// create a small voxels at corners of the endNode Tree, this will is a hack
// to work around a bug in voxel server that will send Voxel not exists
// for regions that don't contain anything even if they're not in the
// jurisdiction of the server
// This hack assumes the end nodes for demo dinner since it only guarantees
// nodes in the 8 child voxels of the main root voxel
const float verySmall = verySmall;
endNodeTree.createVoxel(0.0, 0.0, 0.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(1.0, 0.0, 0.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(0.0, 1.0, 0.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(0.0, 0.0, 1.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(1.0, 1.0, 1.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(1.0, 1.0, 0.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(0.0, 1.0, 1.0, verySmall, 1, 1, 1, true);
endNodeTree.createVoxel(1.0, 0.0, 1.0, verySmall, 1, 1, 1, true);
// Delete the voxel for the EndNode from the temporary tree, so we can
// import our endNode content into it...
endNodeTree.deleteVoxelCodeFromTree(endNodeCode, COLLAPSE_EMPTY_TREE);
VoxelNode* endNode = rootSVO.getVoxelAt(endNodeDetails.x,
endNodeDetails.y,
endNodeDetails.z,
endNodeDetails.s);
rootSVO.copySubTreeIntoNewTree(endNode, &endNodeTree, false);
sprintf(outputFileName, "splitENDNODE%d%s", i, splitSVOFile);
printf("outputFile: %s\n", outputFileName);
endNodeTree.writeToSVOFile(outputFileName);
// Delete the voxel for the EndNode from the root tree...
rootSVO.deleteVoxelCodeFromTree(endNodeCode, COLLAPSE_EMPTY_TREE);
// create a small voxel in center of each EndNode, this will is a hack
// to work around a bug in voxel server that will send Voxel not exists
// for regions that don't contain anything even if they're not in the
// jurisdiction of the server
float x = endNodeDetails.x + endNodeDetails.s * 0.5;
float y = endNodeDetails.y + endNodeDetails.s * 0.5;
float z = endNodeDetails.z + endNodeDetails.s * 0.5;
float s = endNodeDetails.s * verySmall;
rootSVO.createVoxel(x, y, z, s, 1, 1, 1, true);
}
sprintf(outputFileName, "splitROOT%s", splitSVOFile);
printf("outputFile: %s\n", outputFileName);
rootSVO.writeToSVOFile(outputFileName);
printf("exiting now\n");
return 0;
}
const char* DONT_CREATE_FILE = "--dontCreateSceneFile";
bool dontCreateFile = cmdOptionExists(argc, argv, DONT_CREATE_FILE);
if (dontCreateFile) {
printf("You asked us not to create a scene file, so we will not.\n");
} else {
printf("Creating Scene File...\n");
printf("You asked us not to create a scene file, so we will not.\n");
} else {
printf("Creating Scene File...\n");
const char* RUN_TUTORIAL = "--runTutorial";
if (cmdOptionExists(argc, argv, RUN_TUTORIAL)) {
voxelTutorial(&myTree);

View file

@ -47,7 +47,7 @@ const float DEATH_STAR_RADIUS = 4.0;
const float MAX_CUBE = 0.05f;
const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps
int PACKETS_PER_CLIENT_PER_INTERVAL = 20;
int PACKETS_PER_CLIENT_PER_INTERVAL = 10;
const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels
const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS;
@ -67,6 +67,7 @@ bool displayVoxelStats = false;
bool debugVoxelReceiving = false;
bool sendEnvironments = true;
bool sendMinimalEnvironment = false;
bool dumpVoxelsOnMove = false;
EnvironmentData environmentData[3];
@ -237,7 +238,9 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
// if our view has changed, we need to reset these things...
if (viewFrustumChanged) {
nodeData->nodeBag.deleteAll();
if (::dumpVoxelsOnMove) {
nodeData->nodeBag.deleteAll();
}
nodeData->map.erase();
}
@ -253,12 +256,17 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
nodeData->stats.printDebugDetails();
}
// This is the start of "resending" the scene.
nodeData->nodeBag.insert(serverTree.rootNode);
// start tracking our stats
bool isFullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging();
// If we're starting a full scene, then definitely we want to empty the nodeBag
if (isFullScene) {
nodeData->nodeBag.deleteAll();
}
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, ::serverTree.rootNode, ::jurisdiction);
// This is the start of "resending" the scene.
nodeData->nodeBag.insert(serverTree.rootNode);
}
// If we have something in our nodeBag, then turn them into packets and send them out...
@ -477,7 +485,13 @@ int main(int argc, const char * argv[]) {
jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
}
}
// should we send environments? Default is yes, but this command line suppresses sending
const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
::dumpVoxelsOnMove = cmdOptionExists(argc, argv, DUMP_VOXELS_ON_MOVE);
printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
// should we send environments? Default is yes, but this command line suppresses sending
const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
bool dontSendEnvironments = cmdOptionExists(argc, argv, DONT_SEND_ENVIRONMENTS);