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_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
# Copyright (c) 2013 High Fidelity
#
if (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS)
if (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
# in cache already
set(LIBOVR_FOUND TRUE)
else (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS)
set(LIBOVR_INCLUDE_DIRS ${LIBOVR_ROOT_DIR}/Include)
else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
find_path(LIBOVR_INCLUDE_DIRS OVR.h ${LIBOVR_ROOT_DIR}/Include)
if (APPLE)
set(LIBOVR_LIBRARY ${LIBOVR_ROOT_DIR}/Lib/MacOS/libovr.a)
else (WIN32)
set(LIBOVR_LIBRARY ${LIBOVR_ROOT_DIR}/Lib/Win32/libovr.lib)
find_library(LIBOVR_LIBRARIES libovr.a ${LIBOVR_ROOT_DIR}/Lib/MacOS/)
elseif (WIN32)
find_library(LIBOVR_LIBRARIES libovr.lib ${LIBOVR_ROOT_DIR}/Lib/Win32/)
endif ()
if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARY)
if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES)
set(LIBOVR_FOUND TRUE)
endif (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARY)
endif (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES)
if (LIBOVR_FOUND)
if (NOT LibOVR_FIND_QUIETLY)
message(STATUS "Found LibOVR: ${LIBOVR_LIBRARY}")
message(STATUS "Found LibOVR: ${LIBOVR_LIBRARIES}")
endif (NOT LibOVR_FIND_QUIETLY)
else (LIBOVR_FOUND)
if (LibOVR_FIND_REQUIRED)
@ -38,7 +38,7 @@ else (LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIRS)
endif (LibOVR_FIND_REQUIRED)
endif (LIBOVR_FOUND)
# show the LIBOVR_INCLUDE_DIRS and LIBOVR_LIBRARY variables only in the advanced view
mark_as_advanced(LIBOVR_INCLUDE_DIRS LIBOVR_LIBRARY)
# show the LIBOVR_INCLUDE_DIRS and LIBOVR_LIBRARIES variables only in the advanced view
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_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>
#
if (LODEPNG_LIBRARY AND LODEPNG_INCLUDE_DIRS)
if (LODEPNG_LIBRARIES AND LODEPNG_INCLUDE_DIRS)
# in cache already
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"
PATHS ${LODEPNG_ROOT_DIR})
find_path(LODEPNG_INCLUDE_DIRS lodepng.h ${LODEPNG_ROOT_DIR})
find_file(LODEPNG_LIBRARIES lodepng.cpp ${LODEPNG_ROOT_DIR})
set(LODEPNG_INCLUDE_DIRS
${LODEPNG_INCLUDE_DIR}
)
set(LODEPNG_LIBRARY
${LODEPNG_ROOT_DIR}/lodepng.cpp
)
if (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARY)
if (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARIES)
set(LODEPNG_FOUND TRUE)
endif (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARY)
endif (LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARIES)
if (LODEPNG_FOUND)
if (NOT LodePNG_FIND_QUIETLY)
message(STATUS "Found LodePNG: ${LODEPNG_LIBRARY}")
message(STATUS "Found LodePNG: ${LODEPNG_LIBRARIES}")
endif (NOT LodePNG_FIND_QUIETLY)
else (LODEPNG_FOUND)
if (LodePNG_FIND_REQUIRED)
@ -41,7 +33,7 @@ else (LODEPNG_LIBRARY AND LODEPNG_INCLUDE_DIRS)
endif (LodePNG_FIND_REQUIRED)
endif (LODEPNG_FOUND)
# show the LODEPNG_INCLUDE_DIRS and LODEPNG_LIBRARY variables only in the advanced view
mark_as_advanced(LODEPNG_INCLUDE_DIRS LODEPNG_LIBRARY)
# show the LODEPNG_INCLUDE_DIRS and LODEPNG_LIBRARIES variables only in the advanced view
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_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
# Copyright (c) 2013 High Fidelity
#
if (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS)
if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
# in cache already
set(PORTAUDIO_FOUND TRUE)
else (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS)
set(PORTAUDIO_INCLUDE_DIRS ${PORTAUDIO_ROOT_DIR}/include)
else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
find_path(PORTAUDIO_INCLUDE_DIRS portaudio.h ${PORTAUDIO_ROOT_DIR}/include)
if (APPLE)
set(PORTAUDIO_LIBRARY ${PORTAUDIO_ROOT_DIR}/lib/MacOS/libportaudio.a)
else (WIN32)
set(PORTAUDIO_LIBRARY ${PORTAUDIO_ROOT_DIR}/lib/UNIX/libportaudio.a)
find_library(PORTAUDIO_LIBRARIES libportaudio.a ${PORTAUDIO_ROOT_DIR}/lib/MacOS/)
elseif (UNIX)
find_library(PORTAUDIO_LIBRARIES libportaudio.a ${PORTAUDIO_ROOT_DIR}/lib/UNIX/)
endif ()
if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARY)
set(PORTAUDIO_FOUND TRUE)
endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARY)
if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
set(PORTAUDIO_FOUND TRUE)
endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
if (PORTAUDIO_FOUND)
if (NOT PortAudio_FIND_QUIETLY)
message(STATUS "Found PortAudio: ${PORTAUDIO_LIBRARY}")
message(STATUS "Found PortAudio: ${PORTAUDIO_LIBRARIES}")
endif (NOT PortAudio_FIND_QUIETLY)
else (PORTAUDIO_FOUND)
if (PortAudio_FIND_REQUIRED)
@ -38,7 +38,7 @@ else (PORTAUDIO_LIBRARY AND PORTAUDIO_INCLUDE_DIRS)
endif (PortAudio_FIND_REQUIRED)
endif (PORTAUDIO_FOUND)
# show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARY variables only in the advanced view
mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARY)
# show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
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(LODEPNG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LodePNG)
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)
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})
endif (APPLE)
find_package(Qt4 REQUIRED QtCore QtGui)
find_package(Qt4 REQUIRED QtCore QtGui QtOpenGL)
include(${QT_USE_FILE})
# run qt moc on qt-enabled headers
@ -109,7 +109,7 @@ if (APPLE)
${GLUT}
${OpenGL}
${IOKit}
${LIBOVR_LIBRARY}
${LIBOVR_LIBRARIES}
)
else (APPLE)
find_package(OpenGL REQUIRED)
@ -129,12 +129,12 @@ if (WIN32)
wsock32.lib
)
else (WIN32)
target_link_libraries(${TARGET_NAME} ${LODEPNG_LIBRARY})
target_link_libraries(${TARGET_NAME} ${LODEPNG_LIBRARIES})
# link the PortAudio library
find_package(PortAudio REQUIRED)
include_directories(${PORTAUDIO_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${PORTAUDIO_LIBRARY})
target_link_libraries(${TARGET_NAME} ${PORTAUDIO_LIBRARIES})
# link required libraries on UNIX
if (UNIX AND NOT APPLE)

File diff suppressed because it is too large Load diff

View file

@ -9,16 +9,228 @@
#ifndef __interface__Application__
#define __interface__Application__
#include <pthread.h>
#include <time.h>
#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 {
Q_OBJECT
public:
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 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__) */

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);
};
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);
//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();
pthread_mutex_unlock(&_treeLock);
};
void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color) {
_tree->createLine(point1, point2, unitSize, color);
void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
_tree->createLine(point1, point2, unitSize, color, destructive);
setupNewVoxelsForDrawing();
};
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug) {
_tree->createSphere(r, xc, yc, zc, s, solid, mode, debug);
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid,
creationMode mode, bool destructive, bool debug) {
_tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug);
setupNewVoxelsForDrawing();
};

View file

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

View file

@ -15,51 +15,6 @@
// 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 "Camera.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[]) {
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));
printLog( "Created QT Application.\n" );
// 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();
int exitCode = app.exec();
printLog("Normal exit.\n");
::terminate();
return EXIT_SUCCESS;
return exitCode;
}

View file

@ -5,60 +5,71 @@
// Created by Andrzej Kapolka on 4/24/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
#include "InterfaceConfig.h"
#include <QKeyEvent>
#include "ChatEntry.h"
#include "InterfaceConfig.h"
#include "Util.h"
using namespace std;
const int MAX_CONTENT_LENGTH = 140;
ChatEntry::ChatEntry() : _cursorPos(0) {
}
void ChatEntry::clear() {
_contents.clear();
_cursorPos = 0;
}
bool ChatEntry::key(unsigned char k) {
switch (k) {
case '\r':
bool ChatEntry::keyPressEvent(QKeyEvent* event) {
event->accept();
switch (event->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
return false;
case '\b':
case Qt::Key_Escape:
clear();
return false;
case Qt::Key_Backspace:
if (_cursorPos != 0) {
_contents.erase(_cursorPos - 1, 1);
_cursorPos--;
}
return true;
case 127: // delete
case Qt::Key_Delete:
if (_cursorPos < _contents.size()) {
_contents.erase(_cursorPos, 1);
}
return true;
default:
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:
case Qt::Key_Left:
if (_cursorPos != 0) {
_cursorPos--;
}
break;
return true;
case GLUT_KEY_RIGHT:
case Qt::Key_Right:
if (_cursorPos != _contents.size()) {
_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 - 150);
glEnd();
glEnable(GL_LINE_SMOOTH);
}

View file

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

View file

@ -108,8 +108,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
destinationBuffer += _chatMessage.size() * sizeof(char);
// voxel sending features...
*destinationBuffer++ = _wantResIn;
*destinationBuffer++ = _wantColor;
// voxel sending features...
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;
}
@ -117,6 +121,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
// called on the other agents - assigns it to my views of the others
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
//printf("AvatarData::parseData()\n");
// increment to push past the packet header
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
@ -184,8 +190,12 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
sourceBuffer += chatMessageSize * sizeof(char);
// voxel sending features...
_wantResIn = (bool)*sourceBuffer++;
_wantColor = (bool)*sourceBuffer++;
unsigned char wantItems = 0;
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;
}

View file

@ -15,6 +15,10 @@
#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
{
NO_KEY_DOWN,
@ -124,8 +128,10 @@ public:
// related to Voxel Sending strategies
bool getWantResIn() const { return _wantResIn; }
bool getWantColor() const { return _wantColor; }
bool getWantDelta() const { return _wantDelta; }
void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; }
void setWantColor(bool wantColor) { _wantColor = wantColor; }
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
protected:
glm::vec3 _position;
@ -168,8 +174,10 @@ protected:
// chat message
std::string _chatMessage;
// voxel server sending items
bool _wantResIn;
bool _wantColor;
bool _wantDelta;
};
#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_INJECT_AUDIO = 'I';
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_VOXEL_DATA = 'V';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v';
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_DOMAIN_LIST_REQUEST = 'L';
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);
}
void setAtBit(unsigned char& byte, int bitIndex) {
byte += (1 << (7 - bitIndex));
}
void switchToResourcesParentIfRequired() {
#ifdef __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle();

View file

@ -49,6 +49,7 @@ void outputBits(unsigned char byte, bool withNewLine = true);
void printVoxelCode(unsigned char* voxelCode);
int numberOfOnes(unsigned char byte);
bool oneAtBit(unsigned char byte, int bitIndex);
void setAtBit(unsigned char& byte, int bitIndex);
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);
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 { return matches(*compareTo); };
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);
// 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);
}
@ -287,7 +293,7 @@ void VoxelTree::eraseAllVoxels() {
_isDirty = true;
}
void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive) {
VoxelNode* lastCreatedNode = nodeForOctalCode(rootNode, codeColorBuffer, NULL);
// create the node if it does not exist
@ -297,19 +303,27 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
} else {
// if it does exist, make sure it has no children
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
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer);
if (lastCreatedNode->isLeaf()) {
// give this node its color
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer);
nodeColor newColor;
memcpy(newColor, codeColorBuffer + octalCodeBytes, 3);
newColor[3] = 1;
lastCreatedNode->setColor(newColor);
if (lastCreatedNode->isDirty()) {
_isDirty = true;
nodeColor newColor;
memcpy(newColor, codeColorBuffer + octalCodeBytes, 3);
newColor[3] = 1;
lastCreatedNode->setColor(newColor);
if (lastCreatedNode->isDirty()) {
_isDirty = true;
}
}
}
@ -463,14 +477,15 @@ VoxelNode* VoxelTree::getVoxelAt(float x, float y, float z, float s) const {
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);
this->readCodeColorBufferToTree(voxelData);
this->readCodeColorBufferToTree(voxelData, destructive);
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 items = distance / unitSize;
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;
for (int i = 0; i <= maxItems; i++ ) {
pointAt += increment;
unsigned char* voxelData = pointToVoxel(pointAt.x,pointAt.y,pointAt.z,unitSize,color[0],color[1],color[2]);
readCodeColorBufferToTree(voxelData);
delete voxelData;
createVoxel(pointAt.x, pointAt.y, pointAt.z, unitSize, color[0], color[1], color[2], destructive);
}
}
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 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);
y = yc + (thisRadius + i * subVoxelScale) * sin(theta) * sin(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;
}
}
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);
}
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
int currentSearchLevel = 0;
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode, viewFrustum, bag);
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode,
viewFrustum, bag, deltaViewFrustum, lastViewFrustum);
return levelReached;
}
@ -667,7 +682,8 @@ bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& di
}
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.
currentSearchLevel++;
@ -702,7 +718,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
bool childIsColored = (childNode && childNode->isColored());
bool childIsInView = (childNode && childNode->isInView(viewFrustum));
bool childIsLeaf = (childNode && childNode->isLeaf());
if (childIsInView) {
// 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++) {
VoxelNode* childNode = inViewChildren[i];
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);
}
}
@ -747,7 +764,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
}
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;
int bytesWritten = 0;
@ -767,7 +785,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int currentEncodeLevel = 0;
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
assert(childBytesWritten != 1);
@ -790,7 +809,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
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;
int bytesAtThisLevel = 0;
@ -846,6 +866,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
VoxelNode* childNode = node->getChildAtIndex(i);
bool childIsInView = (childNode && (!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 ? childNode->distanceToCamera(*viewFrustum) : 0;
@ -861,9 +882,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
childrenExistBits += (1 << (7 - i));
inViewNotLeafCount++;
}
bool childWasInView = (childNode && deltaViewFrustum &&
(lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*lastViewFrustum)));
// track children with actual color
if (childNode && childNode->isColored()) {
// track children with actual color, only if the child wasn't previously in view!
if (childNode && childNode->isColored() && !childWasInView) {
childrenColoredBits += (1 << (7 - i));
inViewWithColorCount++;
}
@ -925,7 +949,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
int thisLevel = currentEncodeLevel;
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
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,
// basically, the children below don't contain any info.

View file

@ -22,42 +22,46 @@ typedef enum {GRADIENT, RANDOM, NATURAL} creationMode;
class VoxelTree {
public:
// 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)
long voxelsColored;
long voxelsBytesRead;
long voxelsColored;
long voxelsBytesRead;
SimpleMovingAverage voxelsCreatedStats;
SimpleMovingAverage voxelsColoredStats;
SimpleMovingAverage voxelsBytesReadStats;
SimpleMovingAverage voxelsColoredStats;
SimpleMovingAverage voxelsBytesReadStats;
VoxelTree();
~VoxelTree();
VoxelNode *rootNode;
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 readCodeColorBufferToTree(unsigned char *codeColorBuffer);
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false);
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
void printTreeForDebugging(VoxelNode *startNode);
void reaverageVoxelColors(VoxelNode *startNode);
void deleteVoxelAt(float x, float y, float z, float s, bool stage = false);
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, creationMode mode, bool debug = false);
void createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
creationMode mode, bool destructive = false, bool debug = false);
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
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; };
void clearDirtyBit() { _isDirty = false; };
@ -68,7 +72,7 @@ public:
VoxelNode*& node, float& distance, BoxFace& face);
// 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
void writeToFileV2(const char* filename) const;
@ -79,10 +83,12 @@ public:
private:
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
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,
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);

View file

@ -22,6 +22,7 @@ void VoxelAgentData::init() {
_maxSearchLevel = 1;
_maxLevelReachedInLastSearch = 1;
resetVoxelPacket();
_viewSent = false;
}
void VoxelAgentData::resetVoxelPacket() {
@ -50,3 +51,31 @@ VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
VoxelAgentData* VoxelAgentData::clone() const {
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; }
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:
bool _viewSent;
unsigned char* _voxelPacket;
unsigned char* _voxelPacketAt;
int _voxelPacketAvailableBytes;
bool _voxelPacketWaiting;
int _maxSearchLevel;
int _maxLevelReachedInLastSearch;
ViewFrustum _currentViewFrustum;
ViewFrustum _lastKnownViewFrustum;
};
#endif /* defined(__hifi__VoxelAgentData__) */

View file

@ -107,10 +107,8 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
// Version of voxel distributor that sends each LOD level at a time
void resInVoxelDistributor(AgentList* agentList,
AgentList::iterator& agent,
VoxelAgentData* agentData,
ViewFrustum& viewFrustum) {
printf("resInVoxelDistributor()\n");
VoxelAgentData* agentData) {
ViewFrustum viewFrustum = agentData->getCurrentViewFrustum();
bool searchReset = false;
int searchLoops = 0;
int searchLevelWas = agentData->getMaxSearchLevel();
@ -227,14 +225,32 @@ void resInVoxelDistributor(AgentList* agentList,
void deepestLevelVoxelDistributor(AgentList* agentList,
AgentList::iterator& agent,
VoxelAgentData* agentData,
ViewFrustum& viewFrustum) {
printf("deepestLevelVoxelDistributor()\n");
bool viewFrustumChanged) {
int maxLevelReached = 0;
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 elapsedmsec = (end - start)/1000.0;
@ -266,8 +282,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, &viewFrustum,
agentData->getWantColor());
agentData->nodeBag, &agentData->getCurrentViewFrustum(),
agentData->getWantColor(), wantDelta, lastViewFrustum);
if (agentData->getAvailable() >= 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",
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() {
@ -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
if (agentData) {
ViewFrustum viewFrustum;
// get position and orientation details from the camera
viewFrustum.setPosition(agentData->getCameraPosition());
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();
bool viewFrustumChanged = agentData->updateCurrentViewFrustum();
if (::debugVoxelSending) {
printf("agentData->updateCurrentViewFrustum() changed=%s\n", (viewFrustumChanged ? "yes" : "no"));
}
if (agentData->getWantResIn()) {
resInVoxelDistributor(agentList, agent, agentData, viewFrustum);
resInVoxelDistributor(agentList, agent, agentData);
} 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)) {
// 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]));
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);
int atByte = 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]);
delete []vertices;
randomTree.readCodeColorBufferToTree(pVoxelData);
randomTree.readCodeColorBufferToTree(pVoxelData, destructive);
// skip to next
pVoxelData+=voxelDataSize;
atByte+=voxelDataSize;