Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jeffrey Ventrella 2013-05-14 17:31:03 -07:00
commit a5e696b696
23 changed files with 2552 additions and 339 deletions

View file

@ -6,31 +6,31 @@
# #
# LIBOVR_FOUND - system found LibOVR # LIBOVR_FOUND - system found LibOVR
# LIBOVR_INCLUDE_DIRS - the LibOVR include directory # LIBOVR_INCLUDE_DIRS - the LibOVR include directory
# LIBOVR_LIBRARY - Link this to use LibOVR # LIBOVR_LIBRARIES - Link this to use LibOVR
# #
# Created on 5/9/2013 by Stephen Birarda # Created on 5/9/2013 by Stephen Birarda
# Copyright (c) 2013 High Fidelity # Copyright (c) 2013 High Fidelity
# #
if (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS) if (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
# in cache already # in cache already
set(LIBOVR_FOUND TRUE) set(LIBOVR_FOUND TRUE)
else (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS) else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
set(LIBOVR_INCLUDE_DIRS ${LIBOVR_ROOT_DIR}/Include) find_path(LIBOVR_INCLUDE_DIRS OVR.h ${LIBOVR_ROOT_DIR}/Include)
if (APPLE) if (APPLE)
set(LIBOVR_LIBRARY ${LIBOVR_ROOT_DIR}/Lib/MacOS/libovr.a) find_library(LIBOVR_LIBRARIES libovr.a ${LIBOVR_ROOT_DIR}/Lib/MacOS/)
else (WIN32) elseif (WIN32)
set(LIBOVR_LIBRARY ${LIBOVR_ROOT_DIR}/Lib/Win32/libovr.lib) find_library(LIBOVR_LIBRARIES libovr.lib ${LIBOVR_ROOT_DIR}/Lib/Win32/)
endif () endif ()
if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARY) if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES)
set(LIBOVR_FOUND TRUE) set(LIBOVR_FOUND TRUE)
endif (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARY) endif (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES)
if (LIBOVR_FOUND) if (LIBOVR_FOUND)
if (NOT LibOVR_FIND_QUIETLY) if (NOT LibOVR_FIND_QUIETLY)
message(STATUS "Found LibOVR: ${LIBOVR_LIBRARY}") message(STATUS "Found LibOVR: ${LIBOVR_LIBRARIES}")
endif (NOT LibOVR_FIND_QUIETLY) endif (NOT LibOVR_FIND_QUIETLY)
else (LIBOVR_FOUND) else (LIBOVR_FOUND)
if (LibOVR_FIND_REQUIRED) if (LibOVR_FIND_REQUIRED)
@ -38,7 +38,7 @@ else (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS)
endif (LibOVR_FIND_REQUIRED) endif (LibOVR_FIND_REQUIRED)
endif (LIBOVR_FOUND) endif (LIBOVR_FOUND)
# show the LIBOVR_INCLUDE_DIRS and LIBOVR_LIBRARY variables only in the advanced view # show the LIBOVR_INCLUDE_DIRS and LIBOVR_LIBRARIES variables only in the advanced view
mark_as_advanced(LIBOVR_INCLUDE_DIRS LIBOVR_LIBRARY) mark_as_advanced(LIBOVR_INCLUDE_DIRS LIBOVR_LIBRARIES)
endif (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS) endif (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)

View file

@ -6,34 +6,26 @@
# #
# LODEPNG_FOUND - system has LODEPNG_FOUND # LODEPNG_FOUND - system has LODEPNG_FOUND
# LODEPNG_INCLUDE_DIRS - the LodePNG include directory # LODEPNG_INCLUDE_DIRS - the LodePNG include directory
# LODEPNG_LIBRARY - Link these to use LodePNG # LODEPNG_LIBRARIES- Link these to use LodePNG
# #
# Copyright (c) 2013 Stephen Birarda <birarda@coffeeandpower.com> # Copyright (c) 2013 Stephen Birarda <birarda@coffeeandpower.com>
# #
if (LODEPNG_LIBRARY AND LODEPNG_INCLUDE_DIRS) if (LODEPNG_LIBRARIES AND LODEPNG_INCLUDE_DIRS)
# in cache already # in cache already
set(LODEPNG_FOUND TRUE) set(LODEPNG_FOUND TRUE)
else (LODEPNG_LIBRARY AND LODEPNG_INCLUDE_DIRS) else (LODEPNG_LIBRARIES AND LODEPNG_INCLUDE_DIRS)
FIND_PATH(LODEPNG_INCLUDE_DIR "lodepng.h" find_path(LODEPNG_INCLUDE_DIRS lodepng.h ${LODEPNG_ROOT_DIR})
PATHS ${LODEPNG_ROOT_DIR}) find_file(LODEPNG_LIBRARIES lodepng.cpp ${LODEPNG_ROOT_DIR})
set(LODEPNG_INCLUDE_DIRS if (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARIES)
${LODEPNG_INCLUDE_DIR}
)
set(LODEPNG_LIBRARY
${LODEPNG_ROOT_DIR}/lodepng.cpp
)
if (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARY)
set(LODEPNG_FOUND TRUE) set(LODEPNG_FOUND TRUE)
endif (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARY) endif (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARIES)
if (LODEPNG_FOUND) if (LODEPNG_FOUND)
if (NOT LodePNG_FIND_QUIETLY) if (NOT LodePNG_FIND_QUIETLY)
message(STATUS "Found LodePNG: ${LODEPNG_LIBRARY}") message(STATUS "Found LodePNG: ${LODEPNG_LIBRARIES}")
endif (NOT LodePNG_FIND_QUIETLY) endif (NOT LodePNG_FIND_QUIETLY)
else (LODEPNG_FOUND) else (LODEPNG_FOUND)
if (LodePNG_FIND_REQUIRED) if (LodePNG_FIND_REQUIRED)
@ -41,7 +33,7 @@ else (LODEPNG_LIBRARY AND LODEPNG_INCLUDE_DIRS)
endif (LodePNG_FIND_REQUIRED) endif (LodePNG_FIND_REQUIRED)
endif (LODEPNG_FOUND) endif (LODEPNG_FOUND)
# show the LODEPNG_INCLUDE_DIRS and LODEPNG_LIBRARY variables only in the advanced view # show the LODEPNG_INCLUDE_DIRS and LODEPNG_LIBRARIES variables only in the advanced view
mark_as_advanced(LODEPNG_INCLUDE_DIRS LODEPNG_LIBRARY) mark_as_advanced(LODEPNG_INCLUDE_DIRS LODEPNG_LIBRARIES)
endif (LODEPNG_LIBRARY AND LODEPNG_INCLUDE_DIRS) endif (LODEPNG_LIBRARIES AND LODEPNG_INCLUDE_DIRS)

View file

