Working on avatar voxels.

This commit is contained in:
Andrzej Kapolka 2013-05-31 14:52:29 -07:00
parent f5e7d6e3fe
commit e4bc7af6b4
6 changed files with 68 additions and 43 deletions

View file

@ -156,8 +156,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_window->setWindowTitle("Interface"); _window->setWindowTitle("Interface");
printLog("Interface Startup:\n"); printLog("Interface Startup:\n");
_voxels.setViewFrustum(&_viewFrustum);
unsigned int listenPort = AGENT_SOCKET_LISTEN_PORT; unsigned int listenPort = AGENT_SOCKET_LISTEN_PORT;
const char** constArgv = const_cast<const char**>(argv); const char** constArgv = const_cast<const char**>(argv);
const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); const char* portStr = getCmdOption(argc, constArgv, "--listenPort");
@ -1417,8 +1415,6 @@ void Application::initDisplay() {
void Application::init() { void Application::init() {
_voxels.init(); _voxels.init();
_voxels.setViewerAvatar(&_myAvatar);
_voxels.setCamera(&_myCamera);
_environment.init(); _environment.init();
@ -1429,6 +1425,7 @@ void Application::init() {
_stars.readInput(STAR_FILE, STAR_CACHE_FILE, 0); _stars.readInput(STAR_FILE, STAR_CACHE_FILE, 0);
_myAvatar.init();
_myAvatar.setPosition(START_LOCATION); _myAvatar.setPosition(START_LOCATION);
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON ); _myCamera.setMode(CAMERA_MODE_THIRD_PERSON );
_myCamera.setModeShiftRate(1.0f); _myCamera.setModeShiftRate(1.0f);
@ -2298,7 +2295,9 @@ QAction* Application::checkedVoxelModeAction() const {
void Application::attachNewHeadToAgent(Agent* newAgent) { void Application::attachNewHeadToAgent(Agent* newAgent) {
if (newAgent->getLinkedData() == NULL) { if (newAgent->getLinkedData() == NULL) {
newAgent->setLinkedData(new Avatar(newAgent)); Avatar* newAvatar = new Avatar(newAgent);
newAvatar->init();
newAgent->setLinkedData(newAvatar);
} }
} }

View file

@ -65,6 +65,7 @@ public:
Avatar* getAvatar() { return &_myAvatar; } Avatar* getAvatar() { return &_myAvatar; }
Camera* getCamera() { return &_myCamera; } Camera* getCamera() { return &_myCamera; }
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
VoxelSystem* getVoxels() { return &_voxels; } VoxelSystem* getVoxels() { return &_voxels; }
Environment* getEnvironment() { return &_environment; } Environment* getEnvironment() { return &_environment; }
bool shouldEchoAudio() { return _echoAudioMode->isChecked(); } bool shouldEchoAudio() { return _echoAudioMode->isChecked(); }

View file

@ -61,6 +61,8 @@ const float SKIN_COLOR[] = {1.0, 0.84, 0.66};
const float DARK_SKIN_COLOR[] = {0.9, 0.78, 0.63}; const float DARK_SKIN_COLOR[] = {0.9, 0.78, 0.63};
const int NUM_BODY_CONE_SIDES = 9; const int NUM_BODY_CONE_SIDES = 9;
const float AVATAR_TREE_SCALE = 1.0f;
const int MAX_VOXELS_PER_AVATAR = 2000;
bool usingBigSphereCollisionTest = true; bool usingBigSphereCollisionTest = true;
@ -93,7 +95,8 @@ Avatar::Avatar(Agent* owningAgent) :
_mouseRayDirection(0.0f, 0.0f, 0.0f), _mouseRayDirection(0.0f, 0.0f, 0.0f),
_interactingOther(NULL), _interactingOther(NULL),
_cumulativeMouseYaw(0.0f), _cumulativeMouseYaw(0.0f),
_isMouseTurningRight(false) _isMouseTurningRight(false),
_voxels(AVATAR_TREE_SCALE, MAX_VOXELS_PER_AVATAR)
{ {
// give the pointer to our head to inherited _headData variable from AvatarData // give the pointer to our head to inherited _headData variable from AvatarData
@ -119,6 +122,12 @@ Avatar::~Avatar() {
delete _balls; delete _balls;
} }
void Avatar::init() {
_voxels.init();
_voxels.createVoxel(0.0f, 0.0f, 0.0f, 1.0f, 255, 0, 255);
}
void Avatar::reset() { void Avatar::reset() {
_head.reset(); _head.reset();
} }
@ -1132,6 +1141,15 @@ void Avatar::renderBody(bool lookingInMirror) {
const float RENDER_OPAQUE_BEYOND = 1.0f; // Meters beyond which body is shown opaque const float RENDER_OPAQUE_BEYOND = 1.0f; // Meters beyond which body is shown opaque
const float RENDER_TRANSLUCENT_BEYOND = 0.5f; const float RENDER_TRANSLUCENT_BEYOND = 0.5f;
// Render the body's voxels
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z);
glm::quat rotation = getOrientation();
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
_voxels.render(false);
glPopMatrix();
// Render the body as balls and cones // Render the body as balls and cones
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); float distanceToCamera = glm::length(_cameraPosition - _joint[b].position);

View file

@ -19,6 +19,7 @@
#include "Head.h" #include "Head.h"
#include "Skeleton.h" #include "Skeleton.h"
#include "Transmitter.h" #include "Transmitter.h"
#include "VoxelSystem.h"
enum DriveKeys enum DriveKeys
{ {
@ -46,6 +47,7 @@ public:
Avatar(Agent* owningAgent = NULL); Avatar(Agent* owningAgent = NULL);
~Avatar(); ~Avatar();
void init();
void reset(); void reset();
void simulate(float deltaTime, Transmitter* transmitter); void simulate(float deltaTime, Transmitter* transmitter);
void updateHeadFromGyros(float frametime, SerialInterface * serialInterface); void updateHeadFromGyros(float frametime, SerialInterface * serialInterface);
@ -147,6 +149,7 @@ private:
Avatar* _interactingOther; Avatar* _interactingOther;
float _cumulativeMouseYaw; float _cumulativeMouseYaw;
bool _isMouseTurningRight; bool _isMouseTurningRight;
VoxelSystem _voxels;
// private methods... // private methods...
glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat)

View file

@ -19,6 +19,7 @@
#include <PerfStat.h> #include <PerfStat.h>
#include <OctalCode.h> #include <OctalCode.h>
#include <pthread.h> #include <pthread.h>
#include "Application.h"
#include "Log.h" #include "Log.h"
#include "VoxelConstants.h" #include "VoxelConstants.h"
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
@ -37,14 +38,15 @@ GLfloat identityNormals[] = { 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1,
-1,0,0, +1,0,0, +1,0,0, -1,0,0, -1,0,0, +1,0,0, +1,0,0, -1,0,0,
-1,0,0, +1,0,0, +1,0,0, -1,0,0 }; -1,0,0, +1,0,0, +1,0,0, -1,0,0 };
GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z-
8,9,13, 8,13,12, // Y- 8,9,13, 8,13,12, // Y-
16,23,19, 16,20,23, // X- 16,23,19, 16,20,23, // X-
17,18,22, 17,22,21, // X+ 17,18,22, 17,22,21, // X+
10,11,15, 10,15,14, // Y+ 10,11,15, 10,15,14, // Y+
4,5,6, 4,6,7 }; // Z+ . 4,5,6, 4,6,7 }; // Z+
VoxelSystem::VoxelSystem() : AgentData(NULL) { VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) :
AgentData(NULL), _treeScale(treeScale), _maxVoxels(maxVoxels) {
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
_writeRenderFullVBO = true; _writeRenderFullVBO = true;
_readRenderFullVBO = true; _readRenderFullVBO = true;
@ -312,12 +314,11 @@ void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) {
} }
int VoxelSystem::newTreeToArrays(VoxelNode* node) { int VoxelSystem::newTreeToArrays(VoxelNode* node) {
assert(_viewFrustum); // you must set up _viewFrustum before calling this
int voxelsUpdated = 0; int voxelsUpdated = 0;
bool shouldRender = false; // assume we don't need to render it bool shouldRender = false; // assume we don't need to render it
// if it's colored, we might need to render it! // if it's colored, we might need to render it!
if (node->isColored()) { if (node->isColored()) {
float distanceToNode = node->distanceToCamera(*_viewFrustum); float distanceToNode = node->distanceToCamera(*Application::getInstance()->getViewFrustum());
float boundary = boundaryDistanceForRenderLevel(node->getLevel()); float boundary = boundaryDistanceForRenderLevel(node->getLevel());
float childBoundary = boundaryDistanceForRenderLevel(node->getLevel() + 1); float childBoundary = boundaryDistanceForRenderLevel(node->getLevel() + 1);
bool inBoundary = (distanceToNode <= boundary); bool inBoundary = (distanceToNode <= boundary);
@ -352,7 +353,7 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) {
// If we've run out of room, then just bail... // If we've run out of room, then just bail...
if (_voxelsInWriteArrays >= MAX_VOXELS_PER_SYSTEM) { if (_voxelsInWriteArrays >= _maxVoxels) {
return 0; return 0;
} }
@ -382,7 +383,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) {
int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
// If we've run out of room, then just bail... // If we've run out of room, then just bail...
if (_voxelsInWriteArrays >= MAX_VOXELS_PER_SYSTEM) { if (_voxelsInWriteArrays >= _maxVoxels) {
return 0; return 0;
} }
@ -425,6 +426,9 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
return 0; // not-updated return 0; // not-updated
} }
ProgramObject* VoxelSystem::_perlinModulateProgram = 0;
GLuint VoxelSystem::_permutationNormalTextureID = 0;
void VoxelSystem::init() { void VoxelSystem::init() {
_renderWarningsOn = false; _renderWarningsOn = false;
@ -440,23 +444,23 @@ void VoxelSystem::init() {
_unusedArraySpace = 0; _unusedArraySpace = 0;
// we will track individual dirty sections with these arrays of bools // we will track individual dirty sections with these arrays of bools
_writeVoxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; _writeVoxelDirtyArray = new bool[_maxVoxels];
memset(_writeVoxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
_readVoxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; _readVoxelDirtyArray = new bool[_maxVoxels];
memset(_readVoxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
// prep the data structures for incoming voxel data // prep the data structures for incoming voxel data
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels];
// populate the indicesArray // populate the indicesArray
// this will not change given new voxels, so we can set it all up now // this will not change given new voxels, so we can set it all up now
for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) { for (int n = 0; n < _maxVoxels; n++) {
// fill the indices array // fill the indices array
int voxelIndexOffset = n * INDICES_PER_VOXEL; int voxelIndexOffset = n * INDICES_PER_VOXEL;
GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; GLuint* currentIndicesPos = indicesArray + voxelIndexOffset;
@ -468,11 +472,11 @@ void VoxelSystem::init() {
} }
} }
GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
GLfloat* normalsArrayEndPointer = normalsArray; GLfloat* normalsArrayEndPointer = normalsArray;
// populate the normalsArray // populate the normalsArray
for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) { for (int n = 0; n < _maxVoxels; n++) {
for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) {
*(normalsArrayEndPointer++) = identityNormals[i]; *(normalsArrayEndPointer++) = identityNormals[i];
} }
@ -481,32 +485,35 @@ void VoxelSystem::init() {
// VBO for the verticesArray // VBO for the verticesArray
glGenBuffers(1, &_vboVerticesID); glGenBuffers(1, &_vboVerticesID);
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
// VBO for the normalsArray // VBO for the normalsArray
glGenBuffers(1, &_vboNormalsID); glGenBuffers(1, &_vboNormalsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER,
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
normalsArray, GL_STATIC_DRAW); normalsArray, GL_STATIC_DRAW);
// VBO for colorsArray // VBO for colorsArray
glGenBuffers(1, &_vboColorsID); glGenBuffers(1, &_vboColorsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
// VBO for the indicesArray // VBO for the indicesArray
glGenBuffers(1, &_vboIndicesID); glGenBuffers(1, &_vboIndicesID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, glBufferData(GL_ELEMENT_ARRAY_BUFFER,
INDICES_PER_VOXEL * sizeof(GLuint) * MAX_VOXELS_PER_SYSTEM, INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
indicesArray, GL_STATIC_DRAW); indicesArray, GL_STATIC_DRAW);
// delete the indices and normals arrays that are no longer needed // delete the indices and normals arrays that are no longer needed
delete[] indicesArray; delete[] indicesArray;
delete[] normalsArray; delete[] normalsArray;
// create our simple fragment shader // create our simple fragment shader if we're the first system to init
if (_perlinModulateProgram != 0) {
return;
}
switchToResourcesParentIfRequired(); switchToResourcesParentIfRequired();
_perlinModulateProgram = new ProgramObject(); _perlinModulateProgram = new ProgramObject();
_perlinModulateProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert"); _perlinModulateProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert");
@ -661,7 +668,7 @@ void VoxelSystem::render(bool texture) {
// draw the number of voxels we have // draw the number of voxels we have
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); glScalef(_treeScale, _treeScale, _treeScale);
glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1,
36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0);
@ -855,7 +862,7 @@ bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
VoxelNode* childNode = node->getChildAtIndex(i); VoxelNode* childNode = node->getChildAtIndex(i);
if (childNode) { if (childNode) {
ViewFrustum::location inFrustum = childNode->inFrustum(*thisVoxelSystem->_viewFrustum); ViewFrustum::location inFrustum = childNode->inFrustum(*Application::getInstance()->getViewFrustum());
switch (inFrustum) { switch (inFrustum) {
case ViewFrustum::OUTSIDE: { case ViewFrustum::OUTSIDE: {
args->nodesOutside++; args->nodesOutside++;
@ -907,9 +914,9 @@ bool VoxelSystem::hasViewChanged() {
} }
// If our viewFrustum has changed since our _lastKnowViewFrustum // If our viewFrustum has changed since our _lastKnowViewFrustum
if (_viewFrustum && !_lastStableViewFrustum.matches(_viewFrustum)) { if (!_lastStableViewFrustum.matches(Application::getInstance()->getViewFrustum())) {
result = true; result = true;
_lastStableViewFrustum = *_viewFrustum; // save last stable _lastStableViewFrustum = *Application::getInstance()->getViewFrustum(); // save last stable
} }
return result; return result;
} }

View file

@ -16,7 +16,6 @@
#include <AgentData.h> #include <AgentData.h>
#include <VoxelTree.h> #include <VoxelTree.h>
#include <ViewFrustum.h> #include <ViewFrustum.h>
#include "Avatar.h"
#include "Camera.h" #include "Camera.h"
#include "Util.h" #include "Util.h"
#include "world.h" #include "world.h"
@ -27,7 +26,7 @@ const int NUM_CHILDREN = 8;
class VoxelSystem : public AgentData { class VoxelSystem : public AgentData {
public: public:
VoxelSystem(); VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM);
~VoxelSystem(); ~VoxelSystem();
int parseData(unsigned char* sourceBuffer, int numBytes); int parseData(unsigned char* sourceBuffer, int numBytes);
@ -41,8 +40,6 @@ public:
unsigned long getVoxelsUpdated() const {return _voxelsUpdated;}; unsigned long getVoxelsUpdated() const {return _voxelsUpdated;};
unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;}; unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;};
void setViewerAvatar(Avatar *newViewerAvatar) { _viewerAvatar = newViewerAvatar; };
void setCamera(Camera* newCamera) { _camera = newCamera; };
void loadVoxelsFile(const char* fileName,bool wantColorRandomizer); void loadVoxelsFile(const char* fileName,bool wantColorRandomizer);
long int getVoxelsCreated(); long int getVoxelsCreated();
@ -114,8 +111,8 @@ private:
static float _maxDistance; static float _maxDistance;
static float _minDistance; static float _minDistance;
Avatar* _viewerAvatar; float _treeScale;
Camera* _camera; int _maxVoxels;
VoxelTree* _tree; VoxelTree* _tree;
GLfloat* _readVerticesArray; GLfloat* _readVerticesArray;
GLubyte* _readColorsArray; GLubyte* _readColorsArray;
@ -143,9 +140,6 @@ private:
pthread_mutex_t _bufferWriteLock; pthread_mutex_t _bufferWriteLock;
pthread_mutex_t _treeLock; pthread_mutex_t _treeLock;
ProgramObject* _perlinModulateProgram;
GLuint _permutationNormalTextureID;
ViewFrustum* _viewFrustum; ViewFrustum* _viewFrustum;
ViewFrustum _lastKnowViewFrustum; ViewFrustum _lastKnowViewFrustum;
ViewFrustum _lastStableViewFrustum; ViewFrustum _lastStableViewFrustum;
@ -158,6 +152,9 @@ private:
bool _voxelsDirty; bool _voxelsDirty;
static ProgramObject* _perlinModulateProgram;
static GLuint _permutationNormalTextureID;
public: public:
void updateVBOs(); void updateVBOs();
void updateFullVBOs(); // all voxels in the VBO void updateFullVBOs(); // all voxels in the VBO