This commit is contained in:
Philip Rosedale 2013-08-08 16:01:02 -07:00
commit 43ad461275
21 changed files with 178 additions and 42 deletions

View file

@ -10,13 +10,17 @@
#include <fstream>
#include <queue>
#include <QtCore/QString>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <UDPSocket.h>
const int MAX_PACKET_SIZE_BYTES = 1400;
struct Assignment {};
struct Assignment {
QString scriptFilename;
};
int main(int argc, const char* argv[]) {
@ -28,28 +32,46 @@ int main(int argc, const char* argv[]) {
UDPSocket serverSocket(ASSIGNMENT_SERVER_PORT);
int numHeaderBytes = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_SEND_ASSIGNMENT);
unsigned char assignmentPacket[numHeaderBytes + sizeof(char)];
populateTypeAndVersion(assignmentPacket, PACKET_TYPE_SEND_ASSIGNMENT);
unsigned char assignmentPacket[MAX_PACKET_SIZE_BYTES];
int numSendHeaderBytes = populateTypeAndVersion(assignmentPacket, PACKET_TYPE_SEND_ASSIGNMENT);
while (true) {
if (serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) {
// int numHeaderBytes = numBytesForPacketHeader(senderData);
int numHeaderBytes = numBytesForPacketHeader(senderData);
if (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
if (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
qDebug() << "Assignment request received.\n";
// grab the FI assignment in the queue, if it exists
if (assignmentQueue.size() > 0) {
// Assignment firstAssignment = assignmentQueue.front();
Assignment firstAssignment = assignmentQueue.front();
assignmentQueue.pop();
QString scriptURL = QString("http://base8-compute.s3.amazonaws.com/%1").arg(firstAssignment.scriptFilename);
qDebug() << "Sending assignment with URL" << scriptURL << "\n";
int scriptURLBytes = scriptURL.size();
memcpy(assignmentPacket + numSendHeaderBytes, scriptURL.toLocal8Bit().constData(), scriptURLBytes);
// send the assignment
serverSocket.send((sockaddr*) &senderSocket, assignmentPacket, sizeof(assignmentPacket));
serverSocket.send((sockaddr*) &senderSocket, assignmentPacket, numHeaderBytes + scriptURLBytes);
}
} else if (senderData[0] == PACKET_TYPE_SEND_ASSIGNMENT) {
Assignment newAssignment;
senderData[receivedBytes] = '\0';
newAssignment.scriptFilename = QString((const char*)senderData + numHeaderBytes);
qDebug() << "Added an assignment with script with filename" << newAssignment.scriptFilename << "\n";
// add this assignment to the queue
// we're not a queue right now, only keep one assignment
if (assignmentQueue.size() > 0) {
assignmentQueue.pop();
}
assignmentQueue.push(newAssignment);
}
}

View file

@ -51,6 +51,11 @@ Pod::Spec.new do |s|
sp.dependency 'glm'
end
s.subspec "voxels" do |sp|
sp.source_files = 'libraries/voxels/src', 'libraries/voxels/moc_*'
sp.dependency 'glm'
end
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/../../qt5-device/qtbase/include' }
s.libraries = 'libQtCoreCombined', 'libQt5Network', 'libQt5Script'

View file

@ -1189,6 +1189,13 @@ void Application::sendAvatarVoxelURLMessage(const QUrl& url) {
}
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
// record the packet for stats-tracking
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AVATARS).updateValue(dataBytes);
Node* avatarMixerNode = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
if (avatarMixerNode) {
avatarMixerNode->recordBytesReceived(dataBytes);
}
// skip the header
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
packetData += numBytesPacketHeader;
@ -2937,6 +2944,9 @@ void Application::displayOculus(Camera& whichCamera) {
glPopMatrix();
}
const GLfloat WHITE_SPECULAR_COLOR[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat NO_SPECULAR_COLOR[] = { 0.0f, 0.0f, 0.0f, 1.0f };
void Application::setupWorldLight(Camera& whichCamera) {
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
@ -2951,10 +2961,9 @@ void Application::setupWorldLight(Camera& whichCamera) {
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);
glLightfv(GL_LIGHT0, GL_SPECULAR, WHITE_SPECULAR_COLOR);
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR);
glMateriali(GL_FRONT, GL_SHININESS, 96);
}
@ -3032,6 +3041,9 @@ void Application::displaySide(Camera& whichCamera) {
glutSolidSphere(sphereRadius, 15, 15);
glPopMatrix();
// disable specular lighting for ground and voxels
glMaterialfv(GL_FRONT, GL_SPECULAR, NO_SPECULAR_COLOR);
//draw a grid ground plane....
if (_renderGroundPlaneOn->isChecked()) {
// draw grass plane with fog
@ -3060,6 +3072,9 @@ void Application::displaySide(Camera& whichCamera) {
_voxels.render(_renderVoxelTextures->isChecked());
}
// restore default, white specular
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR);
// indicate what we'll be adding/removing in mouse mode, if anything
if (_mouseVoxel.s != 0) {
glDisable(GL_LIGHTING);
@ -3958,6 +3973,8 @@ void Application::nodeKilled(Node* node) {
// Add the jurisditionDetails object to the list of "fade outs"
VoxelFade fade(VoxelFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE);
fade.voxelDetails = jurisditionDetails;
const float slightly_smaller = 0.99;
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_voxelFades.push_back(fade);
}
}
@ -3987,6 +4004,8 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
// 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;
const float slightly_smaller = 0.99;
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_voxelFades.push_back(fade);
}
// store jurisdiction details for later use
@ -4075,11 +4094,9 @@ 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

@ -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) {
@ -1538,6 +1539,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 +1547,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 +1559,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

@ -100,6 +100,7 @@ static Closure cmakeBuild(srcDir, instCommand) {
def targets = [
'animation-server':true,
'assignment-server':true,
'audio-mixer':true,
'avatar-mixer':true,
'domain-server':true,

View file

@ -42,7 +42,7 @@ void Agent::run(QUrl scriptURL) {
AvatarData *testAvatarData = new AvatarData;
QScriptValue avatarDataValue = engine.newQObject(testAvatarData);
engine.globalObject().setProperty("AvatarData", avatarDataValue);
engine.globalObject().setProperty("Avatar", avatarDataValue);
QScriptValue agentValue = engine.newQObject(this);
engine.globalObject().setProperty("Agent", agentValue);
@ -55,7 +55,7 @@ void Agent::run(QUrl scriptURL) {
timeval lastDomainServerCheckIn = {};
int numMicrosecondsSleep = 0;
const float DATA_SEND_INTERVAL_USECS = (1 / 60) * 1000 * 1000;
const float DATA_SEND_INTERVAL_USECS = (1 / 60.0f) * 1000 * 1000;
sockaddr_in senderAddress;
unsigned char receivedData[MAX_PACKET_SIZE];

View file

@ -52,6 +52,38 @@ AvatarData::~AvatarData() {
delete _handData;
}
void AvatarData::setPositionFromVariantMap(QVariantMap positionMap) {
_position = glm::vec3(positionMap.value("x").toFloat(),
positionMap.value("y").toFloat(),
positionMap.value("z").toFloat());
}
QVariantMap AvatarData::getPositionVariantMap() {
QVariantMap positionMap;
positionMap.insert("x", _position.x);
positionMap.insert("y", _position.y);
positionMap.insert("z", _position.z);
return positionMap;
}
void AvatarData::setHandPositionFromVariantMap(QVariantMap handPositionMap) {
_handPosition = glm::vec3(handPositionMap.value("x").toFloat(),
handPositionMap.value("y").toFloat(),
handPositionMap.value("z").toFloat());
}
QVariantMap AvatarData::getHandPositionVariantMap() {
QVariantMap positionMap;
positionMap.insert("x", _handPosition.x);
positionMap.insert("y", _handPosition.y);
positionMap.insert("z", _handPosition.z);
return positionMap;
}
void AvatarData::sendData() {
// called from Agent visual loop to send data

View file

@ -17,6 +17,7 @@
#include <glm/gtc/quaternion.hpp>
#include <QtCore/QObject>
#include <QtCore/QVariantMap>
#include <NodeData.h>
#include "HeadData.h"
@ -41,7 +42,14 @@ enum KeyState
class JointData;
class AvatarData : public NodeData {
Q_OBJECT
Q_OBJECT
Q_PROPERTY(QVariantMap position READ getPositionVariantMap WRITE setPositionFromVariantMap)
Q_PROPERTY(QVariantMap handPosition READ getHandPositionVariantMap WRITE setHandPositionFromVariantMap)
Q_PROPERTY(float bodyYaw READ getBodyYaw WRITE setBodyYaw)
Q_PROPERTY(float bodyPitch READ getBodyPitch WRITE setBodyPitch)
Q_PROPERTY(float bodyRoll READ getBodyRoll WRITE setBodyRoll)
Q_PROPERTY(QString chatMessage READ getQStringChatMessage WRITE setChatMessage)
public:
AvatarData(Node* owningNode = NULL);
~AvatarData();
@ -51,15 +59,23 @@ public:
void setPosition (const glm::vec3 position ) { _position = position; }
void setHandPosition (const glm::vec3 handPosition ) { _handPosition = handPosition; }
void setPositionFromVariantMap(QVariantMap positionMap);
QVariantMap getPositionVariantMap();
void setHandPositionFromVariantMap(QVariantMap handPositionMap);
QVariantMap getHandPositionVariantMap();
int getBroadcastData(unsigned char* destinationBuffer);
int parseData(unsigned char* sourceBuffer, int numBytes);
// Body Rotation
float getBodyYaw() const { return _bodyYaw; }
void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; }
float getBodyPitch() const { return _bodyPitch; }
void setBodyPitch(float bodyPitch) { _bodyPitch = bodyPitch; }
float getBodyRoll() const {return _bodyRoll; }
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
// Hand State
void setHandState(char s) { _handState = s; };
@ -89,7 +105,9 @@ public:
// chat message
void setChatMessage(const std::string& msg) { _chatMessage = msg; }
const std::string& chatMessage () const { return _chatMessage; }
void setChatMessage(const QString& string) { _chatMessage = string.toLocal8Bit().constData(); }
const std::string& setChatMessage() const { return _chatMessage; }
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
// related to Voxel Sending strategies
bool getWantColor() const { return _wantColor; }
@ -107,8 +125,6 @@ public:
void setHandData(HandData* handData) { _handData = handData; }
public slots:
void setPosition(float x, float y, float z) { _position = glm::vec3(x, y, z); }
void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; }
void sendData();
protected:

View file

@ -94,6 +94,8 @@ const char* Node::getTypeName() const {
return NODE_TYPE_NAME_AUDIO_INJECTOR;
case NODE_TYPE_ANIMATION_SERVER:
return NODE_TYPE_NAME_ANIMATION_SERVER;
case NODE_TYPE_UNASSIGNED:
return NODE_TYPE_NAME_UNASSIGNED;
default:
return NODE_TYPE_NAME_UNKNOWN;
}

View file

@ -24,5 +24,6 @@ const NODE_TYPE NODE_TYPE_AUDIO_MIXER = 'M';
const NODE_TYPE NODE_TYPE_AVATAR_MIXER = 'W';
const NODE_TYPE NODE_TYPE_AUDIO_INJECTOR = 'A';
const NODE_TYPE NODE_TYPE_ANIMATION_SERVER = 'a';
const NODE_TYPE NODE_TYPE_UNASSIGNED = 1;
#endif

View file

@ -8,7 +8,7 @@
#include <cstring>
#include <QDebug>
#include <QtCore/QDebug>
#include <SharedUtil.h>

View file

@ -9,7 +9,7 @@
#include <algorithm>
#include <cstring>
#include <QDebug>
#include <QtCore/QDebug>
#include <SharedUtil.h>

View file

@ -7,7 +7,7 @@
#include <cstring>
#include <QDebug>
#include <QtCore/QDebug>
#include <SharedUtil.h>

View file

@ -6,9 +6,9 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include <QSettings>
#include <QString>
#include <QStringList>
#include <QtCore/QSettings>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include "JurisdictionMap.h"
#include "VoxelNode.h"

View file

@ -10,7 +10,7 @@
#define __hifi__JurisdictionMap__
#include <vector>
#include <QString>
#include <QtCore/QString>
class JurisdictionMap {
public:

View file

@ -12,7 +12,7 @@
#include <glm/gtx/transform.hpp>
#include <QDebug>
#include <QtCore/QDebug>
#include "CoverageMap.h"
#include "GeometryUtil.h"

View file

@ -10,7 +10,7 @@
#include <cstring>
#include <stdio.h>
#include <QDebug>
#include <QtCore/QDebug>
#include <NodeList.h>

View file

@ -7,7 +7,7 @@
#include <algorithm>
#include <QDebug>
#include <QtCore/QDebug>
#include "GeometryUtil.h"
#include "SharedUtil.h"

View file

@ -17,7 +17,7 @@
#include <glm/gtc/noise.hpp>
#include <QDebug>
#include <QtCore/QDebug>
#include "CoverageMap.h"
#include "GeometryUtil.h"

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;
@ -66,6 +66,8 @@ bool shouldShowAnimationDebug = false;
bool displayVoxelStats = false;
bool debugVoxelReceiving = false;
bool sendEnvironments = true;
bool sendMinimalEnvironment = false;
bool dumpVoxelsOnMove = false;
EnvironmentData environmentData[3];
@ -236,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();
}
@ -252,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...
@ -325,8 +334,9 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
if (shouldSendEnvironments) {
int numBytesPacketHeader = populateTypeAndVersion(tempOutputBuffer, PACKET_TYPE_ENVIRONMENT_DATA);
int envPacketLength = numBytesPacketHeader;
int environmentsToSend = ::sendMinimalEnvironment ? 1 : sizeof(environmentData) / sizeof(EnvironmentData);
for (int i = 0; i < sizeof(environmentData) / sizeof(EnvironmentData); i++) {
for (int i = 0; i < environmentsToSend; i++) {
envPacketLength += environmentData[i].getBroadcastData(tempOutputBuffer + envPacketLength);
}
@ -475,13 +485,24 @@ 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);
if (dontSendEnvironments) {
printf("Sending environments suppressed...\n");
::sendEnvironments = false;
} else {
// should we send environments? Default is yes, but this command line suppresses sending
const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
::sendMinimalEnvironment = cmdOptionExists(argc, argv, MINIMAL_ENVIRONMENT);
printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
}
printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
@ -494,6 +515,11 @@ int main(int argc, const char * argv[]) {
if (::wantLocalDomain) {
printf("Local Domain MODE!\n");
nodeList->setDomainIPToLocalhost();
} else {
const char* domainIP = getCmdOption(argc, argv, "--domain");
if (domainIP) {
NodeList::getInstance()->setDomainHostname(domainIP);
}
}
nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;