@ -6,31 +6,31 @@
# #
# PORTAUDIO_FOUND - system found PortAudio # PORTAUDIO_FOUND - system found PortAudio
# PORTAUDIO_INCLUDE_DIRS - the PortAudio include directory # PORTAUDIO_INCLUDE_DIRS - the PortAudio include directory
# PORTAUDIO_LIBRARY - Link this to use PortAudio # PORTAUDIO_LIBRARIES - Link this to use PortAudio
# #
# Created on 5/14/2013 by Stephen Birarda # Created on 5/14/2013 by Stephen Birarda
# Copyright (c) 2013 High Fidelity # Copyright (c) 2013 High Fidelity
# #
if (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS) if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
# in cache already # in cache already
set(PORTAUDIO_FOUND TRUE) set(PORTAUDIO_FOUND TRUE)
else (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS) else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
set(PORTAUDIO_INCLUDE_DIRS ${PORTAUDIO_ROOT_DIR}/include) find_path(PORTAUDIO_INCLUDE_DIRS portaudio.h ${PORTAUDIO_ROOT_DIR}/include)
if (APPLE) if (APPLE)
set(PORTAUDIO_LIBRARY ${PORTAUDIO_ROOT_DIR}/lib/MacOS/libportaudio.a) find_library(PORTAUDIO_LIBRARIES libportaudio.a ${PORTAUDIO_ROOT_DIR}/lib/MacOS/)
else (WIN32) elseif (UNIX)
set(PORTAUDIO_LIBRARY ${PORTAUDIO_ROOT_DIR}/lib/UNIX/libportaudio.a) find_library(PORTAUDIO_LIBRARIES libportaudio.a ${PORTAUDIO_ROOT_DIR}/lib/UNIX/)
endif () endif ()
if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARY) if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
set(PORTAUDIO_FOUND TRUE) set(PORTAUDIO_FOUND TRUE)
endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARY) endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
if (PORTAUDIO_FOUND) if (PORTAUDIO_FOUND)
if (NOT PortAudio_FIND_QUIETLY) if (NOT PortAudio_FIND_QUIETLY)
message(STATUS "Found PortAudio: ${PORTAUDIO_LIBRARY}") message(STATUS "Found PortAudio: ${PORTAUDIO_LIBRARIES}")
endif (NOT PortAudio_FIND_QUIETLY) endif (NOT PortAudio_FIND_QUIETLY)
else (PORTAUDIO_FOUND) else (PORTAUDIO_FOUND)
if (PortAudio_FIND_REQUIRED) if (PortAudio_FIND_REQUIRED)
@ -38,7 +38,7 @@ else (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS)
endif (PortAudio_FIND_REQUIRED) endif (PortAudio_FIND_REQUIRED)
endif (PORTAUDIO_FOUND) endif (PORTAUDIO_FOUND)
# show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARY variables only in the advanced view # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARY) mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
endif (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS) endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)

View file

@ -10,7 +10,7 @@ project(${TARGET_NAME})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/")
set(LODEPNG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LodePNG) set(LODEPNG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LodePNG)
set(LIBOVR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibOVR) set(LIBOVR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibOVR)
set(PORTAUDIO_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/portaudio) set(PORTAUDIO_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/PortAudio)
if (APPLE) if (APPLE)
set(GL_HEADERS "#include <GLUT/glut.h>\n#include <OpenGL/glext.h>") set(GL_HEADERS "#include <GLUT/glut.h>\n#include <OpenGL/glext.h>")
@ -55,7 +55,7 @@ if (APPLE)
SET(INTERFACE_SRCS ${INTERFACE_SRCS} ${INTERFACE_RSRCS}) SET(INTERFACE_SRCS ${INTERFACE_SRCS} ${INTERFACE_RSRCS})
endif (APPLE) endif (APPLE)
find_package(Qt4 REQUIRED QtCore QtGui) find_package(Qt4 REQUIRED QtCore QtGui QtOpenGL)
include(${QT_USE_FILE}) include(${QT_USE_FILE})
# run qt moc on qt-enabled headers # run qt moc on qt-enabled headers
@ -109,7 +109,7 @@ if (APPLE)
${GLUT} ${GLUT}
${OpenGL} ${OpenGL}
${IOKit} ${IOKit}
${LIBOVR_LIBRARY} ${LIBOVR_LIBRARIES}
) )
else (APPLE) else (APPLE)
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
@ -129,12 +129,12 @@ if (WIN32)
wsock32.lib wsock32.lib
) )
else (WIN32) else (WIN32)
target_link_libraries(${TARGET_NAME} ${LODEPNG_LIBRARY}) target_link_libraries(${TARGET_NAME} ${LODEPNG_LIBRARIES})
# link the PortAudio library # link the PortAudio library
find_package(PortAudio REQUIRED) find_package(PortAudio REQUIRED)
include_directories(${PORTAUDIO_INCLUDE_DIRS}) include_directories(${PORTAUDIO_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${PORTAUDIO_LIBRARY}) target_link_libraries(${TARGET_NAME} ${PORTAUDIO_LIBRARIES})
# link required libraries on UNIX # link required libraries on UNIX
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)

File diff suppressed because it is too large Load diff

View file

@ -9,16 +9,228 @@
#ifndef __interface__Application__ #ifndef __interface__Application__
#define __interface__Application__ #define __interface__Application__
#include <pthread.h>
#include <time.h>
#include <QApplication> #include <QApplication>
#include <AgentList.h>
#ifndef _WIN32
#include "Audio.h"
#endif
#include "Camera.h"
#include "Environment.h"
#include "HandControl.h"
#include "SerialInterface.h"
#include "Stars.h"
#include "ViewFrustum.h"
#include "VoxelSystem.h"
#include "ui/ChatEntry.h"
class QAction;
class QGLWidget;
class QKeyEvent;
class QMainWindow;
class QMouseEvent;
class QWheelEvent;
class Agent;
class ProgramObject;
class Application : public QApplication { class Application : public QApplication {
Q_OBJECT Q_OBJECT
public: public:
Application(int& argc, char** argv); Application(int& argc, char** argv);
public slots: void initializeGL();
void paintGL();
void resizeGL(int width, int height);
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent* event);
private slots:
void timer();
void idle();
void terminate();
void pair(); void pair();
void setHead(bool head);
void setNoise(bool noise);
void setFullscreen(bool fullscreen);
void setRenderFirstPerson(bool firstPerson);
void setOculus(bool oculus);
void setFrustumOffset(bool frustumOffset);
void cycleFrustumRenderMode();
void setDestructivePaint(bool destructive);
void setRenderWarnings(bool renderWarnings);
void doKillLocalVoxels();
void doRandomizeVoxelColors();
void doFalseRandomizeVoxelColors();
void doFalseRandomizeEveryOtherVoxelColors();
void doFalseColorizeByDistance();
void doFalseColorizeInView();
void doTrueVoxelColors();
void doTreeStats();
void setWantsMonochrome(bool wantsMonochrome);
void setWantsResIn(bool wantsResIn);
void setWantsDelta(bool wantsDelta);
void chooseVoxelPaintColor();
private:
void initMenu();
void updateFrustumRenderModeAction();
void initDisplay();
void init();
void updateAvatar(float deltaTime);
void loadViewFrustum(ViewFrustum& viewFrustum);
void displayOculus(Camera& whichCamera);
void displaySide(Camera& whichCamera);
void displayOverlay();
void displayStats();
void renderViewFrustum(ViewFrustum& viewFrustum);
void setupPaintingVoxel();
void shiftPaintingColor();
void addVoxelInFrontOfAvatar();
void addVoxelUnderCursor();
void deleteVoxelUnderCursor();
void resetSensors();
void setMenuShortcutsEnabled(bool enabled);
static void attachNewHeadToAgent(Agent *newAgent);
#ifndef _WIN32
static void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort);
#endif
static void* networkReceive(void* args);
QMainWindow* _window;
QGLWidget* _glWidget;
QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror?
QAction* _gyroLook; // Whether to allow the gyro data from head to move your view
QAction* _renderVoxels; // Whether to render voxels
QAction* _renderStarsOn; // Whether to display the stars
QAction* _renderAtmosphereOn; // Whether to display the atmosphere
QAction* _renderAvatarsOn; // Whether to render avatars
QAction* _oculusOn; // Whether to configure the display for the Oculus Rift
QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats
QAction* _logOn; // Whether to show on-screen log
QAction* _voxelPaintColor; // The color with which to paint voxels
QAction* _frustumOn; // Whether or not to display the debug view frustum
QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum
QAction* _cameraFrustum; // which frustum to look at
QAction* _frustumRenderModeAction;
SerialInterface _serialPort;
bool _displayLevels;
glm::vec3 _gravity;
// Frame Rate Measurement
int _frameCount;
float _fps;
timeval _applicationStartupTime;
timeval _timerStart, _timerEnd;
timeval _lastTimeIdle;
bool _justStarted;
Stars _stars;
VoxelSystem _voxels;
QByteArray _voxelsFilename;
bool _wantToKillLocalVoxels;
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
enum FrustumDrawMode { FRUSTUM_DRAW_MODE_ALL, FRUSTUM_DRAW_MODE_VECTORS, FRUSTUM_DRAW_MODE_PLANES,
FRUSTUM_DRAW_MODE_NEAR_PLANE, FRUSTUM_DRAW_MODE_FAR_PLANE, FRUSTUM_DRAW_MODE_COUNT };
FrustumDrawMode _frustumDrawingMode;
float _viewFrustumOffsetYaw; // the following variables control yaw, pitch, roll and distance form regular
float _viewFrustumOffsetPitch; // camera to the offset camera
float _viewFrustumOffsetRoll;
float _viewFrustumOffsetDistance;
float _viewFrustumOffsetUp;
float _mouseViewShiftYaw;
float _mouseViewShiftPitch;
Oscilloscope _audioScope;
Avatar _myAvatar; // The rendered avatar of oneself
Camera _myCamera; // My view onto the world
Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
Environment _environment;
int _headMouseX, _headMouseY;
HandControl _handControl;
int _mouseX;
int _mouseY;
bool _mousePressed; // true if mouse has been pressed (clear when finished)
// The current mode for mouse interaction
enum MouseMode { NO_EDIT_MODE, ADD_VOXEL_MODE, DELETE_VOXEL_MODE, COLOR_VOXEL_MODE };
MouseMode _mouseMode;
VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor
float _mouseVoxelScale; // the scale for adding/removing voxels
bool _paintOn; // Whether to paint voxels as you fly around
unsigned char _dominantColor; // The dominant color of the voxel we're painting
VoxelDetail _paintingVoxel; // The voxel we're painting if we're painting
bool _perfStatsOn; // Do we want to display perfStats?
bool _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive
ChatEntry _chatEntry; // chat entry field
bool _chatEntryOn; // Whether to show the chat entry
GLuint _oculusTextureID; // The texture to which we render for Oculus distortion
ProgramObject* _oculusProgram; // The GLSL program containing the distortion shader
float _oculusDistortionScale; // Controls the Oculus field of view
int _textureLocation;
int _lensCenterLocation;
int _screenCenterLocation;
int _scaleLocation;
int _scaleInLocation;
int _hmdWarpParamLocation;
#ifndef _WIN32
Audio _audio;
#endif
bool _enableNetworkThread;
pthread_t _networkReceiveThread;
bool _stopNetworkReceiveThread;
unsigned char _incomingPacket[MAX_PACKET_SIZE];
int _packetCount;
int _packetsPerSecond;
int _bytesPerSecond;
int _bytesCount;
}; };
#endif /* defined(__interface__Application__) */ #endif /* defined(__interface__Application__) */

View file

@ -1020,22 +1020,24 @@ VoxelNode* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const {
return _tree->getVoxelAt(x, y, z, s); return _tree->getVoxelAt(x, y, z, s);
}; };
void VoxelSystem::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue) { void VoxelSystem::createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
pthread_mutex_lock(&_treeLock); pthread_mutex_lock(&_treeLock);
//printLog("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s); //printLog("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);
_tree->createVoxel(x, y, z, s, red, green, blue); _tree->createVoxel(x, y, z, s, red, green, blue, destructive);
setupNewVoxelsForDrawing(); setupNewVoxelsForDrawing();
pthread_mutex_unlock(&_treeLock); pthread_mutex_unlock(&_treeLock);
}; };
void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color) { void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
_tree->createLine(point1, point2, unitSize, color); _tree->createLine(point1, point2, unitSize, color, destructive);
setupNewVoxelsForDrawing(); setupNewVoxelsForDrawing();
}; };
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug) { void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid,
_tree->createSphere(r, xc, yc, zc, s, solid, mode, debug); creationMode mode, bool destructive, bool debug) {
_tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug);
setupNewVoxelsForDrawing(); setupNewVoxelsForDrawing();
}; };

View file

@ -73,9 +73,11 @@ public:
void deleteVoxelAt(float x, float y, float z, float s); void deleteVoxelAt(float x, float y, float z, float s);
VoxelNode* getVoxelAt(float x, float y, float z, float s) const; 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 createVoxel(float x, float y, float z, float s,
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color); unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug = false); void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
creationMode mode, bool destructive = false, bool debug = false);
private: private:
int _callsToTreesToArrays; int _callsToTreesToArrays;

View file

@ -15,51 +15,6 @@
// Welcome Aboard! // Welcome Aboard!
// //
#include <math.h>
#include <string.h>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include "Syssocket.h"
#include "Systime.h"
#else
#include <sys/time.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#endif
#include <pthread.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "InterfaceConfig.h"
#include "Log.h"
#include "shared_Log.h"
#include "voxels_Log.h"
#include "avatars_Log.h"
#include "world.h"
#include "Util.h"
#ifndef _WIN32
#include "Audio.h"
#endif
#include "AngleUtil.h"
#include "Stars.h"
#include "ui/ChatEntry.h"
#include "ui/MenuRow.h"
#include "ui/MenuColumn.h"
#include "ui/Menu.h"
#include "ui/TextRenderer.h"
#include "renderer/ProgramObject.h"
#include "renderer/ShaderObject.h"
#include "Application.h" #include "Application.h"
#include "Camera.h" #include "Camera.h"
#include "Avatar.h" #include "Avatar.h"
@ -2088,125 +2043,9 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) {
int main(int argc, const char * argv[]) { int main(int argc, const char * argv[]) {
gettimeofday(&applicationStartupTime, NULL);
printLog("Interface Startup:\n");
voxels.setViewFrustum(&::viewFrustum);
shared_lib::printLog = & ::printLog;
voxels_lib::printLog = & ::printLog;
avatars_lib::printLog = & ::printLog;
unsigned int listenPort = AGENT_SOCKET_LISTEN_PORT;
const char* portStr = getCmdOption(argc, argv, "--listenPort");
if (portStr) {
listenPort = atoi(portStr);
}
AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort);
enableNetworkThread = !cmdOptionExists(argc, argv, "--nonblocking");
if (!enableNetworkThread) {
AgentList::getInstance()->getAgentSocket().setBlocking(false);
}
const char* domainIP = getCmdOption(argc, argv, "--domain");
if (domainIP) {
strcpy(DOMAIN_IP,domainIP);
}
// Handle Local Domain testing with the --local command line
if (cmdOptionExists(argc, argv, "--local")) {
printLog("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));
}
// the callback for our instance of AgentList is attachNewHeadToAgent
AgentList::getInstance()->linkedDataCreateCallback = &attachNewHeadToAgent;
#ifndef _WIN32
AgentList::getInstance()->audioMixerSocketUpdate = &audioMixerUpdate;
#endif
#ifdef _WIN32
WSADATA WsaData;
int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData);
#endif
// start the agentList threads
AgentList::getInstance()->startSilentAgentRemovalThread();
AgentList::getInstance()->startDomainServerCheckInThread();
AgentList::getInstance()->startPingUnknownAgentsThread();
glutInit(&argc, (char**)argv);
::screenWidth = glutGet(GLUT_SCREEN_WIDTH);
::screenHeight = glutGet(GLUT_SCREEN_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(::screenWidth, ::screenHeight);
glutCreateWindow("Interface");
printLog( "Created Display Window.\n" );
#ifdef _WIN32
glewInit();
printLog( "Glew Init complete.\n" );
#endif
// we need to create a QApplication instance in order to use Qt's font rendering
Application app(argc, const_cast<char**>(argv)); Application app(argc, const_cast<char**>(argv));
printLog( "Created QT Application.\n" ); printLog( "Created QT Application.\n" );
int exitCode = app.exec();
// Before we render anything, let's set up our viewFrustumOffsetCamera with a sufficiently large
// field of view and near and far clip to make it interesting.
//viewFrustumOffsetCamera.setFieldOfView(90.0);
viewFrustumOffsetCamera.setNearClip(0.1);
viewFrustumOffsetCamera.setFarClip(500.0*TREE_SCALE);
initMenu();
initDisplay();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutKeyboardUpFunc(keyUp);
glutSpecialFunc(specialkey);
glutSpecialUpFunc(specialkeyUp);
glutMotionFunc(motionFunc);
glutPassiveMotionFunc(mouseoverFunc);
glutMouseFunc(mouseFunc);
glutIdleFunc(idle);
printLog( "Initialized Display.\n" );
init();
printLog( "Init() complete.\n" );
// Check to see if the user passed in a command line option for randomizing colors
if (cmdOptionExists(argc, argv, "--NoColorRandomizer")) {
wantColorRandomizer = false;
}
// 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* voxelsFilename = getCmdOption(argc, argv, "-i");
if (voxelsFilename) {
voxels.loadVoxelsFile(voxelsFilename,wantColorRandomizer);
printLog("Local Voxel File loaded.\n");
}
// create thread for receipt of data via UDP
if (enableNetworkThread) {
pthread_create(&networkReceiveThread, NULL, networkReceive, NULL);
printLog("Network receive thread created.\n");
}
myAvatar.readAvatarDataFromFile();
glutTimerFunc(1000, Timer, 0);
glutMainLoop();
printLog("Normal exit.\n"); printLog("Normal exit.\n");
::terminate(); return exitCode;
return EXIT_SUCCESS;
} }

View file

@ -5,60 +5,71 @@
// Created by Andrzej Kapolka on 4/24/13. // Created by Andrzej Kapolka on 4/24/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
#include "InterfaceConfig.h" #include <QKeyEvent>
#include "ChatEntry.h" #include "ChatEntry.h"
#include "InterfaceConfig.h"
#include "Util.h" #include "Util.h"
using namespace std; using namespace std;
const int MAX_CONTENT_LENGTH = 140; const int MAX_CONTENT_LENGTH = 140;
ChatEntry::ChatEntry() : _cursorPos(0) {
}
void ChatEntry::clear() { void ChatEntry::clear() {
_contents.clear(); _contents.clear();
_cursorPos = 0; _cursorPos = 0;
} }
bool ChatEntry::key(unsigned char k) { bool ChatEntry::keyPressEvent(QKeyEvent* event) {
switch (k) { event->accept();
case '\r': switch (event->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
return false; return false;
case '\b': case Qt::Key_Escape:
clear();
return false;
case Qt::Key_Backspace:
if (_cursorPos != 0) { if (_cursorPos != 0) {
_contents.erase(_cursorPos - 1, 1); _contents.erase(_cursorPos - 1, 1);
_cursorPos--; _cursorPos--;
} }
return true; return true;
case 127: // delete case Qt::Key_Delete:
if (_cursorPos < _contents.size()) { if (_cursorPos < _contents.size()) {
_contents.erase(_cursorPos, 1); _contents.erase(_cursorPos, 1);
} }
return true; return true;
default: case Qt::Key_Left:
if (_contents.size() != MAX_CONTENT_LENGTH) {
_contents.insert(_cursorPos, 1, k);
_cursorPos++;
}
return true;
}
}
void ChatEntry::specialKey(unsigned char k) {
switch (k) {
case GLUT_KEY_LEFT:
if (_cursorPos != 0) { if (_cursorPos != 0) {
_cursorPos--; _cursorPos--;
} }
break; return true;
case GLUT_KEY_RIGHT: case Qt::Key_Right:
if (_cursorPos != _contents.size()) { if (_cursorPos != _contents.size()) {
_cursorPos++; _cursorPos++;
} }
break; return true;
default:
QString text = event->text();
if (text.isEmpty()) {
event->ignore();
return true;
}
if (_contents.size() != MAX_CONTENT_LENGTH) {
_contents.insert(_cursorPos, 1, text.at(0).toAscii());
_cursorPos++;
}
return true;
} }
} }
@ -74,5 +85,4 @@ void ChatEntry::render(int screenWidth, int screenHeight) {
glVertex2f(20 + width, screenHeight - 165); glVertex2f(20 + width, screenHeight - 165);
glVertex2f(20 + width, screenHeight - 150); glVertex2f(20 + width, screenHeight - 150);
glEnd(); glEnd();
glEnable(GL_LINE_SMOOTH);
} }

View file

