mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-14 09:06:51 +02:00
Added wantResIn and wantColor feature between client and server
- Updated Voxel Server to support non-res-in version of voxel distribution - Updated agent data to allow client to send desired res-in and color state - added menu items to client debug menu to toggle wantResIn and wantColor
This commit is contained in:
parent
dd4303800d
commit
b196227385
7 changed files with 180 additions and 28 deletions
|
@ -104,6 +104,13 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
_tree->readBitstreamToTree(voxelData, numBytes - 1);
|
||||
}
|
||||
break;
|
||||
case PACKET_HEADER_VOXEL_DATA_MONOCHROME:
|
||||
{
|
||||
PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()");
|
||||
// ask the VoxelTree to read the MONOCHROME bitstream into the tree
|
||||
_tree->readBitstreamToTree(voxelData, numBytes - 1, false);
|
||||
}
|
||||
break;
|
||||
case PACKET_HEADER_ERASE_VOXEL:
|
||||
// ask the tree to read the "remove" bitstream
|
||||
_tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);
|
||||
|
|
|
@ -163,6 +163,8 @@ bool paintOn = false; // Whether to paint voxels as you fly aroun
|
|||
VoxelDetail paintingVoxel; // The voxel we're painting if we're painting
|
||||
unsigned char dominantColor = 0; // The dominant color of the voxel we're painting
|
||||
bool perfStatsOn = false; // Do we want to display perfStats?
|
||||
bool wantMonochrome = false; // ask server to send us in monochrome
|
||||
bool wantResIn = false; // ask server to res in
|
||||
|
||||
bool logOn = true; // Whether to show on-screen log
|
||||
|
||||
|
@ -1278,6 +1280,22 @@ int setRenderWarnings(int state) {
|
|||
return value;
|
||||
}
|
||||
|
||||
int setWantResIn(int state) {
|
||||
int value = setValue(state, &::wantResIn);
|
||||
if (state == MENU_ROW_PICKED) {
|
||||
::myAvatar.setWantResIn(::wantResIn);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int setWantMonochrome(int state) {
|
||||
int value = setValue(state, &::wantMonochrome);
|
||||
if (state == MENU_ROW_PICKED) {
|
||||
::myAvatar.setWantColor(!::wantMonochrome);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int setDisplayFrustum(int state) {
|
||||
return setValue(state, &::frustumOn);
|
||||
}
|
||||
|
@ -1370,6 +1388,8 @@ int doFalseColorizeInView(int state) {
|
|||
return state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* modeAll = " - All ";
|
||||
const char* modeVectors = " - Vectors ";
|
||||
const char* modePlanes = " - Planes ";
|
||||
|
@ -1441,6 +1461,8 @@ void initMenu() {
|
|||
menuColumnDebug->addRow("FALSE Color Voxel Out of View", doFalseColorizeInView);
|
||||
menuColumnDebug->addRow("Show TRUE Colors", doTrueVoxelColors);
|
||||
menuColumnDebug->addRow("Calculate Tree Stats", doTreeStats);
|
||||
menuColumnDebug->addRow("Wants Res-In", setWantResIn);
|
||||
menuColumnDebug->addRow("Wants Monochrome", setWantMonochrome);
|
||||
}
|
||||
|
||||
void testPointToVoxel() {
|
||||
|
@ -1728,6 +1750,7 @@ void* networkReceive(void* args) {
|
|||
myAvatar.processTransmitterData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_VOXEL_DATA:
|
||||
case PACKET_HEADER_VOXEL_DATA_MONOCHROME:
|
||||
case PACKET_HEADER_Z_COMMAND:
|
||||
case PACKET_HEADER_ERASE_VOXEL:
|
||||
voxels.parseData(incomingPacket, bytesReceived);
|
||||
|
|
|
@ -34,29 +34,6 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
|
|||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
AvatarData::AvatarData() :
|
||||
_handPosition(0,0,0),
|
||||
_bodyYaw(-90.0),
|
||||
_bodyPitch(0.0),
|
||||
_bodyRoll(0.0),
|
||||
_headYaw(0),
|
||||
_headPitch(0),
|
||||
_headRoll(0),
|
||||
_headLeanSideways(0),
|
||||
_headLeanForward(0),
|
||||
_handState(0),
|
||||
_cameraPosition(0,0,0),
|
||||
_cameraDirection(0,0,0),
|
||||
_cameraUp(0,0,0),
|
||||
_cameraRight(0,0,0),
|
||||
_cameraFov(0.0f),
|
||||
_cameraAspectRatio(0.0f),
|
||||
_cameraNearClip(0.0f),
|
||||
_cameraFarClip(0.0f),
|
||||
_keyState(NO_KEY_DOWN) {
|
||||
|
||||
}
|
||||
|
||||
AvatarData::~AvatarData() {
|
||||
|
||||
}
|
||||
|
@ -130,6 +107,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
memcpy(destinationBuffer, _chatMessage.data(), _chatMessage.size() * sizeof(char));
|
||||
destinationBuffer += _chatMessage.size() * sizeof(char);
|
||||
|
||||
// voxel sending features...
|
||||
*destinationBuffer++ = _wantResIn;
|
||||
*destinationBuffer++ = _wantColor;
|
||||
|
||||
return destinationBuffer - bufferStart;
|
||||
}
|
||||
|
||||
|
@ -201,6 +182,10 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
int chatMessageSize = *sourceBuffer++;
|
||||
_chatMessage = string((char*)sourceBuffer, chatMessageSize);
|
||||
sourceBuffer += chatMessageSize * sizeof(char);
|
||||
|
||||
// voxel sending features...
|
||||
_wantResIn = (bool)*sourceBuffer++;
|
||||
_wantColor = (bool)*sourceBuffer++;
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,30 @@ enum KeyState
|
|||
|
||||
class AvatarData : public AgentData {
|
||||
public:
|
||||
AvatarData();
|
||||
AvatarData() :
|
||||
_handPosition(0,0,0),
|
||||
_bodyYaw(-90.0),
|
||||
_bodyPitch(0.0),
|
||||
_bodyRoll(0.0),
|
||||
_headYaw(0),
|
||||
_headPitch(0),
|
||||
_headRoll(0),
|
||||
_headLeanSideways(0),
|
||||
_headLeanForward(0),
|
||||
_handState(0),
|
||||
_cameraPosition(0,0,0),
|
||||
_cameraDirection(0,0,0),
|
||||
_cameraUp(0,0,0),
|
||||
_cameraRight(0,0,0),
|
||||
_cameraFov(0.0f),
|
||||
_cameraAspectRatio(0.0f),
|
||||
_cameraNearClip(0.0f),
|
||||
_cameraFarClip(0.0f),
|
||||
_keyState(NO_KEY_DOWN),
|
||||
_wantResIn(false),
|
||||
_wantColor(true) { };
|
||||
|
||||
|
||||
~AvatarData();
|
||||
|
||||
AvatarData* clone() const;
|
||||
|
@ -96,6 +119,12 @@ public:
|
|||
// chat message
|
||||
void setChatMessage(const std::string& msg) { _chatMessage = msg; }
|
||||
const std::string& chatMessage () const { return _chatMessage; }
|
||||
|
||||
// related to Voxel Sending strategies
|
||||
bool getWantResIn() const { return _wantResIn; }
|
||||
bool getWantColor() const { return _wantColor; }
|
||||
void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; }
|
||||
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
||||
|
||||
protected:
|
||||
glm::vec3 _position;
|
||||
|
@ -137,6 +166,9 @@ protected:
|
|||
|
||||
// chat message
|
||||
std::string _chatMessage;
|
||||
|
||||
bool _wantResIn;
|
||||
bool _wantColor;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AvatarData__) */
|
||||
|
|
|
@ -23,6 +23,7 @@ const PACKET_HEADER PACKET_HEADER_INJECT_AUDIO = 'I';
|
|||
const PACKET_HEADER PACKET_HEADER_SET_VOXEL = 'S';
|
||||
const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E';
|
||||
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V';
|
||||
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v';
|
||||
const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X';
|
||||
const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA = 't';
|
||||
const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e';
|
||||
|
|
|
@ -25,7 +25,7 @@ void VoxelAgentData::init() {
|
|||
}
|
||||
|
||||
void VoxelAgentData::resetVoxelPacket() {
|
||||
_voxelPacket[0] = PACKET_HEADER_VOXEL_DATA;
|
||||
_voxelPacket[0] = getWantColor() ? PACKET_HEADER_VOXEL_DATA : PACKET_HEADER_VOXEL_DATA_MONOCHROME;
|
||||
_voxelPacketAt = &_voxelPacket[1];
|
||||
_voxelPacketAvailableBytes = MAX_VOXEL_PACKET_SIZE - 1;
|
||||
_voxelPacketWaiting = false;
|
||||
|
|
|
@ -104,7 +104,13 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
|
|||
}
|
||||
|
||||
|
||||
void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAgentData* agentData, ViewFrustum& viewFrustum) {
|
||||
// Version of voxel distributor that sends each LOD level at a time
|
||||
void resInVoxelDistributor(AgentList* agentList,
|
||||
AgentList::iterator& agent,
|
||||
VoxelAgentData* agentData,
|
||||
ViewFrustum& viewFrustum) {
|
||||
|
||||
printf("resInVoxelDistributor()\n");
|
||||
bool searchReset = false;
|
||||
int searchLoops = 0;
|
||||
int searchLevelWas = agentData->getMaxSearchLevel();
|
||||
|
@ -158,7 +164,8 @@ void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAge
|
|||
VoxelNode* subTree = agentData->nodeBag.extract();
|
||||
bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree,
|
||||
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
||||
agentData->nodeBag, &viewFrustum);
|
||||
agentData->nodeBag, &viewFrustum,
|
||||
agentData->getWantColor());
|
||||
|
||||
if (agentData->getAvailable() >= bytesWritten) {
|
||||
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||
|
@ -216,6 +223,99 @@ void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAge
|
|||
}
|
||||
}
|
||||
|
||||
// Version of voxel distributor that sends each LOD level at a time
|
||||
void deepestLevelVoxelDistributor(AgentList* agentList,
|
||||
AgentList::iterator& agent,
|
||||
VoxelAgentData* agentData,
|
||||
ViewFrustum& viewFrustum) {
|
||||
|
||||
printf("deepestLevelVoxelDistributor()\n");
|
||||
|
||||
int maxLevelReached = 0;
|
||||
double start = usecTimestampNow();
|
||||
if (agentData->nodeBag.isEmpty()) {
|
||||
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, viewFrustum, agentData->nodeBag);
|
||||
}
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - start)/1000000.0;
|
||||
printf("WARNING! searchForColoredNodes() took %lf seconds to identify %d nodes at level %d\n",
|
||||
elapsedsec, agentData->nodeBag.count(), maxLevelReached);
|
||||
} else {
|
||||
printf("WARNING! searchForColoredNodes() took %lf milliseconds to identify %d nodes at level %d\n",
|
||||
elapsedmsec, agentData->nodeBag.count(), maxLevelReached);
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("searchForColoredNodes() took %lf milliseconds to identify %d nodes at level %d\n",
|
||||
elapsedmsec, agentData->nodeBag.count(), maxLevelReached);
|
||||
}
|
||||
|
||||
// If we have something in our nodeBag, then turn them into packets and send them out...
|
||||
if (!agentData->nodeBag.isEmpty()) {
|
||||
static unsigned char tempOutputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static
|
||||
int bytesWritten = 0;
|
||||
int packetsSentThisInterval = 0;
|
||||
int truePacketsSent = 0;
|
||||
int trueBytesSent = 0;
|
||||
double start = usecTimestampNow();
|
||||
|
||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - 1) {
|
||||
if (!agentData->nodeBag.isEmpty()) {
|
||||
VoxelNode* subTree = agentData->nodeBag.extract();
|
||||
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
|
||||
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
||||
agentData->nodeBag, &viewFrustum,
|
||||
agentData->getWantColor());
|
||||
|
||||
if (agentData->getAvailable() >= bytesWritten) {
|
||||
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||
} else {
|
||||
agentList->getAgentSocket().send(agent->getActiveSocket(),
|
||||
agentData->getPacket(), agentData->getPacketLength());
|
||||
trueBytesSent += agentData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
packetsSentThisInterval++;
|
||||
agentData->resetVoxelPacket();
|
||||
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||
}
|
||||
} else {
|
||||
if (agentData->isPacketWaiting()) {
|
||||
agentList->getAgentSocket().send(agent->getActiveSocket(),
|
||||
agentData->getPacket(), agentData->getPacketLength());
|
||||
trueBytesSent += agentData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
agentData->resetVoxelPacket();
|
||||
|
||||
}
|
||||
packetsSentThisInterval = PACKETS_PER_CLIENT_PER_INTERVAL; // done for now, no nodes left
|
||||
}
|
||||
}
|
||||
// send the environment packet
|
||||
int envPacketLength = environmentData.getBroadcastData(tempOutputBuffer);
|
||||
agentList->getAgentSocket().send(agent->getActiveSocket(), tempOutputBuffer, envPacketLength);
|
||||
trueBytesSent += envPacketLength;
|
||||
truePacketsSent++;
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - start)/1000000.0;
|
||||
printf("WARNING! packetLoop() took %lf seconds to generate %d bytes in %d packets %d nodes still to send\n",
|
||||
elapsedsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
|
||||
} else {
|
||||
printf("WARNING! packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||
elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||
elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void persistVoxelsWhenDirty() {
|
||||
// check the dirty bit and persist here...
|
||||
if (::wantVoxelPersist && ::randomTree.isDirty()) {
|
||||
|
@ -253,7 +353,11 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
|
||||
viewFrustum.calculate();
|
||||
|
||||
voxelDistributor(agentList, agent, agentData, viewFrustum);
|
||||
if (agentData->getWantResIn()) {
|
||||
resInVoxelDistributor(agentList, agent, agentData, viewFrustum);
|
||||
} else {
|
||||
deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue