Merge branch 'master' of git://github.com/worklist/hifi into 19188

Conflicts:
	interface/src/starfield/renderer/Renderer.h
This commit is contained in:
tosh 2013-04-19 03:09:53 +02:00
commit bc9279917d
58 changed files with 1984 additions and 1136 deletions

View file

@ -133,7 +133,7 @@ int main(int argc, const char * argv[])
if (DEBUG_TO_SELF ||
!agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) {
if (strchr(SOLO_AGENT_TYPES_STRING, (int) agent->getType()) == NULL) {
if (memchr(SOLO_AGENT_TYPES_STRING, agent->getType(), 1) == NULL) {
// this is an agent of which there can be multiple, just add them to the packet
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent));
} else {

View file

@ -19,6 +19,7 @@
#include <PacketHeaders.h>
#include "Audio.h"
#include "Util.h"
#include "Log.h"
Oscilloscope * scope;
@ -115,7 +116,7 @@ int audioCallback (const void *inputBuffer,
int16_t *inputLeft = ((int16_t **) inputBuffer)[0];
// int16_t *inputRight = ((int16_t **) inputBuffer)[1];
//printf("Audio callback at %6.0f\n", usecTimestampNow()/1000);
//printLog("Audio callback at %6.0f\n", usecTimestampNow()/1000);
if (inputLeft != NULL) {
@ -231,21 +232,21 @@ int audioCallback (const void *inputBuffer,
if (ringBuffer->getEndOfLastWrite() != NULL) {
if (!ringBuffer->isStarted() && ringBuffer->diffLastWriteNextOutput() < PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES) {
//printf("Held back, buffer has %d of %d samples required.\n", ringBuffer->diffLastWriteNextOutput(), PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES);
//printLog("Held back, buffer has %d of %d samples required.\n", ringBuffer->diffLastWriteNextOutput(), PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES);
} else if (ringBuffer->diffLastWriteNextOutput() < PACKET_LENGTH_SAMPLES) {
ringBuffer->setStarted(false);
starve_counter++;
packetsReceivedThisPlayback = 0;
//printf("Starved #%d\n", starve_counter);
//printLog("Starved #%d\n", starve_counter);
data->wasStarved = 10; // Frames to render the indication that the system was starved.
} else {
if (!ringBuffer->isStarted()) {
ringBuffer->setStarted(true);
//printf("starting playback %3.1f msecs delayed \n", (usecTimestampNow() - usecTimestamp(&firstPlaybackTimer))/1000.0);
//printLog("starting playback %3.1f msecs delayed \n", (usecTimestampNow() - usecTimestamp(&firstPlaybackTimer))/1000.0);
} else {
//printf("pushing buffer\n");
//printLog("pushing buffer\n");
}
// play whatever we have in the audio buffer
@ -391,12 +392,12 @@ void *receiveAudioViaUDP(void *args) {
}
double tDiff = diffclock(&previousReceiveTime, &currentReceiveTime);
//printf("tDiff %4.1f\n", tDiff);
//printLog("tDiff %4.1f\n", tDiff);
// Discard first few received packets for computing jitter (often they pile up on start)
if (totalPacketsReceived > 3) stdev.addValue(tDiff);
if (stdev.getSamples() > 500) {
sharedAudioData->measuredJitter = stdev.getStDev();
//printf("Avg: %4.2f, Stdev: %4.2f\n", stdev.getAverage(), sharedAudioData->measuredJitter);
//printLog("Avg: %4.2f, Stdev: %4.2f\n", stdev.getAverage(), sharedAudioData->measuredJitter);
stdev.reset();
}
@ -407,7 +408,7 @@ void *receiveAudioViaUDP(void *args) {
packetsReceivedThisPlayback++;
}
else {
//printf("Audio packet received at %6.0f\n", usecTimestampNow()/1000);
//printLog("Audio packet received at %6.0f\n", usecTimestampNow()/1000);
}
if (packetsReceivedThisPlayback == 1) gettimeofday(&firstPlaybackTimer, NULL);
@ -494,8 +495,8 @@ Audio::Audio(Oscilloscope *s, Head *linkedHead)
return;
error:
fprintf(stderr, "-- Failed to initialize portaudio --\n");
fprintf(stderr, "PortAudio error (%d): %s\n", paError, Pa_GetErrorText(paError));
printLog("-- Failed to initialize portaudio --\n");
printLog("PortAudio error (%d): %s\n", paError, Pa_GetErrorText(paError));
initialized = false;
delete[] audioData;
}
@ -629,8 +630,8 @@ bool Audio::terminate ()
return true;
error:
fprintf(stderr, "-- portaudio termination error --\n");
fprintf(stderr, "PortAudio error (%d): %s\n", paError, Pa_GetErrorText(paError));
printLog("-- portaudio termination error --\n");
printLog("PortAudio error (%d): %s\n", paError, Pa_GetErrorText(paError));
return false;
}

View file

@ -9,8 +9,6 @@
#ifndef __interface__Audio__
#define __interface__Audio__
#include <iostream>
#include <portaudio.h>
#include "AudioData.h"
#include "Oscilloscope.h"

View file

@ -9,7 +9,6 @@
#ifndef __interface__AudioData__
#define __interface__AudioData__
#include <iostream>
#include <stdint.h>
#include <glm/glm.hpp>
#include "AudioRingBuffer.h"

View file

@ -6,6 +6,7 @@
//---------------------------------------------------------------------
#include <SharedUtil.h>
// #include "Log.h"
#include "Camera.h"
@ -67,6 +68,6 @@ void Camera::update( float deltaTime )
_orientation.pitch ( _pitch );
_orientation.roll ( _roll );
//printf( "orientation.front = %f, %f, %f\n", _orientation.front.x, _orientation.front.y, _orientation.front.z );
//printLog( "orientation.front = %f, %f, %f\n", _orientation.front.x, _orientation.front.y, _orientation.front.z );
}

View file

@ -9,7 +9,6 @@
#ifndef __interface__Field__
#define __interface__Field__
#include <iostream>
#include <glm/glm.hpp>
#include "InterfaceConfig.h"
#include "world.h"

File diff suppressed because it is too large Load diff

View file

@ -9,8 +9,6 @@
#ifndef __interface__head__
#define __interface__head__
#include <iostream>
#include <AvatarData.h>
#include <Orientation.h>
@ -22,8 +20,7 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/quaternion.hpp> //looks like we might not need this
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
@ -85,12 +82,13 @@ struct AvatarBone
glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position)
glm::dvec3 springyVelocity; // used for special effects ( the velocity of the springy position)
float springBodyTightness; // how tightly the springy position tries to stay on the position
glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orienttion)
glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation)
float yaw; // the yaw Euler angle of the bone rotation off the parent
float pitch; // the pitch Euler angle of the bone rotation off the parent
float roll; // the roll Euler angle of the bone rotation off the parent
Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll
float length; // the length of the bone
float radius; // used for detecting collisions for certain physical effects
};
struct Avatar
@ -110,25 +108,25 @@ class Head : public AvatarData {
void reset();
void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity);
void setNoise (float mag) { noise = mag; }
void setPitch(float p) {Pitch = p; }
void setYaw(float y) {Yaw = y; }
void setRoll(float r) {Roll = r; };
void setScale(float s) {scale = s; };
void setRenderYaw(float y) {renderYaw = y;}
void setRenderPitch(float p) {renderPitch = p;}
float getRenderYaw() {return renderYaw;}
float getRenderPitch() {return renderPitch;}
void setNoise (float mag) { _noise = mag; }
void setPitch(float p) {_headPitch = p; }
void setYaw(float y) {_headYaw = y; }
void setRoll(float r) {_headRoll = r; };
void setScale(float s) {_scale = s; };
void setRenderYaw(float y) {_renderYaw = y;}
void setRenderPitch(float p) {_renderPitch = p;}
float getRenderYaw() {return _renderYaw;}
float getRenderPitch() {return _renderPitch;}
void setLeanForward(float dist);
void setLeanSideways(float dist);
void addPitch(float p) {Pitch -= p; }
void addYaw(float y){Yaw -= y; }
void addRoll(float r){Roll += r; }
void addPitch(float p) {_headPitch -= p; }
void addYaw(float y){_headYaw -= y; }
void addRoll(float r){_headRoll += r; }
void addLean(float x, float z);
float getPitch() {return Pitch;}
float getRoll() {return Roll;}
float getYaw() {return Yaw;}
float getLastMeasuredYaw() {return YawRate;}
float getPitch() {return _headPitch;}
float getRoll() {return _headRoll;}
float getYaw() {return _headYaw;}
float getLastMeasuredYaw() {return _headYawRate;}
float getBodyYaw() {return _bodyYaw;};
void addBodyYaw(float y) {_bodyYaw += y;};
@ -154,16 +152,16 @@ class Head : public AvatarData {
void setHandMovement( glm::vec3 movement );
void updateHandMovement();
float getLoudness() {return loudness;};
float getAverageLoudness() {return averageLoudness;};
void setAverageLoudness(float al) {averageLoudness = al;};
void setLoudness(float l) {loudness = l;};
float getLoudness() {return _loudness;};
float getAverageLoudness() {return _averageLoudness;};
void setAverageLoudness(float al) {_averageLoudness = al;};
void setLoudness(float l) {_loudness = l;};
void SetNewHeadTarget(float, float);
// Set what driving keys are being pressed to control thrust levels
void setDriveKeys(int key, bool val) { driveKeys[key] = val; };
bool getDriveKeys(int key) { return driveKeys[key]; };
void setDriveKeys(int key, bool val) { _driveKeys[key] = val; };
bool getDriveKeys(int key) { return _driveKeys[key]; };
// Set/Get update the thrust that will move the avatar around
void setThrust(glm::vec3 newThrust) { _avatar.thrust = newThrust; };
@ -175,49 +173,48 @@ class Head : public AvatarData {
//
void processTransmitterData(unsigned char * packetData, int numBytes);
float getTransmitterHz() { return transmitterHz; };
float getTransmitterHz() { return _transmitterHz; };
private:
bool _isMine;
float noise;
float Pitch;
float Yaw;
float Roll;
float PitchRate;
float YawRate;
float RollRate;
float EyeballPitch[2];
float EyeballYaw[2];
float EyebrowPitch[2];
float EyebrowRoll[2];
float EyeballScaleX, EyeballScaleY, EyeballScaleZ;
float interPupilDistance;
float interBrowDistance;
float NominalPupilSize;
float PupilSize;
float MouthPitch;
float MouthYaw;
float MouthWidth;
float MouthHeight;
float leanForward;
float leanSideways;
float PitchTarget;
float YawTarget;
float NoiseEnvelope;
float PupilConverge;
float scale;
bool _isMine;
float _noise;
float _headPitch;
float _headYaw;
float _headRoll;
float _headPitchRate;
float _headYawRate;
float _headRollRate;
float _eyeballPitch[2];
float _eyeballYaw[2];
float _eyebrowPitch[2];
float _eyebrowRoll[2];
float _eyeballScaleX, _eyeballScaleY, _eyeballScaleZ;
float _interPupilDistance;
float _interBrowDistance;
float _nominalPupilSize;
float _pupilSize;
float _mouthPitch;
float _mouthYaw;
float _mouthWidth;
float _mouthHeight;
float _leanForward;
float _leanSideways;
float _pitchTarget;
float _yawTarget;
float _noiseEnvelope;
float _pupilConverge;
float _scale;
// Sound loudness information
float loudness, lastLoudness;
float averageLoudness;
float audioAttack;
float browAudioLift;
float _loudness, _lastLoudness;
float _averageLoudness;
float _audioAttack;
float _browAudioLift;
//temporary - placeholder for real other avs
glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ];
float DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ];
glm::vec3 _TEST_bigSpherePosition;
float _TEST_bigSphereRadius;
glm::vec3 _DEBUG_otherAvatarListPosition[ NUM_OTHER_AVATARS ];
float _DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ];
bool _triggeringAction;
float _bodyYawDelta;
float _closeEnoughToInteract;
@ -232,33 +229,31 @@ class Head : public AvatarData {
AvatarBone _bone[ NUM_AVATAR_BONES ];
AvatarMode _mode;
Avatar _avatar;
int _driveKeys[MAX_DRIVE_KEYS];
int _eyeContact;
eyeContactTargets _eyeContactTarget;
int driveKeys[MAX_DRIVE_KEYS];
int eyeContact;
eyeContactTargets eyeContactTarget;
GLUquadric *sphere;
GLUquadric *_sphere;
float renderYaw, renderPitch; // Pitch from view frustum when this is own head.
float _renderYaw;
float _renderPitch; // Pitch from view frustum when this is own head.
//
// Related to getting transmitter UDP data used to animate the avatar hand
//
timeval transmitterTimer;
float transmitterHz;
int transmitterPackets;
timeval _transmitterTimer;
float _transmitterHz;
int _transmitterPackets;
//-----------------------------
// private methods...
//-----------------------------
void initializeAvatar();
void initializeSkeleton();
void updateSkeleton();
void initializeBodySprings();
void updateBodySprings( float deltaTime );
void calculateBoneLengths();
void updateBigSphereCollisionTest( float deltaTime );
void readSensors();
};

323
interface/src/Log.cpp Normal file
View file

@ -0,0 +1,323 @@
//
// Log.cpp
// interface
//
// Created by Tobias Schwinger on 4/14/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "Log.h"
#include "InterfaceConfig.h"
#include <string.h>
#include <stdarg.h>
#include "Util.h"
namespace {
// anonymous namespace - everything in here only exists within this very .cpp file
// just as 'static' on every effective line in plain C
unsigned const CHARACTER_BUFFER_SIZE = 16384; // number of character that are buffered
unsigned const LINE_BUFFER_SIZE = 256; // number of lines that are buffered
unsigned const MAX_MESSAGE_LENGTH = 512; // maximum number of characters for a message
bool const TEXT_MONOSPACED = true;
float const TEXT_RED = 0.7f;
float const TEXT_GREEN = 0.6f;
float const TEXT_BLUE = 1.0f;
// magic constants from the GLUT spec
// http://www.opengl.org/resources/libraries/glut/spec3/node78.html
// ultimately this stuff should be in Util.h??
float const CHAR_UP = 119.05f;
float const CHAR_DOWN = 33.33f;
float const CHAR_WIDTH = 104.76f;
// derived values
float const CHAR_HEIGHT = CHAR_UP + CHAR_DOWN;
float const CHAR_FRACT_BASELINE = CHAR_DOWN / CHAR_HEIGHT;
// unsigned integer division rounded towards infinity
unsigned divRoundUp(unsigned l, unsigned r) { return (l + r - 1) / r; }
}
Log::Log(FILE* tPipeTo, unsigned bufferedLines,
unsigned defaultLogWidth, unsigned defaultCharWidth, unsigned defaultCharHeight) :
_ptrStream(tPipeTo),
_arrChars(0l),
_arrLines(0l),
_valLogWidth(defaultLogWidth) {
pthread_mutex_init(& _mtx, 0l);
// allocate twice as much (so we have spare space for a copy not to block
// logging from other threads during 'render')
_arrChars = new char[CHARACTER_BUFFER_SIZE * 2];
_ptrCharsEnd = _arrChars + CHARACTER_BUFFER_SIZE;
_arrLines = new char*[LINE_BUFFER_SIZE * 2];
_ptrLinesEnd = _arrLines + LINE_BUFFER_SIZE;
// initialize the log to all empty lines
_arrChars[0] = '\0';
_itrWritePos = _arrChars;
_itrWriteLineStart = _arrChars;
_itrLastLine = _arrLines;
_valWrittenInLine = 0;
memset(_arrLines, 0, LINE_BUFFER_SIZE * sizeof(char*));
setCharacterSize(defaultCharWidth, defaultCharHeight);
}
Log::~Log() {
delete[] _arrChars;
delete[] _arrLines;
}
inline void Log::addMessage(char const* ptr) {
// precondition: mutex is locked so noone gets in our way
// T-pipe, if requested
if (_ptrStream != 0l) {
fprintf(_ptrStream, "%s", ptr);
}
while (*ptr != '\0') {
// process the characters
char c = *ptr++;
if (c == '\t') {
// found TAB -> write SPACE
c = ' ';
} else if (c == '\n') {
// found LF -> write NUL (c == '\0' tells us to wrap, below)
c = '\0';
}
*_itrWritePos++ = c;
if (_itrWritePos == _ptrCharsEnd) {
// reached the end of the circular character buffer? -> start over
_itrWritePos = _arrChars;
}
if (++_valWrittenInLine >= _valLineLength || c == '\0') {
// new line? store its start to the line buffer and mark next line as empty
++_itrLastLine;
if (_itrLastLine == _ptrLinesEnd) {
_itrLastLine = _arrLines;
_itrLastLine[1] = 0l;
} else if (_itrLastLine + 1 != _ptrLinesEnd) {
_itrLastLine[1] = 0l;
} else {
_arrLines[0] = 0l;
}
*_itrLastLine = _itrWriteLineStart;
// debug mode: make sure all line pointers we write here are valid
assert(! (_itrLastLine < _arrLines || _itrLastLine >= _ptrLinesEnd));
assert(! (*_itrLastLine < _arrChars || *_itrLastLine >= _ptrCharsEnd));
// terminate line, unless done already
if (c != '\0') {
*_itrWritePos++ = '\0';
if (_itrWritePos == _ptrCharsEnd) {
_itrWritePos = _arrChars;
}
}
// remember start position in character buffer for next line and reset character count
_itrWriteLineStart = _itrWritePos;
_valWrittenInLine = 0;
}
}
}
int Log::vprint(char const* fmt, va_list args) {
pthread_mutex_lock(& _mtx);
// print to buffer
char buf[MAX_MESSAGE_LENGTH];
int n = vsnprintf(buf, MAX_MESSAGE_LENGTH, fmt, args);
if (n > 0) {
// all fine? log the message
addMessage(buf);
} else {
// error? -> mutter on stream or stderr
fprintf(_ptrStream != 0l ? _ptrStream : stderr,
"Log: Failed to log message with format string = \"%s\".\n", fmt);
}
pthread_mutex_unlock(& _mtx);
return n;
}
void Log::operator()(char const* fmt, ...) {
va_list args;
va_start(args,fmt);
vprint(fmt, args);
va_end(args);
}
void Log::setLogWidth(unsigned pixels) {
pthread_mutex_lock(& _mtx);
_valLogWidth = pixels;
_valLineLength = _valLogWidth / _valCharWidth;
pthread_mutex_unlock(& _mtx);
}
void Log::setCharacterSize(unsigned width, unsigned height) {
pthread_mutex_lock(& _mtx);
_valCharWidth = width;
_valCharHeight = height;
_valCharYoffset = height * CHAR_FRACT_BASELINE;
_valCharScale = float(width) / CHAR_WIDTH;
_valCharAspect = (height * CHAR_WIDTH) / (width * CHAR_HEIGHT);
_valLineLength = _valLogWidth / _valCharWidth;
pthread_mutex_unlock(& _mtx);
}
void Log::render(unsigned screenWidth, unsigned screenHeight) {
// rendering might take some time, so create a local copy of the portion we need
// instead of having to hold the mutex all the time
pthread_mutex_lock(& _mtx);
// determine number of visible lines
unsigned showLines = divRoundUp(screenHeight, _valCharHeight);
char** lastLine = _itrLastLine;
char** firstLine = _itrLastLine;
if (! *lastLine) {
// empty log
pthread_mutex_unlock(& _mtx);
return;
}
// scan for first line
for (int n = 2; n <= showLines; ++n) {
char** prevFirstLine = firstLine;
--firstLine;
if (firstLine < _arrLines) {
firstLine = _ptrLinesEnd - 1;
}
if (! *firstLine) {
firstLine = prevFirstLine;
showLines = n - 1;
break;
}
// debug mode: make sure all line pointers we find here are valid
assert(! (firstLine < _arrLines || firstLine >= _ptrLinesEnd));
assert(! (*firstLine < _arrChars || *firstLine >= _ptrCharsEnd));
}
// copy the line buffer portion into a contiguous region at _ptrLinesEnd
if (firstLine <= lastLine) {
memcpy(_ptrLinesEnd, firstLine, showLines * sizeof(char*));
} else {
unsigned atEnd = _ptrLinesEnd - firstLine;
memcpy(_ptrLinesEnd, firstLine, atEnd * sizeof(char*));
memcpy(_ptrLinesEnd + atEnd, _arrLines, (showLines - atEnd) * sizeof(char*));
}
// copy relevant char buffer portion and determine information to remap the pointers
char* firstChar = *firstLine;
char* lastChar = *lastLine + strlen(*lastLine) + 1;
ptrdiff_t charOffset = _ptrCharsEnd - firstChar, charOffsetBeforeFirst = 0;
if (firstChar <= lastChar) {
memcpy(_ptrCharsEnd, firstChar, lastChar - firstChar + 1);
} else {
unsigned atEnd = _ptrCharsEnd - firstChar;
memcpy(_ptrCharsEnd, firstChar, atEnd);
memcpy(_ptrCharsEnd + atEnd, _arrChars, lastChar + 1 - _arrChars);
charOffsetBeforeFirst = _ptrCharsEnd + atEnd - _arrChars;
}
// get values for rendering
float scaleFactor = _valCharScale;
int yStart = int((screenHeight - _valCharYoffset) / _valCharAspect);
int yStep = int(_valCharHeight / _valCharAspect);
float yScale = _valCharAspect;
// render text
char** line = _ptrLinesEnd + showLines;
int x = screenWidth - _valLogWidth;
pthread_mutex_unlock(& _mtx);
// ok, we got all we need
GLint matrixMode;
glGetIntegerv(GL_MATRIX_MODE, & matrixMode);
glPushMatrix();
glScalef(1.0f, yScale, 1.0f);
for (int y = yStart; y > 0; y -= yStep) {
// debug mode: check line pointer is valid
assert(! (line < _ptrLinesEnd || line >= _ptrLinesEnd + (_ptrLinesEnd - _arrLines)));
// get character pointer
if (--line < _ptrLinesEnd) {
break;
}
char* chars = *line;
// debug mode: check char pointer we find is valid
assert(! (chars < _arrChars || chars >= _ptrCharsEnd));
// remap character pointer it to copied buffer
chars += chars >= firstChar ? charOffset : charOffsetBeforeFirst;
// debug mode: check char pointer is still valid (in new range)
assert(! (chars < _ptrCharsEnd || chars >= _ptrCharsEnd + (_ptrCharsEnd - _arrChars)));
// render the string
drawtext(x, y, scaleFactor, 0.0f, 1.0f, int(TEXT_MONOSPACED),
chars, TEXT_RED, TEXT_GREEN, TEXT_BLUE);
//fprintf(stderr, "Log::render, message = \"%s\"\n", chars);
}
glPopMatrix();
glMatrixMode(matrixMode);
}
Log logger;
int printLog(char const* fmt, ...) {
int result;
va_list args;
va_start(args,fmt);
result = logger.vprint(fmt, args);
va_end(args);
return result;
}

80
interface/src/Log.h Normal file
View file

@ -0,0 +1,80 @@
//
// Log.h
// interface
//
// Created by Tobias Schwinger on 4/14/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Log__
#define __interface__Log__
#include <stdio.h>
#include <stdarg.h>
#include <glm/glm.hpp>
#include <pthread.h>
class Log;
//
// Call it as you would call 'printf'.
//
int printLog(char const* fmt, ...);
//
// Global instance.
//
extern Log logger;
//
// Logging subsystem.
//
class Log {
FILE* _ptrStream;
char* _arrChars;
char* _ptrCharsEnd;
char** _arrLines;
char** _ptrLinesEnd;
char* _itrWritePos; // character position to write to
char* _itrWriteLineStart; // character position where line being written starts
char** _itrLastLine; // last line in the log
unsigned _valWrittenInLine; // character counter for line wrapping
unsigned _valLineLength; // number of characters before line wrap
unsigned _valLogWidth; // width of the log in pixels
unsigned _valCharWidth; // width of a character in pixels
unsigned _valCharHeight; // height of a character in pixels
unsigned _valCharYoffset; // baseline offset in pixels
float _valCharScale; // scale factor
float _valCharAspect; // aspect (h/w)
pthread_mutex_t _mtx;
public:
explicit Log(FILE* tPipeTo = stdout, unsigned bufferedLines = 1024,
unsigned defaultLogWidth = 240, unsigned defaultCharWidth = 6, unsigned defaultCharHeight = 20);
~Log();
void setLogWidth(unsigned pixels);
void setCharacterSize(unsigned width, unsigned height);
void render(unsigned screenWidth, unsigned screenHeight);
void operator()(char const* fmt, ...);
int vprint(char const* fmt, va_list);
private:
// don't copy/assign
Log(Log const&); // = delete;
Log& operator=(Log const&); // = delete;
inline void addMessage(char const*);
friend class LogStream; // for optional iostream-style interface that has to be #included separately
};
#endif

106
interface/src/LogStream.h Normal file
View file

@ -0,0 +1,106 @@
//
// LogStream.h
// interface
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__LogStream__
#define __interface__LogStream__
#include <sstream>
#include "Log.h"
//
// Makes the logging facility accessible as a C++ stream.
//
// Example:
//
// // somewhere central - ideally one per thread (else pass 'true' as
// // second constructor argument and compromise some efficiency)
// LogStream lOut(printLog);
//
// // elsewhere:
// lOut << "Hello there!" << std::endl;
//
class LogStream {
std::ostringstream _objOutStream;
Log& _refLog;
bool _flgThreadSafe;
public:
inline LogStream(Log& log, bool threadSafe = false);
class StreamRef; friend class StreamRef;
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
private:
// don't
LogStream(LogStream const&); // = delete;
LogStream& operator=(LogStream const&); // = delete;
inline void ostreamBegin();
inline void ostreamEnd();
};
inline LogStream::LogStream(Log& log, bool threadSafe) :
_objOutStream(std::ios_base::out), _refLog(log), _flgThreadSafe(threadSafe) { }
inline void LogStream::ostreamBegin() {
if (_flgThreadSafe) {
// the user wants to share this LogStream among threads,
// so lock the global log here, already
pthread_mutex_lock(& _refLog._mtx);
}
_objOutStream.str("");
}
inline void LogStream::ostreamEnd() {
if (! _flgThreadSafe) {
// haven't locked, so far (we have memory for each thread)
pthread_mutex_lock(& _refLog._mtx);
}
_refLog.addMessage(_objOutStream.str().c_str());
pthread_mutex_unlock(& _refLog._mtx);
}
//
// The Log::StreamRef class makes operator<< work. It...
//
class LogStream::StreamRef {
mutable LogStream* _ptrLogStream;
typedef std::ostream& (*manipulator)(std::ostream&);
friend class LogStream;
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
StreamRef(LogStream* log) : _ptrLogStream(log) { }
public:
// ...forwards << operator calls to stringstream...
template< typename T > StreamRef const operator<<(T const& x) const { _ptrLogStream->_objOutStream << x; return *this; }
// ...has to dance around to make manipulators (such as std::hex, std::endl) work...
StreamRef const operator<<(manipulator x) const { _ptrLogStream->_objOutStream << x; return *this; }
// ...informs the logger that a stream has ended when it has the responsibility...
~StreamRef() { if (_ptrLogStream != 0l) { _ptrLogStream->ostreamEnd(); } }
// ...which is passed on upon copy.
StreamRef(StreamRef const& other) : _ptrLogStream(other._ptrLogStream) { other._ptrLogStream = 0l; }
private:
// don't
StreamRef& operator=(StreamRef const&); // = delete;
};
template< typename T > inline LogStream::StreamRef const operator<<(LogStream& s, T const& x) {
s.ostreamBegin();
s._objOutStream << x;
return LogStream::StreamRef(& s); // calls streamEnd at the end of the stream expression
}
#endif

View file

@ -2,18 +2,19 @@
#define __interface__OpenGlSupport__
#include "InterfaceConfig.h"
#include "Log.h"
/**
* Macro to log OpenGl errors to stderr.
* Example: oglLog( glPushMatrix() );
*/
//
// Macro to log OpenGl errors.
// Example: oglLog( glPushMatrix() );
//
#define oGlLog(stmt) \
stmt; \
{ \
GLenum e = glGetError(); \
if (e != GL_NO_ERROR) { \
fprintf(stderr, __FILE__ ":" oGlLog_stringize(__LINE__) \
" [OpenGL] %s\n", gluErrorString(e)); \
printLog(__FILE__ ":" oGlLog_stringize(__LINE__) \
" [OpenGL] %s\n", gluErrorString(e)); \
} \
} \
(void) 0
@ -21,10 +22,10 @@
#define oGlLog_stringize(x) oGlLog_stringize_i(x)
#define oGlLog_stringize_i(x) # x
/**
* Encapsulation of the otherwise lengthy call sequence to compile
* and link shading pipelines.
*/
//
// Encapsulation of the otherwise lengthy call sequence to compile
// and link shading pipelines.
//
class OGlProgram {
GLuint _hndProg;
@ -54,10 +55,10 @@ public:
}
#endif
/**
* Activates the executable for rendering.
* Shaders must be added and linked before this will work.
*/
//
// Activates the executable for rendering.
// Shaders must be added and linked before this will work.
//
void activate() const {
if (_hndProg != 0u) {
@ -66,17 +67,17 @@ public:
}
}
/**
* Adds a shader to the program.
*/
//
// Adds a shader to the program.
//
bool addShader(GLenum type, GLchar const* cString) {
return addShader(type, 1, & cString);
}
/**
* Adds a shader to the program and logs to stderr.
*/
//
// Adds a shader to the program and logs to stderr.
//
bool addShader(GLenum type, GLsizei nStrings, GLchar const** strings) {
if (! _hndProg && !! glCreateProgram) {
@ -100,9 +101,9 @@ public:
return !! status;
}
/**
* Links the program and logs to stderr.
*/
//
// Links the program and logs to stderr.
//
bool link() {
if (! _hndProg) { return false; }
@ -136,7 +137,7 @@ private:
if (!! logLength) {
GLchar* message = new GLchar[logLength];
getLog(handle, logLength, 0l, message);
fprintf(stderr, "%s\n", message);
printLog("%s\n", message);
delete[] message;
}
}

View file

@ -13,7 +13,6 @@
#include "Util.h"
#include "world.h"
#include "InterfaceConfig.h"
#include <iostream>
class Oscilloscope {
public:

View file

@ -19,6 +19,7 @@
#ifdef __APPLE__
#include <regex.h>
#include <sys/time.h>
#include <string>
#endif
int serialFd;
@ -67,10 +68,10 @@ int SerialInterface::initializePort(char* portname, int baud)
#ifdef __APPLE__
serialFd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
printf("Opening SerialUSB %s: ", portname);
printLog("Opening SerialUSB %s: ", portname);
if (serialFd == -1) {
printf("Failed.\n");
printLog("Failed.\n");
return -1; // Failed to open port
}
struct termios options;
@ -101,7 +102,7 @@ int SerialInterface::initializePort(char* portname, int baud)
tcsetattr(serialFd,TCSANOW,&options);
printf("Connected.\n");
printLog("Connected.\n");
resetSerial();
active = true;
#endif
@ -167,14 +168,13 @@ void SerialInterface::readData() {
int initialSamples = totalSamples;
while (read(serialFd, &bufchar, 1) > 0) {
//std::cout << bufchar[0];
while (read(serialFd, &bufchar, 1) > 0) {
serialBuffer[serialBufferPos] = bufchar[0];
serialBufferPos++;
// Have we reached end of a line of input?
if ((bufchar[0] == '\n') || (serialBufferPos >= MAX_BUFFER)) {
std::string serialLine(serialBuffer, serialBufferPos-1);
//std::cout << serialLine << "\n";
//printLog("%s\n", serialLine.c_str());
int spot;
//int channel = 0;
std::string val;
@ -182,7 +182,7 @@ void SerialInterface::readData() {
spot = serialLine.find_first_of(" ", 0);
if (spot != std::string::npos) {
val = serialLine.substr(0,spot);
//std::cout << val << "\n";
//printLog("%s\n", val.c_str());
if (i < NUM_CHANNELS) lastMeasured[i] = atoi(val.c_str());
else samplesAveraged = atoi(val.c_str());
} else LED = atoi(serialLine.c_str());
@ -208,8 +208,7 @@ void SerialInterface::readData() {
}
if (totalSamples == GRAVITY_SAMPLES) {
gravity = glm::normalize(gravity);
std::cout << "gravity: " << gravity.x << "," <<
gravity.y << "," << gravity.z << "\n";
printLog("gravity: %f,%f,%f\n", gravity.x, gravity.y, gravity.z);
}
totalSamples++;
@ -222,7 +221,7 @@ void SerialInterface::readData() {
gettimeofday(&now, NULL);
if (diffclock(&lastGoodRead, &now) > NO_READ_MAXIMUM_MSECS) {
std::cout << "No data - Shutting down SerialInterface.\n";
printLog("No data - Shutting down SerialInterface.\n");
resetSerial();
}
} else {

View file

@ -10,7 +10,7 @@
#include "Util.h"
#include "world.h"
#include "InterfaceConfig.h"
#include <iostream>
#include "Log.h"
// These includes are for serial port reading/writing
#ifdef __APPLE__
@ -28,9 +28,9 @@
#define ACCEL_Z 5
// Gyro sensors, in coodinate system of head/airplane
#define PITCH_RATE 1
#define YAW_RATE 0
#define ROLL_RATE 2
#define HEAD_PITCH_RATE 1
#define HEAD_YAW_RATE 0
#define HEAD_ROLL_RATE 2
class SerialInterface {
public:

View file

@ -9,6 +9,8 @@
#include "Texture.h"
#include "InterfaceConfig.h"
#include "Log.h"
#include <lodepng.h>
#include <vector>
#include <cstdio>
@ -30,7 +32,7 @@ int load_png_as_texture(char* filename)
unsigned int width = 1, height = 1;
unsigned error = lodepng::decode(image, width, height, filename);
if (error) {
std::cout << "Error loading texture" << std::endl;
printLog("Error loading texture\n");
return (int) error;
}
@ -43,7 +45,7 @@ int load_png_as_texture(char* filename)
if(glGetError() != GL_NO_ERROR)
{
std::cout << "Error initing GL" << std::endl;
printLog("Error initing GL\n");
return 1;
}

View file

@ -9,7 +9,6 @@
#ifndef __interface__Texture__
#define __interface__Texture__
#include <iostream>
#include "InterfaceConfig.h"
int load_png_as_texture(char* filename);

View file

@ -11,11 +11,50 @@
#include <cstring>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <SharedUtil.h>
#include "Log.h"
#include "world.h"
#include "Util.h"
using namespace std;
// no clue which versions are affected...
#define WORKAROUND_BROKEN_GLUT_STROKES
// see http://www.opengl.org/resources/libraries/glut/spec3/node78.html
static float MONO_STROKE_WIDTH_GLUT = 104.76;
void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * front, glm::vec3 * right, glm::vec3 * up) {
//
// Converts from three euler angles to the associated orthonormal vectors
//
// Angles contains (pitch, yaw, roll) in radians
//
// First, create the quaternion associated with these euler angles
glm::quat q(glm::vec3(angles->x, -(angles->y), angles->z));
// Next, create a rotation matrix from that quaternion
glm::mat4 rotation;
rotation = glm::mat4_cast(q);
// Transform the original vectors by the rotation matrix to get the new vectors
glm::vec4 qup(0,1,0,0);
glm::vec4 qright(-1,0,0,0);
glm::vec4 qfront(0,0,1,0);
glm::vec4 upNew = qup*rotation;
glm::vec4 rightNew = qright*rotation;
glm::vec4 frontNew = qfront*rotation;
// Copy the answers to output vectors
up->x = upNew.x; up->y = upNew.y; up->z = upNew.z;
right->x = rightNew.x; right->y = rightNew.y; right->z = rightNew.z;
front->x = frontNew.x; front->y = frontNew.y; front->z = frontNew.z;
}
// Return the azimuth angle in degrees between two points.
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) {
@ -111,12 +150,17 @@ double diffclock(timeval *clock1,timeval *clock2)
return diffms;
}
int widthText(float scale, int mono, char *string) {
int widthText(float scale, int mono, char const* string) {
int width = 0;
if (!mono) {
width = scale * glutStrokeLength(GLUT_STROKE_ROMAN, (const unsigned char *) string);
} else {
#ifndef WORKAROUND_BROKEN_GLUT_STROKES
width = scale * glutStrokeLength(GLUT_STROKE_MONO_ROMAN, (const unsigned char *) string);
#else
// return value is unreliable, so just calculate it
width = scale * float(strlen(string)) * MONO_STROKE_WIDTH_GLUT;
#endif
}
return width;
}
@ -138,8 +182,27 @@ void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
len = (int) strlen(string);
for (i = 0; i < len; i++)
{
if (!mono) glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i]));
else glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int(string[i]));
if (!mono) {
glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i]));
} else {
#ifdef WORKAROUND_BROKEN_GLUT_STROKES
if (string[i] != 'm') {
#endif
glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int(string[i]));
#ifdef WORKAROUND_BROKEN_GLUT_STROKES
} else {
// some glut implementations have a broken 'm'...
unsigned char tmpStr[2];
tmpStr[0] = string[i];
tmpStr[1] = '\0';
float scale = MONO_STROKE_WIDTH_GLUT / glutStrokeLength(GLUT_STROKE_ROMAN, tmpStr);
glScalef(scale, 1.0f, 1.0f);
glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i]));
// staying humble on the stack - might be in projection mode
glScalef(1.0f / scale, 1.0f, 1.0f);
}
#endif
}
}
glPopMatrix();
@ -179,7 +242,7 @@ void drawGroundPlaneGrid( float size, int resolution )
glLineWidth(2.0);
float gridSize = 10.0;
int gridResolution = 10;
int gridResolution = 20;
for (int g=0; g<gridResolution; g++)
{
@ -200,6 +263,15 @@ void drawGroundPlaneGrid( float size, int resolution )
glVertex3f( gridSize * ONE_HALF, 0.0f, inc );
glEnd();
}
// Draw a translucent quad just underneath the grid.
glColor4f(0.5, 0.5, 0.5, 0.4);
glBegin(GL_QUADS);
glVertex3f(-gridSize * ONE_HALF, 0, -gridSize * ONE_HALF);
glVertex3f(gridSize * ONE_HALF, 0, -gridSize * ONE_HALF);
glVertex3f(gridSize * ONE_HALF, 0, gridSize * ONE_HALF);
glVertex3f(-gridSize * ONE_HALF, 0, gridSize * ONE_HALF);
glEnd();
}
@ -227,8 +299,15 @@ void renderOrientationDirections( glm::vec3 position, Orientation orientation, f
glEnd();
}
bool closeEnoughForGovernmentWork(float a, float b) {
float distance = std::abs(a-b);
//printLog("closeEnoughForGovernmentWork() a=%1.10f b=%1.10f distance=%1.10f\n",a,b,distance);
return (distance < 0.00001f);
}
void testOrientationClass() {
printf("\n----------\ntestOrientationClass()\n----------\n\n");
printLog("\n----------\ntestOrientationClass()\n----------\n\n");
oTestCase tests[] = {
// - inputs ------------, outputs -------------------- ------------------- ----------------------------
@ -236,14 +315,45 @@ void testOrientationClass() {
// ( yaw , pitch, roll , front.x , front.y , front.z , up.x , up.y , up.z , right.x , right.y , right.z )
// simple yaw tests
oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f , 0.f , -1.0f , 0.f , 0.f ),
oTestCase( 90.0f, 0.f , 0.f , 1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , 1.0f ),
oTestCase(180.0f, 0.f , 0.f , 0.f , 0.f , -1.0f , 0.f , 1.0f , 0.f , 1.0f , 0.f , 0.f ),
oTestCase(270.0f, 0.f , 0.f , -1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , -1.0f ),
oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f , 0.f , -1.0f , 0.f , 0.f ),
oTestCase(45.0f , 0.f , 0.f , 0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , 0.707107f),
oTestCase( 90.0f, 0.f , 0.f , 1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , 1.0f ),
oTestCase(135.0f, 0.f , 0.f , 0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , 0.707107f),
oTestCase(180.0f, 0.f , 0.f , 0.f , 0.f , -1.0f , 0.f , 1.0f , 0.f , 1.0f , 0.f , 0.f ),
oTestCase(225.0f, 0.f , 0.f , -0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , -0.707107f),
oTestCase(270.0f, 0.f , 0.f , -1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , -1.0f ),
oTestCase(315.0f, 0.f , 0.f , -0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , -0.707107f),
oTestCase(-45.0f, 0.f , 0.f , -0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , -0.707107f),
oTestCase(-90.0f, 0.f , 0.f , -1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , -1.0f ),
oTestCase(-135.0f,0.f , 0.f , -0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , -0.707107f),
oTestCase(-180.0f,0.f , 0.f , 0.f , 0.f , -1.0f , 0.f , 1.0f , 0.f , 1.0f , 0.f , 0.f ),
oTestCase(-225.0f,0.f , 0.f , 0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , 0.707107f),
oTestCase(-270.0f,0.f , 0.f , 1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , 1.0f ),
oTestCase(-315.0f,0.f , 0.f , 0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , 0.707107f),
// simple pitch tests
oTestCase( 0.f ,90.f , 0.f , 0.f , 1.0f , 0.0f , 0.f , 0.0f , -1.0f, -1.0f , 0.f , 0.f ),
oTestCase( 0.f , 0.f , 0.f , 0.f, 0.f , 1.0f , 0.f , 1.0f , 0.f , -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,45.0f , 0.f , 0.f, 0.707107f , 0.707107f, 0.f ,0.707107f, -0.707107f, -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,90.f , 0.f , 0.f, 1.0f , 0.0f , 0.f ,0.0f , -1.0f , -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,135.0f, 0.f , 0.f, 0.707107f , -0.707107f, 0.f ,-0.707107f, -0.707107f, -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,180.f , 0.f , 0.f, 0.0f ,-1.0f , 0.f ,-1.0f , 0.f , -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,225.0f, 0.f , 0.f,-0.707107f , -0.707107f, 0.f ,-0.707107f, 0.707107f, -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,270.f , 0.f , 0.f,-1.0f , 0.0f , 0.f ,0.0f , 1.0f , -1.0f , 0.f , 0.f ),
oTestCase( 0.f ,315.0f, 0.f , 0.f,-0.707107f , 0.707107f, 0.f , 0.707107f, 0.707107f, -1.0f , 0.f , 0.f ),
// simple roll tests
oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f ,0.0f , -1.0f , 0.f , 0.0f ),
oTestCase( 0.f , 0.f ,45.0f , 0.f , 0.f , 1.0f , 0.707107f , 0.707107f ,0.0f , -0.707107f, 0.707107f, 0.0f ),
oTestCase( 0.f , 0.f ,90.f , 0.f , 0.f , 1.0f , 1.0f , 0.0f ,0.0f , 0.0f , 1.0f , 0.0f ),
oTestCase( 0.f , 0.f ,135.0f , 0.f , 0.f , 1.0f , 0.707107f , -0.707107f,0.0f , 0.707107f , 0.707107f, 0.0f ),
oTestCase( 0.f , 0.f ,180.f , 0.f , 0.f , 1.0f , 0.0f , -1.0f ,0.0f , 1.0f , 0.0f , 0.0f ),
oTestCase( 0.f , 0.f ,225.0f , 0.f , 0.f , 1.0f , -0.707107f, -0.707107f,0.0f , 0.707107f ,-0.707107f, 0.0f ),
oTestCase( 0.f , 0.f ,270.f , 0.f , 0.f , 1.0f , -1.0f , 0.0f ,0.0f , 0.0f , -1.0f , 0.0f ),
oTestCase( 0.f , 0.f ,315.0f , 0.f , 0.f , 1.0f , -0.707107f, 0.707107f ,0.0f , -0.707107f,-0.707107f, 0.0f ),
// yaw combo tests
oTestCase( 90.f , 90.f , 0.f , 0.f , 1.0f , 0.0f , -1.0f , 0.0f , 0.f , 0.0f , 0.f , 1.0f ),
oTestCase( 90.f , 0.f , 90.f , 1.0f , 0.0f, 0.f , 0.0f , 0.0f , -1.f , 0.0f , 1.0f , 0.0f ),
};
int failedCount = 0;
@ -267,47 +377,55 @@ void testOrientationClass() {
glm::vec3 up = o1.getUp();
glm::vec3 right = o1.getRight();
printf("\n-----\nTest: %d - yaw=%f , pitch=%f , roll=%f \n\n",i+1,yaw,pitch,roll);
printLog("\n-----\nTest: %d - yaw=%f , pitch=%f , roll=%f \n",i+1,yaw,pitch,roll);
printf(" +front.x=%f, front.y=%f, front.z=%f\n",front.x,front.y,front.z);
if (front.x == tests[i].frontX && front.y == tests[i].frontY && front.z == tests[i].frontZ) {
printf(" front vector PASSES!\n");
printLog("\nFRONT\n");
printLog(" + received: front.x=%f, front.y=%f, front.z=%f\n",front.x,front.y,front.z);
if (closeEnoughForGovernmentWork(front.x, tests[i].frontX)
&& closeEnoughForGovernmentWork(front.y, tests[i].frontY)
&& closeEnoughForGovernmentWork(front.z, tests[i].frontZ)) {
printLog(" front vector PASSES!\n");
} else {
printf(" front vector FAILED! expected: \n");
printf(" front.x=%f, front.y=%f, front.z=%f\n",tests[i].frontX,tests[i].frontY,tests[i].frontZ);
printLog(" expected: front.x=%f, front.y=%f, front.z=%f\n",tests[i].frontX,tests[i].frontY,tests[i].frontZ);
printLog(" front vector FAILED! \n");
passed = false;
}
printf(" +up.x=%f, up.y=%f, up.z=%f\n",up.x,up.y,up.z);
if (up.x == tests[i].upX && up.y == tests[i].upY && up.z == tests[i].upZ) {
printf(" up vector PASSES!\n");
printLog("\nUP\n");
printLog(" + received: up.x=%f, up.y=%f, up.z=%f\n",up.x,up.y,up.z);
if (closeEnoughForGovernmentWork(up.x, tests[i].upX)
&& closeEnoughForGovernmentWork(up.y, tests[i].upY)
&& closeEnoughForGovernmentWork(up.z, tests[i].upZ)) {
printLog(" up vector PASSES!\n");
} else {
printf(" up vector FAILED! expected: \n");
printf(" up.x=%f, up.y=%f, up.z=%f\n",tests[i].upX,tests[i].upY,tests[i].upZ);
printLog(" expected: up.x=%f, up.y=%f, up.z=%f\n",tests[i].upX,tests[i].upY,tests[i].upZ);
printLog(" up vector FAILED!\n");
passed = false;
}
printf(" +right.x=%f, right.y=%f, right.z=%f\n",right.x,right.y,right.z);
if (right.x == tests[i].rightX && right.y == tests[i].rightY && right.z == tests[i].rightZ) {
printf(" right vector PASSES!\n");
printLog("\nRIGHT\n");
printLog(" + received: right.x=%f, right.y=%f, right.z=%f\n",right.x,right.y,right.z);
if (closeEnoughForGovernmentWork(right.x, tests[i].rightX)
&& closeEnoughForGovernmentWork(right.y, tests[i].rightY)
&& closeEnoughForGovernmentWork(right.z, tests[i].rightZ)) {
printLog(" right vector PASSES!\n");
} else {
printf(" right vector FAILED! expected: \n");
printf(" right.x=%f, right.y=%f, right.z=%f\n",tests[i].rightX,tests[i].rightY,tests[i].rightZ);
printLog(" expected: right.x=%f, right.y=%f, right.z=%f\n",tests[i].rightX,tests[i].rightY,tests[i].rightZ);
printLog(" right vector FAILED!\n");
passed = false;
}
if (!passed) {
printf("\n-----\nTest: %d - FAILED! \n----------\n\n",i+1);
printLog("\n-----\nTest: %d - FAILED! \n----------\n\n",i+1);
failedCount++;
}
}
printf("\n-----\nTotal Failed: %d out of %d \n----------\n\n",failedCount,totalTests);
printf("\n----------DONE----------\n\n");
printLog("\n-----\nTotal Failed: %d out of %d \n----------\n\n",failedCount,totalTests);
printLog("\n----------DONE----------\n\n");
}

View file

@ -19,6 +19,7 @@
#include <Orientation.h>
void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, glm::vec3 * up);
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos);
float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw);
@ -26,7 +27,7 @@ float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float
float randFloat();
void render_world_box();
void render_vector(glm::vec3 * vec);
int widthText(float scale, int mono, char *string);
int widthText(float scale, int mono, char const* string);
void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
char const* string, float r=1.0, float g=1.0, float b=1.0);
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec,

