mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:21:16 +02:00
Working on avatar voxel system.
This commit is contained in:
parent
929797516d
commit
7425b39237
6 changed files with 216 additions and 105 deletions
|
@ -57,9 +57,6 @@ 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;
|
||||||
|
|
||||||
float chatMessageScale = 0.0015;
|
float chatMessageScale = 0.0015;
|
||||||
|
@ -91,8 +88,7 @@ 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
|
||||||
|
@ -1153,7 +1149,8 @@ void Avatar::renderBody(bool lookingInMirror) {
|
||||||
|
|
||||||
// Render the body's voxels
|
// Render the body's voxels
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_position.x, _position.y, _position.z);
|
const glm::vec3& voxelPosition = _joint[AVATAR_JOINT_PELVIS].springyPosition;
|
||||||
|
glTranslatef(voxelPosition.x, voxelPosition.y, voxelPosition.z);
|
||||||
glm::quat rotation = getOrientation();
|
glm::quat rotation = getOrientation();
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "AvatarTouch.h"
|
#include "AvatarTouch.h"
|
||||||
|
#include "AvatarVoxelSystem.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "SerialInterface.h"
|
#include "SerialInterface.h"
|
||||||
#include "Balls.h"
|
#include "Balls.h"
|
||||||
#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
|
||||||
{
|
{
|
||||||
|
@ -149,7 +149,8 @@ private:
|
||||||
Avatar* _interactingOther;
|
Avatar* _interactingOther;
|
||||||
float _cumulativeMouseYaw;
|
float _cumulativeMouseYaw;
|
||||||
bool _isMouseTurningRight;
|
bool _isMouseTurningRight;
|
||||||
VoxelSystem _voxels;
|
|
||||||
|
AvatarVoxelSystem _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)
|
||||||
|
|
97
interface/src/AvatarVoxelSystem.cpp
Normal file
97
interface/src/AvatarVoxelSystem.cpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
//
|
||||||
|
// AvatarVoxelSystem.cpp
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 5/31/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "AvatarVoxelSystem.h"
|
||||||
|
|
||||||
|
const float AVATAR_TREE_SCALE = 1.0f;
|
||||||
|
const int MAX_VOXELS_PER_AVATAR = 2000;
|
||||||
|
const int BONE_INDEX_ELEMENTS_PER_VOXEL = 4 * VERTICES_PER_VOXEL;
|
||||||
|
const int BONE_WEIGHT_ELEMENTS_PER_VOXEL = 4 * VERTICES_PER_VOXEL;
|
||||||
|
|
||||||
|
AvatarVoxelSystem::AvatarVoxelSystem() : VoxelSystem(AVATAR_TREE_SCALE, MAX_VOXELS_PER_AVATAR) {
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarVoxelSystem::~AvatarVoxelSystem() {
|
||||||
|
delete[] _readBoneIndicesArray;
|
||||||
|
delete[] _readBoneWeightsArray;
|
||||||
|
delete[] _writeBoneIndicesArray;
|
||||||
|
delete[] _writeBoneWeightsArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarVoxelSystem::init() {
|
||||||
|
VoxelSystem::init();
|
||||||
|
|
||||||
|
// prep the data structures for incoming voxel data
|
||||||
|
_writeBoneIndicesArray = new GLubyte[BONE_INDEX_ELEMENTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_readBoneIndicesArray = new GLubyte[BONE_INDEX_ELEMENTS_PER_VOXEL * _maxVoxels];
|
||||||
|
|
||||||
|
_writeBoneWeightsArray = new GLfloat[BONE_WEIGHT_ELEMENTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_readBoneWeightsArray = new GLfloat[BONE_WEIGHT_ELEMENTS_PER_VOXEL * _maxVoxels];
|
||||||
|
|
||||||
|
// VBO for the boneIndicesArray
|
||||||
|
glGenBuffers(1, &_vboBoneIndicesID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneIndicesID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, BONE_INDEX_ELEMENTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
// VBO for the boneWeightsArray
|
||||||
|
glGenBuffers(1, &_vboBoneWeightsID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneWeightsID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, BONE_WEIGHT_ELEMENTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarVoxelSystem::render(bool texture) {
|
||||||
|
VoxelSystem::render(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarVoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||||
|
float voxelScale, const nodeColor& color) {
|
||||||
|
VoxelSystem::updateNodeInArrays(nodeIndex, startVertex, voxelScale, color);
|
||||||
|
|
||||||
|
for (int j = 0; j < BONE_INDEX_ELEMENTS_PER_VOXEL; j++) {
|
||||||
|
GLubyte* writeBoneIndicesAt = _writeBoneIndicesArray + (nodeIndex * BONE_INDEX_ELEMENTS_PER_VOXEL);
|
||||||
|
GLfloat* writeBoneWeightsAt = _writeBoneWeightsArray + (nodeIndex * BONE_WEIGHT_ELEMENTS_PER_VOXEL);
|
||||||
|
*(writeBoneIndicesAt + j) = 0;
|
||||||
|
*(writeBoneWeightsAt + j) = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarVoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||||
|
VoxelSystem::copyWrittenDataSegmentToReadArrays(segmentStart, segmentEnd);
|
||||||
|
|
||||||
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
GLintptr segmentStartAt = segmentStart * BONE_INDEX_ELEMENTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLsizeiptr segmentSizeBytes = segmentLength * BONE_INDEX_ELEMENTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLubyte* readBoneIndicesAt = _readBoneIndicesArray + (segmentStart * BONE_INDEX_ELEMENTS_PER_VOXEL);
|
||||||
|
GLubyte* writeBoneIndicesAt = _writeBoneIndicesArray + (segmentStart * BONE_INDEX_ELEMENTS_PER_VOXEL);
|
||||||
|
memcpy(readBoneIndicesAt, writeBoneIndicesAt, segmentSizeBytes);
|
||||||
|
|
||||||
|
segmentStartAt = segmentStart * BONE_WEIGHT_ELEMENTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
segmentSizeBytes = segmentLength * BONE_WEIGHT_ELEMENTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLfloat* readBoneWeightsAt = _readBoneWeightsArray + (segmentStart * BONE_WEIGHT_ELEMENTS_PER_VOXEL);
|
||||||
|
GLfloat* writeBoneWeightsAt = _writeBoneWeightsArray + (segmentStart * BONE_WEIGHT_ELEMENTS_PER_VOXEL);
|
||||||
|
memcpy(readBoneWeightsAt, writeBoneWeightsAt, segmentSizeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarVoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||||
|
VoxelSystem::updateVBOSegment(segmentStart, segmentEnd);
|
||||||
|
|
||||||
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
GLintptr segmentStartAt = segmentStart * BONE_INDEX_ELEMENTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLsizeiptr segmentSizeBytes = segmentLength * BONE_INDEX_ELEMENTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLubyte* readBoneIndicesFrom = _readBoneIndicesArray + (segmentStart * BONE_INDEX_ELEMENTS_PER_VOXEL);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneIndicesID);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readBoneIndicesFrom);
|
||||||
|
|
||||||
|
segmentStartAt = segmentStart * BONE_WEIGHT_ELEMENTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
segmentSizeBytes = segmentLength * BONE_WEIGHT_ELEMENTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLfloat* readBoneWeightsFrom = _readBoneWeightsArray + (segmentStart * BONE_WEIGHT_ELEMENTS_PER_VOXEL);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneWeightsID);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readBoneWeightsFrom);
|
||||||
|
}
|
||||||
|
|
43
interface/src/AvatarVoxelSystem.h
Normal file
43
interface/src/AvatarVoxelSystem.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// AvatarVoxelSystem.h
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 5/31/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __interface__AvatarVoxelSystem__
|
||||||
|
#define __interface__AvatarVoxelSystem__
|
||||||
|
|
||||||
|
#include "VoxelSystem.h"
|
||||||
|
|
||||||
|
class AvatarVoxelSystem : public VoxelSystem {
|
||||||
|
public:
|
||||||
|
|
||||||
|
AvatarVoxelSystem();
|
||||||
|
virtual ~AvatarVoxelSystem();
|
||||||
|
|
||||||
|
virtual void init();
|
||||||
|
virtual void render(bool texture);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||||
|
float voxelScale, const nodeColor& color);
|
||||||
|
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||||
|
virtual void updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
GLubyte* _readBoneIndicesArray;
|
||||||
|
GLfloat* _readBoneWeightsArray;
|
||||||
|
GLubyte* _writeBoneIndicesArray;
|
||||||
|
GLfloat* _writeBoneWeightsArray;
|
||||||
|
|
||||||
|
GLuint _vboBoneIndicesID;
|
||||||
|
GLuint _vboBoneWeightsID;
|
||||||
|
|
||||||
|
ProgramObject* _skinProgram;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__interface__AvatarVoxelSystem__) */
|
|
@ -231,10 +231,8 @@ void VoxelSystem::cleanupRemovedVoxels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() {
|
void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() {
|
||||||
int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
|
copyWrittenDataSegmentToReadArrays(0, _voxelsInWriteArrays - 1);
|
||||||
int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
|
|
||||||
memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices);
|
|
||||||
memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
|
|
||||||
_voxelsInReadArrays = _voxelsInWriteArrays;
|
_voxelsInReadArrays = _voxelsInWriteArrays;
|
||||||
|
|
||||||
// clear our dirty flags
|
// clear our dirty flags
|
||||||
|
@ -261,47 +259,37 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() {
|
||||||
if (!thisVoxelDirty) {
|
if (!thisVoxelDirty) {
|
||||||
// If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before
|
// If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before
|
||||||
// this one and so that's where the "segment" ends
|
// this one and so that's where the "segment" ends
|
||||||
segmentEnd = i - 1;
|
copyWrittenDataSegmentToReadArrays(segmentStart, i - 1);
|
||||||
inSegment = false;
|
inSegment = false;
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
|
||||||
|
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes);
|
|
||||||
|
|
||||||
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
memcpy(readColorsAt, writeColorsAt, segmentSizeBytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we got to the end of the array, and we're in an active dirty segment...
|
// if we got to the end of the array, and we're in an active dirty segment...
|
||||||
if (inSegment) {
|
if (inSegment) {
|
||||||
segmentEnd = _voxelsInWriteArrays - 1;
|
copyWrittenDataSegmentToReadArrays(segmentStart, _voxelsInWriteArrays - 1);
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
|
||||||
|
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes);
|
|
||||||
|
|
||||||
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
memcpy(readColorsAt, writeColorsAt, segmentSizeBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update our length
|
// update our length
|
||||||
_voxelsInReadArrays = _voxelsInWriteArrays;
|
_voxelsInReadArrays = _voxelsInWriteArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||||
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
|
||||||
|
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes);
|
||||||
|
|
||||||
|
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
memcpy(readColorsAt, writeColorsAt, segmentSizeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) {
|
void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) {
|
||||||
PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()");
|
PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()");
|
||||||
if (_voxelsDirty && _voxelsUpdated) {
|
if (_voxelsDirty && _voxelsUpdated) {
|
||||||
|
@ -364,12 +352,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) {
|
||||||
|
|
||||||
// populate the array with points for the 8 vertices
|
// populate the array with points for the 8 vertices
|
||||||
// and RGB color for each added vertex
|
// and RGB color for each added vertex
|
||||||
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
updateNodeInArrays(nodeIndex, startVertex, voxelScale, node->getColor());
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
*(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
|
||||||
*(writeColorsAt +j) = node->getColor()[j % 3];
|
|
||||||
}
|
|
||||||
node->setBufferIndex(nodeIndex);
|
node->setBufferIndex(nodeIndex);
|
||||||
_writeVoxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode
|
_writeVoxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode
|
||||||
_voxelsInWriteArrays++; // our know vertices in the arrays
|
_voxelsInWriteArrays++; // our know vertices in the arrays
|
||||||
|
@ -415,17 +398,23 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
|
||||||
|
|
||||||
// populate the array with points for the 8 vertices
|
// populate the array with points for the 8 vertices
|
||||||
// and RGB color for each added vertex
|
// and RGB color for each added vertex
|
||||||
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
updateNodeInArrays(nodeIndex, startVertex, voxelScale, node->getColor());
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
*(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
|
||||||
*(writeColorsAt +j) = node->getColor()[j % 3];
|
|
||||||
}
|
|
||||||
return 1; // updated!
|
return 1; // updated!
|
||||||
}
|
}
|
||||||
return 0; // not-updated
|
return 0; // not-updated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||||
|
float voxelScale, const nodeColor& color) {
|
||||||
|
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
||||||
|
GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
*(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
||||||
|
*(writeColorsAt +j) = color[j % 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ProgramObject* VoxelSystem::_perlinModulateProgram = 0;
|
ProgramObject* VoxelSystem::_perlinModulateProgram = 0;
|
||||||
GLuint VoxelSystem::_permutationNormalTextureID = 0;
|
GLuint VoxelSystem::_permutationNormalTextureID = 0;
|
||||||
|
|
||||||
|
@ -546,20 +535,7 @@ void VoxelSystem::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::updateFullVBOs() {
|
void VoxelSystem::updateFullVBOs() {
|
||||||
glBufferIndex segmentStart = 0;
|
updateVBOSegment(0, _voxelsInReadArrays);
|
||||||
glBufferIndex segmentEnd = _voxelsInReadArrays;
|
|
||||||
|
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
|
||||||
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
|
||||||
|
|
||||||
// consider the _readVoxelDirtyArray[] clean!
|
// consider the _readVoxelDirtyArray[] clean!
|
||||||
memset(_readVoxelDirtyArray, false, _voxelsInReadArrays * sizeof(bool));
|
memset(_readVoxelDirtyArray, false, _voxelsInReadArrays * sizeof(bool));
|
||||||
|
@ -581,39 +557,17 @@ void VoxelSystem::updatePartialVBOs() {
|
||||||
if (!thisVoxelDirty) {
|
if (!thisVoxelDirty) {
|
||||||
// If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before
|
// If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before
|
||||||
// this one and so that's where the "segment" ends
|
// this one and so that's where the "segment" ends
|
||||||
segmentEnd = i - 1;
|
updateVBOSegment(segmentStart, i - 1);
|
||||||
inSegment = false;
|
inSegment = false;
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
|
||||||
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
|
||||||
}
|
}
|
||||||
_readVoxelDirtyArray[i] = false; // consider us clean!
|
_readVoxelDirtyArray[i] = false; // consider us clean!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we got to the end of the array, and we're in an active dirty segment...
|
// if we got to the end of the array, and we're in an active dirty segment...
|
||||||
if (inSegment) {
|
if (inSegment) {
|
||||||
segmentEnd = _voxelsInReadArrays - 1;
|
updateVBOSegment(segmentStart, _voxelsInReadArrays - 1);
|
||||||
inSegment = false;
|
inSegment = false;
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
|
||||||
GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
|
||||||
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
|
||||||
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,6 +589,20 @@ void VoxelSystem::updateVBOs() {
|
||||||
_callsToTreesToArrays = 0; // clear it
|
_callsToTreesToArrays = 0; // clear it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||||
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
||||||
|
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
||||||
|
}
|
||||||
|
|
||||||
void VoxelSystem::render(bool texture) {
|
void VoxelSystem::render(bool texture) {
|
||||||
PerformanceWarning warn(_renderWarningsOn, "render()");
|
PerformanceWarning warn(_renderWarningsOn, "render()");
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,9 @@ public:
|
||||||
|
|
||||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||||
|
|
||||||
void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; };
|
virtual void init();
|
||||||
|
|
||||||
void init();
|
|
||||||
void simulate(float deltaTime) { };
|
void simulate(float deltaTime) { };
|
||||||
void render(bool texture);
|
virtual void render(bool texture);
|
||||||
|
|
||||||
unsigned long getVoxelsUpdated() const {return _voxelsUpdated;};
|
unsigned long getVoxelsUpdated() const {return _voxelsUpdated;};
|
||||||
unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;};
|
unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;};
|
||||||
|
@ -80,6 +78,16 @@ public:
|
||||||
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
|
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
|
||||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
|
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
|
||||||
creationMode mode, bool destructive = false, bool debug = false);
|
creationMode mode, bool destructive = false, bool debug = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int _maxVoxels;
|
||||||
|
|
||||||
|
virtual void updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||||
|
float voxelScale, const nodeColor& color);
|
||||||
|
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||||
|
virtual void updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disallow copying of VoxelSystem objects
|
// disallow copying of VoxelSystem objects
|
||||||
VoxelSystem(const VoxelSystem&);
|
VoxelSystem(const VoxelSystem&);
|
||||||
|
@ -107,12 +115,13 @@ private:
|
||||||
void copyWrittenDataToReadArraysFullVBOs();
|
void copyWrittenDataToReadArraysFullVBOs();
|
||||||
void copyWrittenDataToReadArraysPartialVBOs();
|
void copyWrittenDataToReadArraysPartialVBOs();
|
||||||
|
|
||||||
|
void updateVBOs();
|
||||||
|
|
||||||
// these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here
|
// these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here
|
||||||
static float _maxDistance;
|
static float _maxDistance;
|
||||||
static float _minDistance;
|
static float _minDistance;
|
||||||
|
|
||||||
float _treeScale;
|
float _treeScale;
|
||||||
int _maxVoxels;
|
|
||||||
VoxelTree* _tree;
|
VoxelTree* _tree;
|
||||||
GLfloat* _readVerticesArray;
|
GLfloat* _readVerticesArray;
|
||||||
GLubyte* _readColorsArray;
|
GLubyte* _readColorsArray;
|
||||||
|
@ -121,8 +130,8 @@ private:
|
||||||
bool* _writeVoxelDirtyArray;
|
bool* _writeVoxelDirtyArray;
|
||||||
bool* _readVoxelDirtyArray;
|
bool* _readVoxelDirtyArray;
|
||||||
unsigned long _voxelsUpdated;
|
unsigned long _voxelsUpdated;
|
||||||
unsigned long _voxelsInWriteArrays;
|
|
||||||
unsigned long _voxelsInReadArrays;
|
unsigned long _voxelsInReadArrays;
|
||||||
|
unsigned long _voxelsInWriteArrays;
|
||||||
unsigned long _unusedArraySpace;
|
unsigned long _unusedArraySpace;
|
||||||
|
|
||||||
bool _writeRenderFullVBO;
|
bool _writeRenderFullVBO;
|
||||||
|
@ -140,7 +149,6 @@ private:
|
||||||
pthread_mutex_t _bufferWriteLock;
|
pthread_mutex_t _bufferWriteLock;
|
||||||
pthread_mutex_t _treeLock;
|
pthread_mutex_t _treeLock;
|
||||||
|
|
||||||
ViewFrustum* _viewFrustum;
|
|
||||||
ViewFrustum _lastKnowViewFrustum;
|
ViewFrustum _lastKnowViewFrustum;
|
||||||
ViewFrustum _lastStableViewFrustum;
|
ViewFrustum _lastStableViewFrustum;
|
||||||
|
|
||||||
|
@ -149,17 +157,14 @@ private:
|
||||||
|
|
||||||
void setupNewVoxelsForDrawing();
|
void setupNewVoxelsForDrawing();
|
||||||
void copyWrittenDataToReadArrays(bool fullVBOs);
|
void copyWrittenDataToReadArrays(bool fullVBOs);
|
||||||
|
|
||||||
|
void updateFullVBOs(); // all voxels in the VBO
|
||||||
|
void updatePartialVBOs(); // multiple segments, only dirty voxels
|
||||||
|
|
||||||
bool _voxelsDirty;
|
bool _voxelsDirty;
|
||||||
|
|
||||||
static ProgramObject* _perlinModulateProgram;
|
static ProgramObject* _perlinModulateProgram;
|
||||||
static GLuint _permutationNormalTextureID;
|
static GLuint _permutationNormalTextureID;
|
||||||
|
|
||||||
public:
|
|
||||||
void updateVBOs();
|
|
||||||
void updateFullVBOs(); // all voxels in the VBO
|
|
||||||
void updatePartialVBOs(); // multiple segments, only dirty voxels
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue