From 9b34427570c0211c17113311bb3d862a99c064d9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:12:08 -0700 Subject: [PATCH 01/10] Added camera data to AvatarData class, and include it in interface --- interface/src/main.cpp | 19 ++++++++++- libraries/avatars/src/AvatarData.cpp | 51 +++++++++++++++++++++++++++- libraries/avatars/src/AvatarData.h | 32 +++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8712700efc..967b597c81 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -85,6 +85,7 @@ using namespace std; void reshape(int width, int height); // will be defined below +void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below pthread_t networkReceiveThread; @@ -522,6 +523,22 @@ void updateAvatar(float frametime) myAvatar.setAverageLoudness(averageLoudness); #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(::viewFrustum); + myAvatar.setCameraPosition(::viewFrustum.getPosition()); + myAvatar.setCameraDirection(::viewFrustum.getDirection()); + myAvatar.setCameraUp(::viewFrustum.getUp()); + myAvatar.setCameraRight(::viewFrustum.getRight()); + myAvatar.setCameraFov(::viewFrustum.getFieldOfView()); + myAvatar.setCameraAspectRatio(::viewFrustum.getAspectRatio()); + myAvatar.setCameraNearClip(::viewFrustum.getNearClip()); + myAvatar.setCameraFarClip(::viewFrustum.getFarClip()); + // Send my stream of head/hand data to the avatar mixer and voxel server unsigned char broadcastString[200]; *broadcastString = PACKET_HEADER_HEAD_DATA; @@ -559,7 +576,7 @@ void updateAvatar(float frametime) } ///////////////////////////////////////////////////////////////////////////////////// -// renderViewFrustum() +// loadViewFrustum() // // Description: this will load the view frustum bounds for EITHER the head // or the "myCamera". diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f3ec0a31b0..89c8c828bc 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -36,7 +36,15 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo AvatarData::AvatarData() : _bodyYaw(-90.0), _bodyPitch(0.0), - _bodyRoll(0.0) { + _bodyRoll(0.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) { } @@ -64,14 +72,37 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; + + // camera details + memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition)); + destinationBuffer += sizeof(_cameraPosition); + memcpy(destinationBuffer, &_cameraDirection, sizeof(_cameraDirection)); + destinationBuffer += sizeof(_cameraDirection); + memcpy(destinationBuffer, &_cameraRight, sizeof(_cameraRight)); + destinationBuffer += sizeof(_cameraRight); + memcpy(destinationBuffer, &_cameraUp, sizeof(_cameraUp)); + destinationBuffer += sizeof(_cameraUp); + memcpy(destinationBuffer, &_cameraFov, sizeof(_cameraFov)); + destinationBuffer += sizeof(_cameraFov); + memcpy(destinationBuffer, &_cameraAspectRatio, sizeof(_cameraAspectRatio)); + destinationBuffer += sizeof(_cameraAspectRatio); + memcpy(destinationBuffer, &_cameraNearClip, sizeof(_cameraNearClip)); + destinationBuffer += sizeof(_cameraNearClip); + memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip)); + destinationBuffer += sizeof(_cameraFarClip); //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); + + //printf("AvatarData::getBroadcastData() numBytes=%ld\n",(destinationBuffer - bufferStart)); return destinationBuffer - bufferStart; } // called on the other agents - assigns it to my views of the others void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { + + //printf("AvatarData::parseData() numBytes=%d\n",numBytes); + // increment to push past the packet header sourceBuffer++; @@ -85,6 +116,24 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + // camera details + memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition)); + sourceBuffer += sizeof(_cameraPosition); + memcpy(&_cameraDirection, sourceBuffer, sizeof(_cameraDirection)); + sourceBuffer += sizeof(_cameraDirection); + memcpy(&_cameraRight, sourceBuffer, sizeof(_cameraRight)); + sourceBuffer += sizeof(_cameraRight); + memcpy(&_cameraUp, sourceBuffer, sizeof(_cameraUp)); + sourceBuffer += sizeof(_cameraUp); + memcpy(&_cameraFov, sourceBuffer, sizeof(_cameraFov)); + sourceBuffer += sizeof(_cameraFov); + memcpy(&_cameraAspectRatio, sourceBuffer, sizeof(_cameraAspectRatio)); + sourceBuffer += sizeof(_cameraAspectRatio); + memcpy(&_cameraNearClip, sourceBuffer, sizeof(_cameraNearClip)); + sourceBuffer += sizeof(_cameraNearClip); + memcpy(&_cameraFarClip, sourceBuffer, sizeof(_cameraFarClip)); + sourceBuffer += sizeof(_cameraFarClip); + //printLog( "_bodyYaw = %f", _bodyYaw ); //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 22186c81a6..df7aa137e5 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -37,6 +37,26 @@ public: float getBodyRoll(); void setBodyRoll(float bodyRoll); + + // getters for camera details + const glm::vec3& getCameraPosition() const { return _cameraPosition; }; + const glm::vec3& getCameraDirection() const { return _cameraDirection; } + const glm::vec3& getCameraUp() const { return _cameraUp; } + const glm::vec3& getCameraRight() const { return _cameraRight; } + float getCameraFov() const { return _cameraFov; } + float getCameraAspectRatio() const { return _cameraAspectRatio; } + float getCameraNearClip() const { return _cameraNearClip; } + float getCameraFarClip() const { return _cameraFarClip; } + + // setters for camera details + void setCameraPosition(const glm::vec3& position) { _cameraPosition = position; }; + void setCameraDirection(const glm::vec3& direction) { _cameraDirection = direction; } + void setCameraUp(const glm::vec3& up) { _cameraUp = up; } + void setCameraRight(const glm::vec3& right) { _cameraRight = right; } + void setCameraFov(float fov) { _cameraFov = fov; } + void setCameraAspectRatio(float aspectRatio) { _cameraAspectRatio = aspectRatio; } + void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; } + void setCameraFarClip(float farClip) { _cameraFarClip = farClip; } protected: glm::vec3 _bodyPosition; @@ -45,6 +65,18 @@ protected: float _bodyYaw; float _bodyPitch; float _bodyRoll; + + // camera details for the avatar + glm::vec3 _cameraPosition; + + // can we describe this in less space? For example, a Quaternion? or Euler angles? + glm::vec3 _cameraDirection; + glm::vec3 _cameraUp; + glm::vec3 _cameraRight; + float _cameraFov; + float _cameraAspectRatio; + float _cameraNearClip; + float _cameraFarClip; }; #endif /* defined(__hifi__AvatarData__) */ From e1da39e2bb8ad0f5d9aad3c3354e4c9684880622 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:13:56 -0700 Subject: [PATCH 02/10] Made several ViewFrustum methods const since they don't modify the class --- libraries/voxels/src/ViewFrustum.cpp | 18 +++++++++++++----- libraries/voxels/src/ViewFrustum.h | 8 ++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 9fdeafa449..5c9022c27e 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -105,7 +105,7 @@ void ViewFrustum::calculate() { } -void ViewFrustum::dump() { +void ViewFrustum::dump() const { printLog("position.x=%f, position.y=%f, position.z=%f\n", _position.x, _position.y, _position.z); printLog("direction.x=%f, direction.y=%f, direction.z=%f\n", _direction.x, _direction.y, _direction.z); @@ -158,17 +158,25 @@ const char* ViewFrustum::debugPlaneName (int plane) const { } -int ViewFrustum::pointInFrustum(const glm::vec3& point) { +int ViewFrustum::pointInFrustum(const glm::vec3& point) const { + + //printf("ViewFrustum::pointInFrustum() point=%f,%f,%f\n",point.x,point.y,point.z); + //dump(); + int result = INSIDE; for(int i=0; i < 6; i++) { - if (_planes[i].distance(point) < 0) { + float distance = _planes[i].distance(point); + + //printf("plane[%d] %s -- distance=%f \n",i,debugPlaneName(i),distance); + + if (distance < 0) { return OUTSIDE; } } return(result); } -int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) { +int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const { int result = INSIDE; float distance; for(int i=0; i < 6; i++) { @@ -182,7 +190,7 @@ int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) { } -int ViewFrustum::boxInFrustum(const AABox& box) { +int ViewFrustum::boxInFrustum(const AABox& box) const { printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n", box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x); diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 6114953099..9ebfba6e9a 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -90,13 +90,13 @@ public: ViewFrustum(); - void dump(); + void dump() const; enum {OUTSIDE, INTERSECT, INSIDE}; - int pointInFrustum(const glm::vec3& point); - int sphereInFrustum(const glm::vec3& center, float radius); - int boxInFrustum(const AABox& box); + int pointInFrustum(const glm::vec3& point) const; + int sphereInFrustum(const glm::vec3& center, float radius) const; + int boxInFrustum(const AABox& box) const; }; From 893996675a3d958bd3b0cab35cf6b916b3210257 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:15:47 -0700 Subject: [PATCH 03/10] Derive VoxelAgentData from AvatarData to get access to camera details - Changed base class for VoxelAgentData - changed parseData() method to call base class implementation - added avatars library to cmake scripts --- voxel-server/CMakeLists.txt | 3 +++ voxel-server/src/VoxelAgentData.cpp | 9 +++++---- voxel-server/src/VoxelAgentData.h | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 99b72be9cb..e1ce2b6f98 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -24,5 +24,8 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi voxels library link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) +# link in the hifi avatars library +link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) + # find required libraries find_package(GLM REQUIRED) diff --git a/voxel-server/src/VoxelAgentData.cpp b/voxel-server/src/VoxelAgentData.cpp index 8f9b41e4ca..5860106e34 100644 --- a/voxel-server/src/VoxelAgentData.cpp +++ b/voxel-server/src/VoxelAgentData.cpp @@ -28,9 +28,10 @@ VoxelAgentData* VoxelAgentData::clone() const { } void VoxelAgentData::parseData(unsigned char* sourceBuffer, int numBytes) { - // push past the packet header - sourceBuffer++; + // call base class to parse the data + AvatarData::parseData(sourceBuffer,numBytes); - // pull the position from the interface agent data packet - memcpy(&position, sourceBuffer, sizeof(float) * 3); + // make sure our class knows it's position + memcpy(&position, &_bodyPosition, sizeof(_bodyPosition)); } + diff --git a/voxel-server/src/VoxelAgentData.h b/voxel-server/src/VoxelAgentData.h index 98ec7e9ed7..1a7293a5a1 100644 --- a/voxel-server/src/VoxelAgentData.h +++ b/voxel-server/src/VoxelAgentData.h @@ -11,9 +11,10 @@ #include #include +#include #include "MarkerNode.h" -class VoxelAgentData : public AgentData { +class VoxelAgentData : public AvatarData { public: float position[3]; MarkerNode *rootMarkerNode; From 030f5328f519633d043ddc49edb5ea542002f9b5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:46:25 -0700 Subject: [PATCH 04/10] First cut at View Frustum Culling between client and server --- libraries/voxels/src/VoxelTree.cpp | 123 ++++++++++++++++++++++++----- libraries/voxels/src/VoxelTree.h | 3 + voxel-server/src/main.cpp | 40 ++++++++-- 3 files changed, 140 insertions(+), 26 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index bd197b53cb..e7923e5976 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -17,6 +17,7 @@ #include "PacketHeaders.h" #include "OctalCode.h" #include "VoxelTree.h" +#include "ViewFrustum.h" #include // to load voxels from file using voxels_lib::printLog; @@ -268,6 +269,8 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, MarkerNode *currentMarkerNode, float * agentPosition, float thisNodePosition[3], + const ViewFrustum& viewFrustum, + bool viewFrustumCulling, unsigned char * stopOctalCode) { static unsigned char *initialBitstreamPos = bitstreamBuffer; @@ -294,22 +297,38 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, unsigned char * childMaskPointer = NULL; float halfUnitForVoxel = powf(0.5, *currentVoxelNode->octalCode) * (0.5 * TREE_SCALE); - - // XXXBHG - Note: It appears as if the X and Z coordinates of Head or Agent are flip-flopped relative to the - // coords of the voxel space. This flip flop causes LOD behavior to be extremely odd. This is my temporary hack - // to fix this behavior. To disable this swap, set swapXandZ to false. - // XXXBHG - 2013/04/11 - adding a note to my branch, I think this code is now broken. - bool swapXandZ=false; - float agentX = swapXandZ ? agentPosition[2] : agentPosition[0]; - float agentZ = swapXandZ ? agentPosition[0] : agentPosition[2]; - - float distanceToVoxelCenter = sqrtf(powf(agentX - thisNodePosition[0] - halfUnitForVoxel, 2) + + float distanceToVoxelCenter = sqrtf(powf(agentPosition[0] - thisNodePosition[0] - halfUnitForVoxel, 2) + powf(agentPosition[1] - thisNodePosition[1] - halfUnitForVoxel, 2) + - powf(agentZ - thisNodePosition[2] - halfUnitForVoxel, 2)); + powf(agentPosition[2] - thisNodePosition[2] - halfUnitForVoxel, 2)); + + // If the voxel is outside of the view frustum, then don't bother sending or recursing + bool voxelInView = true; + + /**** not yet working properly at this level! ************************************************************************** + if (viewFrustumCulling) { + float fullUnitForVoxel = halfUnitForVoxel*2.0f; + AABox voxelBox; + voxelBox.setBox(glm::vec3(thisNodePosition[0],thisNodePosition[1],thisNodePosition[2]), + fullUnitForVoxel,fullUnitForVoxel,fullUnitForVoxel); + + //printf("VoxelTree::loadBitstreamBuffer() voxelBox.corner=(%f,%f,%f) x=%f \n", + // voxelBox.getCorner().x,voxelBox.getCorner().y,voxelBox.getCorner().z, voxelBox.getSize().x); + + voxelInView = (ViewFrustum::OUTSIDE != viewFrustum.pointInFrustum(voxelBox.getCorner())); + } else { + voxelInView = true; + } + **********************************************************************************************************************/ // if the distance to this voxel's center is less than the threshold // distance for its children, we should send the children - if (distanceToVoxelCenter < boundaryDistanceForRenderLevel(*currentVoxelNode->octalCode + 1)) { + bool voxelIsClose = (distanceToVoxelCenter < boundaryDistanceForRenderLevel(*currentVoxelNode->octalCode + 1)); + bool sendVoxel = voxelIsClose && voxelInView; + + //printf("VoxelTree::loadBitstreamBuffer() sendVoxel=%d, voxelIsClose=%d, voxelInView=%d, viewFrustumCulling=%d\n", + // sendVoxel, voxelIsClose, voxelInView, viewFrustumCulling); + + if (sendVoxel) { // write this voxel's data if we're below or at // or at the same level as the stopOctalCode @@ -341,16 +360,78 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, for (int i = 0; i < 8; i++) { - // check if the child exists and is not transparent - if (currentVoxelNode->children[i] != NULL - && currentVoxelNode->children[i]->isColored()) { + // Rules for including a child: + // 1) child must exists + if ((currentVoxelNode->children[i] != NULL)) { + // 2) child must have a color... + if (currentVoxelNode->children[i]->isColored()) { - // copy in the childs color to bitstreamBuffer - memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3); - colorPointer += 3; + unsigned char* childOctalCode = currentVoxelNode->children[i]->octalCode; + + float childPosition[3]; + copyFirstVertexForCode(childOctalCode,(float*)&childPosition); + childPosition[0] *= TREE_SCALE; // scale it up + childPosition[1] *= TREE_SCALE; // scale it up + childPosition[2] *= TREE_SCALE; // scale it up - // set the colorMask by bitshifting the value of childExists - *bitstreamBuffer += (1 << (7 - i)); + float halfChildVoxel = powf(0.5, *childOctalCode) * (0.5 * TREE_SCALE); + float distanceToChildCenter = sqrtf(powf(agentPosition[0] - childPosition[0] - halfChildVoxel, 2) + + powf(agentPosition[1] - childPosition[1] - halfChildVoxel, 2) + + powf(agentPosition[2] - childPosition[2] - halfChildVoxel, 2)); + + float fullChildVoxel = halfChildVoxel*2.0f; + AABox childBox; + childBox.setBox(glm::vec3(childPosition[0],childPosition[1],childPosition[2]), + fullChildVoxel,fullChildVoxel,fullChildVoxel); + + //printf("VoxelTree::loadBitstreamBuffer() childBox.corner=(%f,%f,%f) x=%f \n", + // childBox.getCorner().x,childBox.getCorner().y,childBox.getCorner().z, childBox.getSize().x); + + // XXXBHG - not sure we want to do this "distance/LOD culling" at this level. + //bool childIsClose = (distanceToChildCenter < boundaryDistanceForRenderLevel(*childOctalCode + 1)); + + bool childIsClose = true; // for now, assume we're close enough + bool childInView = !viewFrustumCulling || + (ViewFrustum::OUTSIDE != viewFrustum.pointInFrustum(childBox.getCorner())); + + /// XXXBHG - debug code, switch this to true, and we'll send everything but include false coloring + // on voxels based on whether or not they match these rules. + bool falseColorInsteadOfCulling = false; + + // removed childIsClose - until we determine if we want to include that + bool sendChild = (childInView) || falseColorInsteadOfCulling; + + //printf("VoxelTree::loadBitstreamBuffer() childIsClose=%d, childInView=%d\n", + // childIsClose, childInView); + + // if we sendAnyway, we'll do false coloring of the voxels based on childIsClose && childInView + if (sendChild) { + + // copy in the childs color to bitstreamBuffer + if (childIsClose && childInView) { + // true color + memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3); + } else { + unsigned char red[3] = {255,0,0}; + unsigned char green[3] = {0,255,0}; + unsigned char blue[3] = {0,0,255}; + if (!childIsClose && !childInView) { + // If both too far, and not in view, color them red + memcpy(colorPointer, red, 3); + } else if (!childIsClose) { + // If too far, but in view, color them blue + memcpy(colorPointer, blue, 3); + } else { + // If close, but out of view, color them green + memcpy(colorPointer, green, 3); + } + } + colorPointer += 3; + + // set the colorMask by bitshifting the value of childExists + *bitstreamBuffer += (1 << (7 - i)); + } + } } } @@ -414,6 +495,8 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, currentMarkerNode->children[i], agentPosition, childNodePosition, + viewFrustum, + viewFrustumCulling, stopOctalCode); if (bitstreamBuffer - arrBufferBeforeChild > 0) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 62ff4e4815..77c00b2e63 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -11,6 +11,7 @@ #include "SimpleMovingAverage.h" +#include "ViewFrustum.h" #include "VoxelNode.h" #include "MarkerNode.h" @@ -52,6 +53,8 @@ public: MarkerNode *currentMarkerNode, float * agentPosition, float thisNodePosition[3], + const ViewFrustum& viewFrustum, + bool viewFrustumCulling, unsigned char * octalCode = NULL); void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 8f6bab7dc7..3e411f2d16 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -48,6 +48,8 @@ const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; VoxelTree randomTree; bool wantColorRandomizer = false; +bool debugViewFrustum = false; +bool viewFrustumCulling = false; // for now void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) { float r = random ? randFloatInRange(0.05,0.1) : 0.25; @@ -165,6 +167,24 @@ void *distributeVoxelsToListeners(void *args) { Agent *thisAgent = (Agent *)&agentList->getAgents()[i]; VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData()); + ViewFrustum viewFrustum; + // get position and orientation details from the camera + viewFrustum.setPosition(agentData->getCameraPosition()); + viewFrustum.setOrientation(agentData->getCameraDirection(),agentData->getCameraUp(),agentData->getCameraRight()); + + // Also make sure it's got the correct lens details from the camera + viewFrustum.setFieldOfView(agentData->getCameraFov()); + viewFrustum.setAspectRatio(agentData->getCameraAspectRatio()); + viewFrustum.setNearClip(agentData->getCameraNearClip()); + viewFrustum.setFarClip(agentData->getCameraFarClip()); + + viewFrustum.calculate(); + + // debug for fun!! + if (::debugViewFrustum) { + viewFrustum.dump(); + } + // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it pthread_mutex_lock(thisAgent->deleteMutex); @@ -181,6 +201,8 @@ void *distributeVoxelsToListeners(void *args) { agentData->rootMarkerNode, agentData->position, treeRoot, + viewFrustum, + ::viewFrustumCulling, stopOctal); agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket); @@ -249,16 +271,23 @@ int main(int argc, const char * argv[]) agentList->startDomainServerCheckInThread(); srand((unsigned)time(0)); + + const char* DEBUG_VIEW_FRUSTUM="--DebugViewFrustum"; + ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); + printf("debugViewFrustum=%s\n",(::debugViewFrustum?"yes":"no")); + + const char* VIEW_FRUSTUM_CULLING="--ViewFrustumCulling"; + ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); + printf("viewFrustumCulling=%s\n",(::viewFrustumCulling?"yes":"no")); + const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; + ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); + printf("wantColorRandomizer=%s\n",(::wantColorRandomizer?"yes":"no")); + // Check to see if the user passed in a command line option for loading a local // Voxel File. If so, load it now. - const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; const char* INPUT_FILE="-i"; - ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - - printf("wantColorRandomizer=%s\n",(wantColorRandomizer?"yes":"no")); const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE); - if (voxelsFilename) { randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer); } @@ -269,7 +298,6 @@ int main(int argc, const char * argv[]) // octal codes to the tree nodes that it is creating randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode); } - const char* ADD_SPHERE="--AddSphere"; const char* ADD_RANDOM_SPHERE="--AddRandomSphere"; From 7c73964836f1ffbba8ee4e40119a7abf78ef3c73 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:07:46 -0700 Subject: [PATCH 05/10] code review cleanup --- libraries/avatars/src/AvatarData.cpp | 12 ------------ libraries/voxels/src/VoxelTree.cpp | 8 ++++---- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 89c8c828bc..4189575e67 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -90,19 +90,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(_cameraNearClip); memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip)); destinationBuffer += sizeof(_cameraFarClip); - - //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); - //printf("AvatarData::getBroadcastData() numBytes=%ld\n",(destinationBuffer - bufferStart)); - return destinationBuffer - bufferStart; } // called on the other agents - assigns it to my views of the others void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { - - //printf("AvatarData::parseData() numBytes=%d\n",numBytes); - // increment to push past the packet header sourceBuffer++; @@ -133,11 +126,6 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(_cameraNearClip); memcpy(&_cameraFarClip, sourceBuffer, sizeof(_cameraFarClip)); sourceBuffer += sizeof(_cameraFarClip); - - //printLog( "_bodyYaw = %f", _bodyYaw ); - - //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); - //printLog("%f, %f, %f\n", _bodyPosition.x, _bodyPosition.y, _bodyPosition.z); } glm::vec3 AvatarData::getBodyPosition() { diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index e7923e5976..31d39de3de 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -306,7 +306,7 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, /**** not yet working properly at this level! ************************************************************************** if (viewFrustumCulling) { - float fullUnitForVoxel = halfUnitForVoxel*2.0f; + float fullUnitForVoxel = halfUnitForVoxel * 2.0f; AABox voxelBox; voxelBox.setBox(glm::vec3(thisNodePosition[0],thisNodePosition[1],thisNodePosition[2]), fullUnitForVoxel,fullUnitForVoxel,fullUnitForVoxel); @@ -379,10 +379,10 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, powf(agentPosition[1] - childPosition[1] - halfChildVoxel, 2) + powf(agentPosition[2] - childPosition[2] - halfChildVoxel, 2)); - float fullChildVoxel = halfChildVoxel*2.0f; + float fullChildVoxel = halfChildVoxel * 2.0f; AABox childBox; - childBox.setBox(glm::vec3(childPosition[0],childPosition[1],childPosition[2]), - fullChildVoxel,fullChildVoxel,fullChildVoxel); + childBox.setBox(glm::vec3(childPosition[0], childPosition[1], childPosition[2]), + fullChildVoxel, fullChildVoxel, fullChildVoxel); //printf("VoxelTree::loadBitstreamBuffer() childBox.corner=(%f,%f,%f) x=%f \n", // childBox.getCorner().x,childBox.getCorner().y,childBox.getCorner().z, childBox.getSize().x); From 7d93f07152e5d5453df9f2a1c8c8d5dff34bfcba Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:10:18 -0700 Subject: [PATCH 06/10] code review cleanup --- voxel-server/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 3f6ac2a5ed..2bdba8f6e3 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -26,5 +26,3 @@ link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi avatars library link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) -# find required libraries -find_package(GLM REQUIRED) From 436b43ea8556868519d159a29b938c05489ba850 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:11:40 -0700 Subject: [PATCH 07/10] code review cleanup --- voxel-server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 9496375ca9..bacd253d88 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -170,7 +170,7 @@ void *distributeVoxelsToListeners(void *args) { ViewFrustum viewFrustum; // get position and orientation details from the camera viewFrustum.setPosition(agentData->getCameraPosition()); - viewFrustum.setOrientation(agentData->getCameraDirection(),agentData->getCameraUp(),agentData->getCameraRight()); + viewFrustum.setOrientation(agentData->getCameraDirection(), agentData->getCameraUp(), agentData->getCameraRight()); // Also make sure it's got the correct lens details from the camera viewFrustum.setFieldOfView(agentData->getCameraFov()); From 2f6d2469f472c136ddda839fb1ff9a112c7e07dd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:13:17 -0700 Subject: [PATCH 08/10] code review cleanup --- voxel-server/src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index bacd253d88..127cd36792 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -274,15 +274,15 @@ int main(int argc, const char * argv[]) const char* DEBUG_VIEW_FRUSTUM="--DebugViewFrustum"; ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); - printf("debugViewFrustum=%s\n",(::debugViewFrustum?"yes":"no")); + printf("debugViewFrustum=%s\n", (::debugViewFrustum ? "yes" : "no")); const char* VIEW_FRUSTUM_CULLING="--ViewFrustumCulling"; ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); - printf("viewFrustumCulling=%s\n",(::viewFrustumCulling?"yes":"no")); + printf("viewFrustumCulling=%s\n", (::viewFrustumCulling ? "yes" : "no")); const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - printf("wantColorRandomizer=%s\n",(::wantColorRandomizer?"yes":"no")); + printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); // Check to see if the user passed in a command line option for loading a local // Voxel File. If so, load it now. From cea417027020ae51f7274a2b54e36af06b0c3c45 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:14:35 -0700 Subject: [PATCH 09/10] code review cleanup --- voxel-server/src/main.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 127cd36792..808e33a96d 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -272,42 +272,42 @@ int main(int argc, const char * argv[]) srand((unsigned)time(0)); - const char* DEBUG_VIEW_FRUSTUM="--DebugViewFrustum"; + const char* DEBUG_VIEW_FRUSTUM = "--DebugViewFrustum"; ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); printf("debugViewFrustum=%s\n", (::debugViewFrustum ? "yes" : "no")); - const char* VIEW_FRUSTUM_CULLING="--ViewFrustumCulling"; + const char* VIEW_FRUSTUM_CULLING = "--ViewFrustumCulling"; ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); printf("viewFrustumCulling=%s\n", (::viewFrustumCulling ? "yes" : "no")); - const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; + const char* WANT_COLOR_RANDOMIZER = "--WantColorRandomizer"; ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); // Check to see if the user passed in a command line option for loading a local // Voxel File. If so, load it now. - const char* INPUT_FILE="-i"; + const char* INPUT_FILE = "-i"; const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE); if (voxelsFilename) { randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer); } - const char* ADD_RANDOM_VOXELS="--AddRandomVoxels"; + const char* ADD_RANDOM_VOXELS = "--AddRandomVoxels"; if (cmdOptionExists(argc, argv, ADD_RANDOM_VOXELS)) { // create an octal code buffer and load it with 0 so that the recursive tree fill can give // octal codes to the tree nodes that it is creating randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode); } - const char* ADD_SPHERE="--AddSphere"; - const char* ADD_RANDOM_SPHERE="--AddRandomSphere"; + const char* ADD_SPHERE = "--AddSphere"; + const char* ADD_RANDOM_SPHERE = "--AddRandomSphere"; if (cmdOptionExists(argc, argv, ADD_SPHERE)) { addSphere(&randomTree,false,wantColorRandomizer); } else if (cmdOptionExists(argc, argv, ADD_RANDOM_SPHERE)) { addSphere(&randomTree,true,wantColorRandomizer); } - const char* NO_ADD_SCENE="--NoAddScene"; + const char* NO_ADD_SCENE = "--NoAddScene"; if (!cmdOptionExists(argc, argv, NO_ADD_SCENE)) { addSphereScene(&randomTree,wantColorRandomizer); } From a79659a5d488963eecf815fed2a698f9d923ed52 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:22:41 -0700 Subject: [PATCH 10/10] change VoxelAgentData to not include position, use AvatarData _bodyPosition instead --- libraries/voxels/src/VoxelTree.cpp | 2 +- libraries/voxels/src/VoxelTree.h | 2 +- voxel-server/src/VoxelAgentData.cpp | 11 +---------- voxel-server/src/VoxelAgentData.h | 2 -- voxel-server/src/main.cpp | 2 +- 5 files changed, 4 insertions(+), 15 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 31d39de3de..3e75f76184 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -267,7 +267,7 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, VoxelNode *currentVoxelNode, MarkerNode *currentMarkerNode, - float * agentPosition, + const glm::vec3& agentPosition, float thisNodePosition[3], const ViewFrustum& viewFrustum, bool viewFrustumCulling, diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 77c00b2e63..60c66925ec 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -51,7 +51,7 @@ public: unsigned char * loadBitstreamBuffer(unsigned char *& bitstreamBuffer, VoxelNode *currentVoxelNode, MarkerNode *currentMarkerNode, - float * agentPosition, + const glm::vec3& agentPosition, float thisNodePosition[3], const ViewFrustum& viewFrustum, bool viewFrustumCulling, diff --git a/voxel-server/src/VoxelAgentData.cpp b/voxel-server/src/VoxelAgentData.cpp index 5860106e34..4476cff056 100644 --- a/voxel-server/src/VoxelAgentData.cpp +++ b/voxel-server/src/VoxelAgentData.cpp @@ -19,19 +19,10 @@ VoxelAgentData::~VoxelAgentData() { } VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) { - memcpy(position, otherAgentData.position, sizeof(float) * 3); + memcpy(&_bodyPosition, &otherAgentData._bodyPosition, sizeof(_bodyPosition)); rootMarkerNode = new MarkerNode(); } VoxelAgentData* VoxelAgentData::clone() const { return new VoxelAgentData(*this); } - -void VoxelAgentData::parseData(unsigned char* sourceBuffer, int numBytes) { - // call base class to parse the data - AvatarData::parseData(sourceBuffer,numBytes); - - // make sure our class knows it's position - memcpy(&position, &_bodyPosition, sizeof(_bodyPosition)); -} - diff --git a/voxel-server/src/VoxelAgentData.h b/voxel-server/src/VoxelAgentData.h index 1a7293a5a1..4ca7949b92 100644 --- a/voxel-server/src/VoxelAgentData.h +++ b/voxel-server/src/VoxelAgentData.h @@ -16,14 +16,12 @@ class VoxelAgentData : public AvatarData { public: - float position[3]; MarkerNode *rootMarkerNode; VoxelAgentData(); ~VoxelAgentData(); VoxelAgentData(const VoxelAgentData &otherAgentData); - void parseData(unsigned char* sourceBuffer, int numBytes); VoxelAgentData* clone() const; }; diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 808e33a96d..d85154abc5 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -199,7 +199,7 @@ void *distributeVoxelsToListeners(void *args) { stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd, randomTree.rootNode, agentData->rootMarkerNode, - agentData->position, + agentData->getBodyPosition(), treeRoot, viewFrustum, ::viewFrustumCulling,