From ff974b6cd5a7bc1030a3db9fbbfc3955c5f9e34c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 1 May 2013 12:50:02 -0700 Subject: [PATCH 01/30] half baked communication with shitty invensense --- CMakeLists.txt | 3 +- invensense-test/CMakeLists.txt | 13 ++++++ invensense-test/src/main.cpp | 79 ++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 invensense-test/CMakeLists.txt create mode 100644 invensense-test/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3923f543fa..5b1001119d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,4 +9,5 @@ add_subdirectory(eve) add_subdirectory(interface) add_subdirectory(injector) add_subdirectory(space-server) -add_subdirectory(voxel-server) \ No newline at end of file +add_subdirectory(voxel-server) +add_subdirectory(invensense-test) \ No newline at end of file diff --git a/invensense-test/CMakeLists.txt b/invensense-test/CMakeLists.txt new file mode 100644 index 0000000000..b0dfed8990 --- /dev/null +++ b/invensense-test/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.8) + +set(ROOT_DIR ..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +set(TARGET_NAME invensense-test) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME}) + +# link the shared hifi library +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/invensense-test/src/main.cpp b/invensense-test/src/main.cpp new file mode 100644 index 0000000000..981c8508f0 --- /dev/null +++ b/invensense-test/src/main.cpp @@ -0,0 +1,79 @@ +// +// main.cpp +// invensense-test +// +// Created by Stephen Birarda on 4/30/13. +// Copyright (c) 2013 High Fidelity. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + int serialFd = open("/dev/tty.usbmodemfa141", O_RDWR | O_NOCTTY | O_NDELAY); + + struct termios options; + tcgetattr(serialFd, &options); + + cfsetispeed(&options,B115200); + cfsetospeed(&options,B115200); + + options.c_cflag |= (CLOCAL | CREAD); + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + tcsetattr(serialFd,TCSANOW,&options); + + // Flush the port's buffers (in and out) before we start using it + tcflush(serialFd, TCIOFLUSH); + + // block on read until data is available + int currentFlags = fcntl(serialFd, F_GETFL); + fcntl(serialFd, F_SETFL, currentFlags & ~O_NONBLOCK); + + write(serialFd, "WR686B01\n", 9); + usleep(100000); + + tcflush(serialFd, TCIOFLUSH); + + char gyroBuffer[12] = {}; + int16_t gyroX, gyroY, gyroZ; + + char statusByte[4] = {}; + int dataReadyVal = 0; + + while (true) { + write(serialFd, "RS3A\n", 5); + read(serialFd, statusByte, 4); + + printf("The status byte read was %c%c%c%c\n", statusByte[0], statusByte[1], statusByte[2], statusByte[3]); + dataReadyVal = statusByte[3] - '0'; + + if (dataReadyVal % 2 == 1) { + tcflush(serialFd, TCIOFLUSH); + + write(serialFd, "RD684306\n", 9); + printf("Read %ld bytes from serial\n", read(serialFd, gyroBuffer, 12)); + printf("The first six chars %c%c%c%c%c%c\n", gyroBuffer[0], gyroBuffer[1], gyroBuffer[2], gyroBuffer[3], gyroBuffer[4], gyroBuffer[5]); + + gyroX = (gyroBuffer[6] << 8) | gyroBuffer[7]; + gyroY = (gyroBuffer[8] << 8) | gyroBuffer[9]; + gyroZ = (gyroBuffer[10] << 8) | gyroBuffer[11]; + + printf("The gyro data %d, %d, %d\n", gyroX, gyroY, gyroZ); + } + + tcflush(serialFd, TCIOFLUSH); + } + + close(serialFd); + + return 0; +} + + From 8087d2e0f45ddf04ebc7b51223e582944f11640a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 1 May 2013 17:27:39 -0700 Subject: [PATCH 02/30] a functional test pulling gyro data at 100Hz --- invensense-test/src/main.cpp | 59 ++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/invensense-test/src/main.cpp b/invensense-test/src/main.cpp index 981c8508f0..dac4047ce3 100644 --- a/invensense-test/src/main.cpp +++ b/invensense-test/src/main.cpp @@ -13,6 +13,21 @@ #include #include +void loadIntFromTwoHex(char* sourceBuffer, int& destinationInt) { + + unsigned int byte[2]; + + for(int i = 0; i < 2; i++) { + sscanf(sourceBuffer + 2 * i, "%2x", &byte[i]); +// printf("The hex code is 0x%c%c so the byte is %d\n", (sourceBuffer + 2 * i)[0], (sourceBuffer + 2 * i)[1], byte[i]); + } + + int16_t result = (byte[0] << 8); + result += byte[1]; + + destinationInt = result; +} + int main(int argc, char* argv[]) { int serialFd = open("/dev/tty.usbmodemfa141", O_RDWR | O_NOCTTY | O_NDELAY); @@ -38,37 +53,37 @@ int main(int argc, char* argv[]) { write(serialFd, "WR686B01\n", 9); usleep(100000); + write(serialFd, "SD\n", 3); + usleep(100000); tcflush(serialFd, TCIOFLUSH); - char gyroBuffer[12] = {}; - int16_t gyroX, gyroY, gyroZ; + char gyroBuffer[20] = {}; + int gyroX, gyroY, gyroZ; + int readBytes = 0; - char statusByte[4] = {}; - int dataReadyVal = 0; + double lastRead = usecTimestampNow(); while (true) { - write(serialFd, "RS3A\n", 5); - read(serialFd, statusByte, 4); - - printf("The status byte read was %c%c%c%c\n", statusByte[0], statusByte[1], statusByte[2], statusByte[3]); - dataReadyVal = statusByte[3] - '0'; - - if (dataReadyVal % 2 == 1) { - tcflush(serialFd, TCIOFLUSH); + if (usecTimestampNow() - lastRead >= 10000) { write(serialFd, "RD684306\n", 9); - printf("Read %ld bytes from serial\n", read(serialFd, gyroBuffer, 12)); - printf("The first six chars %c%c%c%c%c%c\n", gyroBuffer[0], gyroBuffer[1], gyroBuffer[2], gyroBuffer[3], gyroBuffer[4], gyroBuffer[5]); - - gyroX = (gyroBuffer[6] << 8) | gyroBuffer[7]; - gyroY = (gyroBuffer[8] << 8) | gyroBuffer[9]; - gyroZ = (gyroBuffer[10] << 8) | gyroBuffer[11]; - printf("The gyro data %d, %d, %d\n", gyroX, gyroY, gyroZ); - } - - tcflush(serialFd, TCIOFLUSH); + readBytes = read(serialFd, gyroBuffer, 20); +// printf("Read %d bytes from serial\n", readBytes); + +// printf("The first two characters are %c%c\n", gyroBuffer[0], gyroBuffer[1]); + + if (readBytes == 20 && gyroBuffer[0] == 'R' && gyroBuffer[1] == 'D') { + loadIntFromTwoHex(gyroBuffer + 6, gyroX); + loadIntFromTwoHex(gyroBuffer + 10, gyroY); + loadIntFromTwoHex(gyroBuffer + 14, gyroZ); + + printf("The gyro data %d, %d, %d\n", gyroX, gyroY, gyroZ); + } + + lastRead = usecTimestampNow(); + } } close(serialFd); From 9e3b862c6715c4c38135a6a29db29602eba10448 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 May 2013 12:26:12 -0700 Subject: [PATCH 03/30] hook up the invensense via existing SerialInterface class --- interface/src/Avatar.cpp | 46 ++++---- interface/src/SerialInterface.cpp | 179 +++++++++++++++++++----------- interface/src/SerialInterface.h | 11 ++ interface/src/main.cpp | 6 +- 4 files changed, 152 insertions(+), 90 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 21fa44e651..1f4f3cd1a7 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -226,45 +226,39 @@ void Avatar::reset() { _head.leanForward = _head.leanSideways = 0; } - -//this pertains to moving the head with the glasses -void Avatar::UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity) +// this pertains to moving the head with the glasses // Using serial data, update avatar/render position and angles -{ - const float PITCH_ACCEL_COUPLING = 0.5; - const float ROLL_ACCEL_COUPLING = -1.0; - float measured_pitch_rate = serialInterface->getRelativeValue(HEAD_PITCH_RATE); - _head.yawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); - float measured_lateral_accel = serialInterface->getRelativeValue(ACCEL_X) - - ROLL_ACCEL_COUPLING*serialInterface->getRelativeValue(HEAD_ROLL_RATE); - float measured_fwd_accel = serialInterface->getRelativeValue(ACCEL_Z) - - PITCH_ACCEL_COUPLING*serialInterface->getRelativeValue(HEAD_PITCH_RATE); - float measured_roll_rate = serialInterface->getRelativeValue(HEAD_ROLL_RATE); - - //printLog("Pitch Rate: %d ACCEL_Z: %d\n", serialInterface->getRelativeValue(PITCH_RATE), - // serialInterface->getRelativeValue(ACCEL_Z)); - //printLog("Pitch Rate: %d ACCEL_X: %d\n", serialInterface->getRelativeValue(PITCH_RATE), - // serialInterface->getRelativeValue(ACCEL_Z)); - //printLog("Pitch: %f\n", Pitch); +void Avatar::UpdateGyros(float frametime, SerialInterface* serialInterface, glm::vec3* gravity) { + float measured_pitch_rate = 0.0f; + float measured_roll_rate = 0.0f; + if (serialInterface->active && USING_INVENSENSE_MPU9150) { + measured_pitch_rate = serialInterface->getLastPitch(); + _head.yawRate = serialInterface->getLastYaw(); + measured_roll_rate = -1 * serialInterface->getLastRoll(); + } else { + measured_pitch_rate = serialInterface->getRelativeValue(HEAD_PITCH_RATE); + _head.yawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); + measured_roll_rate = serialInterface->getRelativeValue(HEAD_ROLL_RATE); + } // Update avatar head position based on measured gyro rates const float HEAD_ROTATION_SCALE = 0.70; const float HEAD_ROLL_SCALE = 0.40; - const float HEAD_LEAN_SCALE = 0.01; const float MAX_PITCH = 45; const float MIN_PITCH = -45; const float MAX_YAW = 85; const float MIN_YAW = -85; - if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH)) + if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH)) { addHeadPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); - + } + addHeadRoll(measured_roll_rate * HEAD_ROLL_SCALE * frametime); - if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) - addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime); - - addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); + if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) { + addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime); + } + } float Avatar::getAbsoluteHeadYaw() const { diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 9fe57ecaaf..44f256cd01 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -32,6 +32,8 @@ const short NO_READ_MAXIMUM_MSECS = 3000; const short SAMPLES_TO_DISCARD = 100; // Throw out the first few samples const int GRAVITY_SAMPLES = 200; // Use the first samples to compute gravity vector +const bool USING_INVENSENSE_MPU9150 = 1; + void SerialInterface::pair() { #ifdef __APPLE__ @@ -62,9 +64,8 @@ void SerialInterface::pair() { } -// Connect to the serial port -int SerialInterface::initializePort(char* portname, int baud) -{ +// connect to the serial port +int SerialInterface::initializePort(char* portname, int baud) { #ifdef __APPLE__ serialFd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY); @@ -76,8 +77,8 @@ int SerialInterface::initializePort(char* portname, int baud) } struct termios options; tcgetattr(serialFd,&options); - switch(baud) - { + + switch(baud) { case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; @@ -94,16 +95,37 @@ int SerialInterface::initializePort(char* portname, int baud) cfsetospeed(&options,B9600); break; } + options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(serialFd,TCSANOW,&options); - + + if (USING_INVENSENSE_MPU9150) { + // block on invensense reads until there is data to read + int currentFlags = fcntl(serialFd, F_GETFL); + fcntl(serialFd, F_SETFL, currentFlags & ~O_NONBLOCK); + + // there are extra commands to send to the invensense when it fires up + + // this takes it out of SLEEP + write(serialFd, "WR686B01\n", 9); + + // delay after the wakeup + usleep(10000); + + // this disables streaming so there's no garbage data on reads + write(serialFd, "SD\n", 3); + + // flush whatever was produced by the last two commands + tcflush(serialFd, TCIOFLUSH); + } printLog("Connected.\n"); - resetSerial(); + resetSerial(); + active = true; #endif @@ -157,62 +179,89 @@ void SerialInterface::renderLevels(int width, int height) { } glEnd(); } +} +void convertHexToInt(unsigned char* sourceBuffer, int& destinationInt) { + unsigned int byte[2]; + + for(int i = 0; i < 2; i++) { + sscanf((char*) sourceBuffer + 2 * i, "%2x", &byte[i]); + } + + int16_t result = (byte[0] << 8); + result += byte[1]; + + destinationInt = result; } void SerialInterface::readData() { #ifdef __APPLE__ - // This array sets the rate of trailing averaging for each channel: - // If the sensor rate is 100Hz, 0.001 will make the long term average a 10-second average - const float AVG_RATE[] = {0.002, 0.002, 0.002, 0.002, 0.002, 0.002}; - char bufchar[1]; int initialSamples = totalSamples; - while (read(serialFd, &bufchar, 1) > 0) { - serialBuffer[serialBufferPos] = bufchar[0]; - serialBufferPos++; - // Have we reached end of a line of input? - if ((bufchar[0] == '\n') || (serialBufferPos >= MAX_BUFFER)) { - std::string serialLine(serialBuffer, serialBufferPos-1); - //printLog("%s\n", serialLine.c_str()); - int spot; - //int channel = 0; - std::string val; - for (int i = 0; i < NUM_CHANNELS + 2; i++) { - spot = serialLine.find_first_of(" ", 0); - if (spot != std::string::npos) { - val = serialLine.substr(0,spot); - //printLog("%s\n", val.c_str()); - if (i < NUM_CHANNELS) lastMeasured[i] = atoi(val.c_str()); - else samplesAveraged = atoi(val.c_str()); - } else LED = atoi(serialLine.c_str()); - serialLine = serialLine.substr(spot+1, serialLine.length() - spot - 1); - } - - // Update Trailing Averages - for (int i = 0; i < NUM_CHANNELS; i++) { - if (totalSamples > SAMPLES_TO_DISCARD) { - trailingAverage[i] = (1.f - AVG_RATE[i])*trailingAverage[i] + - AVG_RATE[i]*(float)lastMeasured[i]; - } else { - trailingAverage[i] = (float)lastMeasured[i]; + if (USING_INVENSENSE_MPU9150) { + unsigned char gyroBuffer[20]; + + // ask the invensense for raw gyro data + write(serialFd, "RD684306\n", 9); + read(serialFd, gyroBuffer, 20); + + convertHexToInt(gyroBuffer + 6, _lastYaw); + convertHexToInt(gyroBuffer + 10, _lastRoll); + convertHexToInt(gyroBuffer + 14, _lastPitch); + + totalSamples++; + } else { + // This array sets the rate of trailing averaging for each channel: + // If the sensor rate is 100Hz, 0.001 will make the long term average a 10-second average + const float AVG_RATE[] = {0.002, 0.002, 0.002, 0.002, 0.002, 0.002}; + char bufchar[1]; + + while (read(serialFd, &bufchar, 1) > 0) { + serialBuffer[serialBufferPos] = bufchar[0]; + serialBufferPos++; + // Have we reached end of a line of input? + if ((bufchar[0] == '\n') || (serialBufferPos >= MAX_BUFFER)) { + std::string serialLine(serialBuffer, serialBufferPos-1); + //printLog("%s\n", serialLine.c_str()); + int spot; + //int channel = 0; + std::string val; + for (int i = 0; i < NUM_CHANNELS + 2; i++) { + spot = serialLine.find_first_of(" ", 0); + if (spot != std::string::npos) { + val = serialLine.substr(0,spot); + //printLog("%s\n", val.c_str()); + if (i < NUM_CHANNELS) lastMeasured[i] = atoi(val.c_str()); + else samplesAveraged = atoi(val.c_str()); + } else LED = atoi(serialLine.c_str()); + serialLine = serialLine.substr(spot+1, serialLine.length() - spot - 1); } - + + // Update Trailing Averages + for (int i = 0; i < NUM_CHANNELS; i++) { + if (totalSamples > SAMPLES_TO_DISCARD) { + trailingAverage[i] = (1.f - AVG_RATE[i])*trailingAverage[i] + + AVG_RATE[i]*(float)lastMeasured[i]; + } else { + trailingAverage[i] = (float)lastMeasured[i]; + } + + } + + // Use a set of initial samples to compute gravity + if (totalSamples < GRAVITY_SAMPLES) { + gravity.x += lastMeasured[ACCEL_X]; + gravity.y += lastMeasured[ACCEL_Y]; + gravity.z += lastMeasured[ACCEL_Z]; + } + if (totalSamples == GRAVITY_SAMPLES) { + gravity = glm::normalize(gravity); + printLog("gravity: %f,%f,%f\n", gravity.x, gravity.y, gravity.z); + } + + totalSamples++; + serialBufferPos = 0; } - - // Use a set of initial samples to compute gravity - if (totalSamples < GRAVITY_SAMPLES) { - gravity.x += lastMeasured[ACCEL_X]; - gravity.y += lastMeasured[ACCEL_Y]; - gravity.z += lastMeasured[ACCEL_Z]; - } - if (totalSamples == GRAVITY_SAMPLES) { - gravity = glm::normalize(gravity); - printLog("gravity: %f,%f,%f\n", gravity.x, gravity.y, gravity.z); - } - - totalSamples++; - serialBufferPos = 0; } } @@ -234,19 +283,23 @@ void SerialInterface::resetSerial() { #ifdef __APPLE__ active = false; totalSamples = 0; - gravity = glm::vec3(0,-1,0); gettimeofday(&lastGoodRead, NULL); - // Clear the measured and average channel data - for (int i = 0; i < NUM_CHANNELS; i++) { - lastMeasured[i] = 0; - trailingAverage[i] = 0.0; - } - // Clear serial input buffer - for (int i = 1; i < MAX_BUFFER; i++) { - serialBuffer[i] = ' '; + if (!USING_INVENSENSE_MPU9150) { + gravity = glm::vec3(0,-1,0); + + // Clear the measured and average channel data + for (int i = 0; i < NUM_CHANNELS; i++) { + lastMeasured[i] = 0; + trailingAverage[i] = 0.0; + } + // Clear serial input buffer + for (int i = 1; i < MAX_BUFFER; i++) { + serialBuffer[i] = ' '; + } } + #endif } diff --git a/interface/src/SerialInterface.h b/interface/src/SerialInterface.h index 150c15fb65..9558a1601f 100644 --- a/interface/src/SerialInterface.h +++ b/interface/src/SerialInterface.h @@ -32,16 +32,24 @@ #define HEAD_YAW_RATE 0 #define HEAD_ROLL_RATE 2 +extern const bool USING_INVENSENSE_MPU9150; + class SerialInterface { public: SerialInterface() { active = false; }; void pair(); void readData(); + + int getLastYaw() const { return _lastYaw; } + int getLastPitch() const { return _lastPitch; } + int getLastRoll() const { return _lastRoll; } + int getLED() {return LED;}; int getNumSamples() {return samplesAveraged;}; int getValue(int num) {return lastMeasured[num];}; int getRelativeValue(int num) {return static_cast(lastMeasured[num] - trailingAverage[num]);}; float getTrailingValue(int num) {return trailingAverage[num];}; + void resetTrailingAverages(); void renderLevels(int width, int height); bool active; @@ -57,6 +65,9 @@ private: int totalSamples; timeval lastGoodRead; glm::vec3 gravity; + int _lastYaw; + int _lastPitch; + int _lastRoll; }; #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 7ef1c491f8..26cb2d0e53 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1476,6 +1476,10 @@ void idle(void) { handControl.stop(); } + if (serialPort.active && USING_INVENSENSE_MPU9150) { + serialPort.readData(); + } + // // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // @@ -1504,7 +1508,7 @@ void idle(void) { } // Read serial data - if (serialPort.active) { + if (serialPort.active && !USING_INVENSENSE_MPU9150) { serialPort.readData(); } } From 4a3d713bc73f7d627c16856afb32793e3a46e187 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 May 2013 12:27:21 -0700 Subject: [PATCH 04/30] remove the invensense testing program --- CMakeLists.txt | 3 +- invensense-test/CMakeLists.txt | 13 ----- invensense-test/src/main.cpp | 94 ---------------------------------- 3 files changed, 1 insertion(+), 109 deletions(-) delete mode 100644 invensense-test/CMakeLists.txt delete mode 100644 invensense-test/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b1001119d..3923f543fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,5 +9,4 @@ add_subdirectory(eve) add_subdirectory(interface) add_subdirectory(injector) add_subdirectory(space-server) -add_subdirectory(voxel-server) -add_subdirectory(invensense-test) \ No newline at end of file +add_subdirectory(voxel-server) \ No newline at end of file diff --git a/invensense-test/CMakeLists.txt b/invensense-test/CMakeLists.txt deleted file mode 100644 index b0dfed8990..0000000000 --- a/invensense-test/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set(ROOT_DIR ..) -set(MACRO_DIR ${ROOT_DIR}/cmake/macros) - -set(TARGET_NAME invensense-test) - -include(${MACRO_DIR}/SetupHifiProject.cmake) -setup_hifi_project(${TARGET_NAME}) - -# link the shared hifi library -include(${MACRO_DIR}/LinkHifiLibrary.cmake) -link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/invensense-test/src/main.cpp b/invensense-test/src/main.cpp deleted file mode 100644 index dac4047ce3..0000000000 --- a/invensense-test/src/main.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// main.cpp -// invensense-test -// -// Created by Stephen Birarda on 4/30/13. -// Copyright (c) 2013 High Fidelity. All rights reserved. -// - -#include -#include -#include -#include -#include -#include - -void loadIntFromTwoHex(char* sourceBuffer, int& destinationInt) { - - unsigned int byte[2]; - - for(int i = 0; i < 2; i++) { - sscanf(sourceBuffer + 2 * i, "%2x", &byte[i]); -// printf("The hex code is 0x%c%c so the byte is %d\n", (sourceBuffer + 2 * i)[0], (sourceBuffer + 2 * i)[1], byte[i]); - } - - int16_t result = (byte[0] << 8); - result += byte[1]; - - destinationInt = result; -} - -int main(int argc, char* argv[]) { - int serialFd = open("/dev/tty.usbmodemfa141", O_RDWR | O_NOCTTY | O_NDELAY); - - struct termios options; - tcgetattr(serialFd, &options); - - cfsetispeed(&options,B115200); - cfsetospeed(&options,B115200); - - options.c_cflag |= (CLOCAL | CREAD); - options.c_cflag &= ~PARENB; - options.c_cflag &= ~CSTOPB; - options.c_cflag &= ~CSIZE; - options.c_cflag |= CS8; - tcsetattr(serialFd,TCSANOW,&options); - - // Flush the port's buffers (in and out) before we start using it - tcflush(serialFd, TCIOFLUSH); - - // block on read until data is available - int currentFlags = fcntl(serialFd, F_GETFL); - fcntl(serialFd, F_SETFL, currentFlags & ~O_NONBLOCK); - - write(serialFd, "WR686B01\n", 9); - usleep(100000); - write(serialFd, "SD\n", 3); - usleep(100000); - - tcflush(serialFd, TCIOFLUSH); - - char gyroBuffer[20] = {}; - int gyroX, gyroY, gyroZ; - int readBytes = 0; - - double lastRead = usecTimestampNow(); - - while (true) { - if (usecTimestampNow() - lastRead >= 10000) { - - write(serialFd, "RD684306\n", 9); - - readBytes = read(serialFd, gyroBuffer, 20); -// printf("Read %d bytes from serial\n", readBytes); - -// printf("The first two characters are %c%c\n", gyroBuffer[0], gyroBuffer[1]); - - if (readBytes == 20 && gyroBuffer[0] == 'R' && gyroBuffer[1] == 'D') { - loadIntFromTwoHex(gyroBuffer + 6, gyroX); - loadIntFromTwoHex(gyroBuffer + 10, gyroY); - loadIntFromTwoHex(gyroBuffer + 14, gyroZ); - - printf("The gyro data %d, %d, %d\n", gyroX, gyroY, gyroZ); - } - - lastRead = usecTimestampNow(); - } - } - - close(serialFd); - - return 0; -} - - From e9d556419f47de14b9741295929b6277b7329b88 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 14:39:00 -0700 Subject: [PATCH 05/30] got rid of some dead code --- libraries/voxels/src/VoxelTree.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 21118c929e..91b8f9f28c 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -260,9 +260,6 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer) { delete[] vertices; if (parentNode) { - float* vertices = firstVertexForCode(parentNode->octalCode); - delete[] vertices; - int childIndex = branchIndexWithDescendant(parentNode->octalCode, codeBuffer); delete parentNode->children[childIndex]; // delete the child nodes From 1366794bdc2717ff64ff53e1152d5072de3ef191 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 15:00:03 -0700 Subject: [PATCH 06/30] added some tree methods for primitive voxel editing --- libraries/voxels/src/VoxelTree.cpp | 19 ++++++++++++++++++- libraries/voxels/src/VoxelTree.h | 8 +++++--- voxel-server/src/main.cpp | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 91b8f9f28c..e27e8da0ba 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -69,7 +69,7 @@ void VoxelTree::recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperati } } -VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * needleCode, VoxelNode** parentOfFoundNode) { +VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * needleCode, VoxelNode** parentOfFoundNode) const { // find the appropriate branch index based on this ancestorNode if (*needleCode > 0) { int branchForNeedle = branchIndexWithDescendant(ancestorNode->octalCode, needleCode); @@ -245,6 +245,13 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, int bufferSizeByt this->voxelsBytesReadStats.updateAverage(bufferSizeBytes); } +void VoxelTree::deleteVoxelAt(float x, float y, float z, float s) { + unsigned char* octalCode = pointToVoxel(x,y,z,s,0,0,0); + deleteVoxelCodeFromTree(octalCode); + delete octalCode; // cleanup memory +} + + // Note: uses the codeColorBuffer format, but the color's are ignored, because // this only finds and deletes the node from the tree. void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer) { @@ -435,6 +442,16 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { } } +VoxelNode* VoxelTree::getVoxelAt(float x, float y, float z, float s) const { + unsigned char* octalCode = pointToVoxel(x,y,z,s,0,0,0); + VoxelNode* node = nodeForOctalCode(rootNode, octalCode, NULL); + if (*node->octalCode != *octalCode) { + node = NULL; + } + delete octalCode; // cleanup memory + return node; +} + void VoxelTree::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue) { unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue); this->readCodeColorBufferToTree(voxelData); diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 309766bcd2..634cccd22f 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -45,10 +45,12 @@ public: void printTreeForDebugging(VoxelNode *startNode); void reaverageVoxelColors(VoxelNode *startNode); void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); - void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer); - void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue); + void deleteVoxelAt(float x, float y, float z, float s); + VoxelNode* getVoxelAt(float x, float y, float z, float s) const; + void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue); void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color); + void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer); void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); @@ -72,7 +74,7 @@ private: VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData); - VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode); + VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const; VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate); int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 17c4915988..7d29fd1457 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -80,6 +80,21 @@ void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) { float voxelSize = 1.f/32; printf("creating corner points...\n"); tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255); + + if (tree->getVoxelAt(0, 0, 0, voxelSize)) { + printf("corner point 0,0,0 exists...\n"); + } + + tree->deleteVoxelAt(0, 0, 0, voxelSize); + printf("attempting to delete corner point 0,0,0\n"); + + if (tree->getVoxelAt(0, 0, 0, voxelSize)) { + printf("corner point 0,0,0 exists...\n"); + } else { + printf("corner point 0,0,0 does not exists...\n"); + } + + tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 ); tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 ); tree->createVoxel(0 , 0 , 1.0 - voxelSize, voxelSize, 0 , 0 ,255); From f4099349e86c565d3f04ccd6b5bd098f3c6956ec Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 15:13:00 -0700 Subject: [PATCH 07/30] change to encodeTreeBitstreamRecursion() to allow calling without viewFrustum --- libraries/voxels/src/VoxelTree.cpp | 43 +++++++++++++++--------------- libraries/voxels/src/VoxelTree.h | 9 +++---- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index e27e8da0ba..6ac8e6327d 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -666,8 +666,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const Vi int currentEncodeLevel = 0; int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, - node, viewFrustum, - outputBuffer, availableBytes, bag); + node, outputBuffer, availableBytes, bag, &viewFrustum); // if childBytesWritten == 1 then something went wrong... that's not possible assert(childBytesWritten != 1); @@ -689,9 +688,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const Vi } int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, - VoxelNode* node, const ViewFrustum& viewFrustum, - unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag) const { + VoxelNode* node, unsigned char* outputBuffer, int availableBytes, + VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const { // How many bytes have we written so far at this level; int bytesAtThisLevel = 0; @@ -703,21 +701,24 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco return bytesAtThisLevel; } - float distance = node->distanceToCamera(viewFrustum); - float boundaryDistance = boundaryDistanceForRenderLevel(*node->octalCode + 1); + // caller can pass NULL as viewFrustum if they want everything + if (viewFrustum) { + float distance = node->distanceToCamera(*viewFrustum); + float boundaryDistance = boundaryDistanceForRenderLevel(*node->octalCode + 1); - // If we're too far away for our render level, then just return - if (distance >= boundaryDistance) { - return bytesAtThisLevel; - } + // If we're too far away for our render level, then just return + if (distance >= boundaryDistance) { + return bytesAtThisLevel; + } - // If we're at a node that is out of view, then we can return, because no nodes below us will be in view! - // although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if - // we're out of view - if (!node->isInView(viewFrustum)) { - return bytesAtThisLevel; + // If we're at a node that is out of view, then we can return, because no nodes below us will be in view! + // although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if + // we're out of view + if (!node->isInView(*viewFrustum)) { + return bytesAtThisLevel; + } } - + bool keepDiggingDeeper = true; // Assuming we're in view we have a great work ethic, we're always ready for more! // At any given point in writing the bitstream, the largest minimum we might need to flesh out the current level @@ -745,11 +746,11 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco for (int i = 0; i < MAX_CHILDREN; i++) { VoxelNode* childNode = node->children[i]; bool childExists = (childNode != NULL); - bool childIsInView = (childExists && childNode->isInView(viewFrustum)); + bool childIsInView = (childExists && (!viewFrustum || childNode->isInView(*viewFrustum))); if (childIsInView) { // Before we determine consider this further, let's see if it's in our LOD scope... - float distance = childNode->distanceToCamera(viewFrustum); - float boundaryDistance = boundaryDistanceForRenderLevel(*childNode->octalCode + 1); + float distance = viewFrustum ? 0 : childNode->distanceToCamera(*viewFrustum); + float boundaryDistance = viewFrustum ? 1 : boundaryDistanceForRenderLevel(*childNode->octalCode + 1); if (distance < boundaryDistance) { inViewCount++; @@ -822,7 +823,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco int thisLevel = currentEncodeLevel; int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode, - viewFrustum, outputBuffer, availableBytes, bag); + outputBuffer, availableBytes, bag, viewFrustum); // if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space, // basically, the children below don't contain any info. diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 634cccd22f..f78f676591 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -63,13 +63,12 @@ public: bool isDirty() const { return _isDirty; }; void clearDirtyBit() { _isDirty = false; }; unsigned long int getNodesChangedFromBitstream() const { return _nodesChangedFromBitstream; }; + + int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, + VoxelNode* node, unsigned char* outputBuffer, int availableBytes, + VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const; private: - int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, - VoxelNode* node, const ViewFrustum& viewFrustum, - unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag) const; - int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); From 66e2771135787fd9792426fb22f8867ffd4f3922 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 May 2013 15:58:55 -0700 Subject: [PATCH 08/30] some cleanup in interface main --- interface/src/main.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index a1f8778ca7..5525a94dc8 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -208,8 +208,7 @@ bool justStarted = true; // Every second, check the frame rates and other stuff -void Timer(int extra) -{ +void Timer(int extra) { gettimeofday(&timerEnd, NULL); FPS = (float)frameCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); packetsPerSecond = (float)packetCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); @@ -227,8 +226,7 @@ void Timer(int extra) } } -void displayStats(void) -{ +void displayStats(void) { int statsVerticalOffset = 50; if (::menuOn == 0) { statsVerticalOffset = 8; @@ -269,6 +267,7 @@ void displayStats(void) Agent *avatarMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); char avatarMixerStats[200]; + if (avatarMixer) { sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps", roundf(avatarMixer->getAverageKilobitsPerSecond()), @@ -276,6 +275,7 @@ void displayStats(void) } else { sprintf(avatarMixerStats, "No Avatar Mixer"); } + drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats); if (::perfStatsOn) { @@ -293,8 +293,7 @@ void displayStats(void) } } -void initDisplay(void) -{ +void initDisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -306,8 +305,7 @@ void initDisplay(void) if (fullscreen) glutFullScreen(); } -void init(void) -{ +void init(void) { voxels.init(); voxels.setViewerAvatar(&myAvatar); voxels.setCamera(&myCamera); @@ -360,8 +358,7 @@ void terminate () { exit(EXIT_SUCCESS); } -void reset_sensors() -{ +void reset_sensors() { myAvatar.setPosition(start_location); headMouseX = WIDTH/2; @@ -377,16 +374,13 @@ void reset_sensors() // // Using gyro data, update both view frustum and avatar head position // -void updateAvatar(float frametime) -{ +void updateAvatar(float frametime) { float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE); float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE ); myAvatar.UpdateGyros(frametime, &serialPort, &gravity); - // // 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 + @@ -401,7 +395,7 @@ void updateAvatar(float frametime) headMouseY = min(headMouseY, HEIGHT); // Update head and body pitch and yaw based on measured gyro rates - if (::gyroLook) { + if (::gyroLook) { // Yaw const float MIN_YAW_RATE = 50; const float YAW_SENSITIVITY = 1.0; From e3164b397607dd98074ae1d5af2dc6584551a5bb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 17:09:43 -0700 Subject: [PATCH 09/30] added read/write voxel files --- libraries/voxels/src/VoxelTree.cpp | 53 ++++++++++++++++++++++++++++-- libraries/voxels/src/VoxelTree.h | 10 ++++-- voxel-server/src/main.cpp | 25 +++++++++++++- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 6ac8e6327d..bfa59b965b 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -205,7 +205,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, return bytesRead; } -void VoxelTree::readBitstreamToTree(unsigned char * bitstream, int bufferSizeBytes) { +void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes) { int bytesRead = 0; unsigned char* bitstreamAt = bitstream; @@ -749,8 +749,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco bool childIsInView = (childExists && (!viewFrustum || childNode->isInView(*viewFrustum))); if (childIsInView) { // Before we determine consider this further, let's see if it's in our LOD scope... - float distance = viewFrustum ? 0 : childNode->distanceToCamera(*viewFrustum); - float boundaryDistance = viewFrustum ? 1 : boundaryDistanceForRenderLevel(*childNode->octalCode + 1); + float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0; + float boundaryDistance = viewFrustum ? boundaryDistanceForRenderLevel(*childNode->octalCode + 1) : 1; if (distance < boundaryDistance) { inViewCount++; @@ -863,3 +863,50 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco } // end keepDiggingDeeper return bytesAtThisLevel; } + +void VoxelTree::readFromFileV2(const char* fileName, bool reset) { + std::ifstream file(fileName, std::ios::in|std::ios::binary); + + if(file.is_open()) { + printLog("loading file...\n"); + + // get file length.... + unsigned long start = file.tellg(); + file.seekg( 0, std::ios::end ); + unsigned long end = file.tellg(); + unsigned long size = end - start; + + // read the entire file into a buffer, WHAT!? Why not. + unsigned char* entireFile = new unsigned char[size]; + file.read((char*)entireFile, size); + readBitstreamToTree(entireFile,size); + delete[] entireFile; + + file.close(); + } +} + +void VoxelTree::writeToFileV2(const char* fileName) const { + + std::ofstream file(fileName, std::ios::out|std::ios::binary); + + if(file.is_open()) { + VoxelNodeBag nodeBag; + nodeBag.insert(rootNode); + + static unsigned char tempOutputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static + int bytesWritten = 0; + + while (!nodeBag.isEmpty()) { + VoxelNode* subTree = nodeBag.extract(); + int currentEncodeLevel = 0; + bytesWritten = encodeTreeBitstreamRecursion(INT_MAX, currentEncodeLevel, subTree, + &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, + nodeBag, NULL); + + file.write((const char*)&tempOutputBuffer[0], bytesWritten); + } + } + file.close(); +} + diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index f78f676591..db4f78b9b4 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -39,12 +39,11 @@ public: void eraseAllVoxels(); void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes); - void readBitstreamToTree(unsigned char * bitstream, int bufferSizeBytes); + void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes); void readCodeColorBufferToTree(unsigned char *codeColorBuffer); void deleteVoxelCodeFromTree(unsigned char *codeBuffer); void printTreeForDebugging(VoxelNode *startNode); void reaverageVoxelColors(VoxelNode *startNode); - void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); void deleteVoxelAt(float x, float y, float z, float s); VoxelNode* getVoxelAt(float x, float y, float z, float s) const; @@ -67,6 +66,13 @@ public: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const; + + // Note: this assumes the fileFormat is the HIO individual voxels code files + void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); + + // these will read/write files that match the wireformat, including the 'V' leading + void writeToFileV2(const char* filename) const; + void readFromFileV2(const char* filename, bool reset); private: int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 7d29fd1457..f827156698 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -94,6 +94,29 @@ void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) { printf("corner point 0,0,0 does not exists...\n"); } + printf("creating corner points...\n"); + tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255); + + printf("saving file voxels.hio2...\n"); + tree->writeToFileV2("voxels.hio2"); + printf("erasing all voxels...\n"); + tree->eraseAllVoxels(); + + if (tree->getVoxelAt(0, 0, 0, voxelSize)) { + printf("corner point 0,0,0 exists...\n"); + } else { + printf("corner point 0,0,0 does not exists...\n"); + } + + printf("loading file voxels.hio2...\n"); + tree->readFromFileV2("voxels.hio2",true); + + if (tree->getVoxelAt(0, 0, 0, voxelSize)) { + printf("corner point 0,0,0 exists...\n"); + } else { + printf("corner point 0,0,0 does not exists...\n"); + } + tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 ); tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 ); @@ -373,7 +396,7 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* local = "--local"; bool wantLocalDomain = cmdOptionExists(argc, argv,local); - if (wantLocalDomain) { + if (true || wantLocalDomain) { printf("Local Domain MODE!\n"); int ip = getLocalAddress(); sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); From 0656b5b14fd4da523401913807768910e954bce5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 17:12:37 -0700 Subject: [PATCH 10/30] fixed acidental local mode --- voxel-server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index f827156698..dcf7588544 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -396,7 +396,7 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* local = "--local"; bool wantLocalDomain = cmdOptionExists(argc, argv,local); - if (true || wantLocalDomain) { + if (wantLocalDomain) { printf("Local Domain MODE!\n"); int ip = getLocalAddress(); sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); From f8cbe34e070faea0c0860877d44d8a01020b09a4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 3 May 2013 17:27:57 -0700 Subject: [PATCH 11/30] Added basic ray intersection testing to VoxelTree. --- libraries/voxels/src/AABox.cpp | 49 ++++++++++++++++++++++++++++++ libraries/voxels/src/AABox.h | 5 ++- libraries/voxels/src/VoxelTree.cpp | 34 +++++++++++++++++++++ libraries/voxels/src/VoxelTree.h | 2 ++ 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index 0187bae853..d79c36882c 100755 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -8,6 +8,8 @@ // Simple axis aligned box class. // +#include "SharedUtil.h" + #include "AABox.h" @@ -66,3 +68,50 @@ glm::vec3 AABox::getVertexN(const glm::vec3 &normal) const { return(res); } + +// determines whether a value is within the extents +static bool isWithin(float value, float corner, float size) { + return value >= corner && value <= corner + size; +} + +bool AABox::contains(const glm::vec3& point) const { + return isWithin(point.x, _corner.x, _size.x) && + isWithin(point.y, _corner.y, _size.y) && + isWithin(point.z, _corner.z, _size.z); +} + +// finds the intersection between the closer plane in one direction +static bool findIntersection(float origin, float direction, float corner, float size, float* t) { + if (direction > EPSILON) { + *t = (corner - origin) / direction; + return true; + + } else if (direction < -EPSILON) { + *t = (corner + size - origin) / direction; + return true; + } + return false; +} + +bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float* t) const { + // handle the trivial case where the box contains the origin + if (contains(origin)) { + *t = 0; + return true; + } + // check each direction + float nt; + if (findIntersection(origin.x, direction.x, _corner.x, _size.x, &nt) && + isWithin(origin.y + nt*direction.y, _corner.y, _size.y) && + isWithin(origin.z + nt*direction.z, _corner.z, _size.z) || + findIntersection(origin.y, direction.y, _corner.y, _size.y, &nt) && + isWithin(origin.x + nt*direction.x, _corner.x, _size.x) && + isWithin(origin.z + nt*direction.z, _corner.z, _size.z) || + findIntersection(origin.z, direction.z, _corner.z, _size.z, &nt) && + isWithin(origin.y + nt*direction.y, _corner.y, _size.y) && + isWithin(origin.x + nt*direction.x, _corner.x, _size.x)) { + *t = nt; + return true; + } + return false; +} diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 0a69b8608d..0dae354860 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -35,10 +35,13 @@ public: const glm::vec3& getCorner() const { return _corner; }; const glm::vec3& getSize() const { return _size; }; + bool contains(const glm::vec3& point) const; + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float* t) const; + private: glm::vec3 _corner; glm::vec3 _size; }; -#endif \ No newline at end of file +#endif diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 21118c929e..a13675f00d 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -546,7 +546,41 @@ int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const return levelReached; } +// combines the ray cast arguments into a single object +class RayArgs { +public: + glm::vec3 origin; + glm::vec3 direction; + VoxelNode** node; + float* t; + bool found; +}; +bool findRayOperation(VoxelNode* node, void* extraData) { + RayArgs* args = static_cast(extraData); + AABox box; + node->getAABox(box); + float t; + if (!box.findRayIntersection(args->origin, args->direction, &t)) { + return false; + } + if (!node->isLeaf()) { + return true; // recurse on children + } + if (!args->found || t < *(args->t)) { + *(args->node) = node; + *(args->t) = t; + args->found = true; + } + return false; +} + +bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode** node, float* t) +{ + RayArgs args = { origin, direction, node, t }; + recurseTreeWithOperation(findRayOperation, &args); + return args.found; +} int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 309766bcd2..e0346ebdb5 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -61,6 +61,8 @@ public: bool isDirty() const { return _isDirty; }; void clearDirtyBit() { _isDirty = false; }; unsigned long int getNodesChangedFromBitstream() const { return _nodesChangedFromBitstream; }; + + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode** node, float* t); private: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, From 2fde890dc2a3f1642a50aface45578e2209ab9a7 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 18:27:40 -0700 Subject: [PATCH 12/30] added save/load persistant file on server startup --- voxel-server/src/main.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index dcf7588544..d029edaeff 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -43,6 +43,7 @@ int PACKETS_PER_CLIENT_PER_INTERVAL = 20; const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; VoxelTree randomTree; +bool wantVoxelPersist = true; bool wantColorRandomizer = false; bool debugVoxelSending = false; @@ -387,9 +388,30 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) { } } +void terminate (int sig) { + printf("terminating now...\n"); + if (::wantVoxelPersist) { + printf("saving voxels to file...\n"); + randomTree.writeToFileV2("voxels.hio2"); + printf("DONE saving voxels to file...\n"); + } + exit(EXIT_SUCCESS); +} + int main(int argc, const char * argv[]) { + signal(SIGABRT,&terminate); + signal(SIGTERM,&terminate); + signal(SIGINT,&terminate); + + // if we want Voxel Persistance, load the local file now... + if (::wantVoxelPersist) { + printf("loading voxels from file...\n"); + randomTree.readFromFileV2("voxels.hio2",true); + printf("DONE loading voxels from file...\n"); + } + AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); From 2c128fd8132acd3fc8eae309195279cce57ae40a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 19:19:48 -0700 Subject: [PATCH 13/30] added voxel-edit tool, as well as made voxel file read/write work, disabled voxel persist on server shutdown --- CMakeLists.txt | 3 +- libraries/voxels/src/VoxelTree.cpp | 35 ++++----- libraries/voxels/src/VoxelTree.h | 13 ++- voxel-edit/CMakeLists.txt | 26 ++++++ voxel-edit/src/main.cpp | 122 +++++++++++++++++++++++++++++ voxel-server/src/main.cpp | 17 ++-- 6 files changed, 182 insertions(+), 34 deletions(-) create mode 100644 voxel-edit/CMakeLists.txt create mode 100644 voxel-edit/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4a8d6c01..9af86e2891 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,4 +10,5 @@ add_subdirectory(interface) add_subdirectory(injector) add_subdirectory(pairing-server) add_subdirectory(space-server) -add_subdirectory(voxel-server) \ No newline at end of file +add_subdirectory(voxel-server) +add_subdirectory(voxel-edit) \ No newline at end of file diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index bfa59b965b..7a1fa48fa4 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -644,15 +644,14 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe return maxChildLevel; } -int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const ViewFrustum& viewFrustum, - unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag) { +int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, + VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const { // How many bytes have we written so far at this level; int bytesWritten = 0; // If we're at a node that is out of view, then we can return, because no nodes below us will be in view! - if (!node->isInView(viewFrustum)) { + if (viewFrustum && !node->isInView(*viewFrustum)) { return bytesWritten; } @@ -666,7 +665,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const Vi int currentEncodeLevel = 0; int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, - node, outputBuffer, availableBytes, bag, &viewFrustum); + node, outputBuffer, availableBytes, bag, viewFrustum); // if childBytesWritten == 1 then something went wrong... that's not possible assert(childBytesWritten != 1); @@ -865,21 +864,18 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco } void VoxelTree::readFromFileV2(const char* fileName, bool reset) { - std::ifstream file(fileName, std::ios::in|std::ios::binary); - + std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate); if(file.is_open()) { printLog("loading file...\n"); // get file length.... - unsigned long start = file.tellg(); - file.seekg( 0, std::ios::end ); - unsigned long end = file.tellg(); - unsigned long size = end - start; + unsigned long fileLength = file.tellg(); + file.seekg( 0, std::ios::beg ); // read the entire file into a buffer, WHAT!? Why not. - unsigned char* entireFile = new unsigned char[size]; - file.read((char*)entireFile, size); - readBitstreamToTree(entireFile,size); + unsigned char* entireFile = new unsigned char[fileLength]; + file.read((char*)entireFile, fileLength); + readBitstreamToTree(entireFile, fileLength); delete[] entireFile; file.close(); @@ -894,17 +890,14 @@ void VoxelTree::writeToFileV2(const char* fileName) const { VoxelNodeBag nodeBag; nodeBag.insert(rootNode); - static unsigned char tempOutputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static + static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static int bytesWritten = 0; - + while (!nodeBag.isEmpty()) { VoxelNode* subTree = nodeBag.extract(); - int currentEncodeLevel = 0; - bytesWritten = encodeTreeBitstreamRecursion(INT_MAX, currentEncodeLevel, subTree, - &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, - nodeBag, NULL); + bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, NULL); - file.write((const char*)&tempOutputBuffer[0], bytesWritten); + file.write((const char*)&outputBuffer[0], bytesWritten); } } file.close(); diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index db4f78b9b4..440345e119 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -53,9 +53,8 @@ public: void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); - int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const ViewFrustum& viewFrustum, - unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag); + int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, + VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const; int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); @@ -63,10 +62,6 @@ public: void clearDirtyBit() { _isDirty = false; }; unsigned long int getNodesChangedFromBitstream() const { return _nodesChangedFromBitstream; }; - int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, - VoxelNode* node, unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const; - // Note: this assumes the fileFormat is the HIO individual voxels code files void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); @@ -75,6 +70,10 @@ public: void readFromFileV2(const char* filename, bool reset); private: + int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, + VoxelNode* node, unsigned char* outputBuffer, int availableBytes, + VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const; + int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt new file mode 100644 index 0000000000..f7acb26e92 --- /dev/null +++ b/voxel-edit/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.8) + +set(TARGET_NAME voxel-edit) + +set(ROOT_DIR ..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") + +# set up the external glm library +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + +include(${MACRO_DIR}/SetupHifiProject.cmake) + +setup_hifi_project(${TARGET_NAME}) + +# link in the shared library +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) + +# link in the hifi voxels library +link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) + + diff --git a/voxel-edit/src/main.cpp b/voxel-edit/src/main.cpp new file mode 100644 index 0000000000..929b696650 --- /dev/null +++ b/voxel-edit/src/main.cpp @@ -0,0 +1,122 @@ +// +// main.cpp +// Voxel Edit +// +// Created by Brad Hefta-Gaub on 05/03/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include + +VoxelTree myTree; + +int _nodeCount=0; +bool countVoxelsOperation(VoxelNode* node, void* extraData) { + if (node->isColored()){ + _nodeCount++; + } + return true; // keep going +} + +void addScene(VoxelTree * tree) { + printf("adding scene...\n"); + + float voxelSize = 1.f/32; + + // Here's an example of how to create a voxel. + printf("creating corner points...\n"); + tree->createVoxel(0, 0, 0, voxelSize, 255, 255 ,255); + + // Here's an example of how to test if a voxel exists + VoxelNode* node = tree->getVoxelAt(0, 0, 0, voxelSize); + if (node) { + // and how to access it's color + printf("corner point 0,0,0 exists... color is (%d,%d,%d) \n", + node->getColor()[0], node->getColor()[1], node->getColor()[2]); + } + + // here's an example of how to delete a voxel + printf("attempting to delete corner point 0,0,0\n"); + tree->deleteVoxelAt(0, 0, 0, voxelSize); + + // Test to see that the delete worked... it should be FALSE... + if (tree->getVoxelAt(0, 0, 0, voxelSize)) { + printf("corner point 0,0,0 exists...\n"); + } else { + printf("corner point 0,0,0 does not exists...\n"); + } + + // Now some more examples... a little more complex + printf("creating corner points...\n"); + tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255); + + + tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 ); + tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 ); + tree->createVoxel(0 , 0 , 1.0 - voxelSize, voxelSize, 0 , 0 ,255); + tree->createVoxel(1.0 - voxelSize, 0 , 1.0 - voxelSize, voxelSize, 255, 0 ,255); + tree->createVoxel(0 , 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 0 , 255 ,255); + tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 0 , voxelSize, 255, 255 ,0 ); + tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 255, 255 ,255); + printf("DONE creating corner points...\n"); + + // Now some more examples... creating some lines using the line primitive + printf("creating voxel lines...\n"); + float lineVoxelSize = 0.99f/256; + rgbColor red = {255,0,0}; + rgbColor green = {0,255,0}; + rgbColor blue = {0,0,255}; + tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), lineVoxelSize, blue); + tree->createLine(glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), lineVoxelSize, red); + tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 1, 0), lineVoxelSize, green); + printf("DONE creating lines...\n"); + + // Now some more examples... creating some spheres using the sphere primitive + int sphereBaseSize = 512; + printf("creating spheres...\n"); + tree->createSphere(0.25, 0.5, 0.5, 0.5, (1.0 / sphereBaseSize), true, false); + printf("one sphere added...\n"); + tree->createSphere(0.030625, 0.5, 0.5, (0.25-0.06125), (1.0 / (sphereBaseSize * 2)), true, true); + + + printf("two spheres added...\n"); + tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), (0.75 - 0.06125), (1.0 / (sphereBaseSize * 2)), true, true); + printf("three spheres added...\n"); + tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), 0.06125, (1.0 / (sphereBaseSize * 2)), true, true); + printf("four spheres added...\n"); + tree->createSphere(0.030625, (0.75 - 0.030625), 0.06125, (0.75 - 0.06125), (1.0 / (sphereBaseSize * 2)), true, true); + printf("five spheres added...\n"); + tree->createSphere(0.06125, 0.125, 0.125, (0.75 - 0.125), (1.0 / (sphereBaseSize * 2)), true, true); + + float radius = 0.0125f; + printf("6 spheres added...\n"); + tree->createSphere(radius, 0.25, radius * 5.0f, 0.25, (1.0 / 4096), true, true); + printf("7 spheres added...\n"); + tree->createSphere(radius, 0.125, radius * 5.0f, 0.25, (1.0 / 4096), true, true); + printf("8 spheres added...\n"); + tree->createSphere(radius, 0.075, radius * 5.0f, 0.25, (1.0 / 4096), true, true); + printf("9 spheres added...\n"); + tree->createSphere(radius, 0.05, radius * 5.0f, 0.25, (1.0 / 4096), true, true); + printf("10 spheres added...\n"); + tree->createSphere(radius, 0.025, radius * 5.0f, 0.25, (1.0 / 4096), true, true); + printf("11 spheres added...\n"); + printf("DONE creating spheres...\n"); + + // Here's an example of how to recurse the tree and do some operation on the nodes as you recurse them. + // This one is really simple, it just couts them... + // Look at the function countVoxelsOperation() for an example of how you could use this function + _nodeCount=0; + tree->recurseTreeWithOperation(countVoxelsOperation); + printf("Nodes after adding scene %d nodes\n", _nodeCount); + + printf("DONE adding scene of spheres...\n"); +} + + +int main(int argc, const char * argv[]) +{ + addScene(&myTree); + myTree.writeToFileV2("voxels.hio2"); + + return 0; +} \ No newline at end of file diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index d029edaeff..678ef9ef00 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -284,9 +284,9 @@ void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAge while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL) { if (!agentData->nodeBag.isEmpty()) { VoxelNode* subTree = agentData->nodeBag.extract(); - bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree, viewFrustum, + bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, - agentData->nodeBag); + agentData->nodeBag, &viewFrustum); if (agentData->getAvailable() >= bytesWritten) { agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); @@ -390,7 +390,11 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) { void terminate (int sig) { printf("terminating now...\n"); - if (::wantVoxelPersist) { + if (false && ::wantVoxelPersist) { + _nodeCount=0; + ::randomTree.recurseTreeWithOperation(countVoxelsOperation); + printf("Nodes in scene before saving: %d nodes\n", _nodeCount); + printf("saving voxels to file...\n"); randomTree.writeToFileV2("voxels.hio2"); printf("DONE saving voxels to file...\n"); @@ -408,8 +412,11 @@ int main(int argc, const char * argv[]) // if we want Voxel Persistance, load the local file now... if (::wantVoxelPersist) { printf("loading voxels from file...\n"); - randomTree.readFromFileV2("voxels.hio2",true); + ::randomTree.readFromFileV2("voxels.hio2",true); printf("DONE loading voxels from file...\n"); + _nodeCount=0; + ::randomTree.recurseTreeWithOperation(countVoxelsOperation); + printf("Nodes after loading scene %d nodes\n", _nodeCount); } AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); @@ -418,7 +425,7 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* local = "--local"; bool wantLocalDomain = cmdOptionExists(argc, argv,local); - if (wantLocalDomain) { + if (true || wantLocalDomain) { printf("Local Domain MODE!\n"); int ip = getLocalAddress(); sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); From 48a597a9b9f760f018f6ca14baba6863e4ed9b43 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 19:29:25 -0700 Subject: [PATCH 14/30] added --wantVoxelPersist command line to server --- voxel-server/src/main.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 678ef9ef00..84ea769fbc 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -43,7 +43,7 @@ int PACKETS_PER_CLIENT_PER_INTERVAL = 20; const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; VoxelTree randomTree; -bool wantVoxelPersist = true; +bool wantVoxelPersist = false; bool wantColorRandomizer = false; bool debugVoxelSending = false; @@ -390,7 +390,10 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) { void terminate (int sig) { printf("terminating now...\n"); - if (false && ::wantVoxelPersist) { + + // This apparently does not work, because the randomTree has already been freed before this + // sig term handler runs... So, we need to find a better solution than this. + if (false) { _nodeCount=0; ::randomTree.recurseTreeWithOperation(countVoxelsOperation); printf("Nodes in scene before saving: %d nodes\n", _nodeCount); @@ -409,16 +412,6 @@ int main(int argc, const char * argv[]) signal(SIGTERM,&terminate); signal(SIGINT,&terminate); - // if we want Voxel Persistance, load the local file now... - if (::wantVoxelPersist) { - printf("loading voxels from file...\n"); - ::randomTree.readFromFileV2("voxels.hio2",true); - printf("DONE loading voxels from file...\n"); - _nodeCount=0; - ::randomTree.recurseTreeWithOperation(countVoxelsOperation); - printf("Nodes after loading scene %d nodes\n", _nodeCount); - } - AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); @@ -445,8 +438,22 @@ int main(int argc, const char * argv[]) ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); - // Check to see if the user passed in a command line option for loading a local - // Voxel File. If so, load it now. + const char* WANT_VOXEL_PERSIST = "--wantVoxelPersist"; + ::wantVoxelPersist = cmdOptionExists(argc, argv, WANT_VOXEL_PERSIST); + printf("wantVoxelPersist=%s\n", (::wantVoxelPersist ? "yes" : "no")); + + // if we want Voxel Persistance, load the local file now... + if (::wantVoxelPersist) { + printf("loading voxels from file...\n"); + ::randomTree.readFromFileV2("voxels.hio2",true); + printf("DONE loading voxels from file...\n"); + _nodeCount=0; + ::randomTree.recurseTreeWithOperation(countVoxelsOperation); + printf("Nodes after loading scene %d nodes\n", _nodeCount); + } + + // Check to see if the user passed in a command line option for loading an old style local + // Voxel File. If so, load it now. This is not the same as a voxel persist file const char* INPUT_FILE = "-i"; const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE); if (voxelsFilename) { From 286c6e0e39c9d55da567eba0b4bd740d93488687 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 19:36:30 -0700 Subject: [PATCH 15/30] fixed local domain --- voxel-server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 84ea769fbc..8d6be3dd40 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -418,7 +418,7 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* local = "--local"; bool wantLocalDomain = cmdOptionExists(argc, argv,local); - if (true || wantLocalDomain) { + if (wantLocalDomain) { printf("Local Domain MODE!\n"); int ip = getLocalAddress(); sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); From 196752667571b6865fd951521d235ebd6a5932e4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 May 2013 19:36:40 -0700 Subject: [PATCH 16/30] adding command options --- voxel-edit/src/main.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/voxel-edit/src/main.cpp b/voxel-edit/src/main.cpp index 929b696650..7592de00f4 100644 --- a/voxel-edit/src/main.cpp +++ b/voxel-edit/src/main.cpp @@ -7,6 +7,7 @@ // #include +#include VoxelTree myTree; @@ -115,8 +116,20 @@ void addScene(VoxelTree * tree) { int main(int argc, const char * argv[]) { - addScene(&myTree); - myTree.writeToFileV2("voxels.hio2"); + const char* SAY_HELLO = "--sayHello"; + if (cmdOptionExists(argc, argv, SAY_HELLO)) { + printf("I'm just saying hello...\n"); + } + + const char* DONT_CREATE_FILE = "--dontCreateSceneFile"; + bool dontCreateFile = cmdOptionExists(argc, argv, DONT_CREATE_FILE); + if (dontCreateFile) { + printf("You asked us not to create a scene file, so we will not.\n"); + } else { + printf("Creating Scene File...\n"); + addScene(&myTree); + myTree.writeToFileV2("voxels.hio2"); + } return 0; } \ No newline at end of file From ff4e21e50490c0ef947db7b7c5d24b3a78f47efb Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 3 May 2013 20:12:46 -0700 Subject: [PATCH 17/30] Remaining pick bits. --- libraries/voxels/src/AABox.cpp | 6 +++--- libraries/voxels/src/ViewFrustum.cpp | 4 ++++ libraries/voxels/src/ViewFrustum.h | 1 + libraries/voxels/src/VoxelTree.cpp | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index d79c36882c..1d85b3181a 100755 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -101,13 +101,13 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct } // check each direction float nt; - if (findIntersection(origin.x, direction.x, _corner.x, _size.x, &nt) && + if (findIntersection(origin.x, direction.x, _corner.x, _size.x, &nt) && nt >= 0 && isWithin(origin.y + nt*direction.y, _corner.y, _size.y) && isWithin(origin.z + nt*direction.z, _corner.z, _size.z) || - findIntersection(origin.y, direction.y, _corner.y, _size.y, &nt) && + findIntersection(origin.y, direction.y, _corner.y, _size.y, &nt) && nt >= 0 && isWithin(origin.x + nt*direction.x, _corner.x, _size.x) && isWithin(origin.z + nt*direction.z, _corner.z, _size.z) || - findIntersection(origin.z, direction.z, _corner.z, _size.z, &nt) && + findIntersection(origin.z, direction.z, _corner.z, _size.z, &nt) && nt >= 0 && isWithin(origin.y + nt*direction.y, _corner.y, _size.y) && isWithin(origin.x + nt*direction.x, _corner.x, _size.x)) { *t = nt; diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 8bdb2d97cb..4f725ff1b4 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -225,3 +225,7 @@ int ViewFrustum::boxInFrustum(const AABox& box) const { return(result); } +void ViewFrustum::computePickRay(float x, float y, glm::vec3* origin, glm::vec3* direction) const { + *origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft); + *direction = glm::normalize(*origin - _position); +} diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index d05bb9e1cf..feb1ecc8c6 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -98,6 +98,7 @@ public: int sphereInFrustum(const glm::vec3& center, float radius) const; int boxInFrustum(const AABox& box) const; + void computePickRay(float x, float y, glm::vec3* origin, glm::vec3* direction) const; }; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index a13675f00d..263c2f016e 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -577,7 +577,7 @@ bool findRayOperation(VoxelNode* node, void* extraData) { bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode** node, float* t) { - RayArgs args = { origin, direction, node, t }; + RayArgs args = { origin / (float)TREE_SCALE, direction, node, t }; recurseTreeWithOperation(findRayOperation, &args); return args.found; } From 5253485261dc068d07915e48140e1ff72cf60545 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 07:46:42 -0700 Subject: [PATCH 18/30] added TREE_SCALE to default camera farClip --- interface/src/Camera.cpp | 3 ++- libraries/voxels/src/VoxelConstants.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 74195a8761..1a417c6fb1 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -6,6 +6,7 @@ //--------------------------------------------------------------------- #include +#include // #include "Log.h" #include "Camera.h" @@ -16,7 +17,7 @@ Camera::Camera() { _tightness = 10.0; // default _fieldOfView = 60.0; // default _nearClip = 0.08; // default - _farClip = 50.0; // default + _farClip = 50.0 * TREE_SCALE; // default _modeShift = 0.0; _yaw = 0.0; _pitch = 0.0; diff --git a/libraries/voxels/src/VoxelConstants.h b/libraries/voxels/src/VoxelConstants.h index 8669ec7130..16bab45e4f 100644 --- a/libraries/voxels/src/VoxelConstants.h +++ b/libraries/voxels/src/VoxelConstants.h @@ -12,6 +12,8 @@ #ifndef __hifi_VoxelConstants_h__ #define __hifi_VoxelConstants_h__ +#include + const int MAX_VOXEL_PACKET_SIZE = 1492; const int MAX_TREE_SLICE_BYTES = 26; const int TREE_SCALE = 10; From 34565a4956c640f0edab7e6dd3f3eed9b6df271f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Sat, 4 May 2013 07:56:30 -0700 Subject: [PATCH 19/30] Pointers to references for in/out parameters, renamed line parameter to more descriptive "distance." --- libraries/voxels/src/AABox.cpp | 36 +++++++++++++++--------------- libraries/voxels/src/AABox.h | 2 +- libraries/voxels/src/VoxelTree.cpp | 18 +++++++-------- libraries/voxels/src/VoxelTree.h | 2 +- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index 1d85b3181a..3c28401c66 100755 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -80,37 +80,37 @@ bool AABox::contains(const glm::vec3& point) const { isWithin(point.z, _corner.z, _size.z); } -// finds the intersection between the closer plane in one direction -static bool findIntersection(float origin, float direction, float corner, float size, float* t) { +// finds the intersection between a ray and the facing plane on one axis +static bool findIntersection(float origin, float direction, float corner, float size, float& distance) { if (direction > EPSILON) { - *t = (corner - origin) / direction; + distance = (corner - origin) / direction; return true; } else if (direction < -EPSILON) { - *t = (corner + size - origin) / direction; + distance = (corner + size - origin) / direction; return true; } return false; } -bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float* t) const { +bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { // handle the trivial case where the box contains the origin if (contains(origin)) { - *t = 0; + distance = 0; return true; } - // check each direction - float nt; - if (findIntersection(origin.x, direction.x, _corner.x, _size.x, &nt) && nt >= 0 && - isWithin(origin.y + nt*direction.y, _corner.y, _size.y) && - isWithin(origin.z + nt*direction.z, _corner.z, _size.z) || - findIntersection(origin.y, direction.y, _corner.y, _size.y, &nt) && nt >= 0 && - isWithin(origin.x + nt*direction.x, _corner.x, _size.x) && - isWithin(origin.z + nt*direction.z, _corner.z, _size.z) || - findIntersection(origin.z, direction.z, _corner.z, _size.z, &nt) && nt >= 0 && - isWithin(origin.y + nt*direction.y, _corner.y, _size.y) && - isWithin(origin.x + nt*direction.x, _corner.x, _size.x)) { - *t = nt; + // check each axis + float axisDistance; + if (findIntersection(origin.x, direction.x, _corner.x, _size.x, axisDistance) && axisDistance >= 0 && + isWithin(origin.y + axisDistance*direction.y, _corner.y, _size.y) && + isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z) || + findIntersection(origin.y, direction.y, _corner.y, _size.y, axisDistance) && axisDistance >= 0 && + isWithin(origin.x + axisDistance*direction.x, _corner.x, _size.x) && + isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z) || + findIntersection(origin.z, direction.z, _corner.z, _size.z, axisDistance) && axisDistance >= 0 && + isWithin(origin.y + axisDistance*direction.y, _corner.y, _size.y) && + isWithin(origin.x + axisDistance*direction.x, _corner.x, _size.x)) { + distance = axisDistance; return true; } return false; diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 0dae354860..0184355de2 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -36,7 +36,7 @@ public: const glm::vec3& getSize() const { return _size; }; bool contains(const glm::vec3& point) const; - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float* t) const; + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const; private: glm::vec3 _corner; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 263c2f016e..23027de420 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -551,8 +551,8 @@ class RayArgs { public: glm::vec3 origin; glm::vec3 direction; - VoxelNode** node; - float* t; + VoxelNode*& node; + float& distance; bool found; }; @@ -560,24 +560,24 @@ bool findRayOperation(VoxelNode* node, void* extraData) { RayArgs* args = static_cast(extraData); AABox box; node->getAABox(box); - float t; - if (!box.findRayIntersection(args->origin, args->direction, &t)) { + float distance; + if (!box.findRayIntersection(args->origin, args->direction, distance)) { return false; } if (!node->isLeaf()) { return true; // recurse on children } - if (!args->found || t < *(args->t)) { - *(args->node) = node; - *(args->t) = t; + if (!args->found || distance < args->distance) { + args->node = node; + args->distance = distance; args->found = true; } return false; } -bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode** node, float* t) +bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode*& node, float& distance) { - RayArgs args = { origin / (float)TREE_SCALE, direction, node, t }; + RayArgs args = { origin / (float)TREE_SCALE, direction, node, distance }; recurseTreeWithOperation(findRayOperation, &args); return args.found; } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index e0346ebdb5..221a04138b 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -62,7 +62,7 @@ public: void clearDirtyBit() { _isDirty = false; }; unsigned long int getNodesChangedFromBitstream() const { return _nodesChangedFromBitstream; }; - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode** node, float* t); + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode*& node, float& distance); private: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, From aff465b17bef372f877275aa82561fb4ac0df841 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Sat, 4 May 2013 07:59:45 -0700 Subject: [PATCH 20/30] Missed a spot with the conversion from pointers to references. --- libraries/voxels/src/ViewFrustum.cpp | 6 +++--- libraries/voxels/src/ViewFrustum.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 4f725ff1b4..999c1c3efd 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -225,7 +225,7 @@ int ViewFrustum::boxInFrustum(const AABox& box) const { return(result); } -void ViewFrustum::computePickRay(float x, float y, glm::vec3* origin, glm::vec3* direction) const { - *origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft); - *direction = glm::normalize(*origin - _position); +void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const { + origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft); + direction = glm::normalize(origin - _position); } diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index feb1ecc8c6..291697f2b9 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -98,7 +98,7 @@ public: int sphereInFrustum(const glm::vec3& center, float radius) const; int boxInFrustum(const AABox& box) const; - void computePickRay(float x, float y, glm::vec3* origin, glm::vec3* direction) const; + void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const; }; From 7d1e271c39c4c99b0cc1707bbfd10ae4e246c135 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 08:23:06 -0700 Subject: [PATCH 21/30] fix bug in bogus avatar data file --- interface/src/Avatar.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 675d4ce1c0..3cf38f1527 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1556,6 +1556,15 @@ void Avatar::readAvatarDataFromFile() { FILE* avatarFile = fopen(AVATAR_DATA_FILENAME, "r"); if (avatarFile) { - fscanf(avatarFile, "%f,%f,%f %f", &_position.x, &_position.y, &_position.z, &_bodyYaw); + glm::vec3 readPosition; + float readYaw; + fscanf(avatarFile, "%f,%f,%f %f", &readPosition.x, &readPosition.y, &readPosition.z, &readYaw); + + // make sure these values are sane + if (!isnan(readPosition.x) && !isnan(readPosition.y) && !isnan(readPosition.z) && !isnan(readYaw)) { + _position = readPosition; + _bodyYaw = readYaw; + } + fclose(avatarFile); } } From 3ed19ccb91a5f4b36b6d308a64fbacdc878b9665 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 08:28:00 -0700 Subject: [PATCH 22/30] fixed comment --- libraries/voxels/src/VoxelTree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 440345e119..3eb53309a5 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -65,7 +65,7 @@ public: // Note: this assumes the fileFormat is the HIO individual voxels code files void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); - // these will read/write files that match the wireformat, including the 'V' leading + // these will read/write files that match the wireformat, excluding the 'V' leading void writeToFileV2(const char* filename) const; void readFromFileV2(const char* filename, bool reset); From c1847a75118bb635297fee22b7d42206bc7173eb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 09:19:46 -0700 Subject: [PATCH 23/30] set dirty bit on tree in a couple new places --- libraries/voxels/src/VoxelTree.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 7a1fa48fa4..05473ef711 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -262,10 +262,6 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer) { int lengthInBytes = bytesRequiredForCodeLength(*codeBuffer); // includes octet count, not color! if (0 == memcmp(nodeToDelete->octalCode,codeBuffer,lengthInBytes)) { - - float* vertices = firstVertexForCode(nodeToDelete->octalCode); - delete[] vertices; - if (parentNode) { int childIndex = branchIndexWithDescendant(parentNode->octalCode, codeBuffer); @@ -273,6 +269,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer) { parentNode->children[childIndex] = NULL; // set it to NULL reaverageVoxelColors(rootNode); // Fix our colors!! Need to call it on rootNode + _isDirty = true; } } } @@ -283,6 +280,7 @@ void VoxelTree::eraseAllVoxels() { rootNode = new VoxelNode(); rootNode->octalCode = new unsigned char[1]; *rootNode->octalCode = 0; + _isDirty = true; } void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { @@ -291,6 +289,7 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { // create the node if it does not exist if (*lastCreatedNode->octalCode != *codeColorBuffer) { lastCreatedNode = createMissingNode(lastCreatedNode, codeColorBuffer); + _isDirty = true; } // give this node its color @@ -300,6 +299,9 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { memcpy(newColor, codeColorBuffer + octalCodeBytes, 3); newColor[3] = 1; lastCreatedNode->setColor(newColor); + if (lastCreatedNode->isDirty()) { + _isDirty = true; + } } void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) { From 89eefe461dce44671cce6af1d318a68b478f628e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 09:20:22 -0700 Subject: [PATCH 24/30] persist voxels in main loop --- voxel-server/src/main.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 8d6be3dd40..e912852fa0 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -338,6 +338,16 @@ void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAge } } +void persistVoxelsWhenDirty() { + // check the dirty bit and persist here... + if (::wantVoxelPersist && ::randomTree.isDirty()) { + printf("saving voxels to file...\n"); + randomTree.writeToFileV2("voxels.hio2"); + randomTree.clearDirtyBit(); // tree is clean after saving + printf("DONE saving voxels to file...\n"); + } +} + void *distributeVoxelsToListeners(void *args) { AgentList* agentList = AgentList::getInstance(); @@ -390,18 +400,6 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) { void terminate (int sig) { printf("terminating now...\n"); - - // This apparently does not work, because the randomTree has already been freed before this - // sig term handler runs... So, we need to find a better solution than this. - if (false) { - _nodeCount=0; - ::randomTree.recurseTreeWithOperation(countVoxelsOperation); - printf("Nodes in scene before saving: %d nodes\n", _nodeCount); - - printf("saving voxels to file...\n"); - randomTree.writeToFileV2("voxels.hio2"); - printf("DONE saving voxels to file...\n"); - } exit(EXIT_SUCCESS); } @@ -446,6 +444,7 @@ int main(int argc, const char * argv[]) if (::wantVoxelPersist) { printf("loading voxels from file...\n"); ::randomTree.readFromFileV2("voxels.hio2",true); + ::randomTree.clearDirtyBit(); // the tree is clean since we just loaded it printf("DONE loading voxels from file...\n"); _nodeCount=0; ::randomTree.recurseTreeWithOperation(countVoxelsOperation); @@ -493,7 +492,7 @@ int main(int argc, const char * argv[]) pthread_t sendVoxelThread; pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL); - + sockaddr agentPublicAddress; unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; @@ -501,6 +500,9 @@ int main(int argc, const char * argv[]) // loop to send to agents requesting data while (true) { + // check to see if we need to persist our voxel state + persistVoxelsWhenDirty(); + if (agentList->getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) { // XXXBHG: Hacked in support for 'S' SET command if (packetData[0] == PACKET_HEADER_SET_VOXEL) { From 6a32424fb2a8435ed848aaf1ca66e3e100e5af46 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 09:41:10 -0700 Subject: [PATCH 25/30] make readFromFileV2() return bool for file exists --- libraries/voxels/src/VoxelTree.cpp | 4 +++- libraries/voxels/src/VoxelTree.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 05473ef711..26803272d7 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -865,7 +865,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco return bytesAtThisLevel; } -void VoxelTree::readFromFileV2(const char* fileName, bool reset) { +bool VoxelTree::readFromFileV2(const char* fileName) { std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate); if(file.is_open()) { printLog("loading file...\n"); @@ -881,7 +881,9 @@ void VoxelTree::readFromFileV2(const char* fileName, bool reset) { delete[] entireFile; file.close(); + return true; } + return false; } void VoxelTree::writeToFileV2(const char* fileName) const { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 3eb53309a5..7bd7ed5125 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -67,7 +67,7 @@ public: // these will read/write files that match the wireformat, excluding the 'V' leading void writeToFileV2(const char* filename) const; - void readFromFileV2(const char* filename, bool reset); + bool readFromFileV2(const char* filename); private: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, From eb56810ef2015bb37729cc064ffc92b700bfcd3a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 09:41:45 -0700 Subject: [PATCH 26/30] make default server behavior be voxel persistance --- voxel-server/src/main.cpp | 66 +++++++++++++-------------------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index e912852fa0..2d7288614d 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -43,7 +43,7 @@ int PACKETS_PER_CLIENT_PER_INTERVAL = 20; const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; VoxelTree randomTree; -bool wantVoxelPersist = false; +bool wantVoxelPersist = true; bool wantColorRandomizer = false; bool debugVoxelSending = false; @@ -81,49 +81,9 @@ void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) { float voxelSize = 1.f/32; printf("creating corner points...\n"); tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255); - - if (tree->getVoxelAt(0, 0, 0, voxelSize)) { - printf("corner point 0,0,0 exists...\n"); - } - - tree->deleteVoxelAt(0, 0, 0, voxelSize); - printf("attempting to delete corner point 0,0,0\n"); - - if (tree->getVoxelAt(0, 0, 0, voxelSize)) { - printf("corner point 0,0,0 exists...\n"); - } else { - printf("corner point 0,0,0 does not exists...\n"); - } - - printf("creating corner points...\n"); - tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255); - - printf("saving file voxels.hio2...\n"); - tree->writeToFileV2("voxels.hio2"); - printf("erasing all voxels...\n"); - tree->eraseAllVoxels(); - - if (tree->getVoxelAt(0, 0, 0, voxelSize)) { - printf("corner point 0,0,0 exists...\n"); - } else { - printf("corner point 0,0,0 does not exists...\n"); - } - - printf("loading file voxels.hio2...\n"); - tree->readFromFileV2("voxels.hio2",true); - - if (tree->getVoxelAt(0, 0, 0, voxelSize)) { - printf("corner point 0,0,0 exists...\n"); - } else { - printf("corner point 0,0,0 does not exists...\n"); - } - - tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 ); tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 ); tree->createVoxel(0 , 0 , 1.0 - voxelSize, voxelSize, 0 , 0 ,255); - - tree->createVoxel(1.0 - voxelSize, 0 , 1.0 - voxelSize, voxelSize, 255, 0 ,255); tree->createVoxel(0 , 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 0 , 255 ,255); tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 0 , voxelSize, 255, 255 ,0 ); @@ -436,14 +396,18 @@ int main(int argc, const char * argv[]) ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); - const char* WANT_VOXEL_PERSIST = "--wantVoxelPersist"; - ::wantVoxelPersist = cmdOptionExists(argc, argv, WANT_VOXEL_PERSIST); + // By default we will voxel persist, if you want to disable this, then pass in this parameter + const char* NO_VOXEL_PERSIST = "--NoVoxelPersist"; + if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) { + ::wantVoxelPersist = false; + } printf("wantVoxelPersist=%s\n", (::wantVoxelPersist ? "yes" : "no")); // if we want Voxel Persistance, load the local file now... + bool persistantFileRead = false; if (::wantVoxelPersist) { printf("loading voxels from file...\n"); - ::randomTree.readFromFileV2("voxels.hio2",true); + persistantFileRead = ::randomTree.readFromFileV2("voxels.hio2"); ::randomTree.clearDirtyBit(); // the tree is clean since we just loaded it printf("DONE loading voxels from file...\n"); _nodeCount=0; @@ -485,8 +449,20 @@ int main(int argc, const char * argv[]) addSphere(&randomTree,true,wantColorRandomizer); } + const char* ADD_SCENE = "--AddScene"; + bool addScene = cmdOptionExists(argc, argv, ADD_SCENE); const char* NO_ADD_SCENE = "--NoAddScene"; - if (!cmdOptionExists(argc, argv, NO_ADD_SCENE)) { + bool noAddScene = cmdOptionExists(argc, argv, NO_ADD_SCENE); + if (addScene && noAddScene) { + printf("WARNING! --AddScene and --NoAddScene are mutually exclusive. We will honor --NoAddScene\n"); + } + + // We will add a scene if... + // 1) we attempted to load a persistant file and it wasn't there + // 2) you asked us to add a scene + // HOWEVER -- we will NEVER add a scene if you explicitly tell us not to! + bool actuallyAddScene = !noAddScene && (addScene || (::wantVoxelPersist && !persistantFileRead)); + if (actuallyAddScene) { addSphereScene(&randomTree,wantColorRandomizer); } From 17fbc2347bd61b222e54c3bcdfb4ffd6323360ad Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 09:46:03 -0700 Subject: [PATCH 27/30] removed signal handlers, since we weren't using them and they were segfaulting --- voxel-server/src/main.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 2d7288614d..6eda2b0dbb 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -358,18 +358,8 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) { } } -void terminate (int sig) { - printf("terminating now...\n"); - exit(EXIT_SUCCESS); -} - - int main(int argc, const char * argv[]) { - signal(SIGABRT,&terminate); - signal(SIGTERM,&terminate); - signal(SIGINT,&terminate); - AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); From 0a488e358588a0848a628a79e9f86b25bb42ad9d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 09:48:11 -0700 Subject: [PATCH 28/30] whitespace fixes --- voxel-server/src/main.cpp | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 6eda2b0dbb..eec5bb308a 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -367,9 +367,9 @@ int main(int argc, const char * argv[]) const char* local = "--local"; bool wantLocalDomain = cmdOptionExists(argc, argv,local); if (wantLocalDomain) { - printf("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + printf("Local Domain MODE!\n"); + int ip = getLocalAddress(); + sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); } agentList->linkedDataCreateCallback = &attachVoxelAgentDataToAgent; @@ -378,20 +378,20 @@ int main(int argc, const char * argv[]) srand((unsigned)time(0)); - const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending"; + const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending"; ::debugVoxelSending = cmdOptionExists(argc, argv, DEBUG_VOXEL_SENDING); - printf("debugVoxelSending=%s\n", (::debugVoxelSending ? "yes" : "no")); - - const char* WANT_COLOR_RANDOMIZER = "--wantColorRandomizer"; + printf("debugVoxelSending=%s\n", (::debugVoxelSending ? "yes" : "no")); + + const char* WANT_COLOR_RANDOMIZER = "--wantColorRandomizer"; ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); + printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); // By default we will voxel persist, if you want to disable this, then pass in this parameter - const char* NO_VOXEL_PERSIST = "--NoVoxelPersist"; + const char* NO_VOXEL_PERSIST = "--NoVoxelPersist"; if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) { ::wantVoxelPersist = false; } - printf("wantVoxelPersist=%s\n", (::wantVoxelPersist ? "yes" : "no")); + printf("wantVoxelPersist=%s\n", (::wantVoxelPersist ? "yes" : "no")); // if we want Voxel Persistance, load the local file now... bool persistantFileRead = false; @@ -406,42 +406,42 @@ int main(int argc, const char * argv[]) } // Check to see if the user passed in a command line option for loading an old style local - // Voxel File. If so, load it now. This is not the same as a voxel persist file - const char* INPUT_FILE = "-i"; + // Voxel File. If so, load it now. This is not the same as a voxel persist file + const char* INPUT_FILE = "-i"; const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE); if (voxelsFilename) { - randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer); - } - - // Check to see if the user passed in a command line option for setting packet send rate - const char* PACKETS_PER_SECOND = "--packetsPerSecond"; - const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND); - if (packetsPerSecond) { - PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/10; - if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) { - PACKETS_PER_CLIENT_PER_INTERVAL = 1; - } - printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL); - } - - const char* ADD_RANDOM_VOXELS = "--AddRandomVoxels"; - if (cmdOptionExists(argc, argv, ADD_RANDOM_VOXELS)) { - // 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); - } - - const char* ADD_SPHERE = "--AddSphere"; - const char* ADD_RANDOM_SPHERE = "--AddRandomSphere"; - if (cmdOptionExists(argc, argv, ADD_SPHERE)) { - addSphere(&randomTree,false,wantColorRandomizer); - } else if (cmdOptionExists(argc, argv, ADD_RANDOM_SPHERE)) { - addSphere(&randomTree,true,wantColorRandomizer); + randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer); } - const char* ADD_SCENE = "--AddScene"; + // Check to see if the user passed in a command line option for setting packet send rate + const char* PACKETS_PER_SECOND = "--packetsPerSecond"; + const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND); + if (packetsPerSecond) { + PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/10; + if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) { + PACKETS_PER_CLIENT_PER_INTERVAL = 1; + } + printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL); + } + + const char* ADD_RANDOM_VOXELS = "--AddRandomVoxels"; + if (cmdOptionExists(argc, argv, ADD_RANDOM_VOXELS)) { + // 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); + } + + const char* ADD_SPHERE = "--AddSphere"; + const char* ADD_RANDOM_SPHERE = "--AddRandomSphere"; + if (cmdOptionExists(argc, argv, ADD_SPHERE)) { + addSphere(&randomTree,false,wantColorRandomizer); + } else if (cmdOptionExists(argc, argv, ADD_RANDOM_SPHERE)) { + addSphere(&randomTree,true,wantColorRandomizer); + } + + const char* ADD_SCENE = "--AddScene"; bool addScene = cmdOptionExists(argc, argv, ADD_SCENE); - const char* NO_ADD_SCENE = "--NoAddScene"; + const char* NO_ADD_SCENE = "--NoAddScene"; bool noAddScene = cmdOptionExists(argc, argv, NO_ADD_SCENE); if (addScene && noAddScene) { printf("WARNING! --AddScene and --NoAddScene are mutually exclusive. We will honor --NoAddScene\n"); @@ -452,8 +452,8 @@ int main(int argc, const char * argv[]) // 2) you asked us to add a scene // HOWEVER -- we will NEVER add a scene if you explicitly tell us not to! bool actuallyAddScene = !noAddScene && (addScene || (::wantVoxelPersist && !persistantFileRead)); - if (actuallyAddScene) { - addSphereScene(&randomTree,wantColorRandomizer); + if (actuallyAddScene) { + addSphereScene(&randomTree,wantColorRandomizer); } pthread_t sendVoxelThread; From 34982227e49e16fd8e7457170f9dbe1e4c59e7a9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 May 2013 21:58:16 -0700 Subject: [PATCH 29/30] removed color reaveraging from readNodeData() because server will already send averages --- libraries/voxels/src/VoxelTree.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 26803272d7..fee0c698bb 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -157,16 +157,6 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, bytesRead += 3; } } - // average node's color based on color of children - bool nodeWasDirty = destinationNode->isDirty(); - destinationNode->setColorFromAverageOfChildren(); - bool nodeIsDirty = destinationNode->isDirty(); - if (nodeIsDirty) { - _isDirty = true; - } - if (!nodeWasDirty && nodeIsDirty) { - _nodesChangedFromBitstream++; - } // give this destination node the child mask from the packet unsigned char childMask = *(nodeData + bytesRead); From 37f1360542e28ff309f2f819e4b3035f3eed345d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 May 2013 10:39:36 -0700 Subject: [PATCH 30/30] fix spacing for gravity vector --- interface/src/SerialInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 44f256cd01..5878ab672e 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -287,7 +287,7 @@ void SerialInterface::resetSerial() { gettimeofday(&lastGoodRead, NULL); if (!USING_INVENSENSE_MPU9150) { - gravity = glm::vec3(0,-1,0); + gravity = glm::vec3(0, -1, 0); // Clear the measured and average channel data for (int i = 0; i < NUM_CHANNELS; i++) {