mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 15:14:19 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
ea0fa8e5c7
34 changed files with 409 additions and 48 deletions
|
@ -10,6 +10,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
add_subdirectory(animation-server)
|
||||
add_subdirectory(assignment-server)
|
||||
add_subdirectory(avatar-mixer)
|
||||
add_subdirectory(audio-mixer)
|
||||
add_subdirectory(domain-server)
|
||||
|
|
13
assignment-server/CMakeLists.txt
Normal file
13
assignment-server/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(TARGET_NAME assignment-server)
|
||||
|
||||
set(ROOT_DIR ..)
|
||||
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
||||
|
||||
include(${MACRO_DIR}/SetupHifiProject.cmake)
|
||||
setup_hifi_project(${TARGET_NAME} TRUE)
|
||||
|
||||
# link in the shared library
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
57
assignment-server/src/main.cpp
Normal file
57
assignment-server/src/main.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// main.cpp
|
||||
// assignment-server
|
||||
//
|
||||
// Created by Stephen Birarda on 7/1/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <UDPSocket.h>
|
||||
|
||||
const int MAX_PACKET_SIZE_BYTES = 1400;
|
||||
|
||||
struct Assignment {};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
|
||||
std::queue<Assignment> assignmentQueue;
|
||||
|
||||
sockaddr_in senderSocket;
|
||||
unsigned char senderData[MAX_PACKET_SIZE_BYTES] = {};
|
||||
ssize_t receivedBytes = 0;
|
||||
|
||||
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);
|
||||
|
||||
while (true) {
|
||||
if (serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) {
|
||||
|
||||
// int numHeaderBytes = numBytesForPacketHeader(senderData);
|
||||
|
||||
if (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||
// grab the FI assignment in the queue, if it exists
|
||||
if (assignmentQueue.size() > 0) {
|
||||
// Assignment firstAssignment = assignmentQueue.front();
|
||||
assignmentQueue.pop();
|
||||
|
||||
// send the assignment
|
||||
serverSocket.send((sockaddr*) &senderSocket, assignmentPacket, sizeof(assignmentPacket));
|
||||
}
|
||||
} else if (senderData[0] == PACKET_TYPE_SEND_ASSIGNMENT) {
|
||||
Assignment newAssignment;
|
||||
|
||||
// add this assignment to the queue
|
||||
assignmentQueue.push(newAssignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -375,7 +375,7 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
InjectedAudioRingBuffer* ringBuffer = (InjectedAudioRingBuffer*) node->getLinkedData();
|
||||
if (memcmp(ringBuffer->getStreamIdentifier(),
|
||||
packetData + 1,
|
||||
packetData + numBytesForPacketHeader(packetData),
|
||||
STREAM_IDENTIFIER_NUM_BYTES) == 0) {
|
||||
// this is the matching stream, assign to matchingInjector and stop looking
|
||||
matchingInjector = &*node;
|
||||
|
|
|
@ -18,4 +18,4 @@ include_glm(${TARGET_NAME} ${ROOT_DIR})
|
|||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
|
15
hifi.podspec
15
hifi.podspec
|
@ -35,17 +35,24 @@ Pod::Spec.new do |s|
|
|||
# s.exclude_files = 'Classes/Exclude'
|
||||
|
||||
s.subspec "shared" do |sp|
|
||||
sp.source_files = "libraries/shared/src"
|
||||
sp.public_header_files = "librares/shared/src"
|
||||
sp.source_files = 'libraries/shared/src', 'libraries/shared/moc_*'
|
||||
sp.exclude_files = "libraries/shared/src/UrlReader.*"
|
||||
sp.dependency 'glm'
|
||||
sp.xcconfig = { 'CLANG_CXX_LIBRARY' => "libc++" }
|
||||
end
|
||||
|
||||
s.subspec "audio" do |sp|
|
||||
sp.source_files = "libraries/audio/src"
|
||||
sp.public_header_files = "libraries/audio/src"
|
||||
sp.xcconfig = { 'CLANG_CXX_LIBRARY' => "libc++" }
|
||||
sp.dependency 'glm'
|
||||
end
|
||||
|
||||
s.subspec "avatars" do |sp|
|
||||
sp.source_files = 'libraries/avatars/src', 'libraries/avatars/moc_*'
|
||||
sp.dependency 'glm'
|
||||
end
|
||||
|
||||
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/../../qt5-device/qtbase/include' }
|
||||
s.libraries = 'libQtCoreCombined', 'libQt5Network', 'libQt5Script'
|
||||
|
||||
# A list of file patterns which select the header files that should be
|
||||
# made available to the application. If the pattern is a directory then the
|
||||
|
|
|
@ -941,8 +941,9 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
_mouseVoxelDragging = _mouseVoxel;
|
||||
_mousePressed = true;
|
||||
|
||||
maybeEditVoxelUnderCursor();
|
||||
|
||||
if (!maybeEditVoxelUnderCursor()) {
|
||||
if (!_palette.isActive()) {
|
||||
_pieMenu.mousePressEvent(_mouseX, _mouseY);
|
||||
}
|
||||
|
||||
|
@ -1686,14 +1687,25 @@ void Application::importVoxels() {
|
|||
const int SVO_TYPE_NAME_LENGTH = 4;
|
||||
const int SCH_TYPE_NAME_LENGTH = 10;
|
||||
|
||||
// assume this is where we'll place it if filename doesn't have tiling
|
||||
int unspecifiedColumnNum = 1;
|
||||
int unspecifiedRowNum = 1;
|
||||
|
||||
// if they select multiple files, but they don't specify the tiling, we
|
||||
// will tile them to this size
|
||||
int unspecifiedSquare = (sqrt(fileNameStringList.size()) + 0.5);
|
||||
qDebug("unspecifiedSquare: %d\n", unspecifiedSquare);
|
||||
|
||||
for (int i = 0; i < fileNameStringList.size(); i++) {
|
||||
QString fileNameString = fileNameStringList.at(i);
|
||||
QString extension;
|
||||
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
||||
const char* fileName = fileNameAscii.data();
|
||||
|
||||
int fileTypeNameLength = 0;
|
||||
VoxelTree importVoxels;
|
||||
if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) {
|
||||
extension = QString(".png");
|
||||
QImage pngImage = QImage(fileName);
|
||||
fileTypeNameLength = PNG_TYPE_NAME_LENGTH;
|
||||
if (pngImage.height() != pngImage.width()) {
|
||||
|
@ -1711,25 +1723,67 @@ void Application::importVoxels() {
|
|||
|
||||
importVoxels.readFromSquareARGB32Pixels(pixels, pngImage.height());
|
||||
} else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) {
|
||||
extension = QString(".svo");
|
||||
importVoxels.readFromSVOFile(fileName);
|
||||
fileTypeNameLength = SVO_TYPE_NAME_LENGTH;
|
||||
} else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) {
|
||||
extension = QString(".schematic");
|
||||
importVoxels.readFromSchematicFile(fileName);
|
||||
fileTypeNameLength = SCH_TYPE_NAME_LENGTH;
|
||||
}
|
||||
|
||||
// Where we plan to place this
|
||||
int columnNum = 1;
|
||||
int rowNum = 1;
|
||||
bool isTileLocationUnspecified = false;
|
||||
|
||||
int indexOfFirstPeriod = fileNameString.indexOf('.');
|
||||
// If we're in multi-file mode, then look for tiling specification in the file name
|
||||
if (fileNameStringList.size() > 1) {
|
||||
int indexOfFirstPeriod = fileNameString.indexOf('.');
|
||||
|
||||
QString fileCoord = fileNameString.mid(indexOfFirstPeriod + 1,
|
||||
fileNameString.length() - indexOfFirstPeriod - fileTypeNameLength - 1);
|
||||
//qDebug("indexOfFirstPeriod: %d\n", indexOfFirstPeriod);
|
||||
|
||||
indexOfFirstPeriod = fileCoord.indexOf('.');
|
||||
QString columnNumString = fileCoord.right(fileCoord.length() - indexOfFirstPeriod - 1);
|
||||
QString rowNumString = fileCoord.left(indexOfFirstPeriod);
|
||||
// If the first period, is the extension, then this is not a grid name;
|
||||
if (fileNameString.mid(indexOfFirstPeriod, fileNameString.length() - indexOfFirstPeriod) == extension) {
|
||||
qDebug("not a valid grid name... treat like tile Location Unspecified\n");
|
||||
isTileLocationUnspecified = true;
|
||||
} else {
|
||||
QString fileCoord = fileNameString.mid(indexOfFirstPeriod + 1,
|
||||
fileNameString.length() - indexOfFirstPeriod - fileTypeNameLength - 1);
|
||||
|
||||
int columnNum = columnNumString.toFloat();
|
||||
int rowNum = rowNumString.toFloat();
|
||||
//qDebug() << "fileCoord: " << fileCoord << "\n";
|
||||
indexOfFirstPeriod = fileCoord.indexOf('.');
|
||||
|
||||
//qDebug("indexOfFirstPeriod: %d\n", indexOfFirstPeriod);
|
||||
|
||||
QString columnNumString = fileCoord.right(fileCoord.length() - indexOfFirstPeriod - 1);
|
||||
QString rowNumString = fileCoord.left(indexOfFirstPeriod);
|
||||
|
||||
//qDebug() << "columnNumString: " << columnNumString << "\n";
|
||||
//qDebug() << "rowNumString: " << rowNumString << "\n";
|
||||
|
||||
columnNum = columnNumString.toFloat();
|
||||
rowNum = rowNumString.toFloat();
|
||||
|
||||
// If there are no "grid sections" in the filename, then we're going to get
|
||||
if (columnNum < 1 || rowNum < 1) {
|
||||
qDebug("not a valid grid name... treat like tile Location Unspecified\n");
|
||||
isTileLocationUnspecified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isTileLocationUnspecified) {
|
||||
qDebug("tile Location is Unspecified... \n");
|
||||
columnNum = unspecifiedColumnNum;
|
||||
rowNum = unspecifiedRowNum;
|
||||
|
||||
unspecifiedColumnNum++;
|
||||
if (unspecifiedColumnNum > unspecifiedSquare) {
|
||||
unspecifiedColumnNum = 1;
|
||||
unspecifiedRowNum++;
|
||||
}
|
||||
}
|
||||
qDebug("columnNum: %d\t rowNum: %d\n", columnNum, rowNum);
|
||||
|
||||
_mouseVoxel.x = originalX + (columnNum - 1) * _mouseVoxel.s;
|
||||
|
|
|
@ -77,3 +77,12 @@ void ToolsPalette::render(int screenWidth, int screenHeight) {
|
|||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
bool ToolsPalette::isActive() {
|
||||
for (unsigned int i = 0; i < _tools.size(); ++i) {
|
||||
if (_tools[i]->isActive()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
void addTool(Tool* tool);
|
||||
void render(int screenWidth, int screenHeight);
|
||||
|
||||
bool isActive();
|
||||
|
||||
private:
|
||||
QImage _textureImage;
|
||||
GLuint _textureID;
|
||||
|
|
|
@ -73,10 +73,29 @@ void VoxelSystem::nodeDeleted(VoxelNode* node) {
|
|||
}
|
||||
}
|
||||
|
||||
// returns an available index, starts by reusing a previously freed index, but if there isn't one available
|
||||
// it will use the end of the VBO array and grow our accounting of that array.
|
||||
// and makes the index available for some other node to use
|
||||
glBufferIndex VoxelSystem::getNextBufferIndex() {
|
||||
glBufferIndex output = GLBUFFER_INDEX_UNKNOWN;
|
||||
// if there's a free index, use it...
|
||||
if (_freeIndexes.size() > 0) {
|
||||
output = _freeIndexes.back();
|
||||
_freeIndexes.pop_back();
|
||||
} else {
|
||||
output = _voxelsInWriteArrays;
|
||||
_voxelsInWriteArrays++;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Doesn't actually clean up the VBOs for the index, but does release responsibility of the index from the VoxelNode,
|
||||
// and makes the index available for some other node to use
|
||||
void VoxelSystem::freeBufferIndex(glBufferIndex index) {
|
||||
_freeIndexes.push_back(index);
|
||||
}
|
||||
|
||||
// This will run through the list of _freeIndexes and reset their VBO array values to be "invisible".
|
||||
void VoxelSystem::clearFreeBufferIndexes() {
|
||||
for (int i = 0; i < _freeIndexes.size(); i++) {
|
||||
glBufferIndex nodeIndex = _freeIndexes[i];
|
||||
|
@ -246,12 +265,13 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
_callsToTreesToArrays++;
|
||||
if (_writeRenderFullVBO) {
|
||||
_voxelsInWriteArrays = 0; // reset our VBO
|
||||
_freeIndexes.clear(); // reset our free indexes
|
||||
}
|
||||
_voxelsUpdated = newTreeToArrays(_tree->rootNode);
|
||||
_tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean
|
||||
|
||||
if (_writeRenderFullVBO) {
|
||||
_abandonedVBOSlots = 0; // reset the count of our abandoned slots
|
||||
_abandonedVBOSlots = 0; // reset the count of our abandoned slots, why is this here and not earlier????
|
||||
}
|
||||
|
||||
// since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are
|
||||
|
@ -399,15 +419,13 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) {
|
|||
if (node->getShouldRender()) {
|
||||
glm::vec3 startVertex = node->getCorner();
|
||||
float voxelScale = node->getScale();
|
||||
glBufferIndex nodeIndex = _voxelsInWriteArrays;
|
||||
glBufferIndex nodeIndex = getNextBufferIndex();
|
||||
|
||||
// populate the array with points for the 8 vertices
|
||||
// and RGB color for each added vertex
|
||||
updateNodeInArrays(nodeIndex, startVertex, voxelScale, node->getColor());
|
||||
node->setBufferIndex(nodeIndex);
|
||||
node->setVoxelSystem(this);
|
||||
_writeVoxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode
|
||||
_voxelsInWriteArrays++; // our know vertices in the arrays
|
||||
return 1; // rendered
|
||||
} else {
|
||||
node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
|
||||
|
@ -444,10 +462,9 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
|
|||
if (node->isKnownBufferIndex()) {
|
||||
nodeIndex = node->getBufferIndex();
|
||||
} else {
|
||||
nodeIndex = _voxelsInWriteArrays;
|
||||
nodeIndex = getNextBufferIndex();
|
||||
node->setBufferIndex(nodeIndex);
|
||||
node->setVoxelSystem(this);
|
||||
_voxelsInWriteArrays++;
|
||||
}
|
||||
_writeVoxelDirtyArray[nodeIndex] = true;
|
||||
|
||||
|
|
|
@ -200,6 +200,7 @@ private:
|
|||
|
||||
void freeBufferIndex(glBufferIndex index);
|
||||
void clearFreeBufferIndexes();
|
||||
glBufferIndex getNextBufferIndex();
|
||||
|
||||
bool _falseColorizeBySource;
|
||||
int _dataSourceID;
|
||||
|
|
|
@ -21,7 +21,7 @@ class QNetworkReply;
|
|||
|
||||
class Avatar;
|
||||
|
||||
class AvatarVoxelSystem : public QObject, public VoxelSystem {
|
||||
class AvatarVoxelSystem : public VoxelSystem {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
|
|
@ -61,6 +61,8 @@ void* AudioInjectionManager::injectAudioViaThread(void* args) {
|
|||
Node* audioMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
if (audioMixer) {
|
||||
_destinationSocket = *audioMixer->getActiveSocket();
|
||||
} else {
|
||||
pthread_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <UDPSocket.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AudioInjector.h"
|
||||
|
||||
|
@ -21,7 +21,8 @@ AudioInjector::AudioInjector(const char* filename) :
|
|||
_radius(0.0f),
|
||||
_volume(MAX_INJECTOR_VOLUME),
|
||||
_indexOfNextSlot(0),
|
||||
_isInjectingAudio(false)
|
||||
_isInjectingAudio(false),
|
||||
_lastFrameIntensity(0.0f)
|
||||
{
|
||||
loadRandomIdentifier(_streamIdentifier, STREAM_IDENTIFIER_NUM_BYTES);
|
||||
|
||||
|
@ -51,7 +52,8 @@ AudioInjector::AudioInjector(int maxNumSamples) :
|
|||
_radius(0.0f),
|
||||
_volume(MAX_INJECTOR_VOLUME),
|
||||
_indexOfNextSlot(0),
|
||||
_isInjectingAudio(false)
|
||||
_isInjectingAudio(false),
|
||||
_lastFrameIntensity(0.0f)
|
||||
{
|
||||
loadRandomIdentifier(_streamIdentifier, STREAM_IDENTIFIER_NUM_BYTES);
|
||||
|
||||
|
@ -114,6 +116,18 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination
|
|||
|
||||
injectorSocket->send(destinationSocket, dataPacket, sizeof(dataPacket));
|
||||
|
||||
// calculate the intensity for this frame
|
||||
float lastRMS = 0;
|
||||
|
||||
for (int j = 0; j < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; j++) {
|
||||
lastRMS += _audioSampleArray[i + j] * _audioSampleArray[i + j];
|
||||
}
|
||||
|
||||
lastRMS /= BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
lastRMS = sqrtf(lastRMS);
|
||||
|
||||
_lastFrameIntensity = lastRMS / std::numeric_limits<int16_t>::max();
|
||||
|
||||
int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * INJECT_INTERVAL_USECS) - usecTimestampNow();
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
@ -131,8 +145,8 @@ void AudioInjector::addSample(const int16_t sample) {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioInjector::addSamples(int16_t* sampleBuffer, int numSamples) {
|
||||
if (_audioSampleArray + _indexOfNextSlot + numSamples <= _audioSampleArray + (_numTotalSamples / sizeof(int16_t))) {
|
||||
void AudioInjector::addSamples(int16_t* sampleBuffer, int numSamples) {
|
||||
if (_audioSampleArray + _indexOfNextSlot + numSamples <= _audioSampleArray + _numTotalSamples) {
|
||||
// only copy the audio from the sample buffer if there's space
|
||||
memcpy(_audioSampleArray + _indexOfNextSlot, sampleBuffer, numSamples * sizeof(int16_t));
|
||||
_indexOfNextSlot += numSamples;
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
#ifndef __hifi__AudioInjector__
|
||||
#define __hifi__AudioInjector__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/component_wise.hpp>
|
||||
|
||||
#include <UDPSocket.h>
|
||||
|
@ -36,6 +35,8 @@ public:
|
|||
unsigned char getVolume() const { return _volume; }
|
||||
void setVolume(unsigned char volume) { _volume = volume; }
|
||||
|
||||
float getLastFrameIntensity() const { return _lastFrameIntensity; }
|
||||
|
||||
const glm::vec3& getPosition() const { return _position; }
|
||||
void setPosition(const glm::vec3& position) { _position = position; }
|
||||
|
||||
|
@ -57,6 +58,7 @@ private:
|
|||
unsigned char _volume;
|
||||
int _indexOfNextSlot;
|
||||
bool _isInjectingAudio;
|
||||
float _lastFrameIntensity;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AudioInjector__) */
|
||||
|
|
88
libraries/avatars/src/Agent.cpp
Normal file
88
libraries/avatars/src/Agent.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
//
|
||||
// Agent.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 7/1/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <QtScript/QScriptEngine>
|
||||
#import <QtNetwork/QtNetwork>
|
||||
|
||||
#include <NodeList.h>
|
||||
|
||||
#include "AvatarData.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
Agent::Agent() :
|
||||
_shouldStop(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Agent::run(QUrl scriptURL) {
|
||||
NodeList::getInstance()->setOwnerType(NODE_TYPE_AGENT);
|
||||
NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||
|
||||
QNetworkAccessManager* manager = new QNetworkAccessManager();
|
||||
|
||||
qDebug() << "Attemping download of " << scriptURL;
|
||||
|
||||
QNetworkReply* reply = manager->get(QNetworkRequest(scriptURL));
|
||||
|
||||
QEventLoop loop;
|
||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
|
||||
QString scriptString = QString(reply->readAll());
|
||||
|
||||
QScriptEngine engine;
|
||||
|
||||
AvatarData *testAvatarData = new AvatarData;
|
||||
|
||||
QScriptValue avatarDataValue = engine.newQObject(testAvatarData);
|
||||
engine.globalObject().setProperty("AvatarData", avatarDataValue);
|
||||
|
||||
QScriptValue agentValue = engine.newQObject(this);
|
||||
engine.globalObject().setProperty("Agent", agentValue);
|
||||
|
||||
qDebug() << "Downloaded script:" << scriptString;
|
||||
|
||||
qDebug() << "Evaluated script:" << engine.evaluate(scriptString).toString();
|
||||
|
||||
timeval thisSend;
|
||||
timeval lastDomainServerCheckIn = {};
|
||||
int numMicrosecondsSleep = 0;
|
||||
|
||||
const float DATA_SEND_INTERVAL_USECS = (1 / 60) * 1000 * 1000;
|
||||
|
||||
sockaddr_in senderAddress;
|
||||
unsigned char receivedData[MAX_PACKET_SIZE];
|
||||
ssize_t receivedBytes;
|
||||
|
||||
while (!_shouldStop) {
|
||||
// update the thisSend timeval to the current time
|
||||
gettimeofday(&thisSend, NULL);
|
||||
|
||||
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
||||
}
|
||||
|
||||
emit preSendCallback();
|
||||
|
||||
testAvatarData->sendData();
|
||||
|
||||
if (NodeList::getInstance()->getNodeSocket()->receive((sockaddr*) &senderAddress, receivedData, &receivedBytes)) {
|
||||
NodeList::getInstance()->processNodeData((sockaddr*) &senderAddress, receivedData, receivedBytes);
|
||||
}
|
||||
|
||||
// sleep for the correct amount of time to have data send be consistently timed
|
||||
if ((numMicrosecondsSleep = DATA_SEND_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) {
|
||||
usleep(numMicrosecondsSleep);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
32
libraries/avatars/src/Agent.h
Normal file
32
libraries/avatars/src/Agent.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// Agent.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 7/1/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__Agent__
|
||||
#define __hifi__Agent__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
class Agent : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Agent();
|
||||
|
||||
bool volatile _shouldStop;
|
||||
|
||||
void run(QUrl scriptUrl);
|
||||
signals:
|
||||
void preSendCallback();
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Operative__) */
|
|
@ -10,8 +10,9 @@
|
|||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AvatarData.h"
|
||||
#include <VoxelConstants.h>
|
||||
|
@ -50,6 +51,22 @@ AvatarData::~AvatarData() {
|
|||
delete _handData;
|
||||
}
|
||||
|
||||
void AvatarData::sendData() {
|
||||
|
||||
// called from Agent visual loop to send data
|
||||
if (Node* avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER)) {
|
||||
unsigned char packet[MAX_PACKET_SIZE];
|
||||
|
||||
unsigned char* endOfPacket = packet;
|
||||
endOfPacket += populateTypeAndVersion(endOfPacket, PACKET_TYPE_HEAD_DATA);
|
||||
endOfPacket += packNodeId(endOfPacket, NodeList::getInstance()->getOwnerID());
|
||||
|
||||
int numPacketBytes = (endOfPacket - packet) + getBroadcastData(endOfPacket);
|
||||
|
||||
NodeList::getInstance()->getNodeSocket()->send(avatarMixer->getActiveSocket(), packet, numPacketBytes);
|
||||
}
|
||||
}
|
||||
|
||||
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <NodeData.h>
|
||||
#include "HeadData.h"
|
||||
#include "HandData.h"
|
||||
|
@ -39,6 +41,7 @@ enum KeyState
|
|||
class JointData;
|
||||
|
||||
class AvatarData : public NodeData {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AvatarData(Node* owningNode = NULL);
|
||||
~AvatarData();
|
||||
|
@ -53,7 +56,6 @@ public:
|
|||
|
||||
// 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; }
|
||||
|
@ -103,6 +105,11 @@ public:
|
|||
void setHeadData(HeadData* headData) { _headData = headData; }
|
||||
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:
|
||||
glm::vec3 _position;
|
||||
glm::vec3 _handPosition;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
class AvatarData;
|
||||
class FingerData;
|
||||
|
|
|
@ -26,3 +26,6 @@ if (UNIX AND NOT APPLE)
|
|||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif (UNIX AND NOT APPLE)
|
||||
|
||||
# include GLM
|
||||
include(${MACRO_DIR}/IncludeGLM.cmake)
|
||||
include_glm(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "SharedUtil.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
int unpackNodeId(unsigned char* packedData, uint16_t* nodeId) {
|
||||
memcpy(nodeId, packedData, sizeof(uint16_t));
|
||||
|
@ -75,6 +75,7 @@ const char* NODE_TYPE_NAME_AUDIO_MIXER = "Audio Mixer";
|
|||
const char* NODE_TYPE_NAME_AVATAR_MIXER = "Avatar Mixer";
|
||||
const char* NODE_TYPE_NAME_AUDIO_INJECTOR = "Audio Injector";
|
||||
const char* NODE_TYPE_NAME_ANIMATION_SERVER = "Animation Server";
|
||||
const char* NODE_TYPE_NAME_UNASSIGNED = "Unassigned";
|
||||
const char* NODE_TYPE_NAME_UNKNOWN = "Unknown";
|
||||
|
||||
const char* Node::getTypeName() const {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "NodeData.h"
|
||||
#include "SimpleMovingAverage.h"
|
||||
|
|
|
@ -9,9 +9,12 @@
|
|||
#ifndef hifi_NodeData_h
|
||||
#define hifi_NodeData_h
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class Node;
|
||||
|
||||
class NodeData {
|
||||
class NodeData : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeData(Node* owningNode);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "NodeList.h"
|
||||
#include "NodeTypes.h"
|
||||
|
@ -366,6 +366,15 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte
|
|||
return readNodes;
|
||||
}
|
||||
|
||||
void NodeList::sendAssignmentRequest() {
|
||||
const char ASSIGNMENT_SERVER_HOSTNAME[] = "assignment.highfidelity.io";
|
||||
|
||||
static sockaddr_in assignmentServerSocket = socketForHostname(ASSIGNMENT_SERVER_HOSTNAME);
|
||||
assignmentServerSocket.sin_port = htons(ASSIGNMENT_SERVER_PORT);
|
||||
|
||||
_nodeSocket.send((sockaddr*) &assignmentServerSocket, &PACKET_TYPE_REQUEST_ASSIGNMENT, 1);
|
||||
}
|
||||
|
||||
Node* NodeList::addOrUpdateNode(sockaddr* publicSocket, sockaddr* localSocket, char nodeType, uint16_t nodeId) {
|
||||
NodeList::iterator node = end();
|
||||
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
#include <iterator>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include "Node.h"
|
||||
#include "NodeTypes.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -54,14 +55,16 @@ public:
|
|||
NodeListIterator begin() const;
|
||||
NodeListIterator end() const;
|
||||
|
||||
|
||||
NODE_TYPE getOwnerType() const { return _ownerType; }
|
||||
void setOwnerType(NODE_TYPE ownerType) { _ownerType = ownerType; }
|
||||
|
||||
const char* getDomainHostname() const { return _domainHostname; };
|
||||
void setDomainHostname(const char* domainHostname);
|
||||
|
||||
void setDomainIP(const char* domainIP);
|
||||
void setDomainIPToLocalhost();
|
||||
|
||||
char getOwnerType() const { return _ownerType; }
|
||||
|
||||
|
||||
uint16_t getLastNodeID() const { return _lastNodeID; }
|
||||
void increaseNodeID() { ++_lastNodeID; }
|
||||
|
||||
|
@ -80,9 +83,12 @@ public:
|
|||
void clear();
|
||||
|
||||
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest);
|
||||
|
||||
void sendDomainServerCheckIn();
|
||||
int processDomainServerList(unsigned char *packetData, size_t dataBytes);
|
||||
|
||||
void sendAssignmentRequest();
|
||||
|
||||
Node* nodeWithAddress(sockaddr *senderAddress);
|
||||
Node* nodeWithID(uint16_t nodeID);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
#include "OctalCode.h"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "PacketHeaders.h"
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ const PACKET_TYPE PACKET_TYPE_TRANSMITTER_DATA_V2 = 'T';
|
|||
const PACKET_TYPE PACKET_TYPE_ENVIRONMENT_DATA = 'e';
|
||||
const PACKET_TYPE PACKET_TYPE_DOMAIN_LIST_REQUEST = 'L';
|
||||
const PACKET_TYPE PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY = 'C';
|
||||
const PACKET_TYPE PACKET_TYPE_REQUEST_ASSIGNMENT = 'r';
|
||||
const PACKET_TYPE PACKET_TYPE_SEND_ASSIGNMENT = 's';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_STATS = '#';
|
||||
|
||||
typedef char PACKET_VERSION;
|
||||
|
@ -52,4 +54,6 @@ const int MAX_PACKET_HEADER_BYTES = sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION)
|
|||
#define ADD_SCENE_COMMAND "add scene"
|
||||
#define TEST_COMMAND "a message"
|
||||
|
||||
const int ASSIGNMENT_SERVER_PORT = 7007;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "PerfStat.h"
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "OctalCode.h"
|
||||
#include "PacketHeaders.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Systime.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "UDPSocket.h"
|
||||
|
||||
|
@ -118,6 +118,17 @@ unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket) {
|
|||
}
|
||||
}
|
||||
|
||||
sockaddr_in socketForHostname(const char* hostname) {
|
||||
struct hostent* pHostInfo;
|
||||
sockaddr_in newSocket;
|
||||
|
||||
if ((pHostInfo = gethostbyname(hostname))) {
|
||||
memcpy(&newSocket.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
||||
}
|
||||
|
||||
return newSocket;
|
||||
}
|
||||
|
||||
UDPSocket::UDPSocket(int listeningPort) : listeningPort(listeningPort), blocking(true) {
|
||||
init();
|
||||
// create the socket
|
||||
|
|
|
@ -42,5 +42,6 @@ int packSocket(unsigned char* packStore, sockaddr* socketToPack);
|
|||
int unpackSocket(unsigned char* packedData, sockaddr* unpackDestSocket);
|
||||
int getLocalAddress();
|
||||
unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket);
|
||||
sockaddr_in socketForHostname(const char* hostname);
|
||||
|
||||
#endif /* defined(__interface__UDPSocket__) */
|
||||
|
|
Loading…
Reference in a new issue