mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 17:43:09 +02:00
2) Added pointToVoxel() to SharedUtils, this will give you a voxel code given x,y,z,s,r,g,b 3) Added '.' keyboard interface to create a random sphere in the local voxel system
269 lines
7.9 KiB
C++
269 lines
7.9 KiB
C++
//
|
|
// SharedUtil.cpp
|
|
// hifi
|
|
//
|
|
// Created by Stephen Birarda on 2/22/13.
|
|
//
|
|
//
|
|
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include "SharedUtil.h"
|
|
|
|
#ifdef __APPLE__
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#endif
|
|
|
|
double usecTimestamp(timeval *time) {
|
|
return (time->tv_sec * 1000000.0 + time->tv_usec);
|
|
}
|
|
|
|
double usecTimestampNow() {
|
|
timeval now;
|
|
gettimeofday(&now, NULL);
|
|
return (now.tv_sec * 1000000.0 + now.tv_usec);
|
|
}
|
|
|
|
float randFloat () {
|
|
return (rand() % 10000)/10000.f;
|
|
}
|
|
|
|
float randFloatInRange (float min,float max) {
|
|
return min + ((rand() % 10000)/10000.f * (max-min));
|
|
}
|
|
|
|
unsigned char randomColorValue(int miniumum) {
|
|
return miniumum + (rand() % (255 - miniumum));
|
|
}
|
|
|
|
bool randomBoolean() {
|
|
return rand() % 2;
|
|
}
|
|
|
|
void outputBits(unsigned char byte) {
|
|
printf("%d: ", byte);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
printf("%d", byte >> (7 - i) & 1);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
int numberOfOnes(unsigned char byte) {
|
|
return (byte >> 7)
|
|
+ ((byte >> 6) & 1)
|
|
+ ((byte >> 5) & 1)
|
|
+ ((byte >> 4) & 1)
|
|
+ ((byte >> 3) & 1)
|
|
+ ((byte >> 2) & 1)
|
|
+ ((byte >> 1) & 1)
|
|
+ (byte & 1);
|
|
}
|
|
|
|
bool oneAtBit(unsigned char byte, int bitIndex) {
|
|
return (byte >> (7 - bitIndex) & 1);
|
|
}
|
|
|
|
void switchToResourcesIfRequired() {
|
|
#ifdef __APPLE__
|
|
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
|
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
|
|
char path[PATH_MAX];
|
|
if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) {
|
|
// error!
|
|
}
|
|
CFRelease(resourcesURL);
|
|
|
|
chdir(path);
|
|
#endif
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function: getCmdOption()
|
|
// Description: Handy little function to tell you if a command line flag and option was
|
|
// included while launching the application, and to get the option value
|
|
// immediately following the flag. For example if you ran:
|
|
// ./app -i filename.txt
|
|
// then you're using the "-i" flag to set the input file name.
|
|
// Usage: char * inputFilename = getCmdOption(argv, argv + argc, "-i");
|
|
// Complaints: Brad :)
|
|
char* getCmdOption(char ** begin, char ** end, const std::string & option)
|
|
{
|
|
char ** itr = std::find(begin, end, option);
|
|
if (itr != end && ++itr != end)
|
|
{
|
|
return *itr;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function: getCmdOption()
|
|
// Description: Handy little function to tell you if a command line option flag was
|
|
// included while launching the application. Returns bool true/false
|
|
// Usage: bool wantDump = cmdOptionExists(argv, argv+argc, "-d");
|
|
// Complaints: Brad :)
|
|
bool cmdOptionExists(char** begin, char** end, const std::string& option)
|
|
{
|
|
return std::find(begin, end, option) != end;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function: pointToVoxel()
|
|
// Description: Given a universal point with location x,y,z this will return the voxel
|
|
// voxel code corresponding to the closest voxel which encloses a cube with
|
|
// lower corners at x,y,z, having side of length S.
|
|
// The input values x,y,z range 0.0 <= v < 1.0
|
|
// TO DO: This code is not very DRY. It should be cleaned up to be DRYer.
|
|
// IMPORTANT: The voxel is returned to you a buffer which you MUST delete when you are
|
|
// done with it.
|
|
// Usage:
|
|
// unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
|
|
// tree->readCodeColorBufferToTree(voxelData);
|
|
// delete voxelData;
|
|
//
|
|
// Complaints: Brad :)
|
|
unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, unsigned char g, unsigned char b ) {
|
|
|
|
float xTest, yTest, zTest, sTest;
|
|
xTest = yTest = zTest = sTest = 0.5;
|
|
|
|
// First determine the voxelSize that will properly encode a
|
|
// voxel of size S.
|
|
int voxelSizeInBits = 0;
|
|
while (sTest > s) {
|
|
sTest /= 2.0;
|
|
voxelSizeInBits+=3;
|
|
}
|
|
|
|
unsigned int voxelSizeInBytes = (voxelSizeInBits/8)+1;
|
|
unsigned int voxelSizeInOctets = (voxelSizeInBits/3);
|
|
unsigned int voxelBufferSize = voxelSizeInBytes+1+3; // 1 for size, 3 for color
|
|
|
|
// allocate our resulting buffer
|
|
unsigned char* voxelOut = new unsigned char[voxelBufferSize];
|
|
|
|
// first byte of buffer is always our size in octets
|
|
voxelOut[0]=voxelSizeInOctets;
|
|
|
|
sTest = 0.5; // reset sTest so we can do this again.
|
|
|
|
unsigned char byte = 0; // we will be adding coding bits here
|
|
int bitInByteNDX = 0; // keep track of where we are in byte as we go
|
|
int byteNDX = 1; // keep track of where we are in buffer of bytes as we go
|
|
int octetsDone = 0;
|
|
|
|
// Now we actually fill out the voxel code
|
|
while (octetsDone < voxelSizeInOctets) {
|
|
|
|
if (x > xTest) {
|
|
//<write 1 bit>
|
|
byte = (byte << 1) | true;
|
|
xTest += sTest/2.0;
|
|
}
|
|
else {
|
|
//<write 0 bit;>
|
|
byte = (byte << 1) | false;
|
|
xTest -= sTest/2.0;
|
|
}
|
|
bitInByteNDX++;
|
|
// If we've reached the last bit of the byte, then we want to copy this byte
|
|
// into our buffer. And get ready to start on a new byte
|
|
if (bitInByteNDX > 7)
|
|
{
|
|
voxelOut[byteNDX]=byte;
|
|
byteNDX++;
|
|
bitInByteNDX=0;
|
|
byte=0;
|
|
}
|
|
|
|
if (y > yTest) {
|
|
//<write 1 bit>
|
|
byte = (byte << 1) | true;
|
|
yTest += sTest/2.0;
|
|
}
|
|
else {
|
|
//<write 0 bit;>
|
|
byte = (byte << 1) | false;
|
|
yTest -= sTest/2.0;
|
|
}
|
|
bitInByteNDX++;
|
|
// If we've reached the last bit of the byte, then we want to copy this byte
|
|
// into our buffer. And get ready to start on a new byte
|
|
if (bitInByteNDX > 7)
|
|
{
|
|
voxelOut[byteNDX]=byte;
|
|
byteNDX++;
|
|
bitInByteNDX=0;
|
|
byte=0;
|
|
}
|
|
|
|
if (z > zTest) {
|
|
//<write 1 bit>
|
|
byte = (byte << 1) | true;
|
|
zTest += sTest/2.0;
|
|
}
|
|
else {
|
|
//<write 0 bit;>
|
|
byte = (byte << 1) | false;
|
|
zTest -= sTest/2.0;
|
|
}
|
|
bitInByteNDX++;
|
|
// If we've reached the last bit of the byte, then we want to copy this byte
|
|
// into our buffer. And get ready to start on a new byte
|
|
if (bitInByteNDX > 7)
|
|
{
|
|
voxelOut[byteNDX]=byte;
|
|
byteNDX++;
|
|
bitInByteNDX=0;
|
|
byte=0;
|
|
}
|
|
|
|
octetsDone++;
|
|
sTest /= 2.0;
|
|
}
|
|
|
|
// If we've got here, and we didn't fill the last byte, we need to zero pad this
|
|
// byte before we copy it into our buffer.
|
|
if (bitInByteNDX > 0 && bitInByteNDX < 7)
|
|
{
|
|
// Pad the last byte
|
|
while (bitInByteNDX <= 7)
|
|
{
|
|
byte = (byte << 1) | false;
|
|
bitInByteNDX++;
|
|
}
|
|
|
|
// Copy it into our output buffer
|
|
voxelOut[byteNDX]=byte;
|
|
byteNDX++;
|
|
}
|
|
// copy color data
|
|
voxelOut[byteNDX]=r;
|
|
voxelOut[byteNDX+1]=g;
|
|
voxelOut[byteNDX+2]=b;
|
|
|
|
return voxelOut;
|
|
}
|
|
|
|
void printVoxelCode(unsigned char* voxelCode)
|
|
{
|
|
unsigned char octets = voxelCode[0];
|
|
unsigned int voxelSizeInBits = octets*3;
|
|
unsigned int voxelSizeInBytes = (voxelSizeInBits/8)+1;
|
|
unsigned int voxelSizeInOctets = (voxelSizeInBits/3);
|
|
unsigned int voxelBufferSize = voxelSizeInBytes+1+3; // 1 for size, 3 for color
|
|
|
|
printf("octets=%d\n",octets);
|
|
printf("voxelSizeInBits=%d\n",voxelSizeInBits);
|
|
printf("voxelSizeInBytes=%d\n",voxelSizeInBytes);
|
|
printf("voxelSizeInOctets=%d\n",voxelSizeInOctets);
|
|
printf("voxelBufferSize=%d\n",voxelBufferSize);
|
|
|
|
for(int i=0;i<voxelBufferSize;i++)
|
|
{
|
|
printf("i=%d ",i);
|
|
outputBits(voxelCode[i]);
|
|
}
|
|
}
|