mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-14 02:06:30 +02:00
first cut at splitting out PACKET_TYPE_VOXEL_QUERY from PACKET_TYPE_HEAD_DATA
This commit is contained in:
parent
ba5db325aa
commit
015adeedcb
18 changed files with 510 additions and 314 deletions
|
@ -1,9 +1,16 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(TARGET_NAME domain-server)
|
||||
|
||||
set(ROOT_DIR ..)
|
||||
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
||||
|
||||
set(TARGET_NAME domain-server)
|
||||
# setup for find modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/")
|
||||
|
||||
# set up the external glm library
|
||||
include(${MACRO_DIR}/IncludeGLM.cmake)
|
||||
include_glm(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
include(${MACRO_DIR}/SetupHifiProject.cmake)
|
||||
|
||||
|
|
|
@ -2301,21 +2301,6 @@ void Application::updateAvatar(float deltaTime) {
|
|||
_myAvatar.getHead().setAudioLoudness(_audio.getLastInputLoudness());
|
||||
#endif
|
||||
|
||||
// Update Avatar with latest camera and view frustum data...
|
||||
// NOTE: we get this from the view frustum, to make it simpler, since the
|
||||
// loadViewFrumstum() method will get the correct details from the camera
|
||||
// We could optimize this to not actually load the viewFrustum, since we don't
|
||||
// actually need to calculate the view frustum planes to send these details
|
||||
// to the server.
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
_myAvatar.setCameraPosition(_viewFrustum.getPosition());
|
||||
_myAvatar.setCameraOrientation(_viewFrustum.getOrientation());
|
||||
_myAvatar.setCameraFov(_viewFrustum.getFieldOfView());
|
||||
_myAvatar.setCameraAspectRatio(_viewFrustum.getAspectRatio());
|
||||
_myAvatar.setCameraNearClip(_viewFrustum.getNearClip());
|
||||
_myAvatar.setCameraFarClip(_viewFrustum.getFarClip());
|
||||
_myAvatar.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
|
@ -2330,7 +2315,7 @@ void Application::updateAvatar(float deltaTime) {
|
|||
|
||||
endOfBroadcastStringWrite += _myAvatar.getBroadcastData(endOfBroadcastStringWrite);
|
||||
|
||||
const char nodeTypesOfInterest[] = { NODE_TYPE_VOXEL_SERVER, NODE_TYPE_AVATAR_MIXER };
|
||||
const char nodeTypesOfInterest[] = { NODE_TYPE_AVATAR_MIXER };
|
||||
controlledBroadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString,
|
||||
nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
|
||||
|
||||
|
@ -2339,6 +2324,48 @@ void Application::updateAvatar(float deltaTime) {
|
|||
if (shouldDo(AVATAR_URLS_SEND_INTERVAL, deltaTime)) {
|
||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL());
|
||||
}
|
||||
|
||||
// Update _viewFrustum with latest camera and view frustum data...
|
||||
// NOTE: we get this from the view frustum, to make it simpler, since the
|
||||
// loadViewFrumstum() method will get the correct details from the camera
|
||||
// We could optimize this to not actually load the viewFrustum, since we don't
|
||||
// actually need to calculate the view frustum planes to send these details
|
||||
// to the server.
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
|
||||
// Update my voxel servers with my current voxel query...
|
||||
queryVoxels();
|
||||
}
|
||||
|
||||
void Application::queryVoxels() {
|
||||
// Need to update this to support multiple different servers...
|
||||
|
||||
_voxelQuery.setCameraPosition(_viewFrustum.getPosition());
|
||||
_voxelQuery.setCameraOrientation(_viewFrustum.getOrientation());
|
||||
_voxelQuery.setCameraFov(_viewFrustum.getFieldOfView());
|
||||
_voxelQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio());
|
||||
_voxelQuery.setCameraNearClip(_viewFrustum.getNearClip());
|
||||
_voxelQuery.setCameraFarClip(_viewFrustum.getFarClip());
|
||||
_voxelQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
unsigned char voxelQueryPacket[MAX_PACKET_SIZE];
|
||||
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
||||
|
||||
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, PACKET_TYPE_VOXEL_QUERY);
|
||||
|
||||
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
||||
endOfVoxelQueryPacket += ownerUUID.size();
|
||||
|
||||
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
||||
|
||||
const char nodeTypesOfInterest[] = { NODE_TYPE_VOXEL_SERVER };
|
||||
controlledBroadcastToNodes(voxelQueryPacket, endOfVoxelQueryPacket - voxelQueryPacket,
|
||||
nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <NetworkPacket.h>
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <VoxelQuery.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "Audio.h"
|
||||
|
@ -218,6 +219,7 @@ private:
|
|||
void renderFollowIndicator();
|
||||
void updateAvatar(float deltaTime);
|
||||
void updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection);
|
||||
void queryVoxels();
|
||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
|
||||
void displayOculus(Camera& whichCamera);
|
||||
|
@ -280,9 +282,11 @@ private:
|
|||
QByteArray _voxelsFilename;
|
||||
bool _wantToKillLocalVoxels;
|
||||
|
||||
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
|
||||
Oscilloscope _audioScope;
|
||||
|
||||
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
|
||||
|
||||
MyAvatar _myAvatar; // The rendered avatar of oneself
|
||||
Profile _profile; // The data-server linked profile for this user
|
||||
|
|
|
@ -32,17 +32,7 @@ AvatarData::AvatarData(Node* owningNode) :
|
|||
_newScale(1.0f),
|
||||
_leaderUUID(),
|
||||
_handState(0),
|
||||
_cameraPosition(0,0,0),
|
||||
_cameraOrientation(),
|
||||
_cameraFov(0.0f),
|
||||
_cameraAspectRatio(0.0f),
|
||||
_cameraNearClip(0.0f),
|
||||
_cameraFarClip(0.0f),
|
||||
_keyState(NO_KEY_DOWN),
|
||||
_wantColor(true),
|
||||
_wantDelta(true),
|
||||
_wantLowResMoving(true),
|
||||
_wantOcclusionCulling(true),
|
||||
_headData(NULL),
|
||||
_handData(NULL)
|
||||
{
|
||||
|
@ -116,17 +106,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
|
||||
destinationBuffer += sizeof(float);
|
||||
|
||||
// camera details
|
||||
memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition));
|
||||
destinationBuffer += sizeof(_cameraPosition);
|
||||
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, _cameraOrientation);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _cameraFov);
|
||||
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _cameraAspectRatio);
|
||||
destinationBuffer += packClipValueToTwoByte(destinationBuffer, _cameraNearClip);
|
||||
destinationBuffer += packClipValueToTwoByte(destinationBuffer, _cameraFarClip);
|
||||
memcpy(destinationBuffer, &_cameraEyeOffsetPosition, sizeof(_cameraEyeOffsetPosition));
|
||||
destinationBuffer += sizeof(_cameraEyeOffsetPosition);
|
||||
|
||||
// chat message
|
||||
*destinationBuffer++ = _chatMessage.size();
|
||||
memcpy(destinationBuffer, _chatMessage.data(), _chatMessage.size() * sizeof(char));
|
||||
|
@ -134,10 +113,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
|
||||
// bitMask of less than byte wide items
|
||||
unsigned char bitItems = 0;
|
||||
if (_wantLowResMoving) { setAtBit(bitItems, WANT_LOW_RES_MOVING_BIT); }
|
||||
if (_wantColor) { setAtBit(bitItems, WANT_COLOR_AT_BIT); }
|
||||
if (_wantDelta) { setAtBit(bitItems, WANT_DELTA_AT_BIT); }
|
||||
if (_wantOcclusionCulling) { setAtBit(bitItems, WANT_OCCLUSION_CULLING_BIT); }
|
||||
|
||||
// key state
|
||||
setSemiNibbleAt(bitItems,KEY_STATE_START_BIT,_keyState);
|
||||
|
@ -182,7 +157,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
*destinationBuffer++ = (unsigned char)it->jointID;
|
||||
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, it->rotation);
|
||||
}
|
||||
|
||||
|
||||
return destinationBuffer - bufferStart;
|
||||
}
|
||||
|
||||
|
@ -259,17 +234,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
|
||||
// camera details
|
||||
memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition));
|
||||
sourceBuffer += sizeof(_cameraPosition);
|
||||
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, _cameraOrientation);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_cameraFov);
|
||||
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer,_cameraAspectRatio);
|
||||
sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer,_cameraNearClip);
|
||||
sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer,_cameraFarClip);
|
||||
memcpy(&_cameraEyeOffsetPosition, sourceBuffer, sizeof(_cameraEyeOffsetPosition));
|
||||
sourceBuffer += sizeof(_cameraEyeOffsetPosition);
|
||||
|
||||
// the rest is a chat message
|
||||
int chatMessageSize = *sourceBuffer++;
|
||||
_chatMessage = string((char*)sourceBuffer, chatMessageSize);
|
||||
|
@ -278,10 +242,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
// voxel sending features...
|
||||
unsigned char bitItems = 0;
|
||||
bitItems = (unsigned char)*sourceBuffer++;
|
||||
_wantLowResMoving = oneAtBit(bitItems, WANT_LOW_RES_MOVING_BIT);
|
||||
_wantColor = oneAtBit(bitItems, WANT_COLOR_AT_BIT);
|
||||
_wantDelta = oneAtBit(bitItems, WANT_DELTA_AT_BIT);
|
||||
_wantOcclusionCulling = oneAtBit(bitItems, WANT_OCCLUSION_CULLING_BIT);
|
||||
|
||||
// key state, stored as a semi-nibble in the bitItems
|
||||
_keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT);
|
||||
|
@ -330,157 +290,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, it->rotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
||||
glm::vec3 AvatarData::calculateCameraDirection() const {
|
||||
glm::vec3 direction = glm::vec3(_cameraOrientation * glm::vec4(IDENTITY_FRONT, 0.0f));
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
|
||||
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix) {
|
||||
int16_t outVal = (int16_t)(scalar * (float)(1 << radix));
|
||||
memcpy(buffer, &outVal, sizeof(uint16_t));
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix) {
|
||||
*destinationPointer = *byteFixedPointer / (float)(1 << radix);
|
||||
return sizeof(int16_t);
|
||||
}
|
||||
|
||||
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix) {
|
||||
const unsigned char* startPosition = destBuffer;
|
||||
destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.x, radix);
|
||||
destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.y, radix);
|
||||
destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.z, radix);
|
||||
return destBuffer - startPosition;
|
||||
}
|
||||
|
||||
int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix) {
|
||||
const unsigned char* startPosition = sourceBuffer;
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.x), radix);
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.y), radix);
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.z), radix);
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
||||
|
||||
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
|
||||
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0);
|
||||
|
||||
uint16_t angleHolder = floorf((angle + 180) * ANGLE_CONVERSION_RATIO);
|
||||
memcpy(buffer, &angleHolder, sizeof(uint16_t));
|
||||
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer) {
|
||||
*destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.0 - 180;
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) {
|
||||
const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.0);
|
||||
uint16_t quatParts[4];
|
||||
quatParts[0] = floorf((quatInput.x + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[1] = floorf((quatInput.y + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[2] = floorf((quatInput.z + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[3] = floorf((quatInput.w + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
|
||||
memcpy(buffer, &quatParts, sizeof(quatParts));
|
||||
return sizeof(quatParts);
|
||||
}
|
||||
|
||||
int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput) {
|
||||
uint16_t quatParts[4];
|
||||
memcpy(&quatParts, buffer, sizeof(quatParts));
|
||||
|
||||
quatOutput.x = ((quatParts[0] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
quatOutput.y = ((quatParts[1] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
quatOutput.z = ((quatParts[2] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
quatOutput.w = ((quatParts[3] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
|
||||
return sizeof(quatParts);
|
||||
}
|
||||
|
||||
float SMALL_LIMIT = 10.0;
|
||||
float LARGE_LIMIT = 1000.0;
|
||||
|
||||
int packFloatRatioToTwoByte(unsigned char* buffer, float ratio) {
|
||||
// if the ratio is less than 10, then encode it as a positive number scaled from 0 to int16::max()
|
||||
int16_t ratioHolder;
|
||||
|
||||
if (ratio < SMALL_LIMIT) {
|
||||
const float SMALL_RATIO_CONVERSION_RATIO = (std::numeric_limits<int16_t>::max() / SMALL_LIMIT);
|
||||
ratioHolder = floorf(ratio * SMALL_RATIO_CONVERSION_RATIO);
|
||||
} else {
|
||||
const float LARGE_RATIO_CONVERSION_RATIO = std::numeric_limits<int16_t>::min() / LARGE_LIMIT;
|
||||
ratioHolder = floorf((std::min(ratio,LARGE_LIMIT) - SMALL_LIMIT) * LARGE_RATIO_CONVERSION_RATIO);
|
||||
}
|
||||
memcpy(buffer, &ratioHolder, sizeof(ratioHolder));
|
||||
return sizeof(ratioHolder);
|
||||
}
|
||||
|
||||
int unpackFloatRatioFromTwoByte(unsigned char* buffer, float& ratio) {
|
||||
int16_t ratioHolder;
|
||||
memcpy(&ratioHolder, buffer, sizeof(ratioHolder));
|
||||
|
||||
// If it's positive, than the original ratio was less than SMALL_LIMIT
|
||||
if (ratioHolder > 0) {
|
||||
ratio = (ratioHolder / (float) std::numeric_limits<int16_t>::max()) * SMALL_LIMIT;
|
||||
} else {
|
||||
// If it's negative, than the original ratio was between SMALL_LIMIT and LARGE_LIMIT
|
||||
ratio = ((ratioHolder / (float) std::numeric_limits<int16_t>::min()) * LARGE_LIMIT) + SMALL_LIMIT;
|
||||
}
|
||||
return sizeof(ratioHolder);
|
||||
}
|
||||
|
||||
int packClipValueToTwoByte(unsigned char* buffer, float clipValue) {
|
||||
// Clip values must be less than max signed 16bit integers
|
||||
assert(clipValue < std::numeric_limits<int16_t>::max());
|
||||
int16_t holder;
|
||||
|
||||
// if the clip is less than 10, then encode it as a positive number scaled from 0 to int16::max()
|
||||
if (clipValue < SMALL_LIMIT) {
|
||||
const float SMALL_RATIO_CONVERSION_RATIO = (std::numeric_limits<int16_t>::max() / SMALL_LIMIT);
|
||||
holder = floorf(clipValue * SMALL_RATIO_CONVERSION_RATIO);
|
||||
} else {
|
||||
// otherwise we store it as a negative integer
|
||||
holder = -1 * floorf(clipValue);
|
||||
}
|
||||
memcpy(buffer, &holder, sizeof(holder));
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue) {
|
||||
int16_t holder;
|
||||
memcpy(&holder, buffer, sizeof(holder));
|
||||
|
||||
// If it's positive, than the original clipValue was less than SMALL_LIMIT
|
||||
if (holder > 0) {
|
||||
clipValue = (holder / (float) std::numeric_limits<int16_t>::max()) * SMALL_LIMIT;
|
||||
} else {
|
||||
// If it's negative, than the original holder can be found as the opposite sign of holder
|
||||
clipValue = -1.0f * holder;
|
||||
}
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
int packFloatToByte(unsigned char* buffer, float value, float scaleBy) {
|
||||
unsigned char holder;
|
||||
const float CONVERSION_RATIO = (255 / scaleBy);
|
||||
holder = floorf(value * CONVERSION_RATIO);
|
||||
memcpy(buffer, &holder, sizeof(holder));
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy) {
|
||||
unsigned char holder;
|
||||
memcpy(&holder, buffer, sizeof(holder));
|
||||
value = ((float)holder / (float) 255) * scaleBy;
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
|
|
@ -27,12 +27,8 @@
|
|||
#include "HandData.h"
|
||||
|
||||
// First bitset
|
||||
const int WANT_LOW_RES_MOVING_BIT = 0;
|
||||
const int WANT_COLOR_AT_BIT = 1;
|
||||
const int WANT_DELTA_AT_BIT = 2;
|
||||
const int KEY_STATE_START_BIT = 3; // 4th and 5th bits
|
||||
const int HAND_STATE_START_BIT = 5; // 6th and 7th bits
|
||||
const int WANT_OCCLUSION_CULLING_BIT = 7; // 8th bit
|
||||
|
||||
// Second bitset
|
||||
const int IS_FACESHIFT_CONNECTED = 0;
|
||||
|
@ -85,26 +81,6 @@ public:
|
|||
void setHandState(char s) { _handState = s; }
|
||||
char getHandState() const { return _handState; }
|
||||
|
||||
// getters for camera details
|
||||
const glm::vec3& getCameraPosition() const { return _cameraPosition; }
|
||||
const glm::quat& getCameraOrientation() const { return _cameraOrientation; }
|
||||
float getCameraFov() const { return _cameraFov; }
|
||||
float getCameraAspectRatio() const { return _cameraAspectRatio; }
|
||||
float getCameraNearClip() const { return _cameraNearClip; }
|
||||
float getCameraFarClip() const { return _cameraFarClip; }
|
||||
const glm::vec3& getCameraEyeOffsetPosition() const { return _cameraEyeOffsetPosition; }
|
||||
|
||||
glm::vec3 calculateCameraDirection() const;
|
||||
|
||||
// setters for camera details
|
||||
void setCameraPosition(const glm::vec3& position) { _cameraPosition = position; }
|
||||
void setCameraOrientation(const glm::quat& orientation) { _cameraOrientation = orientation; }
|
||||
void setCameraFov(float fov) { _cameraFov = fov; }
|
||||
void setCameraAspectRatio(float aspectRatio) { _cameraAspectRatio = aspectRatio; }
|
||||
void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; }
|
||||
void setCameraFarClip(float farClip) { _cameraFarClip = farClip; }
|
||||
void setCameraEyeOffsetPosition(const glm::vec3& eyeOffsetPosition) { _cameraEyeOffsetPosition = eyeOffsetPosition; }
|
||||
|
||||
// key state
|
||||
void setKeyState(KeyState s) { _keyState = s; }
|
||||
KeyState keyState() const { return _keyState; }
|
||||
|
@ -115,22 +91,11 @@ public:
|
|||
const std::string& setChatMessage() const { return _chatMessage; }
|
||||
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
|
||||
|
||||
// related to Voxel Sending strategies
|
||||
bool getWantColor() const { return _wantColor; }
|
||||
bool getWantDelta() const { return _wantDelta; }
|
||||
bool getWantLowResMoving() const { return _wantLowResMoving; }
|
||||
bool getWantOcclusionCulling() const { return _wantOcclusionCulling; }
|
||||
const QUuid& getLeaderUUID() const { return _leaderUUID; }
|
||||
|
||||
void setHeadData(HeadData* headData) { _headData = headData; }
|
||||
void setHandData(HandData* handData) { _handData = handData; }
|
||||
|
||||
public slots:
|
||||
void setWantLowResMoving(bool wantLowResMoving) { _wantLowResMoving = wantLowResMoving; }
|
||||
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
||||
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
||||
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
||||
|
||||
protected:
|
||||
QUuid _uuid;
|
||||
|
||||
|
@ -151,27 +116,12 @@ protected:
|
|||
// Hand state (are we grabbing something or not)
|
||||
char _handState;
|
||||
|
||||
// camera details for the avatar
|
||||
glm::vec3 _cameraPosition;
|
||||
glm::quat _cameraOrientation;
|
||||
float _cameraFov;
|
||||
float _cameraAspectRatio;
|
||||
float _cameraNearClip;
|
||||
float _cameraFarClip;
|
||||
glm::vec3 _cameraEyeOffsetPosition;
|
||||
|
||||
// key state
|
||||
KeyState _keyState;
|
||||
|
||||
// chat message
|
||||
std::string _chatMessage;
|
||||
|
||||
// voxel server sending items
|
||||
bool _wantColor;
|
||||
bool _wantDelta;
|
||||
bool _wantLowResMoving;
|
||||
bool _wantOcclusionCulling;
|
||||
|
||||
std::vector<JointData> _joints;
|
||||
|
||||
HeadData* _headData;
|
||||
|
@ -190,38 +140,4 @@ public:
|
|||
glm::quat rotation;
|
||||
};
|
||||
|
||||
// These pack/unpack functions are designed to start specific known types in as efficient a manner
|
||||
// as possible. Taking advantage of the known characteristics of the semantic types.
|
||||
|
||||
// Angles are known to be between 0 and 360deg, this allows us to encode in 16bits with great accuracy
|
||||
int packFloatAngleToTwoByte(unsigned char* buffer, float angle);
|
||||
int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer);
|
||||
|
||||
// Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0
|
||||
// this allows us to encode each component in 16bits with great accuracy
|
||||
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput);
|
||||
int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput);
|
||||
|
||||
// Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they
|
||||
// are never greater than 1000 to 1, this allows us to encode each component in 16bits
|
||||
int packFloatRatioToTwoByte(unsigned char* buffer, float ratio);
|
||||
int unpackFloatRatioFromTwoByte(unsigned char* buffer, float& ratio);
|
||||
|
||||
// Near/Far Clip values need the be highly accurate when less than 10, but only integer accuracy above 10 and
|
||||
// they are never greater than 16,000, this allows us to encode each component in 16bits
|
||||
int packClipValueToTwoByte(unsigned char* buffer, float clipValue);
|
||||
int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue);
|
||||
|
||||
// Positive floats that don't need to be very precise
|
||||
int packFloatToByte(unsigned char* buffer, float value, float scaleBy);
|
||||
int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy);
|
||||
|
||||
// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
|
||||
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix);
|
||||
int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix);
|
||||
|
||||
// A convenience for sending vec3's as fixed-poimt floats
|
||||
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
|
||||
int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix);
|
||||
|
||||
#endif /* defined(__hifi__AvatarData__) */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "HandData.h"
|
||||
#include "AvatarData.h"
|
||||
#include <SharedUtil.h>
|
||||
|
||||
// Glove flags
|
||||
#define GLOVE_FLAG_RAVE 0x01
|
||||
|
|
|
@ -13,6 +13,11 @@ setup_hifi_library(${TARGET_NAME})
|
|||
|
||||
qt5_use_modules(${TARGET_NAME} Network)
|
||||
|
||||
# include GLM
|
||||
include(${MACRO_DIR}/IncludeGLM.cmake)
|
||||
include_glm(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
|
||||
set(EXTERNAL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
|
||||
|
||||
if (WIN32)
|
||||
|
@ -29,7 +34,3 @@ if (UNIX AND NOT APPLE)
|
|||
find_package(Threads REQUIRED)
|
||||
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})
|
||||
|
|
|
@ -20,7 +20,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
|||
return 2;
|
||||
|
||||
case PACKET_TYPE_HEAD_DATA:
|
||||
return 10;
|
||||
return 11;
|
||||
|
||||
case PACKET_TYPE_AVATAR_URLS:
|
||||
return 2;
|
||||
|
|
|
@ -24,11 +24,6 @@ const PACKET_TYPE PACKET_TYPE_INJECT_AUDIO = 'I';
|
|||
const PACKET_TYPE PACKET_TYPE_MIXED_AUDIO = 'A';
|
||||
const PACKET_TYPE PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO = 'M';
|
||||
const PACKET_TYPE PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO = 'm';
|
||||
const PACKET_TYPE PACKET_TYPE_SET_VOXEL = 'S';
|
||||
const PACKET_TYPE PACKET_TYPE_SET_VOXEL_DESTRUCTIVE = 'O';
|
||||
const PACKET_TYPE PACKET_TYPE_ERASE_VOXEL = 'E';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_DATA = 'V';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_DATA_MONOCHROME = 'v';
|
||||
const PACKET_TYPE PACKET_TYPE_BULK_AVATAR_DATA = 'X';
|
||||
const PACKET_TYPE PACKET_TYPE_AVATAR_URLS = 'U';
|
||||
const PACKET_TYPE PACKET_TYPE_AVATAR_FACE_VIDEO = 'F';
|
||||
|
@ -39,13 +34,19 @@ const PACKET_TYPE PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY = 'C';
|
|||
const PACKET_TYPE PACKET_TYPE_REQUEST_ASSIGNMENT = 'r';
|
||||
const PACKET_TYPE PACKET_TYPE_CREATE_ASSIGNMENT = 's';
|
||||
const PACKET_TYPE PACKET_TYPE_DEPLOY_ASSIGNMENT = 'd';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_STATS = '#';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION = 'J';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION_REQUEST = 'j';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_PUT = 'p';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_GET = 'g';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_SEND = 'u';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_CONFIRM = 'c';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_QUERY = 'q';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_DATA = 'V';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_DATA_MONOCHROME = 'v';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_STATS = '#';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION = 'J';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION_REQUEST = 'j';
|
||||
const PACKET_TYPE PACKET_TYPE_SET_VOXEL = 'S';
|
||||
const PACKET_TYPE PACKET_TYPE_SET_VOXEL_DESTRUCTIVE = 'O';
|
||||
const PACKET_TYPE PACKET_TYPE_ERASE_VOXEL = 'E';
|
||||
|
||||
typedef char PACKET_VERSION;
|
||||
|
||||
|
|
|
@ -535,3 +535,149 @@ int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int*
|
|||
}
|
||||
return -1; // error case
|
||||
}
|
||||
|
||||
// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
|
||||
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix) {
|
||||
int16_t outVal = (int16_t)(scalar * (float)(1 << radix));
|
||||
memcpy(buffer, &outVal, sizeof(uint16_t));
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix) {
|
||||
*destinationPointer = *byteFixedPointer / (float)(1 << radix);
|
||||
return sizeof(int16_t);
|
||||
}
|
||||
|
||||
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix) {
|
||||
const unsigned char* startPosition = destBuffer;
|
||||
destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.x, radix);
|
||||
destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.y, radix);
|
||||
destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.z, radix);
|
||||
return destBuffer - startPosition;
|
||||
}
|
||||
|
||||
int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix) {
|
||||
const unsigned char* startPosition = sourceBuffer;
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.x), radix);
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.y), radix);
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.z), radix);
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
||||
|
||||
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
|
||||
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0);
|
||||
|
||||
uint16_t angleHolder = floorf((angle + 180) * ANGLE_CONVERSION_RATIO);
|
||||
memcpy(buffer, &angleHolder, sizeof(uint16_t));
|
||||
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer) {
|
||||
*destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.0 - 180;
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) {
|
||||
const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.0);
|
||||
uint16_t quatParts[4];
|
||||
quatParts[0] = floorf((quatInput.x + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[1] = floorf((quatInput.y + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[2] = floorf((quatInput.z + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[3] = floorf((quatInput.w + 1.0) * QUAT_PART_CONVERSION_RATIO);
|
||||
|
||||
memcpy(buffer, &quatParts, sizeof(quatParts));
|
||||
return sizeof(quatParts);
|
||||
}
|
||||
|
||||
int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput) {
|
||||
uint16_t quatParts[4];
|
||||
memcpy(&quatParts, buffer, sizeof(quatParts));
|
||||
|
||||
quatOutput.x = ((quatParts[0] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
quatOutput.y = ((quatParts[1] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
quatOutput.z = ((quatParts[2] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
quatOutput.w = ((quatParts[3] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0;
|
||||
|
||||
return sizeof(quatParts);
|
||||
}
|
||||
|
||||
float SMALL_LIMIT = 10.0;
|
||||
float LARGE_LIMIT = 1000.0;
|
||||
|
||||
int packFloatRatioToTwoByte(unsigned char* buffer, float ratio) {
|
||||
// if the ratio is less than 10, then encode it as a positive number scaled from 0 to int16::max()
|
||||
int16_t ratioHolder;
|
||||
|
||||
if (ratio < SMALL_LIMIT) {
|
||||
const float SMALL_RATIO_CONVERSION_RATIO = (std::numeric_limits<int16_t>::max() / SMALL_LIMIT);
|
||||
ratioHolder = floorf(ratio * SMALL_RATIO_CONVERSION_RATIO);
|
||||
} else {
|
||||
const float LARGE_RATIO_CONVERSION_RATIO = std::numeric_limits<int16_t>::min() / LARGE_LIMIT;
|
||||
ratioHolder = floorf((std::min(ratio,LARGE_LIMIT) - SMALL_LIMIT) * LARGE_RATIO_CONVERSION_RATIO);
|
||||
}
|
||||
memcpy(buffer, &ratioHolder, sizeof(ratioHolder));
|
||||
return sizeof(ratioHolder);
|
||||
}
|
||||
|
||||
int unpackFloatRatioFromTwoByte(unsigned char* buffer, float& ratio) {
|
||||
int16_t ratioHolder;
|
||||
memcpy(&ratioHolder, buffer, sizeof(ratioHolder));
|
||||
|
||||
// If it's positive, than the original ratio was less than SMALL_LIMIT
|
||||
if (ratioHolder > 0) {
|
||||
ratio = (ratioHolder / (float) std::numeric_limits<int16_t>::max()) * SMALL_LIMIT;
|
||||
} else {
|
||||
// If it's negative, than the original ratio was between SMALL_LIMIT and LARGE_LIMIT
|
||||
ratio = ((ratioHolder / (float) std::numeric_limits<int16_t>::min()) * LARGE_LIMIT) + SMALL_LIMIT;
|
||||
}
|
||||
return sizeof(ratioHolder);
|
||||
}
|
||||
|
||||
int packClipValueToTwoByte(unsigned char* buffer, float clipValue) {
|
||||
// Clip values must be less than max signed 16bit integers
|
||||
assert(clipValue < std::numeric_limits<int16_t>::max());
|
||||
int16_t holder;
|
||||
|
||||
// if the clip is less than 10, then encode it as a positive number scaled from 0 to int16::max()
|
||||
if (clipValue < SMALL_LIMIT) {
|
||||
const float SMALL_RATIO_CONVERSION_RATIO = (std::numeric_limits<int16_t>::max() / SMALL_LIMIT);
|
||||
holder = floorf(clipValue * SMALL_RATIO_CONVERSION_RATIO);
|
||||
} else {
|
||||
// otherwise we store it as a negative integer
|
||||
holder = -1 * floorf(clipValue);
|
||||
}
|
||||
memcpy(buffer, &holder, sizeof(holder));
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue) {
|
||||
int16_t holder;
|
||||
memcpy(&holder, buffer, sizeof(holder));
|
||||
|
||||
// If it's positive, than the original clipValue was less than SMALL_LIMIT
|
||||
if (holder > 0) {
|
||||
clipValue = (holder / (float) std::numeric_limits<int16_t>::max()) * SMALL_LIMIT;
|
||||
} else {
|
||||
// If it's negative, than the original holder can be found as the opposite sign of holder
|
||||
clipValue = -1.0f * holder;
|
||||
}
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
int packFloatToByte(unsigned char* buffer, float value, float scaleBy) {
|
||||
unsigned char holder;
|
||||
const float CONVERSION_RATIO = (255 / scaleBy);
|
||||
holder = floorf(value * CONVERSION_RATIO);
|
||||
memcpy(buffer, &holder, sizeof(holder));
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy) {
|
||||
unsigned char holder;
|
||||
memcpy(&holder, buffer, sizeof(holder));
|
||||
value = ((float)holder / (float) 255) * scaleBy;
|
||||
return sizeof(holder);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -113,4 +116,39 @@ public:
|
|||
|
||||
bool isBetween(int64_t value, int64_t max, int64_t min);
|
||||
|
||||
|
||||
// These pack/unpack functions are designed to start specific known types in as efficient a manner
|
||||
// as possible. Taking advantage of the known characteristics of the semantic types.
|
||||
|
||||
// Angles are known to be between 0 and 360deg, this allows us to encode in 16bits with great accuracy
|
||||
int packFloatAngleToTwoByte(unsigned char* buffer, float angle);
|
||||
int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer);
|
||||
|
||||
// Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0
|
||||
// this allows us to encode each component in 16bits with great accuracy
|
||||
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput);
|
||||
int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput);
|
||||
|
||||
// Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they
|
||||
// are never greater than 1000 to 1, this allows us to encode each component in 16bits
|
||||
int packFloatRatioToTwoByte(unsigned char* buffer, float ratio);
|
||||
int unpackFloatRatioFromTwoByte(unsigned char* buffer, float& ratio);
|
||||
|
||||
// Near/Far Clip values need the be highly accurate when less than 10, but only integer accuracy above 10 and
|
||||
// they are never greater than 16,000, this allows us to encode each component in 16bits
|
||||
int packClipValueToTwoByte(unsigned char* buffer, float clipValue);
|
||||
int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue);
|
||||
|
||||
// Positive floats that don't need to be very precise
|
||||
int packFloatToByte(unsigned char* buffer, float value, float scaleBy);
|
||||
int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy);
|
||||
|
||||
// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
|
||||
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix);
|
||||
int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix);
|
||||
|
||||
// A convenience for sending vec3's as fixed-poimt floats
|
||||
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
|
||||
int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix);
|
||||
|
||||
#endif /* defined(__hifi__SharedUtil__) */
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "VoxelSendThread.h"
|
||||
|
||||
VoxelNodeData::VoxelNodeData(Node* owningNode) :
|
||||
AvatarData(owningNode),
|
||||
VoxelQuery(owningNode),
|
||||
_viewSent(false),
|
||||
_voxelPacketAvailableBytes(MAX_VOXEL_PACKET_SIZE),
|
||||
_maxSearchLevel(1),
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <NodeData.h>
|
||||
#include <AvatarData.h>
|
||||
#include <VoxelQuery.h>
|
||||
|
||||
#include <CoverageMap.h>
|
||||
#include <VoxelConstants.h>
|
||||
|
@ -21,7 +21,7 @@
|
|||
class VoxelSendThread;
|
||||
class VoxelServer;
|
||||
|
||||
class VoxelNodeData : public AvatarData {
|
||||
class VoxelNodeData : public VoxelQuery {
|
||||
public:
|
||||
VoxelNodeData(Node* owningNode);
|
||||
~VoxelNodeData();
|
||||
|
|
|
@ -219,7 +219,16 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
|||
uint64_t start = usecTimestampNow();
|
||||
|
||||
bool shouldSendEnvironments = _myServer->wantSendEnvironments() && shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
||||
while (packetsSentThisInterval < _myServer->getPacketsPerClientPerInterval() - (shouldSendEnvironments ? 1 : 0)) {
|
||||
|
||||
int clientMaxPacketsPerInterval = nodeData->getMaxVoxelPacketsPerSecond() / INTERVALS_PER_SECOND;
|
||||
int maxPacketsPerInterval = std::max(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
|
||||
|
||||
|
||||
printf("deepestLevelVoxelDistributor()... packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
||||
packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||
nodeData->getMaxVoxelPacketsPerSecond(), clientMaxPacketsPerInterval);
|
||||
|
||||
while (packetsSentThisInterval < maxPacketsPerInterval - (shouldSendEnvironments ? 1 : 0)) {
|
||||
// Check to see if we're taking too long, and if so bail early...
|
||||
uint64_t now = usecTimestampNow();
|
||||
long elapsedUsec = (now - start);
|
||||
|
|
|
@ -419,8 +419,8 @@ void VoxelServer::run() {
|
|||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
|
||||
if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
|
||||
// If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
|
||||
if (packetData[0] == PACKET_TYPE_VOXEL_QUERY) {
|
||||
// If we got a PACKET_TYPE_VOXEL_QUERY, then we're talking to an NODE_TYPE_AVATAR, and we
|
||||
// need to make sure we have it in our nodeList.
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)packetData + numBytesPacketHeader,
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
|
|
|
@ -58,5 +58,6 @@ const float VIEW_FRUSTUM_FOV_OVERSEND = 60.0f;
|
|||
const int UNREASONABLY_DEEP_RECURSION = 20; // use this for something that you want to be shallow, but not spin out
|
||||
const int DANGEROUSLY_DEEP_RECURSION = 200; // use this for something that needs to go deeper
|
||||
|
||||
const int DEFAULT_MAX_VOXEL_PPS = 600; // the default maximum PPS we think a voxel server should send to a client
|
||||
|
||||
#endif
|
131
libraries/voxels/src/VoxelQuery.cpp
Normal file
131
libraries/voxels/src/VoxelQuery.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// VoxelQuery.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 10/24/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <UUID.h>
|
||||
#include "VoxelConstants.h"
|
||||
|
||||
#include "VoxelQuery.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const float fingerVectorRadix = 4; // bits of precision when converting from float<->fixed
|
||||
|
||||
VoxelQuery::VoxelQuery(Node* owningNode) :
|
||||
NodeData(owningNode),
|
||||
_uuid(),
|
||||
_cameraPosition(0,0,0),
|
||||
_cameraOrientation(),
|
||||
_cameraFov(0.0f),
|
||||
_cameraAspectRatio(0.0f),
|
||||
_cameraNearClip(0.0f),
|
||||
_cameraFarClip(0.0f),
|
||||
_wantColor(true),
|
||||
_wantDelta(true),
|
||||
_wantLowResMoving(true),
|
||||
_wantOcclusionCulling(true),
|
||||
_maxVoxelPPS(DEFAULT_MAX_VOXEL_PPS)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VoxelQuery::~VoxelQuery() {
|
||||
}
|
||||
|
||||
int VoxelQuery::getBroadcastData(unsigned char* destinationBuffer) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
// TODO: DRY this up to a shared method
|
||||
// that can pack any type given the number of bytes
|
||||
// and return the number of bytes to push the pointer
|
||||
|
||||
// UUID
|
||||
QByteArray uuidByteArray = _uuid.toRfc4122();
|
||||
memcpy(destinationBuffer, uuidByteArray.constData(), uuidByteArray.size());
|
||||
destinationBuffer += uuidByteArray.size();
|
||||
|
||||
// camera details
|
||||
memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition));
|
||||
destinationBuffer += sizeof(_cameraPosition);
|
||||
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, _cameraOrientation);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _cameraFov);
|
||||
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _cameraAspectRatio);
|
||||
destinationBuffer += packClipValueToTwoByte(destinationBuffer, _cameraNearClip);
|
||||
destinationBuffer += packClipValueToTwoByte(destinationBuffer, _cameraFarClip);
|
||||
memcpy(destinationBuffer, &_cameraEyeOffsetPosition, sizeof(_cameraEyeOffsetPosition));
|
||||
destinationBuffer += sizeof(_cameraEyeOffsetPosition);
|
||||
|
||||
// bitMask of less than byte wide items
|
||||
unsigned char bitItems = 0;
|
||||
if (_wantLowResMoving) { setAtBit(bitItems, WANT_LOW_RES_MOVING_BIT); }
|
||||
if (_wantColor) { setAtBit(bitItems, WANT_COLOR_AT_BIT); }
|
||||
if (_wantDelta) { setAtBit(bitItems, WANT_DELTA_AT_BIT); }
|
||||
if (_wantOcclusionCulling) { setAtBit(bitItems, WANT_OCCLUSION_CULLING_BIT); }
|
||||
|
||||
*destinationBuffer++ = bitItems;
|
||||
|
||||
// desired Max Voxel PPS
|
||||
memcpy(destinationBuffer, &_maxVoxelPPS, sizeof(_maxVoxelPPS));
|
||||
destinationBuffer += sizeof(_maxVoxelPPS);
|
||||
|
||||
return destinationBuffer - bufferStart;
|
||||
}
|
||||
|
||||
// called on the other nodes - assigns it to my views of the others
|
||||
int VoxelQuery::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
|
||||
// increment to push past the packet header
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
sourceBuffer += numBytesPacketHeader;
|
||||
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
// push past the node session UUID
|
||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// user UUID
|
||||
_uuid = QUuid::fromRfc4122(QByteArray((char*) sourceBuffer, NUM_BYTES_RFC4122_UUID));
|
||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// camera details
|
||||
memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition));
|
||||
sourceBuffer += sizeof(_cameraPosition);
|
||||
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, _cameraOrientation);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_cameraFov);
|
||||
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer,_cameraAspectRatio);
|
||||
sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer,_cameraNearClip);
|
||||
sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer,_cameraFarClip);
|
||||
memcpy(&_cameraEyeOffsetPosition, sourceBuffer, sizeof(_cameraEyeOffsetPosition));
|
||||
sourceBuffer += sizeof(_cameraEyeOffsetPosition);
|
||||
|
||||
// voxel sending features...
|
||||
unsigned char bitItems = 0;
|
||||
bitItems = (unsigned char)*sourceBuffer++;
|
||||
_wantLowResMoving = oneAtBit(bitItems, WANT_LOW_RES_MOVING_BIT);
|
||||
_wantColor = oneAtBit(bitItems, WANT_COLOR_AT_BIT);
|
||||
_wantDelta = oneAtBit(bitItems, WANT_DELTA_AT_BIT);
|
||||
_wantOcclusionCulling = oneAtBit(bitItems, WANT_OCCLUSION_CULLING_BIT);
|
||||
|
||||
// desired Max Voxel PPS
|
||||
memcpy(&_maxVoxelPPS, sourceBuffer, sizeof(_maxVoxelPPS));
|
||||
sourceBuffer += sizeof(_maxVoxelPPS);
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
||||
glm::vec3 VoxelQuery::calculateCameraDirection() const {
|
||||
glm::vec3 direction = glm::vec3(_cameraOrientation * glm::vec4(IDENTITY_FRONT, 0.0f));
|
||||
return direction;
|
||||
}
|
||||
|
105
libraries/voxels/src/VoxelQuery.h
Normal file
105
libraries/voxels/src/VoxelQuery.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
//
|
||||
// VoxelQuery.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/9/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__VoxelQuery__
|
||||
#define __hifi__VoxelQuery__
|
||||
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUuid>
|
||||
#include <QtCore/QVariantMap>
|
||||
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
#include <NodeData.h>
|
||||
|
||||
// First bitset
|
||||
const int WANT_LOW_RES_MOVING_BIT = 0;
|
||||
const int WANT_COLOR_AT_BIT = 1;
|
||||
const int WANT_DELTA_AT_BIT = 2;
|
||||
const int WANT_OCCLUSION_CULLING_BIT = 7; // 8th bit
|
||||
|
||||
class VoxelQuery : public NodeData {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VoxelQuery(Node* owningNode = NULL);
|
||||
~VoxelQuery();
|
||||
|
||||
int getBroadcastData(unsigned char* destinationBuffer);
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
QUuid& getUUID() { return _uuid; }
|
||||
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
||||
|
||||
// getters for camera details
|
||||
const glm::vec3& getCameraPosition() const { return _cameraPosition; }
|
||||
const glm::quat& getCameraOrientation() const { return _cameraOrientation; }
|
||||
float getCameraFov() const { return _cameraFov; }
|
||||
float getCameraAspectRatio() const { return _cameraAspectRatio; }
|
||||
float getCameraNearClip() const { return _cameraNearClip; }
|
||||
float getCameraFarClip() const { return _cameraFarClip; }
|
||||
const glm::vec3& getCameraEyeOffsetPosition() const { return _cameraEyeOffsetPosition; }
|
||||
|
||||
glm::vec3 calculateCameraDirection() const;
|
||||
|
||||
// setters for camera details
|
||||
void setCameraPosition(const glm::vec3& position) { _cameraPosition = position; }
|
||||
void setCameraOrientation(const glm::quat& orientation) { _cameraOrientation = orientation; }
|
||||
void setCameraFov(float fov) { _cameraFov = fov; }
|
||||
void setCameraAspectRatio(float aspectRatio) { _cameraAspectRatio = aspectRatio; }
|
||||
void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; }
|
||||
void setCameraFarClip(float farClip) { _cameraFarClip = farClip; }
|
||||
void setCameraEyeOffsetPosition(const glm::vec3& eyeOffsetPosition) { _cameraEyeOffsetPosition = eyeOffsetPosition; }
|
||||
|
||||
// related to Voxel Sending strategies
|
||||
bool getWantColor() const { return _wantColor; }
|
||||
bool getWantDelta() const { return _wantDelta; }
|
||||
bool getWantLowResMoving() const { return _wantLowResMoving; }
|
||||
bool getWantOcclusionCulling() const { return _wantOcclusionCulling; }
|
||||
int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPPS; }
|
||||
|
||||
public slots:
|
||||
void setWantLowResMoving(bool wantLowResMoving) { _wantLowResMoving = wantLowResMoving; }
|
||||
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
||||
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
||||
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
||||
void setMaxVoxelPacketsPerSecond(int maxVoxelPPS) { _maxVoxelPPS = maxVoxelPPS; }
|
||||
|
||||
protected:
|
||||
QUuid _uuid;
|
||||
|
||||
// camera details for the avatar
|
||||
glm::vec3 _cameraPosition;
|
||||
glm::quat _cameraOrientation;
|
||||
float _cameraFov;
|
||||
float _cameraAspectRatio;
|
||||
float _cameraNearClip;
|
||||
float _cameraFarClip;
|
||||
glm::vec3 _cameraEyeOffsetPosition;
|
||||
|
||||
// voxel server sending items
|
||||
bool _wantColor;
|
||||
bool _wantDelta;
|
||||
bool _wantLowResMoving;
|
||||
bool _wantOcclusionCulling;
|
||||
int _maxVoxelPPS;
|
||||
|
||||
private:
|
||||
// privatize the copy constructor and assignment operator so they cannot be called
|
||||
VoxelQuery(const VoxelQuery&);
|
||||
VoxelQuery& operator= (const VoxelQuery&);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelQuery__) */
|
Loading…
Reference in a new issue