mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 18:44:00 +02:00
merge with brad's sphere/load file changes
This commit is contained in:
parent
1b3c15a701
commit
3ead1a5827
3 changed files with 164 additions and 48 deletions
|
@ -88,45 +88,6 @@ VoxelNode * VoxelTree::createMissingNode(VoxelNode *lastParentNode, unsigned cha
|
|||
}
|
||||
}
|
||||
|
||||
// if node has color & <= 4 children then prune children
|
||||
void VoxelTree::pruneTree(VoxelNode* pruneAt) {
|
||||
int childCount = 0;
|
||||
int childMask = 0;
|
||||
|
||||
// determine how many children we have
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (pruneAt->children[i]) {
|
||||
childCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// if appropriate, prune them
|
||||
if (pruneAt->color[3] && childCount <= 4) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (pruneAt->children[i]) {
|
||||
delete pruneAt->children[i];
|
||||
pruneAt->children[i]=NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Otherwise, iterate the children and recursively call
|
||||
// prune on all of them
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (pruneAt->children[i]) {
|
||||
this->pruneTree(pruneAt->children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// repair our child mask
|
||||
// determine how many children we have
|
||||
pruneAt->childMask = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (pruneAt->children[i]) {
|
||||
pruneAt->childMask += (1 << (7 - i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int VoxelTree::readNodeData(VoxelNode *destinationNode,
|
||||
unsigned char * nodeData,
|
||||
int bytesLeftToRead) {
|
||||
|
@ -422,3 +383,129 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Method: VoxelTree::loadVoxelsFile()
|
||||
// Description: Loads HiFidelity encoded Voxels from a binary file. The current file
|
||||
// format is a stream of single voxels with color data.
|
||||
// Complaints: Brad :)
|
||||
void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
|
||||
int vCount = 0;
|
||||
|
||||
std::ifstream file(fileName, std::ios::in|std::ios::binary);
|
||||
|
||||
char octets;
|
||||
unsigned int lengthInBytes;
|
||||
|
||||
int totalBytesRead = 0;
|
||||
if(file.is_open()) {
|
||||
printf("loading file...\n");
|
||||
bool bail = false;
|
||||
while (!file.eof() && !bail) {
|
||||
file.get(octets);
|
||||
//printf("octets=%d...\n",octets);
|
||||
totalBytesRead++;
|
||||
lengthInBytes = bytesRequiredForCodeLength(octets)-1; //(octets*3/8)+1;
|
||||
unsigned char * voxelData = new unsigned char[lengthInBytes+1+3];
|
||||
voxelData[0]=octets;
|
||||
char byte;
|
||||
|
||||
for (size_t i = 0; i < lengthInBytes; i++) {
|
||||
file.get(byte);
|
||||
totalBytesRead++;
|
||||
voxelData[i+1] = byte;
|
||||
}
|
||||
// read color data
|
||||
char colorRead;
|
||||
unsigned char red,green,blue;
|
||||
file.get(colorRead);
|
||||
red = (unsigned char)colorRead;
|
||||
file.get(colorRead);
|
||||
green = (unsigned char)colorRead;
|
||||
file.get(colorRead);
|
||||
blue = (unsigned char)colorRead;
|
||||
|
||||
printf("voxel color from file red:%d, green:%d, blue:%d \n",red,green,blue);
|
||||
vCount++;
|
||||
|
||||
int colorRandomizer = wantColorRandomizer ? randIntInRange (-5, 5) : 0;
|
||||
voxelData[lengthInBytes+1] = std::max(0,std::min(255,red + colorRandomizer));
|
||||
voxelData[lengthInBytes+2] = std::max(0,std::min(255,green + colorRandomizer));
|
||||
voxelData[lengthInBytes+3] = std::max(0,std::min(255,blue + colorRandomizer));
|
||||
printf("voxel color after rand red:%d, green:%d, blue:%d\n",
|
||||
voxelData[lengthInBytes+1], voxelData[lengthInBytes+2], voxelData[lengthInBytes+3]);
|
||||
|
||||
//printVoxelCode(voxelData);
|
||||
this->readCodeColorBufferToTree(voxelData);
|
||||
delete voxelData;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Method: VoxelTree::createSphere()
|
||||
// Description: Creates a sphere of voxels in the local system at a given location/radius
|
||||
// To Do: Move this function someplace better?
|
||||
// Complaints: Brad :)
|
||||
void VoxelTree::createSphere(float r,float xc, float yc, float zc, float s, bool solid) {
|
||||
// About the color of the sphere... we're going to make this sphere be a gradient
|
||||
// between two RGB colors. We will do the gradient along the phi spectrum
|
||||
unsigned char r1 = randomColorValue(165);
|
||||
unsigned char g1 = randomColorValue(165);
|
||||
unsigned char b1 = randomColorValue(165);
|
||||
unsigned char r2 = randomColorValue(65);
|
||||
unsigned char g2 = randomColorValue(65);
|
||||
unsigned char b2 = randomColorValue(65);
|
||||
|
||||
// we don't want them to match!!
|
||||
if (r1==r2 && g1==g2 && b1==b2) {
|
||||
r2=r1/2;
|
||||
g2=g1/2;
|
||||
b2=b1/2;
|
||||
}
|
||||
|
||||
// Psuedocode for creating a sphere:
|
||||
//
|
||||
// for (theta from 0 to 2pi):
|
||||
// for (phi from 0 to pi):
|
||||
// x = xc+r*cos(theta)*sin(phi)
|
||||
// y = yc+r*sin(theta)*sin(phi)
|
||||
// z = zc+r*cos(phi)
|
||||
|
||||
int t=0; // total points
|
||||
|
||||
// We want to make sure that as we "sweep" through our angles we use a delta angle that's small enough to not skip any
|
||||
// voxels we can calculate theta from our desired arc length
|
||||
// lenArc = ndeg/360deg * 2pi*R ---> lenArc = theta/2pi * 2pi*R
|
||||
// lenArc = theta*R ---> theta = lenArc/R ---> theta = g/r
|
||||
float angleDelta = (s/r);
|
||||
|
||||
// assume solid for now
|
||||
float ri = 0.0;
|
||||
if (!solid) {
|
||||
ri=r; // just the outer surface
|
||||
}
|
||||
// If you also iterate form the interior of the sphere to the radius, makeing
|
||||
// larger and larger sphere's you'd end up with a solid sphere. And lots of voxels!
|
||||
for (; ri <= r; ri+=s) {
|
||||
for (float theta=0.0; theta <= 2*M_PI; theta += angleDelta) {
|
||||
for (float phi=0.0; phi <= M_PI; phi += angleDelta) {
|
||||
t++; // total voxels
|
||||
float x = xc+r*cos(theta)*sin(phi);
|
||||
float y = yc+r*sin(theta)*sin(phi);
|
||||
float z = zc+r*cos(phi);
|
||||
|
||||
// gradient color data
|
||||
float gradient = (phi/M_PI);
|
||||
unsigned char red = r1+((r2-r1)*gradient);
|
||||
unsigned char green = g1+((g2-g1)*gradient);
|
||||
unsigned char blue = b1+((b2-b1)*gradient);
|
||||
|
||||
unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
|
||||
this->readCodeColorBufferToTree(voxelData);
|
||||
delete voxelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,8 +36,7 @@ public:
|
|||
float * agentPosition,
|
||||
float thisNodePosition[3],
|
||||
unsigned char * octalCode = NULL);
|
||||
|
||||
void pruneTree(VoxelNode* pruneAt);
|
||||
|
||||
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
|
||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid);
|
||||
};
|
||||
|
|
|
@ -47,6 +47,23 @@ const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
|||
AgentList agentList('V', VOXEL_LISTEN_PORT);
|
||||
VoxelTree randomTree;
|
||||
|
||||
void addRandomSphere(VoxelTree * tree) {
|
||||
float r = randFloatInRange(0.05,0.1);
|
||||
float xc = randFloatInRange(r,(1-r));
|
||||
float yc = randFloatInRange(r,(1-r));
|
||||
float zc = randFloatInRange(r,(1-r));
|
||||
float s = 0.001; // size of voxels to make up surface of sphere
|
||||
bool solid = true;
|
||||
|
||||
printf("random sphere\n");
|
||||
printf("radius=%f\n",r);
|
||||
printf("xc=%f\n",xc);
|
||||
printf("yc=%f\n",yc);
|
||||
printf("zc=%f\n",zc);
|
||||
|
||||
tree->createSphere(r,xc,yc,zc,s,solid);
|
||||
}
|
||||
|
||||
void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
|
||||
// randomly generate children for this node
|
||||
// the first level of the tree (where levelsToGo = MAX_VOXEL_TREE_DEPTH_LEVELS) has all 8
|
||||
|
@ -193,14 +210,29 @@ int main(int argc, const char * argv[])
|
|||
agentList.startDomainServerCheckInThread();
|
||||
|
||||
srand((unsigned)time(0));
|
||||
|
||||
// create an octal code buffer and load it with 0 so that the recursive tree fill can give
|
||||
// octal codes to the tree nodes that it is creating
|
||||
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
|
||||
|
||||
// Check to see if the user passed in a command line option for loading a local
|
||||
// Voxel File. If so, load it now.
|
||||
bool wantColorRandomizer = !cmdOptionExists(argc, argv, "--NoColorRandomizer");
|
||||
const char* voxelsFilename = getCmdOption(argc, argv, "-i");
|
||||
|
||||
if (voxelsFilename) {
|
||||
randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer);
|
||||
}
|
||||
|
||||
if (!cmdOptionExists(argc, argv, "--NoRandomVoxelSheet")) {
|
||||
// create an octal code buffer and load it with 0 so that the recursive tree fill can give
|
||||
// octal codes to the tree nodes that it is creating
|
||||
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
|
||||
}
|
||||
|
||||
if (cmdOptionExists(argc, argv, "--AddRandomSpheres")) {
|
||||
addRandomSphere(&randomTree);
|
||||
}
|
||||
|
||||
pthread_t sendVoxelThread;
|
||||
pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL);
|
||||
|
||||
|
||||
sockaddr agentPublicAddress;
|
||||
|
||||
char *packetData = new char[MAX_PACKET_SIZE];
|
||||
|
@ -224,8 +256,6 @@ int main(int argc, const char * argv[])
|
|||
pVoxelData+=voxelDataSize;
|
||||
atByte+=voxelDataSize;
|
||||
}
|
||||
//printf("about to call pruneTree()\n");
|
||||
//randomTree.pruneTree(randomTree.rootNode); // hack
|
||||
}
|
||||
if (packetData[0] == 'H') {
|
||||
if (agentList.addOrUpdateAgent(&agentPublicAddress,
|
||||
|
|
Loading…
Reference in a new issue