@ -11,15 +11,18 @@
#include <string> #include <string>
class QKeyEvent;
class ChatEntry { class ChatEntry {
public: public:
ChatEntry();
const std::string& getContents() const { return _contents; } const std::string& getContents() const { return _contents; }
void clear(); void clear();
bool key(unsigned char k); bool keyPressEvent(QKeyEvent* event);
void specialKey(unsigned char k);
void render(int screenWidth, int screenHeight); void render(int screenWidth, int screenHeight);

View file

@ -108,8 +108,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
destinationBuffer += _chatMessage.size() * sizeof(char); destinationBuffer += _chatMessage.size() * sizeof(char);
// voxel sending features... // voxel sending features...
*destinationBuffer++ = _wantResIn; // voxel sending features...
*destinationBuffer++ = _wantColor; unsigned char wantItems = 0;
if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); }
if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); }
if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); }
*destinationBuffer++ = wantItems;
return destinationBuffer - bufferStart; return destinationBuffer - bufferStart;
} }
@ -117,6 +121,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
// called on the other agents - assigns it to my views of the others // called on the other agents - assigns it to my views of the others
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
//printf("AvatarData::parseData()\n");
// increment to push past the packet header // increment to push past the packet header
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA); sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
@ -184,8 +190,12 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
sourceBuffer += chatMessageSize * sizeof(char); sourceBuffer += chatMessageSize * sizeof(char);
// voxel sending features... // voxel sending features...
_wantResIn = (bool)*sourceBuffer++; unsigned char wantItems = 0;
_wantColor = (bool)*sourceBuffer++; wantItems = (unsigned char)*sourceBuffer++;
_wantResIn = oneAtBit(wantItems,WANT_RESIN_AT_BIT);
_wantColor = oneAtBit(wantItems,WANT_COLOR_AT_BIT);
_wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT);
return sourceBuffer - startPosition; return sourceBuffer - startPosition;
} }

View file

@ -15,6 +15,10 @@
#include <AgentData.h> #include <AgentData.h>
const int WANT_RESIN_AT_BIT = 0;
const int WANT_COLOR_AT_BIT = 1;
const int WANT_DELTA_AT_BIT = 2;
enum KeyState enum KeyState
{ {
NO_KEY_DOWN, NO_KEY_DOWN,
@ -124,8 +128,10 @@ public:
// related to Voxel Sending strategies // related to Voxel Sending strategies
bool getWantResIn() const { return _wantResIn; } bool getWantResIn() const { return _wantResIn; }
bool getWantColor() const { return _wantColor; } bool getWantColor() const { return _wantColor; }
bool getWantDelta() const { return _wantDelta; }
void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; }
void setWantColor(bool wantColor) { _wantColor = wantColor; } void setWantColor(bool wantColor) { _wantColor = wantColor; }
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
protected: protected:
glm::vec3 _position; glm::vec3 _position;
@ -168,8 +174,10 @@ protected:
// chat message // chat message
std::string _chatMessage; std::string _chatMessage;
// voxel server sending items
bool _wantResIn; bool _wantResIn;
bool _wantColor; bool _wantColor;
bool _wantDelta;
}; };
#endif /* defined(__hifi__AvatarData__) */ #endif /* defined(__hifi__AvatarData__) */

View file

@ -21,11 +21,13 @@ const PACKET_HEADER PACKET_HEADER_HEAD_DATA = 'H';
const PACKET_HEADER PACKET_HEADER_Z_COMMAND = 'Z'; const PACKET_HEADER PACKET_HEADER_Z_COMMAND = 'Z';
const PACKET_HEADER PACKET_HEADER_INJECT_AUDIO = 'I'; const PACKET_HEADER PACKET_HEADER_INJECT_AUDIO = 'I';
const PACKET_HEADER PACKET_HEADER_SET_VOXEL = 'S'; const PACKET_HEADER PACKET_HEADER_SET_VOXEL = 'S';
const PACKET_HEADER PACKET_HEADER_SET_VOXEL_DESTRUCTIVE = 'O';
const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E'; const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V'; const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v'; const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v';
const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X'; const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X';
const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA = 't'; const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA_V1 = 't';
const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA_V2 = 'T';
const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e'; const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e';
const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L'; const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L';
const PACKET_HEADER PACKET_HEADER_DOMAIN_RFD = 'C'; const PACKET_HEADER PACKET_HEADER_DOMAIN_RFD = 'C';

View file

@ -94,6 +94,11 @@ bool oneAtBit(unsigned char byte, int bitIndex) {
return (byte >> (7 - bitIndex) & 1); return (byte >> (7 - bitIndex) & 1);
} }
void setAtBit(unsigned char& byte, int bitIndex) {
byte += (1 << (7 - bitIndex));
}
void switchToResourcesParentIfRequired() { void switchToResourcesParentIfRequired() {
#ifdef __APPLE__ #ifdef __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle(); CFBundleRef mainBundle = CFBundleGetMainBundle();

View file

@ -49,6 +49,7 @@ void outputBits(unsigned char byte, bool withNewLine = true);
void printVoxelCode(unsigned char* voxelCode); void printVoxelCode(unsigned char* voxelCode);
int numberOfOnes(unsigned char byte); int numberOfOnes(unsigned char byte);
bool oneAtBit(unsigned char byte, int bitIndex); bool oneAtBit(unsigned char byte, int bitIndex);
void setAtBit(unsigned char& byte, int bitIndex);
void switchToResourcesParentIfRequired(); void switchToResourcesParentIfRequired();

View file

@ -276,3 +276,17 @@ void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3&
origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft); origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft);
direction = glm::normalize(origin - _position); direction = glm::normalize(origin - _position);
} }
void ViewFrustum::printDebugDetails() const {
printLog("ViewFrustum::printDebugDetails()... \n");
printLog("_position=%f,%f,%f\n", _position.x, _position.y, _position.z );
printLog("_direction=%f,%f,%f\n", _direction.x, _direction.y, _direction.z );
printLog("_up=%f,%f,%f\n", _up.x, _up.y, _up.z );
printLog("_right=%f,%f,%f\n", _right.x, _right.y, _right.z );
printLog("_fieldOfView=%f\n", _fieldOfView);
printLog("_aspectRatio=%f\n", _aspectRatio);
printLog("_nearClip=%f\n", _nearClip);
printLog("_farClip=%f\n", _farClip);
}

View file

@ -102,6 +102,8 @@ public:
bool matches(const ViewFrustum& compareTo) const; bool matches(const ViewFrustum& compareTo) const;
bool matches(const ViewFrustum* compareTo) const { return matches(*compareTo); }; bool matches(const ViewFrustum* compareTo) const { return matches(*compareTo); };
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;
void printDebugDetails() const;
}; };

View file