View file

@ -17,6 +17,8 @@
#include <PacketHeaders.h>
#include <OctalCode.h>
#include <pthread.h>
#include "Log.h"
#include "VoxelSystem.h"
const int MAX_VOXELS_PER_SYSTEM = 250000;
@ -91,24 +93,24 @@ long int VoxelSystem::getVoxelsCreated() {
return tree->voxelsCreated;
}
long int VoxelSystem::getVoxelsCreatedRunningAverage() {
return tree->voxelsCreatedStats.getRunningAverage();
float VoxelSystem::getVoxelsCreatedPerSecondAverage() {
return (1 / tree->voxelsCreatedStats.getEventDeltaAverage());
}
long int VoxelSystem::getVoxelsColored() {
return tree->voxelsColored;
}
long int VoxelSystem::getVoxelsColoredRunningAverage() {
return tree->voxelsColoredStats.getRunningAverage();
float VoxelSystem::getVoxelsColoredPerSecondAverage() {
return (1 / tree->voxelsColoredStats.getEventDeltaAverage());
}
long int VoxelSystem::getVoxelsBytesRead() {
return tree->voxelsBytesRead;
}
long int VoxelSystem::getVoxelsBytesReadRunningAverage() {
return tree->voxelsBytesReadStats.getRunningAverage();
float VoxelSystem::getVoxelsBytesReadPerSecondAverage() {
return tree->voxelsBytesReadStats.getAverageSampleValuePerSecond();
}
@ -136,15 +138,15 @@ void VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
int commandLength = strlen(command); // commands are null terminated strings
int totalLength = 1+commandLength+1;
printf("got Z message len(%d)= %s\n", numBytes, command);
printLog("got Z message len(%d)= %s\n", numBytes, command);
while (totalLength <= numBytes) {
if (0==strcmp(command,(char*)"erase all")) {
printf("got Z message == erase all\n");
printLog("got Z message == erase all\n");
tree->eraseAllVoxels();
}
if (0==strcmp(command,(char*)"add scene")) {
printf("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n");
printLog("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n");
}
totalLength += commandLength+1;
}
@ -194,14 +196,14 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) {
float viewerZ = swapXandZ ? viewerPosition[0] : viewerPosition[2];
// debugging code.
//printf("treeToArrays() halfUnitForVoxel=%f\n",halfUnitForVoxel);
//printf("treeToArrays() viewerPosition {x,y,z or [0],[1],[2]} ={%f,%f,%f}\n",
// viewerPosition[0],viewerPosition[1],viewerPosition[2]);
//printf("treeToArrays() nodePosition {x,y,z or [0],[1],[2]} = {%f,%f,%f}\n",
// nodePosition[0],nodePosition[1],nodePosition[2]);
//printLog("treeToArrays() halfUnitForVoxel=%f\n",halfUnitForVoxel);
//printLog("treeToArrays() viewerPosition {x,y,z or [0],[1],[2]} ={%f,%f,%f}\n",
// viewerPosition[0],viewerPosition[1],viewerPosition[2]);
//printLog("treeToArrays() nodePosition {x,y,z or [0],[1],[2]} = {%f,%f,%f}\n",
// nodePosition[0],nodePosition[1],nodePosition[2]);
//float* vertices = firstVertexForCode(currentNode->octalCode);
//printf("treeToArrays() firstVerticesForCode(currentNode->octalCode)={x,y,z or [0],[1],[2]} = {%f,%f,%f}\n",
// vertices[0],vertices[1],vertices[2]);
//printLog("treeToArrays() firstVerticesForCode(currentNode->octalCode)={x,y,z or [0],[1],[2]} = {%f,%f,%f}\n",
// vertices[0],vertices[1],vertices[2]);
//delete []vertices;
float distanceToVoxelCenter = sqrtf(powf(viewerX - nodePosition[0] - halfUnitForVoxel, 2) +
@ -209,7 +211,7 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) {
powf(viewerZ - nodePosition[2] - halfUnitForVoxel, 2));
int boundaryPosition = boundaryDistanceForRenderLevel(*currentNode->octalCode + 1);
//printf("treeToArrays() distanceToVoxelCenter=%f boundaryPosition=%d\n",distanceToVoxelCenter,boundaryPosition);
//printLog("treeToArrays() distanceToVoxelCenter=%f boundaryPosition=%d\n",distanceToVoxelCenter,boundaryPosition);
bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring

View file

@ -11,7 +11,6 @@
#include "InterfaceConfig.h"
#include <glm/glm.hpp>
#include <iostream>
#include <UDPSocket.h>
#include <AgentData.h>
#include <VoxelTree.h>
@ -41,9 +40,9 @@ public:
long int getVoxelsCreated();
long int getVoxelsColored();
long int getVoxelsBytesRead();
long int getVoxelsCreatedRunningAverage();
long int getVoxelsColoredRunningAverage();
long int getVoxelsBytesReadRunningAverage();
float getVoxelsCreatedPerSecondAverage();
float getVoxelsColoredPerSecondAverage();
float getVoxelsBytesReadPerSecondAverage();
private:
int voxelsRendered;

View file

@ -24,8 +24,6 @@
//
#include "InterfaceConfig.h"
#include <iostream>
#include <fstream>
#include <math.h>
#include <string.h>
#include <sstream>
@ -47,6 +45,11 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Log.h"
#include "shared_Log.h"
#include "voxels_Log.h"
#include "avatars_Log.h"
#include "Field.h"
#include "world.h"
#include "Util.h"
@ -71,9 +74,11 @@
#include "Oscilloscope.h"
#include "UDPSocket.h"
#include "SerialInterface.h"
#include <PerfStat.h>
#include <SharedUtil.h>
#include <PacketHeaders.h>
#include <AvatarData.h>
#include <PerfStat.h>
#include <SimpleMovingAverage.h>
#include "ViewFrustum.h"
@ -146,11 +151,11 @@ float renderPitchRate = 0.f;
// Where one's own agent begins in the world (needs to become a dynamic thing passed to the program)
glm::vec3 start_location(6.1f, 0, 1.4f);
int statsOn = 0; // Whether to show onscreen text overlay with stats
bool starsOn = false; // Whether to display the stars
bool paintOn = false; // Whether to paint voxels as you fly around
VoxelDetail paintingVoxel; // The voxel we're painting if we're painting
unsigned char dominantColor = 0; // The dominant color of the voxel we're painting
bool statsOn = false; // Whether to show onscreen text overlay with stats
bool starsOn = false; // Whether to display the stars
bool paintOn = false; // Whether to paint voxels as you fly around
VoxelDetail paintingVoxel; // The voxel we're painting if we're painting
unsigned char dominantColor = 0; // The dominant color of the voxel we're painting
bool perfStatsOn = false; // Do we want to display perfStats?
int noiseOn = 0; // Whether to add random noise
@ -166,8 +171,8 @@ int headMouseX, headMouseY;
int mouseX, mouseY; // Where is the mouse
// Mouse location at start of last down click
int mouseStartX;// = WIDTH / 2;
int mouseStartY;// = HEIGHT / 2;
int mouseStartX = WIDTH / 2;
int mouseStartY = HEIGHT / 2;
int mousePressed = 0; // true if mouse has been pressed (clear when finished)
Menu menu; // main menu
@ -235,31 +240,36 @@ void displayStats(void)
std::stringstream voxelStats;
voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered();
drawtext(10, statsVerticalOffset + 70, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
voxelStats.str("");
voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() << " (" << voxels.getVoxelsCreatedRunningAverage()
<< "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() << " (" << voxels.getVoxelsCreatedPerSecondAverage()
<< "/sec) ";
drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
voxelStats.str("");
voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() << " (" << voxels.getVoxelsColoredRunningAverage()
<< "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() << " (" << voxels.getVoxelsColoredPerSecondAverage()
<< "/sec) ";
drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
voxelStats.str("");
voxelStats << "Voxels Bytes Read: " << voxels.getVoxelsBytesRead()
<< " (" << voxels.getVoxelsBytesReadRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
voxelStats << "Voxels Bytes Read: " << voxels.getVoxelsBytesRead()
<< " (" << voxels.getVoxelsBytesReadPerSecondAverage() << " Bps)";
drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
voxelStats.str("");
long int voxelsBytesPerColored = voxels.getVoxelsColored() ? voxels.getVoxelsBytesRead()/voxels.getVoxelsColored() : 0;
long int voxelsBytesPerColoredAvg = voxels.getVoxelsColoredRunningAverage() ?
voxels.getVoxelsBytesReadRunningAverage()/voxels.getVoxelsColoredRunningAverage() : 0;
voxelStats << "Voxels Bytes per Colored: " << voxelsBytesPerColored
<< " (" << voxelsBytesPerColoredAvg << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
float voxelsBytesPerColored = voxels.getVoxelsColored()
? ((float) voxels.getVoxelsBytesRead() / voxels.getVoxelsColored())
: 0;
voxelStats << "Voxels Bytes per Colored: " << voxelsBytesPerColored;
drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
Agent *avatarMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER);
char avatarMixerStats[200];
sprintf(avatarMixerStats, "Avatar Mixer - %.f kbps, %.f pps",
roundf(avatarMixer->getAverageKilobitsPerSecond()),
roundf(avatarMixer->getAveragePacketsPerSecond()));
drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats);
if (::perfStatsOn) {
// Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups
@ -315,9 +325,9 @@ void init(void)
marker_capturer.position_updated(&position_updated);
marker_capturer.frame_updated(&marker_frame_available);
if(!marker_capturer.init_capture()){
printf("Camera-based marker capture initialized.\n");
printLog("Camera-based marker capture initialized.\n");
}else{
printf("Error initializing camera-based marker capture.\n");
printLog("Error initializing camera-based marker capture.\n");
}
}
#endif
@ -359,6 +369,7 @@ void reset_sensors()
}
}
/*
void updateAvatarHand(float deltaTime) {
// If mouse is being dragged, send current force to the hand controller
if (mousePressed == 1)
@ -372,14 +383,15 @@ void updateAvatarHand(float deltaTime) {
//myAvatar.hand->addVelocity(vel*deltaTime);
}
}
*/
//
// Using gyro data, update both view frustum and avatar head position
//
void updateAvatar(float frametime)
{
float gyroPitchRate = serialPort.getRelativeValue(PITCH_RATE);
float gyroYawRate = serialPort.getRelativeValue(YAW_RATE);
float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE);
float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE );
myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity);
@ -450,6 +462,8 @@ void updateAvatar(float frametime)
*broadcastString = PACKET_HEADER_HEAD_DATA;
int broadcastBytes = myAvatar.getBroadcastData(broadcastString + 1);
broadcastBytes++;
const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER};
AgentList::getInstance()->broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2);
@ -527,30 +541,39 @@ void render_view_frustum() {
glm::vec3 up;
glm::vec3 right;
float fov, nearClip, farClip;
float yaw, pitch, roll;
// Camera or Head?
if (::cameraFrustum) {
position = ::myCamera.getPosition();
direction = ::myCamera.getOrientation().getFront() * glm::vec3(1,1,-1);
up = ::myCamera.getOrientation().getUp() * glm::vec3(1,1,1);
right = ::myCamera.getOrientation().getRight() * glm::vec3(1,1,-1);
fov = ::myCamera.getFieldOfView();
nearClip = ::myCamera.getNearClip();
farClip = ::myCamera.getFarClip();
} else {
position = ::myAvatar.getHeadPosition();
direction = ::myAvatar.getHeadLookatDirection();
up = ::myAvatar.getHeadLookatDirectionUp();
right = ::myAvatar.getHeadLookatDirectionRight() * glm::vec3(-1,1,-1);
// NOTE: we use the same lens details if we draw from the head
fov = ::myCamera.getFieldOfView();
nearClip = ::myCamera.getNearClip();
farClip = ::myCamera.getFarClip();
}
// This bit of hackery is all because our Cameras report the incorrect yaw.
// For whatever reason, the camera has a yaw set to 180.0-trueYaw, so we basically
// need to get the "yaw" from the camera and adjust it to be the trueYaw
yaw = -(::myCamera.getOrientation().getYaw()-180);
pitch = ::myCamera.getOrientation().getPitch();
roll = ::myCamera.getOrientation().getRoll();
fov = ::myCamera.getFieldOfView();
nearClip = ::myCamera.getNearClip();
farClip = ::myCamera.getFarClip();
// We can't use the camera's Orientation because of it's broken yaw. so we make a new
// correct orientation to get our vectors
Orientation o;
o.yaw(yaw);
o.pitch(pitch);
o.roll(roll);
direction = o.getFront();
up = o.getUp();
right = o.getRight();
/*
printf("position.x=%f, position.y=%f, position.z=%f\n", position.x, position.y, position.z);
printf("yaw=%f, pitch=%f, roll=%f\n", yaw,pitch,roll);
printf("direction.x=%f, direction.y=%f, direction.z=%f\n", direction.x, direction.y, direction.z);
printf("up.x=%f, up.y=%f, up.z=%f\n", up.x, up.y, up.z);
printf("right.x=%f, right.y=%f, right.z=%f\n", right.x, right.y, right.z);
@ -558,7 +581,7 @@ void render_view_frustum() {
printf("nearClip=%f\n", nearClip);
printf("farClip=%f\n", farClip);
*/
// Set the viewFrustum up with the correct position and orientation of the camera
viewFrustum.setPosition(position);
viewFrustum.setOrientation(direction,up,right);
@ -719,7 +742,7 @@ void display(void)
//----------------------------------------------------
myCamera.setTargetPosition ( myAvatar.getBodyPosition() );
myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() );
myCamera.setPitch ( 10.0 ); // temporarily, this must be 0.0 or else bad juju
myCamera.setPitch ( 0.0 ); // temporarily, this must be 0.0 or else bad juju
myCamera.setRoll ( 0.0 );
myCamera.setUp ( 0.45);
myCamera.setDistance ( 1.0 );
@ -816,8 +839,6 @@ void display(void)
if (agent->getLinkedData() != NULL) {
Head *agentHead = (Head *)agent->getLinkedData();
glPushMatrix();
glm::vec3 pos = agentHead->getBodyPosition();
glTranslatef(-pos.x, -pos.y, -pos.z);
agentHead->render(0);
glPopMatrix();
}
@ -831,7 +852,6 @@ void display(void)
// brad's frustum for debugging
if (::frustumOn) render_view_frustum();
//Render my own avatar
myAvatar.render(true);
}
@ -874,6 +894,7 @@ void display(void)
glLineWidth(1.0f);
glPointSize(1.0f);
displayStats();
logger.render(WIDTH, HEIGHT);
}
// Show menu
@ -1073,7 +1094,7 @@ void testPointToVoxel()
float s=0.1;
for (float x=0; x<=1; x+= 0.05)
{
std::cout << " x=" << x << " ";
printLog(" x=%f");
unsigned char red = 200; //randomColorValue(65);
unsigned char green = 200; //randomColorValue(65);
@ -1082,7 +1103,7 @@ void testPointToVoxel()
unsigned char* voxelCode = pointToVoxel(x, y, z, s,red,green,blue);
printVoxelCode(voxelCode);
delete voxelCode;
std::cout << std::endl;
printLog("\n");
}
}
@ -1091,7 +1112,7 @@ void sendVoxelServerEraseAll() {
sprintf(message,"%c%s",'Z',"erase all");
int messageSize = strlen(message) + 1;
AgentList::getInstance()->broadcastToAgents((unsigned char*) message, messageSize, &AGENT_TYPE_VOXEL, 1);
}\
}
void sendVoxelServerAddScene() {
char message[100];
@ -1129,11 +1150,11 @@ void addRandomSphere(bool wantColorRandomizer)
float s = 0.001; // size of voxels to make up surface of sphere
bool solid = false;
printf("random sphere\n");
printf("radius=%f\n",r);
printf("xc=%f\n",xc);
printf("yc=%f\n",yc);
printf("zc=%f\n",zc);
printLog("random sphere\n");
printLog("radius=%f\n",r);
printLog("xc=%f\n",xc);
printLog("yc=%f\n",yc);
printLog("zc=%f\n",zc);
voxels.createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
}
@ -1296,7 +1317,7 @@ void *networkReceive(void *args)
AgentList::getInstance()->processBulkAgentData(&senderAddress,
incomingPacket,
bytesReceived,
(sizeof(float) * 3) + (sizeof(uint16_t) * 3));
BYTES_PER_AVATAR);
break;
default:
AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived);
@ -1317,22 +1338,21 @@ void idle(void) {
// Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time
if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) {
// If mouse is being dragged, update hand movement in the avatar
//if ( mousePressed == 1 )
if ( myAvatar.getMode() == AVATAR_MODE_COMMUNICATING ) {
//if ( myAvatar.getMode() == AVATAR_MODE_COMMUNICATING ) {
float leftRight = ( mouseX - mouseStartX ) / (float)WIDTH;
float downUp = ( mouseY - mouseStartY ) / (float)HEIGHT;
float backFront = 0.0;
glm::vec3 handMovement( leftRight, downUp, backFront );
myAvatar.setHandMovement( handMovement );
}
/*}
else {
mouseStartX = mouseX;
mouseStartY = mouseY;
//mouseStartX = (float)WIDTH / 2.0f;
//mouseStartY = (float)HEIGHT / 2.0f;
}
*/
//--------------------------------------------------------
// when the mouse is being pressed, an 'action' is being
@ -1344,31 +1364,33 @@ void idle(void) {
else {
myAvatar.setTriggeringAction( false );
}
float deltaTime = 1.f/FPS;
//
// Sample hardware, update view frustum if needed, send avatar data to mixer/agents
// Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents
//
updateAvatar( 1.f/FPS );
//test
/*
for(std::vector<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++)
//loop through all the other avatars and simulate them.
AgentList * agentList = AgentList::getInstance();
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++)
{
if (agent->getLinkedData() != NULL)
{
Head *agentHead = (Head *)agent->getLinkedData();
agentHead->simulate(1.f/FPS);
Head *avatar = (Head *)agent->getLinkedData();
avatar->simulate(deltaTime);
}
}
*/
updateAvatarHand(1.f/FPS);
//updateAvatarHand(1.f/FPS);
field.simulate(1.f/FPS);
myAvatar.simulate(1.f/FPS);
balls.simulate(1.f/FPS);
cloud.simulate(1.f/FPS);
field.simulate (deltaTime);
myAvatar.simulate(deltaTime);
balls.simulate (deltaTime);
cloud.simulate (deltaTime);
glutPostRedisplay();
lastTimeIdle = check;
@ -1403,7 +1425,7 @@ void reshape(int width, int height)
farClip = ::myCamera.getFarClip();
}
//printf("reshape() width=%d, height=%d, aspectRatio=%f fov=%f near=%f far=%f \n",
//printLog("reshape() width=%d, height=%d, aspectRatio=%f fov=%f near=%f far=%f \n",
// width,height,aspectRatio,fov,nearClip,farClip);
// Tell our viewFrustum about this change
@ -1483,8 +1505,15 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) {
int main(int argc, const char * argv[])
{
shared_lib::printLog = & ::printLog;
voxels_lib::printLog = & ::printLog;
avatars_lib::printLog = & ::printLog;
// Quick test of the Orientation class on startup!
testOrientationClass();
if (cmdOptionExists(argc, argv, "--testOrientation")) {
testOrientationClass();
return EXIT_SUCCESS;
}
AgentList::createInstance(AGENT_TYPE_INTERFACE);
@ -1496,7 +1525,7 @@ int main(int argc, const char * argv[])
// Handle Local Domain testing with the --local command line
if (cmdOptionExists(argc, argv, "--local")) {
printf("Local Domain MODE!\n");
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));
}
@ -1536,11 +1565,11 @@ int main(int argc, const char * argv[])
viewFrustumOffsetCamera.setNearClip(0.1);
viewFrustumOffsetCamera.setFarClip(500.0);
printf( "Created Display Window.\n" );
printLog( "Created Display Window.\n" );
initMenu();
initDisplay();
printf( "Initialized Display.\n" );
printLog( "Initialized Display.\n" );
glutDisplayFunc(display);
glutReshapeFunc(reshape);
@ -1554,7 +1583,7 @@ int main(int argc, const char * argv[])
glutIdleFunc(idle);
init();
printf( "Init() complete.\n" );
printLog( "Init() complete.\n" );
// Check to see if the user passed in a command line option for randomizing colors
if (cmdOptionExists(argc, argv, "--NoColorRandomizer")) {
@ -1566,17 +1595,17 @@ int main(int argc, const char * argv[])
const char* voxelsFilename = getCmdOption(argc, argv, "-i");
if (voxelsFilename) {
voxels.loadVoxelsFile(voxelsFilename,wantColorRandomizer);
printf("Local Voxel File loaded.\n");
printLog("Local Voxel File loaded.\n");
}
// create thread for receipt of data via UDP
pthread_create(&networkReceiveThread, NULL, networkReceive, NULL);
printf("Network receive thread created.\n");
printLog("Network receive thread created.\n");
glutTimerFunc(1000, Timer, 0);
glutMainLoop();
printf("Normal exit.\n");
printLog("Normal exit.\n");
::terminate();
return EXIT_SUCCESS;
}

