mirror of
https://github.com/overte-org/overte.git
synced 2025-07-01 00:59:29 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
caead24462
11 changed files with 268 additions and 65 deletions
|
@ -85,6 +85,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void reshape(int width, int height); // will be defined below
|
void reshape(int width, int height); // will be defined below
|
||||||
|
void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below
|
||||||
|
|
||||||
|
|
||||||
pthread_t networkReceiveThread;
|
pthread_t networkReceiveThread;
|
||||||
|
@ -522,6 +523,22 @@ void updateAvatar(float frametime)
|
||||||
myAvatar.setAverageLoudness(averageLoudness);
|
myAvatar.setAverageLoudness(averageLoudness);
|
||||||
#endif
|
#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
|
// Send my stream of head/hand data to the avatar mixer and voxel server
|
||||||
unsigned char broadcastString[200];
|
unsigned char broadcastString[200];
|
||||||
*broadcastString = PACKET_HEADER_HEAD_DATA;
|
*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
|
// Description: this will load the view frustum bounds for EITHER the head
|
||||||
// or the "myCamera".
|
// or the "myCamera".
|
||||||
|
|
|
@ -36,7 +36,15 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
|
||||||
AvatarData::AvatarData() :
|
AvatarData::AvatarData() :
|
||||||
_bodyYaw(-90.0),
|
_bodyYaw(-90.0),
|
||||||
_bodyPitch(0.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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +73,23 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3);
|
memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3);
|
||||||
destinationBuffer += sizeof(float) * 3;
|
destinationBuffer += sizeof(float) * 3;
|
||||||
|
|
||||||
//printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z);
|
// 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);
|
||||||
|
|
||||||
return destinationBuffer - bufferStart;
|
return destinationBuffer - bufferStart;
|
||||||
}
|
}
|
||||||
|
@ -85,10 +109,23 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3);
|
memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3);
|
||||||
sourceBuffer += sizeof(float) * 3;
|
sourceBuffer += sizeof(float) * 3;
|
||||||
|
|
||||||
//printLog( "_bodyYaw = %f", _bodyYaw );
|
// camera details
|
||||||
|
memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition));
|
||||||
//printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z);
|
sourceBuffer += sizeof(_cameraPosition);
|
||||||
//printLog("%f, %f, %f\n", _bodyPosition.x, _bodyPosition.y, _bodyPosition.z);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 AvatarData::getBodyPosition() {
|
glm::vec3 AvatarData::getBodyPosition() {
|
||||||
|
|
|
@ -38,6 +38,26 @@ public:
|
||||||
float getBodyRoll();
|
float getBodyRoll();
|
||||||
void setBodyRoll(float bodyRoll);
|
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:
|
protected:
|
||||||
glm::vec3 _bodyPosition;
|
glm::vec3 _bodyPosition;
|
||||||
glm::vec3 _handPosition;
|
glm::vec3 _handPosition;
|
||||||
|
@ -45,6 +65,18 @@ protected:
|
||||||
float _bodyYaw;
|
float _bodyYaw;
|
||||||
float _bodyPitch;
|
float _bodyPitch;
|
||||||
float _bodyRoll;
|
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__) */
|
#endif /* defined(__hifi__AvatarData__) */
|
||||||
|
|
|
@ -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("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);
|
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;
|
int result = INSIDE;
|
||||||
for(int i=0; i < 6; i++) {
|
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 OUTSIDE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) {
|
int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
||||||
int result = INSIDE;
|
int result = INSIDE;
|
||||||
float distance;
|
float distance;
|
||||||
for(int i=0; i < 6; i++) {
|
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",
|
printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n",
|
||||||
box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x);
|
box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x);
|
||||||
|
|
|
@ -90,13 +90,13 @@ public:
|
||||||
|
|
||||||
ViewFrustum();
|
ViewFrustum();
|
||||||
|
|
||||||
void dump();
|
void dump() const;
|
||||||
|
|
||||||
enum {OUTSIDE, INTERSECT, INSIDE};
|
enum {OUTSIDE, INTERSECT, INSIDE};
|
||||||
|
|
||||||
int pointInFrustum(const glm::vec3& point);
|
int pointInFrustum(const glm::vec3& point) const;
|
||||||
int sphereInFrustum(const glm::vec3& center, float radius);
|
int sphereInFrustum(const glm::vec3& center, float radius) const;
|
||||||
int boxInFrustum(const AABox& box);
|
int boxInFrustum(const AABox& box) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "PacketHeaders.h"
|
#include "PacketHeaders.h"
|
||||||
#include "OctalCode.h"
|
#include "OctalCode.h"
|
||||||
#include "VoxelTree.h"
|
#include "VoxelTree.h"
|
||||||
|
#include "ViewFrustum.h"
|
||||||
#include <fstream> // to load voxels from file
|
#include <fstream> // to load voxels from file
|
||||||
|
|
||||||
using voxels_lib::printLog;
|
using voxels_lib::printLog;
|
||||||
|
@ -266,8 +267,10 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
|
||||||
unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
||||||
VoxelNode *currentVoxelNode,
|
VoxelNode *currentVoxelNode,
|
||||||
MarkerNode *currentMarkerNode,
|
MarkerNode *currentMarkerNode,
|
||||||
float * agentPosition,
|
const glm::vec3& agentPosition,
|
||||||
float thisNodePosition[3],
|
float thisNodePosition[3],
|
||||||
|
const ViewFrustum& viewFrustum,
|
||||||
|
bool viewFrustumCulling,
|
||||||
unsigned char * stopOctalCode)
|
unsigned char * stopOctalCode)
|
||||||
{
|
{
|
||||||
static unsigned char *initialBitstreamPos = bitstreamBuffer;
|
static unsigned char *initialBitstreamPos = bitstreamBuffer;
|
||||||
|
@ -294,22 +297,38 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
||||||
unsigned char * childMaskPointer = NULL;
|
unsigned char * childMaskPointer = NULL;
|
||||||
|
|
||||||
float halfUnitForVoxel = powf(0.5, *currentVoxelNode->octalCode) * (0.5 * TREE_SCALE);
|
float halfUnitForVoxel = powf(0.5, *currentVoxelNode->octalCode) * (0.5 * TREE_SCALE);
|
||||||
|
float distanceToVoxelCenter = sqrtf(powf(agentPosition[0] - thisNodePosition[0] - halfUnitForVoxel, 2) +
|
||||||
// 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) +
|
|
||||||
powf(agentPosition[1] - thisNodePosition[1] - 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
|
// if the distance to this voxel's center is less than the threshold
|
||||||
// distance for its children, we should send the children
|
// 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
|
// write this voxel's data if we're below or at
|
||||||
// or at the same level as the stopOctalCode
|
// or at the same level as the stopOctalCode
|
||||||
|
@ -341,18 +360,80 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
|
||||||
// check if the child exists and is not transparent
|
// Rules for including a child:
|
||||||
if (currentVoxelNode->children[i] != NULL
|
// 1) child must exists
|
||||||
&& currentVoxelNode->children[i]->isColored()) {
|
if ((currentVoxelNode->children[i] != NULL)) {
|
||||||
|
// 2) child must have a color...
|
||||||
|
if (currentVoxelNode->children[i]->isColored()) {
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
// copy in the childs color to bitstreamBuffer
|
||||||
|
if (childIsClose && childInView) {
|
||||||
|
// true color
|
||||||
memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3);
|
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;
|
colorPointer += 3;
|
||||||
|
|
||||||
// set the colorMask by bitshifting the value of childExists
|
// set the colorMask by bitshifting the value of childExists
|
||||||
*bitstreamBuffer += (1 << (7 - i));
|
*bitstreamBuffer += (1 << (7 - i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// push the bitstreamBuffer forwards for the number of added colors
|
// push the bitstreamBuffer forwards for the number of added colors
|
||||||
bitstreamBuffer += (colorPointer - bitstreamBuffer);
|
bitstreamBuffer += (colorPointer - bitstreamBuffer);
|
||||||
|
@ -414,6 +495,8 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
||||||
currentMarkerNode->children[i],
|
currentMarkerNode->children[i],
|
||||||
agentPosition,
|
agentPosition,
|
||||||
childNodePosition,
|
childNodePosition,
|
||||||
|
viewFrustum,
|
||||||
|
viewFrustumCulling,
|
||||||
stopOctalCode);
|
stopOctalCode);
|
||||||
|
|
||||||
if (bitstreamBuffer - arrBufferBeforeChild > 0) {
|
if (bitstreamBuffer - arrBufferBeforeChild > 0) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "SimpleMovingAverage.h"
|
#include "SimpleMovingAverage.h"
|
||||||
|
|
||||||
|
#include "ViewFrustum.h"
|
||||||
#include "VoxelNode.h"
|
#include "VoxelNode.h"
|
||||||
#include "MarkerNode.h"
|
#include "MarkerNode.h"
|
||||||
|
|
||||||
|
@ -50,8 +51,10 @@ public:
|
||||||
unsigned char * loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
unsigned char * loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
||||||
VoxelNode *currentVoxelNode,
|
VoxelNode *currentVoxelNode,
|
||||||
MarkerNode *currentMarkerNode,
|
MarkerNode *currentMarkerNode,
|
||||||
float * agentPosition,
|
const glm::vec3& agentPosition,
|
||||||
float thisNodePosition[3],
|
float thisNodePosition[3],
|
||||||
|
const ViewFrustum& viewFrustum,
|
||||||
|
bool viewFrustumCulling,
|
||||||
unsigned char * octalCode = NULL);
|
unsigned char * octalCode = NULL);
|
||||||
|
|
||||||
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
|
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
|
||||||
|
|
|
@ -22,3 +22,7 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||||
|
|
||||||
# link in the hifi voxels library
|
# link in the hifi voxels library
|
||||||
link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
|
link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
|
||||||
|
|
||||||
|
# link in the hifi avatars library
|
||||||
|
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,10 @@ VoxelAgentData::~VoxelAgentData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
|
VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
|
||||||
memcpy(position, otherAgentData.position, sizeof(float) * 3);
|
memcpy(&_bodyPosition, &otherAgentData._bodyPosition, sizeof(_bodyPosition));
|
||||||
rootMarkerNode = new MarkerNode();
|
rootMarkerNode = new MarkerNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelAgentData* VoxelAgentData::clone() const {
|
VoxelAgentData* VoxelAgentData::clone() const {
|
||||||
return new VoxelAgentData(*this);
|
return new VoxelAgentData(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelAgentData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|
||||||
// push past the packet header
|
|
||||||
sourceBuffer++;
|
|
||||||
|
|
||||||
// pull the position from the interface agent data packet
|
|
||||||
memcpy(&position, sourceBuffer, sizeof(float) * 3);
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,18 +11,17 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <AgentData.h>
|
#include <AgentData.h>
|
||||||
|
#include <AvatarData.h>
|
||||||
#include "MarkerNode.h"
|
#include "MarkerNode.h"
|
||||||
|
|
||||||
class VoxelAgentData : public AgentData {
|
class VoxelAgentData : public AvatarData {
|
||||||
public:
|
public:
|
||||||
float position[3];
|
|
||||||
MarkerNode *rootMarkerNode;
|
MarkerNode *rootMarkerNode;
|
||||||
|
|
||||||
VoxelAgentData();
|
VoxelAgentData();
|
||||||
~VoxelAgentData();
|
~VoxelAgentData();
|
||||||
VoxelAgentData(const VoxelAgentData &otherAgentData);
|
VoxelAgentData(const VoxelAgentData &otherAgentData);
|
||||||
|
|
||||||
void parseData(unsigned char* sourceBuffer, int numBytes);
|
|
||||||
VoxelAgentData* clone() const;
|
VoxelAgentData* clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
||||||
VoxelTree randomTree;
|
VoxelTree randomTree;
|
||||||
|
|
||||||
bool wantColorRandomizer = false;
|
bool wantColorRandomizer = false;
|
||||||
|
bool debugViewFrustum = false;
|
||||||
|
bool viewFrustumCulling = false; // for now
|
||||||
|
|
||||||
void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) {
|
void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) {
|
||||||
float r = random ? randFloatInRange(0.05,0.1) : 0.25;
|
float r = random ? randFloatInRange(0.05,0.1) : 0.25;
|
||||||
|
@ -165,6 +167,24 @@ void *distributeVoxelsToListeners(void *args) {
|
||||||
Agent *thisAgent = (Agent *)&agentList->getAgents()[i];
|
Agent *thisAgent = (Agent *)&agentList->getAgents()[i];
|
||||||
VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData());
|
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
|
// lock this agent's delete mutex so that the delete thread doesn't
|
||||||
// kill the agent while we are working with it
|
// kill the agent while we are working with it
|
||||||
pthread_mutex_lock(thisAgent->deleteMutex);
|
pthread_mutex_lock(thisAgent->deleteMutex);
|
||||||
|
@ -179,8 +199,10 @@ void *distributeVoxelsToListeners(void *args) {
|
||||||
stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd,
|
stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd,
|
||||||
randomTree.rootNode,
|
randomTree.rootNode,
|
||||||
agentData->rootMarkerNode,
|
agentData->rootMarkerNode,
|
||||||
agentData->position,
|
agentData->getBodyPosition(),
|
||||||
treeRoot,
|
treeRoot,
|
||||||
|
viewFrustum,
|
||||||
|
::viewFrustumCulling,
|
||||||
stopOctal);
|
stopOctal);
|
||||||
|
|
||||||
agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
||||||
|
@ -250,15 +272,22 @@ int main(int argc, const char * argv[])
|
||||||
|
|
||||||
srand((unsigned)time(0));
|
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
|
// Check to see if the user passed in a command line option for loading a local
|
||||||
// Voxel File. If so, load it now.
|
// Voxel File. If so, load it now.
|
||||||
const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer";
|
|
||||||
const char* INPUT_FILE = "-i";
|
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);
|
const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE);
|
||||||
|
|
||||||
if (voxelsFilename) {
|
if (voxelsFilename) {
|
||||||
randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer);
|
randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +299,6 @@ int main(int argc, const char * argv[])
|
||||||
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
|
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* ADD_SPHERE = "--AddSphere";
|
const char* ADD_SPHERE = "--AddSphere";
|
||||||
const char* ADD_RANDOM_SPHERE = "--AddRandomSphere";
|
const char* ADD_RANDOM_SPHERE = "--AddRandomSphere";
|
||||||
if (cmdOptionExists(argc, argv, ADD_SPHERE)) {
|
if (cmdOptionExists(argc, argv, ADD_SPHERE)) {
|
||||||
|
|
Loading…
Reference in a new issue