@ -103,7 +103,13 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char
int indexOfNewChild = branchIndexWithDescendant(lastParentNode->getOctalCode(), codeToReach); int indexOfNewChild = branchIndexWithDescendant(lastParentNode->getOctalCode(), codeToReach);
// we could be coming down a branch that was already created, so don't stomp on it. // we could be coming down a branch that was already created, so don't stomp on it.
if (!lastParentNode->getChildAtIndex(indexOfNewChild)) { if (lastParentNode->isLeaf() && lastParentNode->isColored()) {
// for colored leaves, we must add *all* the children
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
lastParentNode->addChildAtIndex(i);
lastParentNode->getChildAtIndex(i)->setColor(lastParentNode->getColor());
}
} else if (!lastParentNode->getChildAtIndex(indexOfNewChild)) {
lastParentNode->addChildAtIndex(indexOfNewChild); lastParentNode->addChildAtIndex(indexOfNewChild);
} }
@ -287,7 +293,7 @@ void VoxelTree::eraseAllVoxels() {
_isDirty = true; _isDirty = true;
} }
void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive) {
VoxelNode* lastCreatedNode = nodeForOctalCode(rootNode, codeColorBuffer, NULL); VoxelNode* lastCreatedNode = nodeForOctalCode(rootNode, codeColorBuffer, NULL);
// create the node if it does not exist // create the node if it does not exist
@ -297,19 +303,27 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
} else { } else {
// if it does exist, make sure it has no children // if it does exist, make sure it has no children
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
lastCreatedNode->deleteChildAtIndex(i); if (lastCreatedNode->getChildAtIndex(i)) {
if (destructive) {
lastCreatedNode->deleteChildAtIndex(i);
} else {
printLog("WARNING! operation would require deleting child at index %d, add Voxel ignored!\n ", i);
}
}
} }
} }
// give this node its color if (lastCreatedNode->isLeaf()) {
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer); // give this node its color
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer);
nodeColor newColor; nodeColor newColor;
memcpy(newColor, codeColorBuffer + octalCodeBytes, 3); memcpy(newColor, codeColorBuffer + octalCodeBytes, 3);
newColor[3] = 1; newColor[3] = 1;
lastCreatedNode->setColor(newColor); lastCreatedNode->setColor(newColor);
if (lastCreatedNode->isDirty()) { if (lastCreatedNode->isDirty()) {
_isDirty = true; _isDirty = true;
}
} }
} }
@ -463,14 +477,15 @@ VoxelNode* VoxelTree::getVoxelAt(float x, float y, float z, float s) const {
return node; return node;
} }
void VoxelTree::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue) { void VoxelTree::createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue); unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
this->readCodeColorBufferToTree(voxelData); this->readCodeColorBufferToTree(voxelData, destructive);
delete voxelData; delete voxelData;
} }
void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color) { void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
glm::vec3 distance = point2 - point1; glm::vec3 distance = point2 - point1;
glm::vec3 items = distance / unitSize; glm::vec3 items = distance / unitSize;
int maxItems = std::max(items.x, std::max(items.y, items.z)); int maxItems = std::max(items.x, std::max(items.y, items.z));
@ -478,14 +493,12 @@ void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, r
glm::vec3 pointAt = point1; glm::vec3 pointAt = point1;
for (int i = 0; i <= maxItems; i++ ) { for (int i = 0; i <= maxItems; i++ ) {
pointAt += increment; pointAt += increment;
unsigned char* voxelData = pointToVoxel(pointAt.x,pointAt.y,pointAt.z,unitSize,color[0],color[1],color[2]); createVoxel(pointAt.x, pointAt.y, pointAt.z, unitSize, color[0], color[1], color[2], destructive);
readCodeColorBufferToTree(voxelData);
delete voxelData;
} }
} }
void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float voxelSize, void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float voxelSize,
bool solid, creationMode mode, bool debug) { bool solid, creationMode mode, bool destructive, bool debug) {
bool wantColorRandomizer = (mode == RANDOM); bool wantColorRandomizer = (mode == RANDOM);
bool wantNaturalSurface = (mode == NATURAL); bool wantNaturalSurface = (mode == NATURAL);
@ -601,13 +614,13 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v
x = xc + (thisRadius + i * subVoxelScale) * cos(theta) * sin(phi); x = xc + (thisRadius + i * subVoxelScale) * cos(theta) * sin(phi);
y = yc + (thisRadius + i * subVoxelScale) * sin(theta) * sin(phi); y = yc + (thisRadius + i * subVoxelScale) * sin(theta) * sin(phi);
z = zc + (thisRadius + i * subVoxelScale) * cos(phi); z = zc + (thisRadius + i * subVoxelScale) * cos(phi);
this->createVoxel(x, y, z, subVoxelScale, red, green, blue); this->createVoxel(x, y, z, subVoxelScale, red, green, blue, destructive);
} }
naturalSurfaceRendered = true; naturalSurfaceRendered = true;
} }
} }
if (!naturalSurfaceRendered) { if (!naturalSurfaceRendered) {
this->createVoxel(x, y, z, thisVoxelSize, red, green, blue); this->createVoxel(x, y, z, thisVoxelSize, red, green, blue, destructive);
} }
} }
} }
@ -617,12 +630,14 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v
this->reaverageVoxelColors(this->rootNode); this->reaverageVoxelColors(this->rootNode);
} }
int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag) { int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) {
// call the recursive version, this will add all found colored node roots to the bag // call the recursive version, this will add all found colored node roots to the bag
int currentSearchLevel = 0; int currentSearchLevel = 0;
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode, viewFrustum, bag); int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode,
viewFrustum, bag, deltaViewFrustum, lastViewFrustum);
return levelReached; return levelReached;
} }
@ -667,7 +682,8 @@ bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& di
} }
int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag) { VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) {
// Keep track of how deep we've searched. // Keep track of how deep we've searched.
currentSearchLevel++; currentSearchLevel++;
@ -702,7 +718,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
bool childIsColored = (childNode && childNode->isColored()); bool childIsColored = (childNode && childNode->isColored());
bool childIsInView = (childNode && childNode->isInView(viewFrustum)); bool childIsInView = (childNode && childNode->isInView(viewFrustum));
bool childIsLeaf = (childNode && childNode->isLeaf()); bool childIsLeaf = (childNode && childNode->isLeaf());
if (childIsInView) { if (childIsInView) {
// track children in view as existing and not a leaf // track children in view as existing and not a leaf
@ -739,7 +755,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
for (int i = 0; i < inViewCount; i++) { for (int i = 0; i < inViewCount; i++) {
VoxelNode* childNode = inViewChildren[i]; VoxelNode* childNode = inViewChildren[i];
thisLevel = currentSearchLevel; // reset this, since the children will munge it up thisLevel = currentSearchLevel; // reset this, since the children will munge it up
int childLevelReached = searchForColoredNodesRecursion(maxSearchLevel, thisLevel, childNode, viewFrustum, bag); int childLevelReached = searchForColoredNodesRecursion(maxSearchLevel, thisLevel, childNode, viewFrustum, bag,
deltaViewFrustum, lastViewFrustum);
maxChildLevel = std::max(maxChildLevel, childLevelReached); maxChildLevel = std::max(maxChildLevel, childLevelReached);
} }
} }
@ -747,7 +764,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
} }
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const { VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
// How many bytes have we written so far at this level; // How many bytes have we written so far at this level;
int bytesWritten = 0; int bytesWritten = 0;
@ -767,7 +785,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int currentEncodeLevel = 0; int currentEncodeLevel = 0;
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel,
node, outputBuffer, availableBytes, bag, viewFrustum, includeColor); node, outputBuffer, availableBytes, bag, viewFrustum, includeColor,
deltaViewFrustum, lastViewFrustum);
// if childBytesWritten == 1 then something went wrong... that's not possible // if childBytesWritten == 1 then something went wrong... that's not possible
assert(childBytesWritten != 1); assert(childBytesWritten != 1);
@ -790,7 +809,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const { VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
// How many bytes have we written so far at this level; // How many bytes have we written so far at this level;
int bytesAtThisLevel = 0; int bytesAtThisLevel = 0;
@ -846,6 +866,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
VoxelNode* childNode = node->getChildAtIndex(i); VoxelNode* childNode = node->getChildAtIndex(i);
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum))); bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
if (childIsInView) { if (childIsInView) {
// Before we determine consider this further, let's see if it's in our LOD scope... // Before we determine consider this further, let's see if it's in our LOD scope...
float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0; float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0;
@ -861,9 +882,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
childrenExistBits += (1 << (7 - i)); childrenExistBits += (1 << (7 - i));
inViewNotLeafCount++; inViewNotLeafCount++;
} }
bool childWasInView = (childNode && deltaViewFrustum &&
(lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*lastViewFrustum)));
// track children with actual color // track children with actual color, only if the child wasn't previously in view!
if (childNode && childNode->isColored()) { if (childNode && childNode->isColored() && !childWasInView) {
childrenColoredBits += (1 << (7 - i)); childrenColoredBits += (1 << (7 - i));
inViewWithColorCount++; inViewWithColorCount++;
} }
@ -925,7 +949,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
int thisLevel = currentEncodeLevel; int thisLevel = currentEncodeLevel;
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode, int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
outputBuffer, availableBytes, bag, outputBuffer, availableBytes, bag,
viewFrustum, includeColor); viewFrustum, includeColor,
deltaViewFrustum, lastViewFrustum);
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space, // 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. // basically, the children below don't contain any info.