View file

@ -39,6 +39,7 @@
#include "InterfaceConfig.h"
#include "OGlProgram.h"
#include "Log.h"
#include <cstddef>
#include <cfloat>

View file

@ -211,7 +211,7 @@ namespace starfield {
return false;
}
// fprintf(stderr, "Stars.cpp: setResolution(%d)\n", k);
// printLog("Stars.cpp: setResolution(%d)\n", k);
#if STARFIELD_MULTITHREADING
if (k != _valTileResolution.load(memory_order_relaxed))
@ -251,7 +251,7 @@ namespace starfield {
VertexOrder scanner(tiling);
radix2InplaceSort(_seqInput.begin(), _seqInput.end(), scanner);
// fprintf(stderr,
// printLog(
// "Stars.cpp: recreateRenderer(%d, %d, %d, %d)\n", n, k, b, bMin);
recreateRenderer(n, k, b, bMin);
@ -266,7 +266,7 @@ namespace starfield {
assert(overalloc >= realloc && realloc >= 0.0);
assert(overalloc <= 1.0 && realloc <= 1.0);
// fprintf(stderr,
// printLog(
// "Stars.cpp: changeLOD(%lf, %lf, %lf)\n", factor, overalloc, realloc);
size_t n, nRender;
@ -307,7 +307,7 @@ namespace starfield {
_valLodBrightness = b;
#endif
// fprintf(stderr, "Stars.cpp: "
// printLog("Stars.cpp: "
// "fraction = %lf, oaFract = %lf, n = %d, n' = %d, bMin = %d, b = %d\n",
// fraction, oaFract, toBufSize(oaFract * last)), n, bMin, b);
@ -327,7 +327,7 @@ namespace starfield {
recreateRenderer(n, _valTileResolution, b, bMin);
// fprintf(stderr, "Stars.cpp: LOD reallocation\n");
// printLog("Stars.cpp: LOD reallocation\n");
// publish new lod state

View file

@ -45,13 +45,12 @@ namespace starfield {
if (! UrlReader::readUrl(url, *this, cacheFile))
{
fprintf(stderr, "%s:%d: %s\n",
printLog("%s:%d: %s\n",
_strUrl, _valLineNo, getError());
return false;
}
fprintf(stderr, "Stars.cpp: read %u vertices, using %lu\n",
_valRecordsRead, _ptrVertices->size());
printLog("Stars.cpp: read %u vertices, using %lu\n", _valRecordsRead, _ptrVertices->size());
return true;
}
@ -72,7 +71,7 @@ namespace starfield {
_ptrVertices->clear();
_ptrVertices->reserve(_valLimit);
// fprintf(stderr, "Stars.cpp: loader begin %s\n", url);
// printLog("Stars.cpp: loader begin %s\n", url);
}
size_t transfer(char* input, size_t bytes) {
@ -111,7 +110,7 @@ namespace starfield {
} else {
fprintf(stderr, "Stars.cpp:%d: Bad input from %s\n",
printLog("Stars.cpp:%d: Bad input from %s\n",
_valLineNo, _strUrl);
}
@ -136,7 +135,7 @@ namespace starfield {
// remember the brightness at its top
if (_valRecordsRead == _valLimit) {
// fprintf(stderr, "Stars.cpp: vertex limit reached -> heap mode\n");
// printLog("Stars.cpp: vertex limit reached -> heap mode\n");
make_heap(
_ptrVertices->begin(), _ptrVertices->end(),

View file

@ -125,7 +125,7 @@ namespace starfield {
mat4 const& orientation,
BrightnessLevel minBright) {
// fprintf(stderr, "
// printLog("
// Stars.cpp: rendering at minimal brightness %d\n", minBright);
float halfPersp = perspective * 0.5f;
@ -161,8 +161,10 @@ namespace starfield {
#if STARFIELD_HEMISPHERE_ONLY
altitude = std::max(0.0f, altitude);
#endif
// fprintf(stderr, "Stars.cpp: starting on tile #%d\n", tileIndex);
unsigned tileIndex =
_objTiling.getTileIndex(azimuth, altitude);
// printLog("Stars.cpp: starting on tile #%d\n", tileIndex);
#if STARFIELD_DEBUG_CULLING
mat4 matrix_debug = glm::translate(glm::frustum(-hw, hw, -hh, hh, nearClip, 10.0f),
@ -248,7 +250,7 @@ namespace starfield {
if (bv >= b)
++count_active;
// fprintf(stderr, "Stars.cpp: Vertex %d on tile #%d\n", vertexIndex, tileIndex);
// printLog("Stars.cpp: Vertex %d on tile #%d\n", vertexIndex, tileIndex);
// write converted vertex
_arrData[vertexIndex++] = *i;
@ -403,7 +405,7 @@ namespace starfield {
float dal = halfSlice;
float adjustedNear = cos(_valHalfPersp + sqrt(daz * daz + dal * dal));
// fprintf(stderr, "Stars.cpp: checking tile #%d, w = %f, near = %f\n", i, w, nearClip);
// printLog("Stars.cpp: checking tile #%d, w = %f, near = %f\n", i, w, nearClip);
return w >= adjustedNear;
}
@ -513,10 +515,10 @@ namespace starfield {
void glBatch(GLfloat const* matrix, GLsizei n_ranges) {
// fprintf(stderr, "Stars.cpp: rendering %d-multibatch\n", n_ranges);
// printLog("Stars.cpp: rendering %d-multibatch\n", n_ranges);
// for (int i = 0; i < n_ranges; ++i)
// fprintf(stderr, "Stars.cpp: Batch #%d - %d stars @ %d\n", i,
// printLog("Stars.cpp: Batch #%d - %d stars @ %d\n", i,
// _arrBatchOffs[i], _arrBatchCount[i]);
glDisable(GL_DEPTH_TEST);

View file

@ -10,9 +10,14 @@
#include <cstring>
#include <stdint.h>
#include <SharedUtil.h>
#include <PacketHeaders.h>
#include "AvatarData.h"
#include "avatars_Log.h"
using avatars_lib::printLog;
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0);
@ -23,8 +28,8 @@ int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
return sizeof(uint16_t);
}
int unpackFloatAngleFromTwoByte(uint16_t *byteAnglePointer, float *destinationPointer) {
*destinationPointer = (*byteAnglePointer / std::numeric_limits<uint16_t>::max()) * 360.0 - 180;
int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer) {
*destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.0 - 180;
return sizeof(uint16_t);
}
@ -60,14 +65,13 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3);
destinationBuffer += sizeof(float) * 3;
//std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n";
//printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z);
return destinationBuffer - bufferStart;
}
// called on the other agents - assigns it to my views of the others
void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
// increment to push past the packet header
sourceBuffer++;
@ -80,7 +84,11 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3);
sourceBuffer += sizeof(float) * 3;
//printLog( "_bodyYaw = %f", _bodyYaw );
//printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z);
//printLog("%f, %f, %f\n", _bodyPosition.x, _bodyPosition.y, _bodyPosition.z);
}
glm::vec3 AvatarData::getBodyPosition() {

View file

@ -9,12 +9,12 @@
#ifndef __hifi__AvatarData__
#define __hifi__AvatarData__
#include <iostream>
#include <glm/glm.hpp>
#include <AgentData.h>
const int BYTES_PER_AVATAR = 30;
class AvatarData : public AgentData {
public:
AvatarData();

View file

@ -7,19 +7,34 @@
#include "Orientation.h"
#include <SharedUtil.h>
#include "avatars_Log.h"
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
//#include "Util.h"
static bool testingForNormalizationAndOrthogonality = true;
using avatars_lib::printLog;
// XXXBHG - this test has not yet been reworked to match the correct vector orientation
// of the coordinate system, so don't use it for now.
//
// tosh - yep, I noticed... :-)
//
// JJV - I noticed too :-)
//
static bool testingForNormalizationAndOrthogonality = false;
Orientation::Orientation() {
setToIdentity();
}
void Orientation::setToIdentity() {
right = glm::vec3( 1.0, 0.0, 0.0 );
up = glm::vec3( 0.0, 1.0, 0.0 );
front = glm::vec3( 0.0, 0.0, 1.0 );
_yaw = 0.0;
_pitch = 0.0;
_roll = 0.0;
right = glm::vec3( -1.0f, 0.0f, 0.0f );
up = glm::vec3( 0.0f, 1.0f, 0.0f );
front = glm::vec3( 0.0f, 0.0f, 1.0f );
}
void Orientation::set( Orientation o ) {
@ -28,79 +43,82 @@ void Orientation::set( Orientation o ) {
front = o.front;
}
void Orientation::update() {
void Orientation::yaw( float angle ) {
float r = angle * PI_OVER_180;
float s = sin(r);
float c = cos(r);
glm::vec3 cosineFront = front * c;
glm::vec3 cosineRight = right * c;
glm::vec3 sineFront = front * s;
glm::vec3 sineRight = right * s;
front = cosineFront + sineRight;
right = cosineRight - sineFront;
float pitchRads = _pitch * PI_OVER_180;
float yawRads = _yaw * PI_OVER_180;
float rollRads = _roll * PI_OVER_180;
glm::quat q(glm::vec3(pitchRads, -(yawRads), rollRads));
// Next, create a rotation matrix from that quaternion
glm::mat4 rotation;
rotation = glm::mat4_cast(q);
// Transform the original vectors by the rotation matrix to get the new vectors
glm::vec4 qup(0,1,0,0);
glm::vec4 qright(-1,0,0,0);
glm::vec4 qfront(0,0,1,0);
glm::vec4 upNew = qup*rotation;
glm::vec4 rightNew = qright*rotation;
glm::vec4 frontNew = qfront*rotation;
// Copy the answers to output vectors
up.x = upNew.x;
up.y = upNew.y;
up.z = upNew.z;
right.x = rightNew.x;
right.y = rightNew.y;
right.z = rightNew.z;
front.x = frontNew.x;
front.y = frontNew.y;
front.z = frontNew.z;
if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); }
}
void Orientation::yaw(float angle) {
// remember the value for any future changes to other angles
_yaw = angle;
update();
}
void Orientation::pitch( float angle ) {
float r = angle * PI_OVER_180;
float s = sin(r);
float c = cos(r);
glm::vec3 cosineUp = up * c;
glm::vec3 cosineFront = front * c;
glm::vec3 sineUp = up * s;
glm::vec3 sineFront = front * s;
up = cosineUp + sineFront;
front = cosineFront - sineUp;
if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); }
// remember the value for any future changes to other angles
_pitch = angle;
update();
}
void Orientation::roll( float angle ) {
float r = angle * PI_OVER_180;
float s = sin(r);
float c = cos(r);
glm::vec3 cosineUp = up * c;
glm::vec3 cosineRight = right * c;
glm::vec3 sineUp = up * s;
glm::vec3 sineRight = right * s;
up = cosineUp + sineRight;
right = cosineRight - sineUp;
if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); }
_roll = angle;
update();
}
void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) {
right = r;
up = u;
front = f;
right = r;
up = u;
front = f;
}
//----------------------------------------------------------------------
void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) {
//------------------------------------------------------------------
// XXXBHG - this test has not yet been reworked to match the correct vector orientation
// of the coordinate system
// bail for now, assume all is good
return;
// make sure vectors are normalized (or close enough to length 1.0)
//------------------------------------------------------------------
float rightLength = glm::length( right );
float upLength = glm::length( up );
float frontLength = glm::length( front );
if (( rightLength > 1.0f + epsilon )
|| ( rightLength < 1.0f - epsilon )) {
printf( "Error in Orientation class: right direction length is %f \n", rightLength );
printLog( "Error in Orientation class: right direction length is %f \n", rightLength );
}
assert ( rightLength > 1.0f - epsilon );
assert ( rightLength < 1.0f + epsilon );
@ -108,7 +126,7 @@ void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) {
if (( upLength > 1.0f + epsilon )
|| ( upLength < 1.0f - epsilon )) {
printf( "Error in Orientation class: up direction length is %f \n", upLength );
printLog( "Error in Orientation class: up direction length is %f \n", upLength );
}
assert ( upLength > 1.0f - epsilon );
assert ( upLength < 1.0f + epsilon );
@ -116,16 +134,13 @@ void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) {
if (( frontLength > 1.0f + epsilon )
|| ( frontLength < 1.0f - epsilon )) {
printf( "Error in Orientation class: front direction length is %f \n", frontLength );
printLog( "Error in Orientation class: front direction length is %f \n", frontLength );
}
assert ( frontLength > 1.0f - epsilon );
assert ( frontLength < 1.0f + epsilon );
//----------------------------------------------------------------
// make sure vectors are orthogonal (or close enough)
//----------------------------------------------------------------
glm::vec3 rightCross = glm::cross( up, front );
glm::vec3 upCross = glm::cross( front, right );
glm::vec3 frontCross = glm::cross( right, up );
@ -136,22 +151,22 @@ void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) {
if ( rightDiff > epsilon ) {
printf( "Error in Orientation class: right direction not orthogonal to up and/or front. " );
printf( "The tested cross of up and front is off by %f \n", rightDiff );
printLog( "Error in Orientation class: right direction not orthogonal to up and/or front. " );
printLog( "The tested cross of up and front is off by %f \n", rightDiff );
}
assert ( rightDiff < epsilon );
if ( upDiff > epsilon ) {
printf( "Error in Orientation class: up direction not orthogonal to front and/or right. " );
printf( "The tested cross of front and right is off by %f \n", upDiff );
printLog( "Error in Orientation class: up direction not orthogonal to front and/or right. " );
printLog( "The tested cross of front and right is off by %f \n", upDiff );
}
assert ( upDiff < epsilon );
if ( frontDiff > epsilon ) {
printf( "Error in Orientation class: front direction not orthogonal to right and/or up. " );
printf( "The tested cross of right and up is off by %f \n", frontDiff );
printLog( "Error in Orientation class: front direction not orthogonal to right and/or up. " );
printLog( "The tested cross of right and up is off by %f \n", frontDiff );
}
assert ( frontDiff < epsilon );
}

View file

@ -20,6 +20,13 @@ enum Axis
class Orientation
{
private:
float _yaw;
float _pitch;
float _roll;
void update(); // actually updates the vectors from yaw, pitch, roll
public:
Orientation();
@ -27,6 +34,10 @@ public:
void pitch ( float );
void roll ( float );
float getYaw() { return _yaw; };
float getPitch(){ return _pitch; };
float getRoll(){ return _roll; };
void set( Orientation );
void setToIdentity();

View file

@ -0,0 +1,17 @@
//
// avatars_Log.cpp
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "shared_Log.h"
#include <cstdio>
namespace avatars_lib {
using namespace std;
int (* printLog)(char const*, ...) = & printf;
}

View file

@ -0,0 +1,20 @@
//
// avatars_Log.h
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__avatars_Log__
#define __hifi__avatars_Log__
namespace avatars_lib {
// variable that can be set from outside to redirect the log output
// of this library
extern int (* printLog)(char const*, ...);
}
#endif /* defined(__hifi__avatars_Log__) */

View file

@ -10,6 +10,7 @@
#include "Agent.h"
#include "AgentTypes.h"
#include <cstring>
#include "shared_Log.h"
#include "UDPSocket.h"
#include "SharedUtil.h"
@ -19,6 +20,8 @@
#include <arpa/inet.h>
#endif
using shared_lib::printLog;
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) {
publicSocket = new sockaddr;
memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr));
@ -34,6 +37,7 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent
activeSocket = NULL;
linkedData = NULL;
_bytesReceivedMovingAverage = NULL;
deleteMutex = new pthread_mutex_t;
pthread_mutex_init(deleteMutex, NULL);
@ -66,12 +70,18 @@ Agent::Agent(const Agent &otherAgent) {
linkedData = NULL;
}
if (otherAgent._bytesReceivedMovingAverage != NULL) {
_bytesReceivedMovingAverage = new SimpleMovingAverage(100);
memcpy(_bytesReceivedMovingAverage, otherAgent._bytesReceivedMovingAverage, sizeof(SimpleMovingAverage));
} else {
_bytesReceivedMovingAverage = NULL;
}
deleteMutex = new pthread_mutex_t;
pthread_mutex_init(deleteMutex, NULL);
}
Agent& Agent::operator=(Agent otherAgent) {
std::cout << "Agent swap constructor called on resize?\n";
swap(*this, otherAgent);
return *this;
}
@ -87,6 +97,7 @@ void Agent::swap(Agent &first, Agent &second) {
swap(first.agentId, second.agentId);
swap(first.firstRecvTimeUsecs, second.firstRecvTimeUsecs);
swap(first.lastRecvTimeUsecs, second.lastRecvTimeUsecs);
swap(first._bytesReceivedMovingAverage, second._bytesReceivedMovingAverage);
swap(first.deleteMutex, second.deleteMutex);
}
@ -97,6 +108,7 @@ Agent::~Agent() {
delete publicSocket;
delete localSocket;
delete linkedData;
delete _bytesReceivedMovingAverage;
}
char Agent::getType() const {
@ -197,7 +209,6 @@ void Agent::setLinkedData(AgentData *newData) {
linkedData = newData;
}
bool Agent::operator==(const Agent& otherAgent) {
return matches(otherAgent.publicSocket, otherAgent.localSocket, otherAgent.type);
}
@ -209,6 +220,40 @@ bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, cha
&& socketMatch(localSocket, otherLocalSocket);
}
void Agent::recordBytesReceived(int bytesReceived) {
if (_bytesReceivedMovingAverage == NULL) {
_bytesReceivedMovingAverage = new SimpleMovingAverage(100);
}
_bytesReceivedMovingAverage->updateAverage((float) bytesReceived);
}
float Agent::getAveragePacketsPerSecond() {
if (_bytesReceivedMovingAverage != NULL) {
return (1 / _bytesReceivedMovingAverage->getEventDeltaAverage());
} else {
return 0;
}
}
float Agent::getAverageKilobitsPerSecond() {
if (_bytesReceivedMovingAverage != NULL) {
return (_bytesReceivedMovingAverage->getAverageSampleValuePerSecond() * (8.0f / 1000));
} else {
return 0;
}
}
void Agent::printLog(Agent const& agent) {
sockaddr_in *agentPublicSocket = (sockaddr_in *) agent.publicSocket;
sockaddr_in *agentLocalSocket = (sockaddr_in *) agent.localSocket;
::printLog("T: %s (%c) PA: %s:%d LA: %s:%d\n", agent.getTypeName(), agent.type,
inet_ntoa(agentPublicSocket->sin_addr), ntohs(agentPublicSocket->sin_port),
inet_ntoa(agentLocalSocket->sin_addr), ntohs(agentLocalSocket->sin_port));
}
std::ostream& operator<<(std::ostream& os, const Agent* agent) {
sockaddr_in *agentPublicSocket = (sockaddr_in *)agent->publicSocket;
sockaddr_in *agentLocalSocket = (sockaddr_in *)agent->localSocket;

View file

@ -9,9 +9,8 @@
#ifndef __hifi__Agent__
#define __hifi__Agent__
#include <iostream>
#include <stdint.h>
#include "AgentData.h"
#include <ostream>
#ifdef _WIN32
#include "Syssocket.h"
@ -19,6 +18,9 @@
#include <sys/socket.h>
#endif
#include "SimpleMovingAverage.h"
#include "AgentData.h"
class Agent {
public:
Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId);
@ -34,31 +36,45 @@ public:
char getType() const;
const char* getTypeName() const;
void setType(char newType);
uint16_t getAgentId();
void setAgentId(uint16_t thisAgentId);
double getFirstRecvTimeUsecs();
void setFirstRecvTimeUsecs(double newTimeUsecs);
double getLastRecvTimeUsecs();
void setLastRecvTimeUsecs(double newTimeUsecs);
sockaddr* getPublicSocket();
void setPublicSocket(sockaddr *newSocket);
sockaddr* getLocalSocket();
void setLocalSocket(sockaddr *newSocket);
sockaddr* getActiveSocket();
void activatePublicSocket();
void activateLocalSocket();
AgentData* getLinkedData();
void setLinkedData(AgentData *newData);
void recordBytesReceived(int bytesReceived);
float getAverageKilobitsPerSecond();
float getAveragePacketsPerSecond();
static void printLog(Agent const&);
friend std::ostream& operator<<(std::ostream& os, const Agent* agent);
private:
void swap(Agent &first, Agent &second);
sockaddr *publicSocket, *localSocket, *activeSocket;
char type;
uint16_t agentId;
double firstRecvTimeUsecs;
double lastRecvTimeUsecs;
AgentData *linkedData;
SimpleMovingAverage* _bytesReceivedMovingAverage;
AgentData* linkedData;
};
std::ostream& operator<<(std::ostream& os, const Agent* agent);

View file

@ -14,6 +14,7 @@
#include "AgentTypes.h"
#include "PacketHeaders.h"
#include "SharedUtil.h"
#include "shared_Log.h"
#ifdef _WIN32
#include "Syssocket.h"
@ -21,7 +22,14 @@
#include <arpa/inet.h>
#endif
const char * SOLO_AGENT_TYPES_STRING = "MV";
using shared_lib::printLog;
const char SOLO_AGENT_TYPES_STRING[] = {
AGENT_TYPE_AVATAR_MIXER,
AGENT_TYPE_AUDIO_MIXER,
AGENT_TYPE_VOXEL
};
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup
const int DOMAINSERVER_PORT = 40102;
@ -37,7 +45,7 @@ AgentList* AgentList::createInstance(char ownerType, unsigned int socketListenPo
if (_sharedInstance == NULL) {
_sharedInstance = new AgentList(ownerType, socketListenPort);
} else {
printf("AgentList createInstance called with existing instance.\n");
printLog("AgentList createInstance called with existing instance.\n");
}
return _sharedInstance;
@ -45,7 +53,7 @@ AgentList* AgentList::createInstance(char ownerType, unsigned int socketListenPo
AgentList* AgentList::getInstance() {
if (_sharedInstance == NULL) {
printf("AgentList getInstance called before call to createInstance. Returning NULL pointer.\n");
printLog("AgentList getInstance called before call to createInstance. Returning NULL pointer.\n");
}
return _sharedInstance;
@ -105,11 +113,12 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
if (bulkSendAgentIndex >= 0) {
Agent *bulkSendAgent = &agents[bulkSendAgentIndex];
bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow());
bulkSendAgent->recordBytesReceived(numTotalBytes);
}
unsigned char *startPosition = (unsigned char *)packetData;
unsigned char *startPosition = packetData;
unsigned char *currentPosition = startPosition + 1;
unsigned char *packetHolder = new unsigned char[numBytesPerAgent + 1];
unsigned char packetHolder[numBytesPerAgent + 1];
packetHolder[0] = PACKET_HEADER_HEAD_DATA;
@ -122,13 +131,12 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
int matchingAgentIndex = indexOfMatchingAgent(agentID);
if (matchingAgentIndex >= 0) {
updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1);
}
currentPosition += numBytesPerAgent;
}
delete[] packetHolder;
}
void AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) {
@ -142,13 +150,14 @@ void AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *pack
void AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes) {
agent->setLastRecvTimeUsecs(usecTimestampNow());
agent->recordBytesReceived(dataBytes);
if (agent->getLinkedData() == NULL) {
if (linkedDataCreateCallback != NULL) {
linkedDataCreateCallback(agent);
}
}
agent->getLinkedData()->parseData(packetData, dataBytes);
}
@ -238,7 +247,8 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
newAgent.activatePublicSocket();
}
std::cout << "Added agent - " << &newAgent << "\n";
printLog("Added agent - ");
Agent::printLog(newAgent);
pthread_mutex_lock(&vectorChangeMutex);
agents.push_back(newAgent);
@ -282,6 +292,18 @@ void AgentList::handlePingReply(sockaddr *agentAddress) {
}
}
Agent* AgentList::soloAgentOfType(char agentType) {
if (memchr(SOLO_AGENT_TYPES_STRING, agentType, 1)) {
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
if (agent->getType() == agentType) {
return &*agent;
}
}
}
return NULL;
}
void *pingUnknownAgents(void *args) {
AgentList *agentList = (AgentList *)args;
@ -337,7 +359,8 @@ void *removeSilentAgents(void *args) {
&& agent->getType() != AGENT_TYPE_VOXEL
&& pthread_mutex_trylock(agentDeleteMutex) == 0) {
std::cout << "Killing agent " << &(*agent) << "\n";
printLog("Killing agent - ");
Agent::printLog(*agent);
// make sure the vector isn't currently adding an agent
pthread_mutex_lock(&vectorChangeMutex);
@ -391,12 +414,12 @@ void *checkInWithDomainServer(void *args) {
sockaddr_in tempAddress;
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
printf("Domain server: %s \n", DOMAIN_HOSTNAME);
printLog("Domain server: %s \n", DOMAIN_HOSTNAME);
} else {
printf("Failed lookup domainserver\n");
printLog("Failed lookup domainserver\n");
}
} else printf("Using static domainserver IP: %s\n", DOMAIN_IP);
} else printLog("Using static domainserver IP: %s\n", DOMAIN_IP);
while (!domainServerCheckinStopFlag) {

View file

@ -9,9 +9,9 @@
#ifndef __hifi__AgentList__
#define __hifi__AgentList__
#include <iostream>
#include <vector>
#include <stdint.h>
#include "Agent.h"
#include "UDPSocket.h"
@ -22,7 +22,7 @@
const int MAX_PACKET_SIZE = 1500;
const unsigned int AGENT_SOCKET_LISTEN_PORT = 40103;
const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000;
extern const char *SOLO_AGENT_TYPES_STRING;
extern const char SOLO_AGENT_TYPES_STRING[];
extern char DOMAIN_HOSTNAME[];
extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup
@ -59,6 +59,8 @@ public:
char getOwnerType();
unsigned int getSocketListenPort();
Agent* soloAgentOfType(char agentType);
void startSilentAgentRemovalThread();
void stopSilentAgentRemovalThread();
void startDomainServerCheckInThread();

View file

@ -9,7 +9,6 @@
#ifndef __interface__AudioRingBuffer__
#define __interface__AudioRingBuffer__
#include <iostream>
#include <stdint.h>
#include "AgentData.h"

View file

@ -1,142 +0,0 @@
//
// CounterStats.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 2013/04/08.
//
// Poor-man's counter stats collector class. Useful for collecting running averages
// and other stats for countable things.
//
//
#include "CounterStats.h"
#include <cstdio>
#ifdef _WIN32
#include "Systime.h"
#else
#include <sys/time.h>
#endif
#include <string>
#include <map>
//private:
// long int currentCount;
// long int currentDelta;
// double currentTime;
// double totalTime;
//
// long int countSamples[COUNTETSTATS_SAMPLES_TO_KEEP] = {};
// long int deltaSamples[COUNTETSTATS_SAMPLES_TO_KEEP] = {};
// double timeSamples[COUNTETSTATS_SAMPLES_TO_KEEP] = {};
// int sampleAt;
CounterStatHistory::CounterStatHistory() :
currentCount(0),
currentDelta(0),
currentTime(0.0),
lastCount(0),
lastTime(0.0),
totalTime(0.0),
sampleAt(-1),
sampleCount(0) {
}
CounterStatHistory::CounterStatHistory(std::string myName) :
name(myName),
currentCount(0),
currentDelta(0),
currentTime(0.0),
lastCount(0),
lastTime(0.0),
totalTime(0.0),
sampleAt(-1),
sampleCount(0) {
}
CounterStatHistory::CounterStatHistory(std::string myName, double initialTime, long initialCount) :
name(myName),
currentCount(initialCount),
currentDelta(0),
currentTime(initialTime),
lastCount(initialCount),
lastTime(initialTime),
totalTime(initialTime),
sampleAt(-1),
sampleCount(0) {
}
void CounterStatHistory::init() {
currentCount = 0;
currentDelta = 0;
currentTime = 0.0;
lastCount = 0;
lastTime = 0.0;
totalTime = 0.0;
sampleAt = -1;
sampleCount = 0;
}
void CounterStatHistory::recordSample(long thisCount) {
timeval now;
gettimeofday(&now,NULL);
double nowSeconds = (now.tv_usec/1000000.0)+(now.tv_sec);
this->recordSample(nowSeconds,thisCount);
}
void CounterStatHistory::recordSample(double thisTime, long thisCount) {
// how much did we change since last sample?
long thisDelta = thisCount - this->lastCount;
double elapsed = thisTime - this->lastTime;
// record the latest values
this->currentCount = thisCount;
this->currentTime = thisTime;
this->currentDelta = thisDelta;
//printf("CounterStatHistory[%s]::recordSample(thisTime %lf, thisCount= %ld)\n",this->name.c_str(),thisTime,thisCount);
// if more than 1/10th of a second has passed, then record
// things in our rolling history
if (elapsed > 0.1) {
this->lastTime = thisTime;
this->lastCount = thisCount;
// record it in our history...
this->sampleAt = (this->sampleAt+1)%COUNTETSTATS_SAMPLES_TO_KEEP;
if (this->sampleCount<COUNTETSTATS_SAMPLES_TO_KEEP) {
this->sampleCount++;
}
this->countSamples[this->sampleAt]=thisCount;
this->timeSamples[this->sampleAt]=thisTime;
this->deltaSamples[this->sampleAt]=thisDelta;
//printf("CounterStatHistory[%s]::recordSample() ACTUALLY RECORDING IT sampleAt=%d thisTime %lf, thisCount= %ld)\n",this->name.c_str(),this->sampleAt,thisTime,thisCount);
}
}
long CounterStatHistory::getRunningAverage() {
// before we calculate our running average, always "reset" the current count, with the current time
// this will flush out old data, if we haven't been adding any new data.
this->recordSample(this->currentCount);
long runningTotal = 0;
double minTime = this->timeSamples[0];
double maxTime = this->timeSamples[0];
for (int i =0; i < this->sampleCount; i++) {
minTime = std::min(minTime,this->timeSamples[i]);
maxTime = std::max(maxTime,this->timeSamples[i]);
runningTotal += this->deltaSamples[i];
}
double elapsedTime = maxTime-minTime;
long runningAverage = runningTotal/elapsedTime;
return runningAverage;
}

View file

@ -1,65 +0,0 @@
//
// CounterStats.h
// hifi
//
// Created by Brad Hefta-Gaub on 3/29/13.
//
// Poor-man's counter stats collector class. Useful for collecting running averages
// and other stats for countable things.
//
//
#ifndef __hifi__CounterStats__
#define __hifi__CounterStats__
#include <cstring>
#include <string>
#include <map>
// TIME_FRAME should be SAMPLES_TO_KEEP * TIME_BETWEEN_SAMPLES
#define COUNTETSTATS_SAMPLES_TO_KEEP 50
#define COUNTETSTATS_TIME_BETWEEN_SAMPLES 0.1
#define COUNTETSTATS_TIME_FRAME (COUNTETSTATS_SAMPLES_TO_KEEP*COUNTETSTATS_TIME_BETWEEN_SAMPLES)
class CounterStatHistory {
public:
std::string name;
CounterStatHistory();
CounterStatHistory(std::string myName);
CounterStatHistory(std::string myName, double initialTime, long initialCount);
void recordSample(long thisCount);
void recordSample(double thisTime, long thisCount);
long getRunningAverage();
long getAverage() {
return currentCount/totalTime;
};
double getTotalTime() {
return totalTime;
};
long getCount() {
return currentCount;
};
private:
void init();
long currentCount;
long currentDelta;
double currentTime;
long lastCount;
double lastTime;
double totalTime;
long countSamples[COUNTETSTATS_SAMPLES_TO_KEEP];
long deltaSamples[COUNTETSTATS_SAMPLES_TO_KEEP];
double timeSamples[COUNTETSTATS_SAMPLES_TO_KEEP];
int sampleAt;
int sampleCount;
};
#endif /* defined(__hifi__CounterStat__) */

View file

@ -14,6 +14,10 @@
#include <string>
#include <map>
#include "shared_Log.h"
using shared_lib::printLog;
// Static class members initialization here!
std::map<std::string,PerfStatHistory,std::less<std::string> > PerfStat::groupHistoryMap;
bool PerfStat::wantDebugOut = false;
@ -55,7 +59,7 @@ PerfStat::~PerfStat() {
}
if (wantDebugOut) {
printf("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%d us:%d ue:%d t:%ld s:%ld e:%ld\n",
printLog("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%d us:%d ue:%d t:%ld s:%ld e:%ld\n",
this->group.c_str(),elapsed,average,count,totalTime,
(end.tv_usec-start.tv_usec),start.tv_usec,end.tv_usec,
(end.tv_sec-start.tv_sec),start.tv_sec,end.tv_sec

View file

@ -12,6 +12,7 @@
#ifdef _WIN32
#include "Syssocket.h"
#endif
#include "shared_Log.h"
#include "SharedUtil.h"
#include "OctalCode.h"
@ -19,6 +20,8 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
using shared_lib::printLog;
double usecTimestamp(timeval *time) {
return (time->tv_sec * 1000000.0 + time->tv_usec);
}
@ -50,13 +53,13 @@ bool randomBoolean() {
}
void outputBits(unsigned char byte) {
printf("%d: ", byte);
printLog("%d: ", byte);
for (int i = 0; i < 8; i++) {
printf("%d", byte >> (7 - i) & 1);
printLog("%d", byte >> (7 - i) & 1);
}
printf("\n");
printLog("\n");
}
int numberOfOnes(unsigned char byte) {
@ -329,14 +332,14 @@ void printVoxelCode(unsigned char* voxelCode) {
unsigned int voxelSizeInOctets = (voxelSizeInBits/3);
unsigned int voxelBufferSize = voxelSizeInBytes+1+3; // 1 for size, 3 for color
printf("octets=%d\n",octets);
printf("voxelSizeInBits=%d\n",voxelSizeInBits);
printf("voxelSizeInBytes=%d\n",voxelSizeInBytes);
printf("voxelSizeInOctets=%d\n",voxelSizeInOctets);
printf("voxelBufferSize=%d\n",voxelBufferSize);
printLog("octets=%d\n",octets);
printLog("voxelSizeInBits=%d\n",voxelSizeInBits);
printLog("voxelSizeInBytes=%d\n",voxelSizeInBytes);
printLog("voxelSizeInOctets=%d\n",voxelSizeInOctets);
printLog("voxelBufferSize=%d\n",voxelBufferSize);
for(int i=0;i<voxelBufferSize;i++) {
printf("i=%d ",i);
printLog("i=%d ",i);
outputBits(voxelCode[i]);
}
}

View file

@ -0,0 +1,54 @@
//
// SimpleMovingAverage.cpp
// hifi
//
// Created by Stephen Birarda on 4/18/13.
//
//
#include "SharedUtil.h"
#include "SimpleMovingAverage.h"
SimpleMovingAverage::SimpleMovingAverage(int numSamplesToAverage) :
_numSamples(0),
_average(0),
_eventDeltaAverage(0),
WEIGHTING(1.0f / numSamplesToAverage),
ONE_MINUS_WEIGHTING(1 - WEIGHTING) {
}
int SimpleMovingAverage::updateAverage(float sample) {
if (_numSamples > 0) {
_average = (ONE_MINUS_WEIGHTING * _average) + (WEIGHTING * sample);
float eventDelta = (usecTimestampNow() - _lastEventTimestamp) / 1000000;
if (_numSamples > 1) {
_eventDeltaAverage = (ONE_MINUS_WEIGHTING * _eventDeltaAverage) +
(WEIGHTING * eventDelta);
} else {
_eventDeltaAverage = eventDelta;
}
} else {
_average = sample;
_eventDeltaAverage = 0;
}
_lastEventTimestamp = usecTimestampNow();
return ++_numSamples;
}
void SimpleMovingAverage::reset() {
_numSamples = 0;
}
float SimpleMovingAverage::getEventDeltaAverage() {
return (ONE_MINUS_WEIGHTING * _eventDeltaAverage) +
(WEIGHTING * ((usecTimestampNow() - _lastEventTimestamp) / 1000000));
}
float SimpleMovingAverage::getAverageSampleValuePerSecond() {
return _average * (1 / getEventDeltaAverage());
}

View file

@ -0,0 +1,36 @@
//
// SimpleMovingAverage.h
// hifi
//
// Created by Stephen Birarda on 4/18/13.
// Replaces Brad Hefta-Gaub's CounterStats class (RIP)
//
//
#ifndef __hifi__Stats__
#define __hifi__Stats__
#include <iostream>
class SimpleMovingAverage {
public:
SimpleMovingAverage(int numSamplesToAverage);
int updateAverage(float sample);
void reset();
int getSampleCount() { return _numSamples; };
float getAverage() { return _average; };
float getEventDeltaAverage();
float getAverageSampleValuePerSecond();
private:
int _numSamples;
double _lastEventTimestamp;
float _average;
float _eventDeltaAverage;
const float WEIGHTING;
const float ONE_MINUS_WEIGHTING;
};
#endif /* defined(__hifi__Stats__) */

View file

@ -9,8 +9,6 @@
#ifndef __hifi__StdDev__
#define __hifi__StdDev__
#include <iostream>
class StDev {
public:
StDev();

View file

@ -18,8 +18,13 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <unistd.h>
#endif
#include "shared_Log.h"
using shared_lib::printLog;
sockaddr_in destSockaddr, senderAddress;
bool socketMatch(sockaddr *first, sockaddr *second) {
@ -104,7 +109,7 @@ UDPSocket::UDPSocket(int listeningPort) {
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (handle <= 0) {
printf("Failed to create socket.\n");
printLog("Failed to create socket.\n");
return;
}
@ -117,7 +122,7 @@ UDPSocket::UDPSocket(int listeningPort) {
bind_address.sin_port = htons((uint16_t) listeningPort);
if (bind(handle, (const sockaddr*) &bind_address, sizeof(sockaddr_in)) < 0) {
printf("Failed to bind socket to port %d.\n", listeningPort);
printLog("Failed to bind socket to port %d.\n", listeningPort);
return;
}
@ -127,7 +132,7 @@ UDPSocket::UDPSocket(int listeningPort) {
tv.tv_usec = 500000;
setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv);
printf("Created UDP socket listening on port %d.\n", listeningPort);
printLog("Created UDP socket listening on port %d.\n", listeningPort);
}
UDPSocket::~UDPSocket() {
@ -196,7 +201,7 @@ int UDPSocket::send(sockaddr *destAddress, const void *data, size_t byteLength)
0, (sockaddr *) destAddress, sizeof(sockaddr_in));
if (sent_bytes != byteLength) {
printf("Failed to send packet: %s\n", strerror(errno));
printLog("Failed to send packet: %s\n", strerror(errno));
return false;
}

View file

@ -9,8 +9,6 @@
#ifndef __interface__UDPSocket__
#define __interface__UDPSocket__
#include <iostream>
#ifdef _WIN32
#include "Syssocket.h"
#else

View file

@ -0,0 +1,17 @@
//
// shared_Log.cpp
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "shared_Log.h"
#include <cstdio>
namespace shared_lib {
using namespace std;
int (* printLog)(char const*, ...) = & printf;
}

View file

@ -0,0 +1,20 @@
//
// shared_Log.h
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__shared_Log__
#define __hifi__shared_Log__
namespace shared_lib {
// variable that can be set from outside to redirect the log output
// of this library
extern int (* printLog)(char const*, ...);
}
#endif /* defined(__hifi__shared_Log__) */

View file

@ -7,6 +7,7 @@
//
#include "MarkerNode.h"
#include <stddef.h>
MarkerNode::MarkerNode() {
for (int i = 0; i < 8; i++) {
@ -31,4 +32,4 @@ MarkerNode::MarkerNode(const MarkerNode &otherMarkerNode) {
children[i] = new MarkerNode(*otherMarkerNode.children[i]);
}
}
}
}

View file

@ -9,8 +9,6 @@
#ifndef __hifi__MarkerNode__
#define __hifi__MarkerNode__
#include <iostream>
class MarkerNode {
public:
MarkerNode();

View file

@ -5,6 +5,10 @@
#include "Plane.h"
#include <stdio.h>
#include "voxels_Log.h"
using voxels_lib::printLog;
// These are some useful utilities that vec3 is missing
float vec3_length(const glm::vec3& v) {
return((float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z));
@ -79,5 +83,5 @@ float Plane::distance(const glm::vec3 &p) {
}
void Plane::print() {
//printf("Plane(");normal.print();printf("# %f)",d);
//printLog("Plane(");normal.print();printLog("# %f)",d);
}

View file

@ -9,6 +9,9 @@
//
#include "ViewFrustum.h"
#include "voxels_Log.h"
using voxels_lib::printLog;
ViewFrustum::ViewFrustum() :
_position(glm::vec3(0,0,0)),
@ -95,39 +98,39 @@ void ViewFrustum::calculate() {
void ViewFrustum::dump() {
printf("position.x=%f, position.y=%f, position.z=%f\n", this->_position.x, this->_position.y, this->_position.z);
printf("direction.x=%f, direction.y=%f, direction.z=%f\n", this->_direction.x, this->_direction.y, this->_direction.z);
printf("up.x=%f, up.y=%f, up.z=%f\n", this->_up.x, this->_up.y, this->_up.z);
printf("right.x=%f, right.y=%f, right.z=%f\n", this->_right.x, this->_right.y, this->_right.z);
printLog("position.x=%f, position.y=%f, position.z=%f\n", this->_position.x, this->_position.y, this->_position.z);
printLog("direction.x=%f, direction.y=%f, direction.z=%f\n", this->_direction.x, this->_direction.y, this->_direction.z);
printLog("up.x=%f, up.y=%f, up.z=%f\n", this->_up.x, this->_up.y, this->_up.z);
printLog("right.x=%f, right.y=%f, right.z=%f\n", this->_right.x, this->_right.y, this->_right.z);
printf("farDist=%f\n", this->_farClip);
printf("farHeight=%f\n", this->_farHeight);
printf("farWidth=%f\n", this->_farWidth);
printLog("farDist=%f\n", this->_farClip);
printLog("farHeight=%f\n", this->_farHeight);
printLog("farWidth=%f\n", this->_farWidth);
printf("nearDist=%f\n", this->_nearClip);
printf("nearHeight=%f\n", this->_nearHeight);
printf("nearWidth=%f\n", this->_nearWidth);
printLog("nearDist=%f\n", this->_nearClip);
printLog("nearHeight=%f\n", this->_nearHeight);
printLog("nearWidth=%f\n", this->_nearWidth);
printf("farCenter.x=%f, farCenter.y=%f, farCenter.z=%f\n",
printLog("farCenter.x=%f, farCenter.y=%f, farCenter.z=%f\n",
this->_farCenter.x, this->_farCenter.y, this->_farCenter.z);
printf("farTopLeft.x=%f, farTopLeft.y=%f, farTopLeft.z=%f\n",
printLog("farTopLeft.x=%f, farTopLeft.y=%f, farTopLeft.z=%f\n",
this->_farTopLeft.x, this->_farTopLeft.y, this->_farTopLeft.z);
printf("farTopRight.x=%f, farTopRight.y=%f, farTopRight.z=%f\n",
printLog("farTopRight.x=%f, farTopRight.y=%f, farTopRight.z=%f\n",
this->_farTopRight.x, this->_farTopRight.y, this->_farTopRight.z);
printf("farBottomLeft.x=%f, farBottomLeft.y=%f, farBottomLeft.z=%f\n",
printLog("farBottomLeft.x=%f, farBottomLeft.y=%f, farBottomLeft.z=%f\n",
this->_farBottomLeft.x, this->_farBottomLeft.y, this->_farBottomLeft.z);
printf("farBottomRight.x=%f, farBottomRight.y=%f, farBottomRight.z=%f\n",
printLog("farBottomRight.x=%f, farBottomRight.y=%f, farBottomRight.z=%f\n",
this->_farBottomRight.x, this->_farBottomRight.y, this->_farBottomRight.z);
printf("nearCenter.x=%f, nearCenter.y=%f, nearCenter.z=%f\n",
printLog("nearCenter.x=%f, nearCenter.y=%f, nearCenter.z=%f\n",
this->_nearCenter.x, this->_nearCenter.y, this->_nearCenter.z);
printf("nearTopLeft.x=%f, nearTopLeft.y=%f, nearTopLeft.z=%f\n",
printLog("nearTopLeft.x=%f, nearTopLeft.y=%f, nearTopLeft.z=%f\n",
this->_nearTopLeft.x, this->_nearTopLeft.y, this->_nearTopLeft.z);
printf("nearTopRight.x=%f, nearTopRight.y=%f, nearTopRight.z=%f\n",
printLog("nearTopRight.x=%f, nearTopRight.y=%f, nearTopRight.z=%f\n",
this->_nearTopRight.x, this->_nearTopRight.y, this->_nearTopRight.z);
printf("nearBottomLeft.x=%f, nearBottomLeft.y=%f, nearBottomLeft.z=%f\n",
printLog("nearBottomLeft.x=%f, nearBottomLeft.y=%f, nearBottomLeft.z=%f\n",
this->_nearBottomLeft.x, this->_nearBottomLeft.y, this->_nearBottomLeft.z);
printf("nearBottomRight.x=%f, nearBottomRight.y=%f, nearBottomRight.z=%f\n",
printLog("nearBottomRight.x=%f, nearBottomRight.y=%f, nearBottomRight.z=%f\n",
this->_nearBottomRight.x, this->_nearBottomRight.y, this->_nearBottomRight.z);
}

View file

@ -8,9 +8,12 @@
#include <cstring>
#include "SharedUtil.h"
//#include "voxels_Log.h"
#include "VoxelNode.h"
#include "OctalCode.h"
// using voxels_lib::printLog;
VoxelNode::VoxelNode() {
octalCode = NULL;
@ -76,7 +79,7 @@ bool VoxelNode::collapseIdenticalLeaves() {
// if no child, or child doesn't have a color
if (children[i] == NULL || children[i]->color[3] != 1) {
allChildrenMatch=false;
//printf("SADNESS child missing or not colored! i=%d\n",i);
//printLog("SADNESS child missing or not colored! i=%d\n",i);
break;
} else {
if (i==0) {
@ -92,7 +95,7 @@ bool VoxelNode::collapseIdenticalLeaves() {
if (allChildrenMatch) {
//printf("allChildrenMatch: pruning tree\n");
//printLog("allChildrenMatch: pruning tree\n");
for (int i = 0; i < 8; i++) {
delete children[i]; // delete all the child nodes
children[i]=NULL; // set it to NULL
@ -111,4 +114,4 @@ void VoxelNode::setRandomColor(int minimumBrightness) {
}
color[3] = 1;
}
}

View file

@ -9,8 +9,6 @@
#ifndef __hifi__VoxelNode__
#define __hifi__VoxelNode__
#include <iostream>
class VoxelNode {
public:
VoxelNode();

View file

@ -13,13 +13,13 @@
#include <cstdio>
#include <cmath>
#include "SharedUtil.h"
#include "voxels_Log.h"
#include "PacketHeaders.h"
#include "CounterStats.h"
#include "OctalCode.h"
#include "VoxelTree.h"
#include <iostream> // to load voxels from file
#include <fstream> // to load voxels from file
using voxels_lib::printLog;
int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
switch (renderLevel) {
@ -45,19 +45,17 @@ int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
}
}
VoxelTree::VoxelTree() {
VoxelTree::VoxelTree() :
voxelsCreated(0),
voxelsColored(0),
voxelsBytesRead(0),
voxelsCreatedStats(100),
voxelsColoredStats(100),
voxelsBytesReadStats(100) {
rootNode = new VoxelNode();
rootNode->octalCode = new unsigned char[1];
*rootNode->octalCode = 0;
// Some stats tracking
this->voxelsCreated = 0; // when a voxel is created in the tree (object new'd)
this->voxelsColored = 0; // when a voxel is colored/set in the tree (object may have already existed)
this->voxelsBytesRead = 0;
voxelsCreatedStats.name = "voxelsCreated";
voxelsColoredStats.name = "voxelsColored";
voxelsBytesReadStats.name = "voxelsBytesRead";
}
VoxelTree::~VoxelTree() {
@ -125,14 +123,14 @@ int VoxelTree::readNodeData(VoxelNode *destinationNode,
if (destinationNode->children[i] == NULL) {
destinationNode->addChildAtIndex(i);
this->voxelsCreated++;
this->voxelsCreatedStats.recordSample(this->voxelsCreated);
this->voxelsCreatedStats.updateAverage(1);
}
// pull the color for this child
memcpy(destinationNode->children[i]->color, nodeData + bytesRead, 3);
destinationNode->children[i]->color[3] = 1;
this->voxelsColored++;
this->voxelsColoredStats.recordSample(this->voxelsColored);
this->voxelsColoredStats.updateAverage(1);
bytesRead += 3;
}
@ -155,7 +153,7 @@ int VoxelTree::readNodeData(VoxelNode *destinationNode,
// add a child at that index, if it doesn't exist
destinationNode->addChildAtIndex(childIndex);
this->voxelsCreated++;
this->voxelsCreatedStats.recordSample(this->voxelsCreated);
this->voxelsCreatedStats.updateAverage(this->voxelsCreated);
}
// tell the child to read the subsequent data
@ -183,7 +181,7 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, int bufferSizeByt
readNodeData(bitstreamRootNode, bitstream + octalCodeBytes, bufferSizeBytes - octalCodeBytes);
this->voxelsBytesRead += bufferSizeBytes;
this->voxelsBytesReadStats.recordSample(this->voxelsBytesRead);
this->voxelsBytesReadStats.updateAverage(bufferSizeBytes);
}
// Note: uses the codeColorBuffer format, but the color's are ignored, because
@ -416,7 +414,7 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) {
// XXXBHG: validate buffer is at least 4 bytes long? other guards??
unsigned short int itemNumber = (*((unsigned short int*)&bitstream[1]));
printf("processRemoveVoxelBitstream() receivedBytes=%d itemNumber=%d\n",bufferSizeBytes,itemNumber);
printLog("processRemoveVoxelBitstream() receivedBytes=%d itemNumber=%d\n",bufferSizeBytes,itemNumber);
int atByte = 3;
unsigned char* pVoxelData = (unsigned char*)&bitstream[3];
while (atByte < bufferSizeBytes) {
@ -424,7 +422,7 @@ void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int buffe
int voxelDataSize = bytesRequiredForCodeLength(octets)+3; // 3 for color!
float* vertices = firstVertexForCode(pVoxelData);
printf("deleting voxel at: %f,%f,%f\n",vertices[0],vertices[1],vertices[2]);
printLog("deleting voxel at: %f,%f,%f\n",vertices[0],vertices[1],vertices[2]);
delete []vertices;
deleteVoxelCodeFromTree(pVoxelData);
@ -510,11 +508,11 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
int totalBytesRead = 0;
if(file.is_open()) {
printf("loading file...\n");
printLog("loading file...\n");
bool bail = false;
while (!file.eof() && !bail) {
file.get(octets);
//printf("octets=%d...\n",octets);
//printLog("octets=%d...\n",octets);
totalBytesRead++;
lengthInBytes = bytesRequiredForCodeLength(octets)-1; //(octets*3/8)+1;
unsigned char * voxelData = new unsigned char[lengthInBytes+1+3];
@ -536,14 +534,14 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
file.get(colorRead);
blue = (unsigned char)colorRead;
printf("voxel color from file red:%d, green:%d, blue:%d \n",red,green,blue);
printLog("voxel color from file red:%d, green:%d, blue:%d \n",red,green,blue);
vCount++;
int colorRandomizer = wantColorRandomizer ? randIntInRange (-5, 5) : 0;
voxelData[lengthInBytes+1] = std::max(0,std::min(255,red + colorRandomizer));
voxelData[lengthInBytes+2] = std::max(0,std::min(255,green + colorRandomizer));
voxelData[lengthInBytes+3] = std::max(0,std::min(255,blue + colorRandomizer));
printf("voxel color after rand red:%d, green:%d, blue:%d\n",
printLog("voxel color after rand red:%d, green:%d, blue:%d\n",
voxelData[lengthInBytes+1], voxelData[lengthInBytes+2], voxelData[lengthInBytes+3]);
//printVoxelCode(voxelData);
@ -608,7 +606,7 @@ void VoxelTree::createSphere(float r,float xc, float yc, float zc, float s, bool
// If you also iterate form the interior of the sphere to the radius, makeing
// larger and larger sphere's you'd end up with a solid sphere. And lots of voxels!
for (; ri <= (r+(s/2.0)); ri+=s) {
//printf("radius: ri=%f ri+s=%f (r+(s/2.0))=%f\n",ri,ri+s,(r+(s/2.0)));
//printLog("radius: ri=%f ri+s=%f (r+(s/2.0))=%f\n",ri,ri+s,(r+(s/2.0)));
for (float theta=0.0; theta <= 2*M_PI; theta += angleDelta) {
for (float phi=0.0; phi <= M_PI; phi += angleDelta) {
t++; // total voxels
@ -622,7 +620,7 @@ void VoxelTree::createSphere(float r,float xc, float yc, float zc, float s, bool
// only use our actual desired color on the outer edge, otherwise
// use our "average" color
if (ri+(s*2.0)>=r) {
//printf("painting candy shell radius: ri=%f r=%f\n",ri,r);
//printLog("painting candy shell radius: ri=%f r=%f\n",ri,r);
red = wantColorRandomizer ? randomColorValue(165) : r1+((r2-r1)*gradient);
green = wantColorRandomizer ? randomColorValue(165) : g1+((g2-g1)*gradient);
blue = wantColorRandomizer ? randomColorValue(165) : b1+((b2-b1)*gradient);
@ -630,7 +628,7 @@ void VoxelTree::createSphere(float r,float xc, float yc, float zc, float s, bool
unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
this->readCodeColorBufferToTree(voxelData);
//printf("voxel data for x:%f y:%f z:%f s:%f\n",x,y,z,s);
//printLog("voxel data for x:%f y:%f z:%f s:%f\n",x,y,z,s);
//printVoxelCode(voxelData);
delete voxelData;
}

View file

@ -9,7 +9,7 @@
#ifndef __hifi__VoxelTree__
#define __hifi__VoxelTree__
#include "CounterStats.h"
#include "SimpleMovingAverage.h"
#include "VoxelNode.h"
#include "MarkerNode.h"
@ -20,13 +20,15 @@ const int TREE_SCALE = 10;
class VoxelTree {
public:
// when a voxel is created in the tree (object new'd)
long voxelsCreated;
// when a voxel is colored/set in the tree (object may have already existed)
long voxelsColored;
long voxelsBytesRead;
CounterStatHistory voxelsCreatedStats;
CounterStatHistory voxelsColoredStats;
CounterStatHistory voxelsBytesReadStats;
SimpleMovingAverage voxelsCreatedStats;
SimpleMovingAverage voxelsColoredStats;
SimpleMovingAverage voxelsBytesReadStats;
VoxelTree();
~VoxelTree();

View file

@ -0,0 +1,17 @@
//
// voxels_Log.cpp
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "voxels_Log.h"
#include <cstdio>
namespace voxels_lib {
using namespace std;
int (* printLog)(char const*, ...) = & printf;
}

View file

@ -0,0 +1,20 @@
//
// voxels_Log.h
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__voxels_Log__
#define __hifi__voxels_Log__
namespace voxels_lib {
// variable that can be set from outside to redirect the log output
// of this library
extern int (* printLog)(char const*, ...);
}
#endif /* defined(__hifi__voxels_Log__) */