mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 19:04:32 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
0cff127082
24 changed files with 389 additions and 128 deletions
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# gen_stars.py
|
||||
# interface
|
||||
|
@ -12,7 +14,7 @@ from random import random,randint
|
|||
from math import sqrt, hypot, atan2, pi, fmod, degrees
|
||||
from sys import argv,stderr
|
||||
|
||||
hemisphere_only, equator, meridians= False, 1000, 1000
|
||||
hemisphere_only, equator, meridians= False, 0, 1000
|
||||
|
||||
n_random = 100000
|
||||
if len(argv) > 1:
|
||||
|
@ -50,10 +52,13 @@ for i in range(n_random):
|
|||
g = max(0,min(255,w + randint(-20,60)))
|
||||
b = max(0,min(255,w + randint(-10,100)))
|
||||
# position
|
||||
x,y,z = random()*2-1,random(),random()*2-1
|
||||
if not hemisphere_only:
|
||||
y = y*2-1
|
||||
l = sqrt(x*x + y*y + z*z)
|
||||
while True:
|
||||
x,y,z = random()*2-1,random(),random()*2-1
|
||||
if not hemisphere_only:
|
||||
y = y*2-1
|
||||
l = sqrt(x*x + y*y + z*z)
|
||||
if l <= 1.0:
|
||||
break
|
||||
x /= l; y /= l; z /= l
|
||||
xz = hypot(x,z)
|
||||
|
||||
|
|
|
@ -111,7 +111,8 @@ int audioCallback (const void *inputBuffer,
|
|||
|
||||
int16_t *inputLeft = ((int16_t **) inputBuffer)[0];
|
||||
|
||||
// printLog("Audio callback at %6.0f\n", usecTimestampNow()/1000);
|
||||
// Add Procedural effects to input samples
|
||||
data->addProceduralSounds(inputLeft, BUFFER_LENGTH_SAMPLES);
|
||||
|
||||
if (inputLeft != NULL) {
|
||||
|
||||
|
@ -436,15 +437,15 @@ float Audio::getInputLoudness() const {
|
|||
void Audio::render(int screenWidth, int screenHeight)
|
||||
{
|
||||
if (initialized) {
|
||||
glLineWidth(3);
|
||||
glLineWidth(2.0);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(1,1,1);
|
||||
|
||||
int startX = 50.0;
|
||||
int startX = 20.0;
|
||||
int currentX = startX;
|
||||
int topY = screenHeight - 90;
|
||||
int bottomY = screenHeight - 50;
|
||||
float frameWidth = 50.0;
|
||||
int topY = screenHeight - 40;
|
||||
int bottomY = screenHeight - 20;
|
||||
float frameWidth = 20.0;
|
||||
float halfY = topY + ((bottomY - topY) / 2.0);
|
||||
|
||||
// draw the lines for the base of the ring buffer
|
||||
|
@ -484,10 +485,10 @@ void Audio::render(int screenWidth, int screenHeight)
|
|||
}
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(startX, topY + 5);
|
||||
glVertex2f(startX + (remainingBuffer + timeLeftInCurrentBuffer)/AUDIO_CALLBACK_MSECS*frameWidth, topY + 5);
|
||||
glVertex2f(startX + (remainingBuffer + timeLeftInCurrentBuffer)/AUDIO_CALLBACK_MSECS*frameWidth, bottomY - 5);
|
||||
glVertex2f(startX, bottomY - 5);
|
||||
glVertex2f(startX, topY + 2);
|
||||
glVertex2f(startX + (remainingBuffer + timeLeftInCurrentBuffer)/AUDIO_CALLBACK_MSECS*frameWidth, topY + 2);
|
||||
glVertex2f(startX + (remainingBuffer + timeLeftInCurrentBuffer)/AUDIO_CALLBACK_MSECS*frameWidth, bottomY - 2);
|
||||
glVertex2f(startX, bottomY - 2);
|
||||
glEnd();
|
||||
|
||||
if (audioData->averagedLatency == 0.0) audioData->averagedLatency = remainingBuffer + timeLeftInCurrentBuffer;
|
||||
|
@ -504,7 +505,7 @@ void Audio::render(int screenWidth, int screenHeight)
|
|||
|
||||
char out[40];
|
||||
sprintf(out, "%3.0f\n", audioData->averagedLatency);
|
||||
drawtext(startX + audioData->averagedLatency/AUDIO_CALLBACK_MSECS*frameWidth - 10, topY-10, 0.08, 0, 1, 0, out, 1,1,0);
|
||||
drawtext(startX + audioData->averagedLatency/AUDIO_CALLBACK_MSECS*frameWidth - 10, topY-10, 0.10, 0, 1, 0, out, 1,1,0);
|
||||
//drawtext(startX + 0, topY-10, 0.08, 0, 1, 0, out, 1,1,0);
|
||||
|
||||
// Show a Cyan bar with the most recently measured jitter stdev
|
||||
|
@ -520,13 +521,10 @@ void Audio::render(int screenWidth, int screenHeight)
|
|||
glEnd();
|
||||
|
||||
sprintf(out,"%3.1f\n", audioData->measuredJitter);
|
||||
drawtext(startX + jitterPels - 5, topY-10, 0.08, 0, 1, 0, out, 0,1,1);
|
||||
drawtext(startX + jitterPels - 5, topY-10, 0.10, 0, 1, 0, out, 0,1,1);
|
||||
|
||||
sprintf(out, "%3.1fms\n", JITTER_BUFFER_LENGTH_MSECS);
|
||||
drawtext(startX - 10, bottomY + 20, 0.1, 0, 1, 0, out, 1, 0, 0);
|
||||
|
||||
sprintf(out, "%hd samples\n", JITTER_BUFFER_SAMPLES);
|
||||
drawtext(startX - 10, bottomY + 35, 0.1, 0, 1, 0, out, 1, 0, 0);
|
||||
drawtext(startX - 10, bottomY + 15, 0.1, 0, 1, 0, out, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ public:
|
|||
|
||||
void setWalkingState(bool newWalkState);
|
||||
|
||||
void setLastAcceleration(glm::vec3 a) { audioData->setLastAcceleration(a); };
|
||||
void setLastVelocity(glm::vec3 v) { audioData->setLastVelocity(v); };
|
||||
|
||||
// terminates audio I/O
|
||||
bool terminate();
|
||||
private:
|
||||
|
|
|
@ -28,4 +28,21 @@ AudioData::~AudioData() {
|
|||
delete audioSocket;
|
||||
}
|
||||
|
||||
// Take a pointer to the acquired microphone input samples and add procedural sounds
|
||||
void AudioData::addProceduralSounds(int16_t* inputBuffer, int numSamples) {
|
||||
const float MAX_AUDIBLE_VELOCITY = 6.0;
|
||||
const float MIN_AUDIBLE_VELOCITY = 0.1;
|
||||
float speed = glm::length(_lastVelocity);
|
||||
float volume = 400 * (1.f - speed/MAX_AUDIBLE_VELOCITY);
|
||||
// Add a noise-modulated sinewave with volume that tapers off with speed increasing
|
||||
if ((speed > MIN_AUDIBLE_VELOCITY) && (speed < MAX_AUDIBLE_VELOCITY)) {
|
||||
for (int i = 0; i < numSamples; i++) {
|
||||
inputBuffer[i] += (int16_t) ((cosf((float)i / 8.f * speed) * randFloat()) * volume * speed) ;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,17 @@ class AudioData {
|
|||
|
||||
bool mixerLoopbackFlag;
|
||||
bool playWalkSound;
|
||||
|
||||
// Added avatar acceleration and velocity for procedural effects sounds from client
|
||||
void setLastVelocity(glm::vec3 v) { _lastVelocity = v; };
|
||||
void setLastAcceleration(glm::vec3 a) { _lastAcceleration = a; };
|
||||
void addProceduralSounds(int16_t* inputBuffer, int numSamples);
|
||||
|
||||
private:
|
||||
glm::vec3 _lastVelocity;
|
||||
glm::vec3 _lastAcceleration;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__AudioData__) */
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
// Created by Philip Rosedale on 9/11/12.
|
||||
// adapted by Jeffrey Ventrella
|
||||
// Copyright (c) 2013 Physical, Inc.. All rights reserved.
|
||||
//
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
|
@ -31,7 +30,7 @@ const float BODY_SPIN_FRICTION = 5.0;
|
|||
const float BODY_UPRIGHT_FORCE = 10.0;
|
||||
const float BODY_PITCH_WHILE_WALKING = 30.0;
|
||||
const float BODY_ROLL_WHILE_TURNING = 0.1;
|
||||
const float LIN_VEL_DECAY = 5.0;
|
||||
const float LIN_VEL_DECAY = 2.0;
|
||||
const float MY_HAND_HOLDING_PULL = 0.2;
|
||||
const float YOUR_HAND_HOLDING_PULL = 1.0;
|
||||
const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f;
|
||||
|
@ -265,7 +264,7 @@ void Avatar::reset() {
|
|||
|
||||
|
||||
// Update avatar head rotation with sensor data
|
||||
void Avatar::UpdateGyros(float frametime, SerialInterface* serialInterface, glm::vec3* gravity) {
|
||||
void Avatar::updateHeadFromGyros(float frametime, SerialInterface* serialInterface, glm::vec3* gravity) {
|
||||
float measuredPitchRate = 0.0f;
|
||||
float measuredRollRate = 0.0f;
|
||||
float measuredYawRate = 0.0f;
|
||||
|
@ -412,8 +411,8 @@ void Avatar::simulate(float deltaTime) {
|
|||
_velocity *= (1.0 - LIN_VEL_DECAY * deltaTime);
|
||||
|
||||
// If someone is near, damp velocity as a function of closeness
|
||||
const float AVATAR_BRAKING_RANGE = 1.2f;
|
||||
const float AVATAR_BRAKING_STRENGTH = 25.f;
|
||||
const float AVATAR_BRAKING_RANGE = 1.6f;
|
||||
const float AVATAR_BRAKING_STRENGTH = 35.f;
|
||||
if (_isMine && (_distanceToNearestAvatar < AVATAR_BRAKING_RANGE)) {
|
||||
_velocity *=
|
||||
(1.f - deltaTime * AVATAR_BRAKING_STRENGTH *
|
||||
|
@ -950,7 +949,13 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
glColor3f(0,0,0);
|
||||
glRotatef(_head.mouthPitch, 1, 0, 0);
|
||||
glRotatef(_head.mouthYaw, 0, 0, 1);
|
||||
glScalef(_head.mouthWidth*(.7 + sqrt(_head.averageLoudness)/60.0), _head.mouthHeight*(1.0 + sqrt(_head.averageLoudness)/30.0), 1);
|
||||
if (_head.averageLoudness > 1.f) {
|
||||
glScalef(_head.mouthWidth * (.7f + sqrt(_head.averageLoudness) /60.f),
|
||||
_head.mouthHeight * (1.f + sqrt(_head.averageLoudness) /30.f), 1);
|
||||
} else {
|
||||
glScalef(_head.mouthWidth, _head.mouthHeight, 1);
|
||||
}
|
||||
|
||||
glutSolidCube(0.5);
|
||||
glPopMatrix();
|
||||
|
||||
|
|
|
@ -82,8 +82,8 @@ public:
|
|||
Avatar* clone() const;
|
||||
|
||||
void reset();
|
||||
void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
|
||||
|
||||
|
||||
void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
|
||||
void setNoise (float mag) {_head.noise = mag;}
|
||||
void setScale(float s) {_head.scale = s; };
|
||||
void setRenderYaw(float y) {_renderYaw = y;}
|
||||
|
@ -102,9 +102,13 @@ public:
|
|||
void setLeanSideways(float dist);
|
||||
void addLean(float x, float z);
|
||||
const glm::vec3& getHeadPosition() const ;
|
||||
const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].position; };
|
||||
|
||||
//const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].position; };
|
||||
const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].springyPosition; };
|
||||
|
||||
const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); };
|
||||
float getSpeed() const { return _speed; };
|
||||
const glm::vec3& getVelocity() const { return _velocity; };
|
||||
float getGirth();
|
||||
float getHeight();
|
||||
|
||||
|
|
|
@ -15,5 +15,62 @@ AvatarRenderer::AvatarRenderer() {
|
|||
}
|
||||
|
||||
// this method renders the avatar
|
||||
void AvatarRenderer::render(Avatar *avatar, bool lookingInMirror) {
|
||||
}
|
||||
void AvatarRenderer::render(Avatar *avatarToRender, bool lookingInMirror, glm::vec3 cameraPosition) {
|
||||
|
||||
avatar = avatarToRender;
|
||||
|
||||
/*
|
||||
// show avatar position
|
||||
glColor4f(0.5f, 0.5f, 0.5f, 0.6);
|
||||
glPushMatrix();
|
||||
glm::vec3 j( avatar->getJointPosition( AVATAR_JOINT_PELVIS ) );
|
||||
glTranslatef(j.x, j.y, j.z);
|
||||
glScalef(0.08, 0.08, 0.08);
|
||||
glutSolidSphere(1, 10, 10);
|
||||
glPopMatrix();
|
||||
*/
|
||||
|
||||
//renderDiskShadow(avatar->getJointPosition( AVATAR_JOINT_PELVIS ), glm::vec3(0.0f, 1.0f, 0.0f), 0.1f, 0.2f);
|
||||
|
||||
//renderBody();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AvatarRenderer::renderBody() {
|
||||
/*
|
||||
// Render joint positions as spheres
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
|
||||
if (b != AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case in "renderHead"
|
||||
|
||||
//show direction vectors of the bone orientation
|
||||
//renderOrientationDirections(_joint[b].springyPosition, _joint[b].orientation, _joint[b].radius * 2.0);
|
||||
|
||||
glm::vec3 j( avatar->getJointPosition( AVATAR_JOINT_PELVIS ) );
|
||||
glColor3fv(skinColor);
|
||||
glPushMatrix();
|
||||
glTranslatef(j.x, j.y, j.z);
|
||||
glutSolidSphere(_joint[b].radius, 20.0f, 20.0f);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
// Render lines connecting the joint positions
|
||||
glColor3f(0.4f, 0.5f, 0.6f);
|
||||
glLineWidth(3.0);
|
||||
|
||||
for (int b = 1; b < NUM_AVATAR_JOINTS; b++) {
|
||||
if (_joint[b].parent != AVATAR_JOINT_NULL)
|
||||
if (b != AVATAR_JOINT_HEAD_TOP) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(&_joint[ _joint[ b ].parent ].springyPosition.x);
|
||||
glVertex3fv(&_joint[ b ].springyPosition.x);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ class AvatarRenderer {
|
|||
public:
|
||||
|
||||
AvatarRenderer();
|
||||
void render(Avatar *avatar, bool lookingInMirror);
|
||||
void render(Avatar *avatarToRender, bool lookingInMirror, glm::vec3 cameraPosition );
|
||||
|
||||
private:
|
||||
|
||||
Avatar *avatar;
|
||||
void renderBody();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -80,7 +80,7 @@ void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) {
|
|||
_arrWritePos[ch] = newWritePos;
|
||||
}
|
||||
|
||||
void Oscilloscope::render() {
|
||||
void Oscilloscope::render(int x, int y) {
|
||||
|
||||
if (! enabled) {
|
||||
return;
|
||||
|
@ -113,8 +113,9 @@ void Oscilloscope::render() {
|
|||
}
|
||||
}
|
||||
|
||||
glLineWidth(2.0);
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0f, _valHeight / 2.0f, 0.0f);
|
||||
glTranslatef((float)x + 0.0f, (float)y + _valHeight / 2.0f, 0.0f);
|
||||
glScaled(1.0f, _valHeight / 32767.0f, 1.0f);
|
||||
glVertexPointer(2, GL_SHORT, 0, _arrVertices);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
|
||||
void addSamples(unsigned ch, short const* data, unsigned n);
|
||||
|
||||
void render();
|
||||
void render(int x, int y);
|
||||
|
||||
void setLowpass(float w) { assert(w > 0.0f && w <= 1.0f); _valLowpass = w; }
|
||||
void setDownsampling(unsigned f) { assert(f > 0); _valDownsample = f; }
|
||||
|
|
|
@ -139,22 +139,22 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
double start = usecTimestampNow();
|
||||
double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000.0;
|
||||
|
||||
if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed,SIXTY_FPS_IN_MILLISECONDS)) {
|
||||
if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
|
||||
return; // bail early, it hasn't been long enough since the last time we ran
|
||||
}
|
||||
|
||||
double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;
|
||||
|
||||
// If the view frustum has changed, since last time, then remove nodes that are out of view
|
||||
if ((sinceLastViewCulling >= VIEW_CULLING_RATE_IN_MILLISECONDS) && hasViewChanged()) {
|
||||
if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) && hasViewChanged()) {
|
||||
_lastViewCulling = start;
|
||||
removeOutOfView();
|
||||
double endViewCulling = usecTimestampNow();
|
||||
_lastViewCullingElapsed = (endViewCulling - start) / 1000.0;
|
||||
}
|
||||
|
||||
if (_tree->isDirty()) {
|
||||
PerformanceWarning warn(_renderWarningsOn, "calling... newTreeToArrays()");
|
||||
_callsToTreesToArrays++;
|
||||
|
||||
if (_alwaysRenderFullVBO) {
|
||||
_voxelsInWriteArrays = 0; // reset our VBO
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
copyWrittenDataToReadArrays();
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
double elapsedmsec = (end - start) / 1000.0;
|
||||
_setupNewVoxelsForDrawingLastFinished = end;
|
||||
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
|
||||
}
|
||||
|
@ -220,6 +220,11 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
|
|||
}
|
||||
|
||||
int VoxelSystem::newway__updateNodeInArray(VoxelNode* node) {
|
||||
// If we've run out of room, then just bail...
|
||||
if (_voxelsInWriteArrays >= MAX_VOXELS_PER_SYSTEM) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (node->getShouldRender()) {
|
||||
glm::vec3 startVertex = node->getCorner();
|
||||
float voxelScale = node->getScale();
|
||||
|
@ -294,7 +299,7 @@ void VoxelSystem::init() {
|
|||
_callsToTreesToArrays = 0;
|
||||
_setupNewVoxelsForDrawingLastFinished = 0;
|
||||
_setupNewVoxelsForDrawingLastElapsed = 0;
|
||||
_lastViewCulling = 0;
|
||||
_lastViewCullingElapsed = _lastViewCulling = 0;
|
||||
|
||||
// When we change voxels representations in the arrays, we'll update this
|
||||
_voxelsDirty = false;
|
||||
|
@ -583,17 +588,71 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) {
|
|||
setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
// combines the removeOutOfView args into a single class
|
||||
class removeOutOfViewArgs {
|
||||
public:
|
||||
VoxelSystem* thisVoxelSystem;
|
||||
VoxelNodeBag dontRecurseBag;
|
||||
unsigned long nodesScanned;
|
||||
unsigned long nodesRemoved;
|
||||
unsigned long nodesInside;
|
||||
unsigned long nodesIntersect;
|
||||
unsigned long nodesOutside;
|
||||
|
||||
removeOutOfViewArgs(VoxelSystem* voxelSystem) :
|
||||
thisVoxelSystem(voxelSystem),
|
||||
dontRecurseBag(),
|
||||
nodesScanned(0),
|
||||
nodesRemoved(0),
|
||||
nodesInside(0),
|
||||
nodesIntersect(0),
|
||||
nodesOutside(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
// "Remove" voxels from the tree that are not in view. We don't actually delete them,
|
||||
// we remove them from the tree and place them into a holding area for later deletion
|
||||
bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {
|
||||
VoxelSystem* thisVoxelSystem = (VoxelSystem*) extraData;
|
||||
_nodeCount++;
|
||||
removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData;
|
||||
|
||||
// If our node was previously added to the don't recurse bag, then return false to
|
||||
// stop the further recursion. This means that the whole node and it's children are
|
||||
// known to be in view, so don't recurse them
|
||||
if (args->dontRecurseBag.contains(node)) {
|
||||
args->dontRecurseBag.remove(node);
|
||||
return false; // stop recursion
|
||||
}
|
||||
|
||||
VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
|
||||
args->nodesScanned++;
|
||||
// Need to operate on our child nodes, so we can remove them
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||
if (childNode && !childNode->isInView(*thisVoxelSystem->_viewFrustum)) {
|
||||
node->removeChildAtIndex(i);
|
||||
thisVoxelSystem->_removedVoxels.insert(childNode);
|
||||
if (childNode) {
|
||||
ViewFrustum::location inFrustum = childNode->inFrustum(*thisVoxelSystem->_viewFrustum);
|
||||
switch (inFrustum) {
|
||||
case ViewFrustum::OUTSIDE: {
|
||||
args->nodesOutside++;
|
||||
args->nodesRemoved++;
|
||||
node->removeChildAtIndex(i);
|
||||
thisVoxelSystem->_removedVoxels.insert(childNode);
|
||||
// by removing the child, it will not get recursed!
|
||||
} break;
|
||||
case ViewFrustum::INSIDE: {
|
||||
// if the child node is fully INSIDE the view, then there's no need to recurse it
|
||||
// because we know all it's children will also be in the view, so we want to
|
||||
// tell the caller to NOT recurse this child
|
||||
args->nodesInside++;
|
||||
args->dontRecurseBag.insert(childNode);
|
||||
} break;
|
||||
case ViewFrustum::INTERSECT: {
|
||||
// if the child node INTERSECTs the view, then we don't want to remove it because
|
||||
// it is at least partially in view. But we DO want to recurse the children because
|
||||
// some of them may not be in view... nothing specifically to do, just keep iterating
|
||||
// the children
|
||||
args->nodesIntersect++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // keep going!
|
||||
|
@ -609,9 +668,16 @@ bool VoxelSystem::hasViewChanged() {
|
|||
}
|
||||
|
||||
void VoxelSystem::removeOutOfView() {
|
||||
PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); // would like to include removedCount, _nodeCount, _removedVoxels.count()
|
||||
_nodeCount = 0;
|
||||
_tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this);
|
||||
PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()");
|
||||
removeOutOfViewArgs args(this);
|
||||
_tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
|
||||
|
||||
if (_renderWarningsOn) {
|
||||
printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld bag.count()=%d \n",
|
||||
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
||||
args.nodesIntersect, args.nodesOutside, args.dontRecurseBag.count()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance) {
|
||||
|
|
|
@ -107,6 +107,7 @@ private:
|
|||
double _setupNewVoxelsForDrawingLastElapsed;
|
||||
double _setupNewVoxelsForDrawingLastFinished;
|
||||
double _lastViewCulling;
|
||||
double _lastViewCullingElapsed;
|
||||
|
||||
GLuint _vboVerticesID;
|
||||
GLuint _vboNormalsID;
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
|
||||
#include "ViewFrustum.h"
|
||||
#include "HandControl.h"
|
||||
#include "AvatarRenderer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -114,19 +115,17 @@ Avatar myAvatar(true); // The rendered avatar of oneself
|
|||
Camera myCamera; // My view onto the world (sometimes on myself :)
|
||||
Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
||||
|
||||
AvatarRenderer avatarRenderer;
|
||||
|
||||
// Starfield information
|
||||
char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
|
||||
char starCacheFile[] = "cachedStars.txt";
|
||||
Stars stars;
|
||||
|
||||
bool showingVoxels = true;
|
||||
|
||||
glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE);
|
||||
|
||||
VoxelSystem voxels;
|
||||
|
||||
bool wantToKillLocalVoxels = false;
|
||||
|
||||
Environment environment;
|
||||
|
||||
|
||||
|
@ -135,16 +134,18 @@ Audio audio(&audioScope, &myAvatar);
|
|||
#endif
|
||||
|
||||
#define IDLE_SIMULATE_MSECS 16 // How often should call simulate and other stuff
|
||||
// in the idle loop?
|
||||
// in the idle loop? (60 FPS is default)
|
||||
|
||||
// Where one's own agent begins in the world (needs to become a dynamic thing passed to the program)
|
||||
glm::vec3 start_location(6.1f, 0, 1.4f);
|
||||
|
||||
glm::vec3 start_location(6.1f, 0, 1.4f); // Where one's own agent begins in the world
|
||||
// (will be overwritten if avatar data file is found)
|
||||
|
||||
bool renderWarningsOn = false; // Whether to show render pipeline warnings
|
||||
|
||||
bool statsOn = false; // Whether to show onscreen text overlay with stats
|
||||
bool starsOn = false; // Whether to display the stars
|
||||
bool atmosphereOn = true; // Whether to display the atmosphere
|
||||
bool renderStatsOn = false; // Whether to show onscreen text overlay with stats
|
||||
bool renderVoxels = true; // Whether to render voxels
|
||||
bool renderStarsOn = true; // Whether to display the stars
|
||||
bool renderAtmosphereOn = true; // Whether to display the atmosphere
|
||||
bool renderAvatarsOn = true; // Whether to render avatars
|
||||
bool paintOn = false; // Whether to paint voxels as you fly around
|
||||
VoxelDetail paintingVoxel; // The voxel we're painting if we're painting
|
||||
unsigned char dominantColor = 0; // The dominant color of the voxel we're painting
|
||||
|
@ -152,6 +153,8 @@ bool perfStatsOn = false; // Do we want to display perfStats?
|
|||
|
||||
bool logOn = true; // Whether to show on-screen log
|
||||
|
||||
bool wantToKillLocalVoxels = false;
|
||||
|
||||
int noiseOn = 0; // Whether to add random noise
|
||||
float noise = 1.0; // Overall magnitude scaling for random noise levels
|
||||
|
||||
|
@ -370,20 +373,29 @@ void reset_sensors() {
|
|||
//
|
||||
// Using gyro data, update both view frustum and avatar head position
|
||||
//
|
||||
void updateAvatar(float frametime) {
|
||||
float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE);
|
||||
float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE );
|
||||
void updateAvatar(float deltaTime) {
|
||||
|
||||
myAvatar.UpdateGyros(frametime, &serialPort, &gravity);
|
||||
|
||||
// Update my avatar's head position from gyros
|
||||
myAvatar.updateHeadFromGyros(deltaTime, &serialPort, &gravity);
|
||||
|
||||
// Grab latest readings from the gyros
|
||||
float measuredYawRate, measuredPitchRate;
|
||||
if (USING_INVENSENSE_MPU9150) {
|
||||
measuredPitchRate = serialPort.getLastPitchRate();
|
||||
measuredYawRate = serialPort.getLastYawRate();
|
||||
} else {
|
||||
measuredPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE);
|
||||
measuredYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE);
|
||||
}
|
||||
|
||||
// Update gyro-based mouse (X,Y on screen)
|
||||
const float MIN_MOUSE_RATE = 30.0;
|
||||
const float MOUSE_SENSITIVITY = 0.1f;
|
||||
if (powf(gyroYawRate*gyroYawRate +
|
||||
gyroPitchRate*gyroPitchRate, 0.5) > MIN_MOUSE_RATE)
|
||||
if (powf(measuredYawRate * measuredYawRate +
|
||||
measuredPitchRate * measuredPitchRate, 0.5) > MIN_MOUSE_RATE)
|
||||
{
|
||||
headMouseX += gyroYawRate*MOUSE_SENSITIVITY;
|
||||
headMouseY += gyroPitchRate*MOUSE_SENSITIVITY*(float)HEIGHT/(float)WIDTH;
|
||||
headMouseX += measuredYawRate*MOUSE_SENSITIVITY;
|
||||
headMouseY += measuredPitchRate*MOUSE_SENSITIVITY*(float)HEIGHT/(float)WIDTH;
|
||||
}
|
||||
headMouseX = max(headMouseX, 0);
|
||||
headMouseX = min(headMouseX, WIDTH);
|
||||
|
@ -393,26 +405,31 @@ void updateAvatar(float frametime) {
|
|||
// Update head and body pitch and yaw based on measured gyro rates
|
||||
if (::gyroLook) {
|
||||
// Yaw
|
||||
const float MIN_YAW_RATE = 50;
|
||||
const float YAW_SENSITIVITY = 1.0;
|
||||
const float MIN_YAW_RATE = 20.f;
|
||||
const float YAW_MAGNIFY = 3.0;
|
||||
|
||||
if (fabs(gyroYawRate) > MIN_YAW_RATE) {
|
||||
float addToBodyYaw = (gyroYawRate > 0.f)
|
||||
? gyroYawRate - MIN_YAW_RATE : gyroYawRate + MIN_YAW_RATE;
|
||||
if (fabs(measuredYawRate) > MIN_YAW_RATE) {
|
||||
float addToBodyYaw = (measuredYawRate > 0.f)
|
||||
? measuredYawRate - MIN_YAW_RATE : measuredYawRate + MIN_YAW_RATE;
|
||||
|
||||
myAvatar.addBodyYaw(-addToBodyYaw * YAW_SENSITIVITY * frametime);
|
||||
// If we are rotating the body (render angle), move the head reverse amount to compensate
|
||||
myAvatar.addBodyYaw(-addToBodyYaw * YAW_MAGNIFY * deltaTime);
|
||||
myAvatar.addHeadYaw(addToBodyYaw * YAW_MAGNIFY * deltaTime);
|
||||
}
|
||||
// Pitch NOTE: PER - Need to make camera able to pitch first!
|
||||
/*
|
||||
const float MIN_PITCH_RATE = 50;
|
||||
const float PITCH_SENSITIVITY = 1.0;
|
||||
// Pitch
|
||||
const float MIN_PITCH_RATE = 20.f;
|
||||
const float PITCH_MAGNIFY = 2.0;
|
||||
|
||||
if (fabs(gyroPitchRate) > MIN_PITCH_RATE) {
|
||||
float addToBodyPitch = (gyroPitchRate > 0.f)
|
||||
? gyroPitchRate - MIN_PITCH_RATE : gyroPitchRate + MIN_PITCH_RATE;
|
||||
if (fabs(measuredPitchRate) > MIN_PITCH_RATE) {
|
||||
float addToBodyPitch = (measuredPitchRate > 0.f)
|
||||
? measuredPitchRate - MIN_PITCH_RATE : measuredPitchRate + MIN_PITCH_RATE;
|
||||
|
||||
myAvatar.addBodyPitch(addToBodyPitch * PITCH_SENSITIVITY * frametime);
|
||||
*/
|
||||
myAvatar.setRenderPitch(myAvatar.getRenderPitch() + addToBodyPitch * PITCH_MAGNIFY * deltaTime);
|
||||
|
||||
}
|
||||
// Always decay the render pitch, assuming that we are never going to want to permanently look up or down
|
||||
const float RENDER_PITCH_DECAY = 1.0;
|
||||
myAvatar.setRenderPitch(myAvatar.getRenderPitch() * (1.f - RENDER_PITCH_DECAY * deltaTime));
|
||||
}
|
||||
|
||||
// Get audio loudness data from audio input device
|
||||
|
@ -437,7 +454,6 @@ void updateAvatar(float frametime) {
|
|||
myAvatar.setCameraFarClip(::viewFrustum.getFarClip());
|
||||
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
|
||||
if (agentList->getOwnerID() != UNKNOWN_AGENT_ID) {
|
||||
// if I know my ID, send head/hand data to the avatar mixer and voxel server
|
||||
unsigned char broadcastString[200];
|
||||
|
@ -682,12 +698,12 @@ void renderViewFrustum(ViewFrustum& viewFrustum) {
|
|||
void displaySide(Camera& whichCamera) {
|
||||
glPushMatrix();
|
||||
|
||||
if (::starsOn) {
|
||||
if (::renderStarsOn) {
|
||||
// should be the first rendering pass - w/o depth buffer / lighting
|
||||
|
||||
// compute starfield alpha based on distance from atmosphere
|
||||
float alpha = 1.0f;
|
||||
if (::atmosphereOn) {
|
||||
if (::renderAtmosphereOn) {
|
||||
float height = glm::distance(whichCamera.getPosition(), environment.getAtmosphereCenter());
|
||||
if (height < environment.getAtmosphereInnerRadius()) {
|
||||
alpha = 0.0f;
|
||||
|
@ -703,7 +719,7 @@ void displaySide(Camera& whichCamera) {
|
|||
}
|
||||
|
||||
// draw the sky dome
|
||||
if (::atmosphereOn) {
|
||||
if (::renderAtmosphereOn) {
|
||||
environment.renderAtmosphere(whichCamera);
|
||||
}
|
||||
|
||||
|
@ -721,29 +737,31 @@ void displaySide(Camera& whichCamera) {
|
|||
drawGroundPlaneGrid(10.f);
|
||||
|
||||
// Draw voxels
|
||||
if (showingVoxels) {
|
||||
if (renderVoxels) {
|
||||
voxels.render();
|
||||
}
|
||||
|
||||
// Render avatars of other agents
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
agentList->lock();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->render(0, ::myCamera.getPosition());
|
||||
if (::renderAvatarsOn) {
|
||||
// Render avatars of other agents
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
agentList->lock();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->render(0, ::myCamera.getPosition());
|
||||
}
|
||||
}
|
||||
agentList->unlock();
|
||||
|
||||
// Render my own Avatar
|
||||
myAvatar.render(::lookingInMirror, ::myCamera.getPosition());
|
||||
}
|
||||
agentList->unlock();
|
||||
|
||||
// Render the world box
|
||||
if (!::lookingInMirror && ::statsOn) { render_world_box(); }
|
||||
if (!::lookingInMirror && ::renderStatsOn) { render_world_box(); }
|
||||
|
||||
// brad's frustum for debugging
|
||||
if (::frustumOn) renderViewFrustum(::viewFrustum);
|
||||
|
||||
//Render my own avatar
|
||||
myAvatar.render(::lookingInMirror, ::myCamera.getPosition());
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
@ -909,12 +927,12 @@ void displayOverlay() {
|
|||
|
||||
#ifndef _WIN32
|
||||
audio.render(WIDTH, HEIGHT);
|
||||
audioScope.render();
|
||||
audioScope.render(20, HEIGHT - 200);
|
||||
#endif
|
||||
|
||||
//noiseTest(WIDTH, HEIGHT);
|
||||
|
||||
if (displayHeadMouse && !::lookingInMirror && statsOn) {
|
||||
if (displayHeadMouse && !::lookingInMirror && renderStatsOn) {
|
||||
// Display small target box at center or head mouse target that can also be used to measure LOD
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
|
@ -936,7 +954,7 @@ void displayOverlay() {
|
|||
glLineWidth(1.0f);
|
||||
glPointSize(1.0f);
|
||||
|
||||
if (::statsOn) { displayStats(); }
|
||||
if (::renderStatsOn) { displayStats(); }
|
||||
if (::logOn) { logger.render(WIDTH, HEIGHT); }
|
||||
|
||||
// Show menu
|
||||
|
@ -1021,12 +1039,12 @@ void display(void)
|
|||
//float firstPersonDistance = 0.0f;
|
||||
//float firstPersonTightness = 100.0f;
|
||||
|
||||
float firstPersonPitch = 20.0f;
|
||||
float firstPersonPitch = 20.0f + myAvatar.getRenderPitch();
|
||||
float firstPersonUpShift = 0.1f;
|
||||
float firstPersonDistance = 0.4f;
|
||||
float firstPersonTightness = 100.0f;
|
||||
|
||||
float thirdPersonPitch = 0.0f;
|
||||
float thirdPersonPitch = 0.0f + myAvatar.getRenderPitch();
|
||||
float thirdPersonUpShift = -0.2f;
|
||||
float thirdPersonDistance = 1.2f;
|
||||
float thirdPersonTightness = 8.0f;
|
||||
|
@ -1092,12 +1110,14 @@ void display(void)
|
|||
myCamera.update( 1.f/FPS );
|
||||
|
||||
// Render anything (like HUD items) that we want to be in 3D but not in worldspace
|
||||
/*
|
||||
const float HUD_Z_OFFSET = -5.f;
|
||||
glPushMatrix();
|
||||
glm::vec3 test(0.5, 0.5, 0.5);
|
||||
glTranslatef(1, 1, HUD_Z_OFFSET);
|
||||
drawVector(&test);
|
||||
glPopMatrix();
|
||||
*/
|
||||
|
||||
|
||||
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
||||
|
@ -1221,17 +1241,23 @@ int setFullscreen(int state) {
|
|||
}
|
||||
|
||||
int setVoxels(int state) {
|
||||
return setValue(state, &::showingVoxels);
|
||||
return setValue(state, &::renderVoxels);
|
||||
}
|
||||
|
||||
int setStars(int state) {
|
||||
return setValue(state, &::starsOn);
|
||||
return setValue(state, &::renderStarsOn);
|
||||
}
|
||||
|
||||
int setAtmosphere(int state) {
|
||||
return setValue(state, &::atmosphereOn);
|
||||
return setValue(state, &::renderAtmosphereOn);
|
||||
}
|
||||
|
||||
int setRenderAvatars(int state) {
|
||||
return setValue(state, &::renderAvatarsOn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int setOculus(int state) {
|
||||
bool wasOn = ::oculusOn;
|
||||
int value = setValue(state, &::oculusOn);
|
||||
|
@ -1242,7 +1268,7 @@ int setOculus(int state) {
|
|||
}
|
||||
|
||||
int setStats(int state) {
|
||||
return setValue(state, &::statsOn);
|
||||
return setValue(state, &::renderStatsOn);
|
||||
}
|
||||
|
||||
int setMenu(int state) {
|
||||
|
@ -1378,6 +1404,7 @@ void initMenu() {
|
|||
menuColumnRender->addRow("Voxels (V)", setVoxels);
|
||||
menuColumnRender->addRow("Stars (*)", setStars);
|
||||
menuColumnRender->addRow("Atmosphere (A)", setAtmosphere);
|
||||
menuColumnRender->addRow("Avatars", setRenderAvatars);
|
||||
menuColumnRender->addRow("Oculus (o)", setOculus);
|
||||
|
||||
// Tools
|
||||
|
@ -1578,10 +1605,10 @@ void key(unsigned char k, int x, int y) {
|
|||
|
||||
// Process keypresses
|
||||
if (k == 'q' || k == 'Q') ::terminate();
|
||||
if (k == '/') ::statsOn = !::statsOn; // toggle stats
|
||||
if (k == '*') ::starsOn = !::starsOn; // toggle stars
|
||||
if (k == 'V' || k == 'v') ::showingVoxels = !::showingVoxels; // toggle voxels
|
||||
if (k == 'A') ::atmosphereOn = !::atmosphereOn;
|
||||
if (k == '/') ::renderStatsOn = !::renderStatsOn; // toggle stats
|
||||
if (k == '*') ::renderStarsOn = !::renderStarsOn; // toggle stars
|
||||
if (k == 'V' || k == 'v') ::renderVoxels = !::renderVoxels; // toggle voxels
|
||||
if (k == 'A') ::renderAtmosphereOn = !::renderAtmosphereOn;
|
||||
if (k == 'F') ::frustumOn = !::frustumOn; // toggle view frustum debugging
|
||||
if (k == 'C') ::cameraFrustum = !::cameraFrustum; // toggle which frustum to look at
|
||||
if (k == 'O' || k == 'G') setFrustumOffset(MENU_ROW_PICKED); // toggle view frustum offset debugging
|
||||
|
@ -1725,11 +1752,12 @@ void idle(void) {
|
|||
handControl.stop();
|
||||
}
|
||||
|
||||
// Read serial port interface devices
|
||||
if (serialPort.active && USING_INVENSENSE_MPU9150) {
|
||||
serialPort.readData();
|
||||
}
|
||||
|
||||
// Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents
|
||||
// Sample hardware, update view frustum if needed, and send avatar data to mixer/agents
|
||||
updateAvatar(deltaTime);
|
||||
|
||||
// read incoming packets from network
|
||||
|
@ -1750,7 +1778,11 @@ void idle(void) {
|
|||
|
||||
myAvatar.setGravity(getGravity(myAvatar.getPosition()));
|
||||
myAvatar.simulate(deltaTime);
|
||||
|
||||
|
||||
// Update audio stats for procedural sounds
|
||||
audio.setLastAcceleration(myAvatar.getThrust());
|
||||
audio.setLastVelocity(myAvatar.getVelocity());
|
||||
|
||||
glutPostRedisplay();
|
||||
lastTimeIdle = check;
|
||||
}
|
||||
|
|
|
@ -158,12 +158,12 @@ const char* ViewFrustum::debugPlaneName (int plane) const {
|
|||
}
|
||||
|
||||
|
||||
int ViewFrustum::pointInFrustum(const glm::vec3& point) const {
|
||||
ViewFrustum::location 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;
|
||||
ViewFrustum::location result = INSIDE;
|
||||
for(int i=0; i < 6; i++) {
|
||||
float distance = _planes[i].distance(point);
|
||||
|
||||
|
@ -176,8 +176,8 @@ int ViewFrustum::pointInFrustum(const glm::vec3& point) const {
|
|||
return(result);
|
||||
}
|
||||
|
||||
int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
||||
int result = INSIDE;
|
||||
ViewFrustum::location ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
||||
ViewFrustum::location result = INSIDE;
|
||||
float distance;
|
||||
for(int i=0; i < 6; i++) {
|
||||
distance = _planes[i].distance(center);
|
||||
|
@ -190,11 +190,11 @@ int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
|||
}
|
||||
|
||||
|
||||
int ViewFrustum::boxInFrustum(const AABox& box) const {
|
||||
ViewFrustum::location 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);
|
||||
int result = INSIDE;
|
||||
ViewFrustum::location result = INSIDE;
|
||||
for(int i=0; i < 6; i++) {
|
||||
|
||||
//printf("plane[%d] -- point(%f,%f,%f) normal(%f,%f,%f) d=%f \n",i,
|
||||
|
|
|
@ -94,9 +94,9 @@ public:
|
|||
|
||||
typedef enum {OUTSIDE, INTERSECT, INSIDE} location;
|
||||
|
||||
int pointInFrustum(const glm::vec3& point) const;
|
||||
int sphereInFrustum(const glm::vec3& center, float radius) const;
|
||||
int boxInFrustum(const AABox& box) const;
|
||||
ViewFrustum::location pointInFrustum(const glm::vec3& point) const;
|
||||
ViewFrustum::location sphereInFrustum(const glm::vec3& center, float radius) const;
|
||||
ViewFrustum::location boxInFrustum(const AABox& box) const;
|
||||
|
||||
// some frustum comparisons
|
||||
bool matches(const ViewFrustum& compareTo) const;
|
||||
|
|
|
@ -19,7 +19,7 @@ const int TREE_SCALE = 128;
|
|||
const int NUMBER_OF_CHILDREN = 8;
|
||||
const int MAX_VOXEL_PACKET_SIZE = 1492;
|
||||
const int MAX_TREE_SLICE_BYTES = 26;
|
||||
const int MAX_VOXELS_PER_SYSTEM = 500000;
|
||||
const int MAX_VOXELS_PER_SYSTEM = 200000;
|
||||
const int VERTICES_PER_VOXEL = 24;
|
||||
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
|
||||
const int INDICES_PER_VOXEL = 3 * 12;
|
||||
|
|
|
@ -259,6 +259,12 @@ bool VoxelNode::isInView(const ViewFrustum& viewFrustum) const {
|
|||
return inView;
|
||||
}
|
||||
|
||||
ViewFrustum::location VoxelNode::inFrustum(const ViewFrustum& viewFrustum) const {
|
||||
AABox box = _box; // use temporary box so we can scale it
|
||||
box.scale(TREE_SCALE);
|
||||
return viewFrustum.boxInFrustum(box);
|
||||
}
|
||||
|
||||
float VoxelNode::distanceToCamera(const ViewFrustum& viewFrustum) const {
|
||||
glm::vec3 center = _box.getCenter() * (float)TREE_SCALE;
|
||||
float distanceToVoxelCenter = sqrtf(powf(viewFrustum.getPosition().x - center.x, 2) +
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
bool isColored() const { return (_trueColor[3]==1); };
|
||||
bool isInView(const ViewFrustum& viewFrustum) const;
|
||||
ViewFrustum::location inFrustum(const ViewFrustum& viewFrustum) const;
|
||||
float distanceToCamera(const ViewFrustum& viewFrustum) const;
|
||||
bool isLeaf() const;
|
||||
void printDebugDetails(const char* label) const;
|
||||
|
|
|
@ -82,3 +82,39 @@ VoxelNode* VoxelNodeBag::extract() {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool VoxelNodeBag::contains(VoxelNode* node) {
|
||||
for (int i = 0; i < _elementsInUse; i++) {
|
||||
// just compare the pointers... that's good enough
|
||||
if (_bagElements[i] == node) {
|
||||
return true; // exit early!!
|
||||
}
|
||||
// if we're past where it should be, then it's not here!
|
||||
if (_bagElements[i] > node) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if we made it through the entire bag, it's not here!
|
||||
return false;
|
||||
}
|
||||
|
||||
void VoxelNodeBag::remove(VoxelNode* node) {
|
||||
int foundAt = -1;
|
||||
for (int i = 0; i < _elementsInUse; i++) {
|
||||
// just compare the pointers... that's good enough
|
||||
if (_bagElements[i] == node) {
|
||||
foundAt = i;
|
||||
break;
|
||||
}
|
||||
// if we're past where it should be, then it's not here!
|
||||
if (_bagElements[i] > node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if we found it, then we need to remove it....
|
||||
if (foundAt != -1) {
|
||||
memmove(&_bagElements[foundAt], &_bagElements[foundAt + 1], (_elementsInUse - foundAt) * sizeof(VoxelNode*));
|
||||
_elementsInUse--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
void insert(VoxelNode* node); // put a node into the bag
|
||||
VoxelNode* extract(); // pull a node out of the bag (could come in any order)
|
||||
bool contains(VoxelNode* node); // is this node in the bag?
|
||||
void remove(VoxelNode* node); // remove a specific item from the bag
|
||||
|
||||
bool isEmpty() const { return (_elementsInUse == 0); };
|
||||
int count() const { return _elementsInUse; };
|
||||
|
|
|
@ -12,7 +12,21 @@
|
|||
|
||||
VoxelTree myTree;
|
||||
|
||||
void voxelTutorial(VoxelTree* tree) {
|
||||
int _nodeCount=0;
|
||||
bool countVoxelsOperation(VoxelNode* node, void* extraData) {
|
||||
if (node->isColored()){
|
||||
_nodeCount++;
|
||||
}
|
||||
return true; // keep going
|
||||
}
|
||||
|
||||
void addLandscape(VoxelTree * tree) {
|
||||
printf("Adding Landscape...\n");
|
||||
}
|
||||
|
||||
void voxelTutorial(VoxelTree * tree) {
|
||||
printf("adding scene...\n");
|
||||
|
||||
// We want our corner voxels to be about 1/2 meter high, and our TREE_SCALE is in meters, so...
|
||||
float voxelSize = 0.5f / TREE_SCALE;
|
||||
|
||||
|
|
Loading…
Reference in a new issue