View file

@ -22,42 +22,46 @@ typedef enum {GRADIENT, RANDOM, NATURAL} creationMode;
class VoxelTree { class VoxelTree {
public: public:
// when a voxel is created in the tree (object new'd) // when a voxel is created in the tree (object new'd)
long voxelsCreated; long voxelsCreated;
// when a voxel is colored/set in the tree (object may have already existed) // when a voxel is colored/set in the tree (object may have already existed)
long voxelsColored; long voxelsColored;
long voxelsBytesRead; long voxelsBytesRead;
SimpleMovingAverage voxelsCreatedStats; SimpleMovingAverage voxelsCreatedStats;
SimpleMovingAverage voxelsColoredStats; SimpleMovingAverage voxelsColoredStats;
SimpleMovingAverage voxelsBytesReadStats; SimpleMovingAverage voxelsBytesReadStats;
VoxelTree(); VoxelTree();
~VoxelTree(); ~VoxelTree();
VoxelNode *rootNode; VoxelNode *rootNode;
int leavesWrittenToBitstream; int leavesWrittenToBitstream;
void eraseAllVoxels(); void eraseAllVoxels();
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes); void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor = true); void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor = true);
void readCodeColorBufferToTree(unsigned char *codeColorBuffer); void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false);
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false); void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
void printTreeForDebugging(VoxelNode *startNode); void printTreeForDebugging(VoxelNode *startNode);
void reaverageVoxelColors(VoxelNode *startNode); void reaverageVoxelColors(VoxelNode *startNode);
void deleteVoxelAt(float x, float y, float z, float s, bool stage = false); void deleteVoxelAt(float x, float y, float z, float s, bool stage = false);
VoxelNode* getVoxelAt(float x, float y, float z, float s) const; 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 createVoxel(float x, float y, float z, float s,
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color); unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug = false); void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
creationMode mode, bool destructive = false, bool debug = false);
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor = true) const; VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor = true,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const;
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL);
bool isDirty() const { return _isDirty; }; bool isDirty() const { return _isDirty; };
void clearDirtyBit() { _isDirty = false; }; void clearDirtyBit() { _isDirty = false; };
@ -68,7 +72,7 @@ public:
VoxelNode*& node, float& distance, BoxFace& face); VoxelNode*& node, float& distance, BoxFace& face);
// Note: this assumes the fileFormat is the HIO individual voxels code files // Note: this assumes the fileFormat is the HIO individual voxels code files
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
// these will read/write files that match the wireformat, excluding the 'V' leading // these will read/write files that match the wireformat, excluding the 'V' leading
void writeToFileV2(const char* filename) const; void writeToFileV2(const char* filename) const;
@ -79,10 +83,12 @@ public:
private: private:
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const; VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum);
static bool countVoxelsOperation(VoxelNode* node, void* extraData); static bool countVoxelsOperation(VoxelNode* node, void* extraData);

View file

@ -22,6 +22,7 @@ void VoxelAgentData::init() {
_maxSearchLevel = 1; _maxSearchLevel = 1;
_maxLevelReachedInLastSearch = 1; _maxLevelReachedInLastSearch = 1;
resetVoxelPacket(); resetVoxelPacket();
_viewSent = false;
} }
void VoxelAgentData::resetVoxelPacket() { void VoxelAgentData::resetVoxelPacket() {
@ -50,3 +51,31 @@ VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
VoxelAgentData* VoxelAgentData::clone() const { VoxelAgentData* VoxelAgentData::clone() const {
return new VoxelAgentData(*this); return new VoxelAgentData(*this);
} }
bool VoxelAgentData::updateCurrentViewFrustum() {
bool currentViewFrustumChanged = false;
ViewFrustum newestViewFrustum;
// get position and orientation details from the camera
newestViewFrustum.setPosition(getCameraPosition());
newestViewFrustum.setOrientation(getCameraDirection(), getCameraUp(), getCameraRight());
// Also make sure it's got the correct lens details from the camera
newestViewFrustum.setFieldOfView(getCameraFov());
newestViewFrustum.setAspectRatio(getCameraAspectRatio());
newestViewFrustum.setNearClip(getCameraNearClip());
newestViewFrustum.setFarClip(getCameraFarClip());
// if there has been a change, then recalculate
if (!newestViewFrustum.matches(_currentViewFrustum)) {
_currentViewFrustum = newestViewFrustum;
_currentViewFrustum.calculate();
currentViewFrustumChanged = true;
}
return currentViewFrustumChanged;
}
void VoxelAgentData::updateLastKnownViewFrustum() {
// save our currentViewFrustum into our lastKnownViewFrustum
_lastKnownViewFrustum = _currentViewFrustum;
}

View file

@ -40,13 +40,29 @@ public:
void setMaxLevelReached(int maxLevelReached) { _maxLevelReachedInLastSearch = maxLevelReached; } void setMaxLevelReached(int maxLevelReached) { _maxLevelReachedInLastSearch = maxLevelReached; }
VoxelNodeBag nodeBag; VoxelNodeBag nodeBag;
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; };
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; };
// These are not classic setters because they are calculating and maintaining state
// which is set asynchronously through the network receive
bool updateCurrentViewFrustum();
void updateLastKnownViewFrustum();
bool getViewSent() const { return _viewSent; };
void setViewSent(bool viewSent) { _viewSent = viewSent; }
private: private:
bool _viewSent;
unsigned char* _voxelPacket; unsigned char* _voxelPacket;
unsigned char* _voxelPacketAt; unsigned char* _voxelPacketAt;
int _voxelPacketAvailableBytes; int _voxelPacketAvailableBytes;
bool _voxelPacketWaiting; bool _voxelPacketWaiting;
int _maxSearchLevel; int _maxSearchLevel;
int _maxLevelReachedInLastSearch; int _maxLevelReachedInLastSearch;
ViewFrustum _currentViewFrustum;
ViewFrustum _lastKnownViewFrustum;
}; };
#endif /* defined(__hifi__VoxelAgentData__) */ #endif /* defined(__hifi__VoxelAgentData__) */

