Merge remote-tracking branch 'upstream/master' into twopole

This commit is contained in:
Stephen Birarda 2013-06-18 09:55:56 -07:00
commit 667fa566d5
9 changed files with 148 additions and 101 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View file

@ -15,7 +15,10 @@ uniform sampler2D texture;
varying vec4 normal;
void main(void) {
// compute the specular component (sans exponent) based on the normal OpenGL lighting model
float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), normalize(normal)));
gl_FragColor = vec4(gl_Color.rgb * texture2D(texture, gl_TexCoord[0].st).rgb +
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 1.0);
// modulate texture by diffuse color and add specular contribution
gl_FragColor = gl_Color * texture2D(texture, gl_TexCoord[0].st) +
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular;
}

View file

@ -8,13 +8,29 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the location of the eye in model space
uniform vec3 eyePosition;
// the interpolated normal
varying vec4 normal;
// the ratio of the indices of refraction
const float refractionEta = 0.75;
void main(void) {
// transform and store the normal for interpolation
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
gl_TexCoord[0] = gl_MultiTexCoord0;
// compute standard diffuse lighting per-vertex
gl_FrontColor = vec4(gl_Color.rgb * (gl_LightModel.ambient.rgb + gl_LightSource[0].ambient.rgb +
gl_LightSource[0].diffuse.rgb * max(0.0, dot(normal, gl_LightSource[0].position))), gl_Color.a);
// compute the texture coordinate based on where refracted vector hits z=0 in model space
vec4 incidence = normalize(gl_Vertex - vec4(eyePosition, 1.0));
vec4 refracted = refract(incidence, normalize(vec4(gl_Normal, 0.0)), refractionEta);
gl_TexCoord[0] = (gl_Vertex - (gl_Vertex.z / refracted.z) * refracted) + vec4(0.5, 0.5, 0.0, 0.0);
// use standard pipeline transform
gl_Position = ftransform();
}

View file

@ -41,6 +41,7 @@ const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
ProgramObject* Head::_irisProgram = 0;
GLuint Head::_irisTextureID;
int Head::_eyePositionLocation;
Head::Head(Avatar* owningAvatar) :
HeadData((AvatarData*)owningAvatar),
@ -86,13 +87,16 @@ void Head::init() {
_irisProgram->link();
_irisProgram->setUniformValue("texture", 0);
_eyePositionLocation = _irisProgram->uniformLocation("eyePosition");
QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_RGB888);
QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_ARGB32);
glGenTextures(1, &_irisTextureID);
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
@ -462,73 +466,74 @@ void Head::renderEyeBrows() {
void Head::renderEyeBalls() {
// setup the texture to be used on each iris
GLUquadric* irisQuadric = gluNewQuadric();
gluQuadricTexture(irisQuadric, GL_TRUE);
gluQuadricOrientation(irisQuadric, GLU_OUTSIDE);
// render white ball of left eyeball
glPushMatrix();
glColor3fv(EYEBALL_COLOR);
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z);
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30);
glutSolidSphere(EYEBALL_RADIUS, 30, 30);
glPopMatrix();
//render white ball of right eyeball
glPushMatrix();
glColor3fv(EYEBALL_COLOR);
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z);
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30);
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z);
glutSolidSphere(EYEBALL_RADIUS, 30, 30);
glPopMatrix();
_irisProgram->bind();
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glEnable(GL_TEXTURE_2D);
glm::vec3 front = getFrontDirection();
glm::quat orientation = getOrientation();
glm::vec3 front = orientation * IDENTITY_FRONT;
// render left iris
glPushMatrix(); {
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
glPushMatrix();
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _leftEyePosition);
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
glPopMatrix();
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _leftEyePosition;
glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation;
glm::vec3 rotationAxis = glm::axis(rotation);
glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(0.0f, 0.0f, -IRIS_PROTRUSION);
glScalef(IRIS_RADIUS * 2.0f, IRIS_RADIUS * 2.0f, IRIS_RADIUS); // flatten the iris
// this ugliness is simply to invert the model transform and get the eye position in model space
_irisProgram->setUniform(_eyePositionLocation, (glm::inverse(rotation) *
(Application::getInstance()->getCamera()->getPosition() - _leftEyePosition) +
glm::vec3(0.0f, 0.0f, IRIS_PROTRUSION)) * glm::vec3(1.0f / (IRIS_RADIUS * 2.0f),
1.0f / (IRIS_RADIUS * 2.0f), 1.0f / IRIS_RADIUS));
glutSolidSphere(0.5f, 15, 15);
}
glPopMatrix();
// render right iris
glPushMatrix(); {
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
glPushMatrix();
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _rightEyePosition);
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
glPopMatrix();
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _rightEyePosition;
glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation;
glm::vec3 rotationAxis = glm::axis(rotation);
glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(0.0f, 0.0f, -IRIS_PROTRUSION);
glScalef(IRIS_RADIUS * 2.0f, IRIS_RADIUS * 2.0f, IRIS_RADIUS); // flatten the iris
// this ugliness is simply to invert the model transform and get the eye position in model space
_irisProgram->setUniform(_eyePositionLocation, (glm::inverse(rotation) *
(Application::getInstance()->getCamera()->getPosition() - _rightEyePosition) +
glm::vec3(0.0f, 0.0f, IRIS_PROTRUSION)) * glm::vec3(1.0f / (IRIS_RADIUS * 2.0f),
1.0f / (IRIS_RADIUS * 2.0f), 1.0f / IRIS_RADIUS));
glutSolidSphere(0.5f, 15, 15);
}
glPopMatrix();
_irisProgram->release();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
// delete the iris quadric now that we're done with it
gluDeleteQuadric(irisQuadric);
glPopMatrix();
}
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {

View file

@ -109,6 +109,7 @@ private:
static ProgramObject* _irisProgram;
static GLuint _irisTextureID;
static int _eyePositionLocation;
// private methods
void createMohawk();

View file

@ -85,7 +85,7 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
if (isnan(angle) || angle < EPSILON) {
return glm::quat();
}
glm::vec3 axis = glm::cross(v1, v2);
glm::vec3 axis;
if (angle > 179.99f) { // 180 degree rotation; must use another axis
axis = glm::cross(v1, glm::vec3(1.0f, 0.0f, 0.0f));
float axisLength = glm::length(axis);

View file

@ -988,22 +988,21 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
return maxChildLevel;
}
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
EncodeBitstreamParams& params) const {
// How many bytes have we written so far at this level;
int bytesWritten = 0;
// If we're at a node that is out of view, then we can return, because no nodes below us will be in view!
if (viewFrustum && !node->isInView(*viewFrustum)) {
if (params.viewFrustum && !node->isInView(*params.viewFrustum)) {
return bytesWritten;
}
// write the octal code
int codeLength;
if (chopLevels) {
unsigned char* newCode = chopOctalCode(node->getOctalCode(), chopLevels);
if (params.chopLevels) {
unsigned char* newCode = chopOctalCode(node->getOctalCode(), params.chopLevels);
if (newCode) {
codeLength = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(newCode));
memcpy(outputBuffer, newCode, codeLength);
@ -1022,16 +1021,14 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
availableBytes -= codeLength; // keep track or remaining space
int currentEncodeLevel = 0;
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, node, outputBuffer, availableBytes,
bag, viewFrustum, includeColor, includeExistsBits, chopLevels,
deltaViewFrustum, lastViewFrustum);
int childBytesWritten = encodeTreeBitstreamRecursion(node, outputBuffer, availableBytes, bag, params, currentEncodeLevel);
// if childBytesWritten == 1 then something went wrong... that's not possible
assert(childBytesWritten != 1);
// if includeColor and childBytesWritten == 2, then it can only mean that the lower level trees don't exist or for some reason
// couldn't be written... so reset them here... This isn't true for the non-color included case
if (includeColor && childBytesWritten == 2) {
if (params.includeColor && childBytesWritten == 2) {
childBytesWritten = 0;
}
@ -1045,10 +1042,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
return bytesWritten;
}
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node,
unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
EncodeBitstreamParams& params, int& currentEncodeLevel) const {
// How many bytes have we written so far at this level;
int bytesAtThisLevel = 0;
@ -1057,13 +1052,13 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
currentEncodeLevel++;
// If we've reached our max Search Level, then stop searching.
if (currentEncodeLevel >= maxEncodeLevel) {
if (currentEncodeLevel >= params.maxEncodeLevel) {
return bytesAtThisLevel;
}
// caller can pass NULL as viewFrustum if they want everything
if (viewFrustum) {
float distance = node->distanceToCamera(*viewFrustum);
if (params.viewFrustum) {
float distance = node->distanceToCamera(*params.viewFrustum);
float boundaryDistance = boundaryDistanceForRenderLevel(*node->getOctalCode() + 1);
// If we're too far away for our render level, then just return
@ -1074,7 +1069,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// If we're at a node that is out of view, then we can return, because no nodes below us will be in view!
// although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if
// we're out of view
if (!node->isInView(*viewFrustum)) {
if (!node->isInView(*params.viewFrustum)) {
return bytesAtThisLevel;
}
}
@ -1107,16 +1102,16 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
VoxelNode* childNode = node->getChildAtIndex(i);
// if the caller wants to include childExistsBits, then include them even if not in view
if (includeExistsBits && childNode) {
if (params.includeExistsBits && childNode) {
childrenExistInTreeBits += (1 << (7 - i));
}
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
bool childIsInView = (childNode && (!params.viewFrustum || childNode->isInView(*params.viewFrustum)));
if (childIsInView) {
// Before we determine consider this further, let's see if it's in our LOD scope...
float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0;
float boundaryDistance = viewFrustum ? boundaryDistanceForRenderLevel(*childNode->getOctalCode() + 1) : 1;
float distance = params.viewFrustum ? childNode->distanceToCamera(*params.viewFrustum) : 0;
float boundaryDistance = params.viewFrustum ? boundaryDistanceForRenderLevel(*childNode->getOctalCode() + 1) : 1;
if (distance < boundaryDistance) {
inViewCount++;
@ -1129,8 +1124,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
inViewNotLeafCount++;
}
bool childWasInView = (childNode && deltaViewFrustum &&
(lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*lastViewFrustum)));
bool childWasInView = (childNode && params.deltaViewFrustum &&
(params.lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*params.lastViewFrustum)));
// track children with actual color, only if the child wasn't previously in view!
if (childNode && childNode->isColored() && !childWasInView) {
@ -1145,7 +1140,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count
// write the color data...
if (includeColor) {
if (params.includeColor) {
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
if (oneAtBit(childrenColoredBits, i)) {
memcpy(writeToThisLevelBuffer, &node->getChildAtIndex(i)->getColor(), BYTES_PER_COLOR);
@ -1157,7 +1152,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// if the caller wants to include childExistsBits, then include them even if not in view, put them before the
// childrenExistInPacketBits, so that the lower code can properly repair the packet exists bits
if (includeExistsBits) {
if (params.includeExistsBits) {
*writeToThisLevelBuffer = childrenExistInTreeBits;
writeToThisLevelBuffer += sizeof(childrenExistInTreeBits); // move the pointer
bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count
@ -1201,10 +1196,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
VoxelNode* childNode = node->getChildAtIndex(i);
int thisLevel = currentEncodeLevel;
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
outputBuffer, availableBytes, bag,
viewFrustum, includeColor, includeExistsBits, chopLevels,
deltaViewFrustum, lastViewFrustum);
int childTreeBytesOut = encodeTreeBitstreamRecursion(childNode, outputBuffer, availableBytes, bag,
params, thisLevel);
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
// basically, the children below don't contain any info.
@ -1222,7 +1215,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// so, if the child returns 2 bytes out, we can actually consider that an empty tree also!!
//
// we can make this act like no bytes out, by just resetting the bytes out in this case
if (includeColor && childTreeBytesOut == 2) {
if (params.includeColor && childTreeBytesOut == 2) {
childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees
}
@ -1287,8 +1280,9 @@ void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) const {
while (!nodeBag.isEmpty()) {
VoxelNode* subTree = nodeBag.extract();
bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0],
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
bytesWritten = encodeTreeBitstream(subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, params);
file.write((const char*)&outputBuffer[0], bytesWritten);
}
@ -1322,8 +1316,8 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat
VoxelNode* subTree = nodeBag.extract();
// ask our tree to write a bitsteam
bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0],
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels);
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels);
bytesWritten = encodeTreeBitstream(subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, params);
// ask destination tree to read the bitstream
destinationTree->readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS);
@ -1342,9 +1336,9 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin
VoxelNode* subTree = nodeBag.extract();
// ask our tree to write a bitsteam
bytesWritten = sourceTree->encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0],
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
bytesWritten = sourceTree->encodeTreeBitstream(subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, params);
// ask destination tree to read the bitstream
readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS, destinationNode);
}

View file

@ -28,6 +28,35 @@ typedef enum {GRADIENT, RANDOM, NATURAL} creationMode;
#define COLLAPSE_EMPTY_TREE true
#define DONT_COLLAPSE false
class EncodeBitstreamParams {
public:
int maxEncodeLevel;
const ViewFrustum* viewFrustum;
bool includeColor;
bool includeExistsBits;
int chopLevels;
bool deltaViewFrustum;
const ViewFrustum* lastViewFrustum;
EncodeBitstreamParams(
int maxEncodeLevel = INT_MAX,
const ViewFrustum* viewFrustum = IGNORE_VIEW_FRUSTUM,
bool includeColor = WANT_COLOR,
bool includeExistsBits = WANT_EXISTS_BITS,
int chopLevels = 0,
bool deltaViewFrustum = false,
const ViewFrustum* lastViewFrustum = IGNORE_VIEW_FRUSTUM) :
maxEncodeLevel (maxEncodeLevel),
viewFrustum (viewFrustum),
includeColor (includeColor),
includeExistsBits (includeExistsBits),
chopLevels (chopLevels),
deltaViewFrustum (deltaViewFrustum),
lastViewFrustum (lastViewFrustum)
{}
};
class VoxelTree {
public:
// when a voxel is created in the tree (object new'd)
@ -68,10 +97,8 @@ public:
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum,
bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, int chopLevels = 0,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const;
int encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
EncodeBitstreamParams& params) const;
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL);
@ -105,10 +132,8 @@ private:
void deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraData);
void readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraData);
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
int encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
EncodeBitstreamParams& params, int& currentEncodeLevel) const;
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,

View file

@ -167,10 +167,12 @@ void resInVoxelDistributor(AgentList* agentList,
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
if (!agentData->nodeBag.isEmpty()) {
VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = serverTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree,
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, &viewFrustum,
agentData->getWantColor(), WANT_EXISTS_BITS);
EncodeBitstreamParams params(agentData->getMaxSearchLevel(), &viewFrustum,
agentData->getWantColor(), WANT_EXISTS_BITS);
bytesWritten = serverTree.encodeTreeBitstream(subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, params);
if (agentData->getAvailable() >= bytesWritten) {
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
@ -310,12 +312,13 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
if (!agentData->nodeBag.isEmpty()) {
VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = serverTree.encodeTreeBitstream(INT_MAX, subTree,
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, &agentData->getCurrentViewFrustum(),
agentData->getWantColor(), WANT_EXISTS_BITS,
wantDelta, lastViewFrustum);
EncodeBitstreamParams params(INT_MAX, &agentData->getCurrentViewFrustum(), agentData->getWantColor(),
WANT_EXISTS_BITS, wantDelta, lastViewFrustum);
bytesWritten = serverTree.encodeTreeBitstream(subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, params);
if (agentData->getAvailable() >= bytesWritten) {
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
} else {