View file

@ -107,10 +107,8 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
// Version of voxel distributor that sends each LOD level at a time // Version of voxel distributor that sends each LOD level at a time
void resInVoxelDistributor(AgentList* agentList, void resInVoxelDistributor(AgentList* agentList,
AgentList::iterator& agent, AgentList::iterator& agent,
VoxelAgentData* agentData, VoxelAgentData* agentData) {
ViewFrustum& viewFrustum) { ViewFrustum viewFrustum = agentData->getCurrentViewFrustum();
printf("resInVoxelDistributor()\n");
bool searchReset = false; bool searchReset = false;
int searchLoops = 0; int searchLoops = 0;
int searchLevelWas = agentData->getMaxSearchLevel(); int searchLevelWas = agentData->getMaxSearchLevel();
@ -227,14 +225,32 @@ void resInVoxelDistributor(AgentList* agentList,
void deepestLevelVoxelDistributor(AgentList* agentList, void deepestLevelVoxelDistributor(AgentList* agentList,
AgentList::iterator& agent, AgentList::iterator& agent,
VoxelAgentData* agentData, VoxelAgentData* agentData,
ViewFrustum& viewFrustum) { bool viewFrustumChanged) {
printf("deepestLevelVoxelDistributor()\n");
int maxLevelReached = 0; int maxLevelReached = 0;
double start = usecTimestampNow(); double start = usecTimestampNow();
if (agentData->nodeBag.isEmpty()) {
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, viewFrustum, agentData->nodeBag); // FOR NOW... agent tells us if it wants to receive only view frustum deltas
bool wantDelta = agentData->getWantDelta();
const ViewFrustum* lastViewFrustum = wantDelta ? &agentData->getLastKnownViewFrustum() : NULL;
if (::debugVoxelSending) {
printf("deepestLevelVoxelDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s\n",
viewFrustumChanged ? "yes" : "no",
agentData->nodeBag.isEmpty() ? "yes" : "no",
agentData->getViewSent() ? "yes" : "no"
);
}
// If the current view frustum has changed OR we have nothing to send, then search against
// the current view frustum for things to send.
if (viewFrustumChanged || agentData->nodeBag.isEmpty()) {
// If the bag was empty, then send everything in view, not just the delta
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(),
agentData->nodeBag, wantDelta, lastViewFrustum);
agentData->setViewSent(false);
} }
double end = usecTimestampNow(); double end = usecTimestampNow();
double elapsedmsec = (end - start)/1000.0; double elapsedmsec = (end - start)/1000.0;
@ -266,8 +282,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
VoxelNode* subTree = agentData->nodeBag.extract(); VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree, bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, &viewFrustum, agentData->nodeBag, &agentData->getCurrentViewFrustum(),
agentData->getWantColor()); agentData->getWantColor(), wantDelta, lastViewFrustum);
if (agentData->getAvailable() >= bytesWritten) { if (agentData->getAvailable() >= bytesWritten) {
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
@ -313,7 +329,16 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n", printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count()); elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
} }
}
// if after sending packets we've emptied our bag, then we want to remember that we've sent all
// the voxels from the current view frustum
if (agentData->nodeBag.isEmpty()) {
agentData->updateLastKnownViewFrustum();
agentData->setViewSent(true);
}
} // end if bag wasn't empty, and so we sent stuff...
} }
void persistVoxelsWhenDirty() { void persistVoxelsWhenDirty() {
@ -340,23 +365,15 @@ void *distributeVoxelsToListeners(void *args) {
// Sometimes the agent data has not yet been linked, in which case we can't really do anything // Sometimes the agent data has not yet been linked, in which case we can't really do anything
if (agentData) { if (agentData) {
ViewFrustum viewFrustum; bool viewFrustumChanged = agentData->updateCurrentViewFrustum();
// get position and orientation details from the camera if (::debugVoxelSending) {
viewFrustum.setPosition(agentData->getCameraPosition()); printf("agentData->updateCurrentViewFrustum() changed=%s\n", (viewFrustumChanged ? "yes" : "no"));
viewFrustum.setOrientation(agentData->getCameraDirection(), agentData->getCameraUp(), agentData->getCameraRight()); }
// Also make sure it's got the correct lens details from the camera
viewFrustum.setFieldOfView(agentData->getCameraFov());
viewFrustum.setAspectRatio(agentData->getCameraAspectRatio());
viewFrustum.setNearClip(agentData->getCameraNearClip());
viewFrustum.setFarClip(agentData->getCameraFarClip());
viewFrustum.calculate();
if (agentData->getWantResIn()) { if (agentData->getWantResIn()) {
resInVoxelDistributor(agentList, agent, agentData, viewFrustum); resInVoxelDistributor(agentList, agent, agentData);
} else { } else {
deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustum); deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustumChanged);
} }
} }
} }
@ -486,9 +503,11 @@ int main(int argc, const char * argv[])
if (agentList->getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) { if (agentList->getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) {
// XXXBHG: Hacked in support for 'S' SET command // XXXBHG: Hacked in support for 'S' SET command
if (packetData[0] == PACKET_HEADER_SET_VOXEL) { if (packetData[0] == PACKET_HEADER_SET_VOXEL || packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) {
bool destructive = (packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE);
unsigned short int itemNumber = (*((unsigned short int*)&packetData[1])); unsigned short int itemNumber = (*((unsigned short int*)&packetData[1]));
printf("got I - insert voxels - command from client receivedBytes=%ld itemNumber=%d\n", printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n",
destructive ? "PACKET_HEADER_SET_VOXEL_DESTRUCTIVE" : "PACKET_HEADER_SET_VOXEL",
receivedBytes,itemNumber); receivedBytes,itemNumber);
int atByte = 3; int atByte = 3;
unsigned char* pVoxelData = (unsigned char*)&packetData[3]; unsigned char* pVoxelData = (unsigned char*)&packetData[3];
@ -517,7 +536,7 @@ int main(int argc, const char * argv[])
printf("inserting voxel at: %f,%f,%f\n",vertices[0],vertices[1],vertices[2]); printf("inserting voxel at: %f,%f,%f\n",vertices[0],vertices[1],vertices[2]);
delete []vertices; delete []vertices;
randomTree.readCodeColorBufferToTree(pVoxelData); randomTree.readCodeColorBufferToTree(pVoxelData, destructive);
// skip to next // skip to next
pVoxelData+=voxelDataSize; pVoxelData+=voxelDataSize;
atByte+=voxelDataSize; atByte+=voxelDataSize;