mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 12:43:19 +02:00
Merge branch 'master' of git://github.com/worklist/hifi into 19188
Conflicts: interface/src/starfield/renderer/Renderer.h
This commit is contained in:
commit
bc9279917d
58 changed files with 1984 additions and 1136 deletions
|
@ -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 {
|
||||
|
|
|
@ -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, ¤tReceiveTime);
|
||||
//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;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef __interface__Audio__
|
||||
#define __interface__Audio__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <portaudio.h>
|
||||
#include "AudioData.h"
|
||||
#include "Oscilloscope.h"
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#ifndef __interface__AudioData__
|
||||
#define __interface__AudioData__
|
||||
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include "AudioRingBuffer.h"
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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
323
interface/src/Log.cpp
Normal 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
80
interface/src/Log.h
Normal 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
106
interface/src/LogStream.h
Normal 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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "Util.h"
|
||||
#include "world.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include <iostream>
|
||||
|
||||
class Oscilloscope {
|
||||
public:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#ifndef __interface__Texture__
|
||||
#define __interface__Texture__
|
||||
|
||||
#include <iostream>
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
int load_png_as_texture(char* filename);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "InterfaceConfig.h"
|
||||
#include "OGlProgram.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cfloat>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
17
libraries/avatars/src/avatars_Log.cpp
Normal file
17
libraries/avatars/src/avatars_Log.cpp
Normal 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;
|
||||
}
|
20
libraries/avatars/src/avatars_Log.h
Normal file
20
libraries/avatars/src/avatars_Log.h
Normal 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__) */
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#ifndef __interface__AudioRingBuffer__
|
||||
#define __interface__AudioRingBuffer__
|
||||
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include "AgentData.h"
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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__) */
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
54
libraries/shared/src/SimpleMovingAverage.cpp
Normal file
54
libraries/shared/src/SimpleMovingAverage.cpp
Normal 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());
|
||||
}
|
36
libraries/shared/src/SimpleMovingAverage.h
Normal file
36
libraries/shared/src/SimpleMovingAverage.h
Normal 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__) */
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef __hifi__StdDev__
|
||||
#define __hifi__StdDev__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class StDev {
|
||||
public:
|
||||
StDev();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef __interface__UDPSocket__
|
||||
#define __interface__UDPSocket__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Syssocket.h"
|
||||
#else
|
||||
|
|
17
libraries/shared/src/shared_Log.cpp
Normal file
17
libraries/shared/src/shared_Log.cpp
Normal 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;
|
||||
}
|
20
libraries/shared/src/shared_Log.h
Normal file
20
libraries/shared/src/shared_Log.h
Normal 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__) */
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef __hifi__MarkerNode__
|
||||
#define __hifi__MarkerNode__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class MarkerNode {
|
||||
public:
|
||||
MarkerNode();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef __hifi__VoxelNode__
|
||||
#define __hifi__VoxelNode__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class VoxelNode {
|
||||
public:
|
||||
VoxelNode();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
17
libraries/voxels/src/voxels_Log.cpp
Normal file
17
libraries/voxels/src/voxels_Log.cpp
Normal 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;
|
||||
}
|
20
libraries/voxels/src/voxels_Log.h
Normal file
20
libraries/voxels/src/voxels_Log.h
Normal 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__) */
|
||||
|
Loading…
Reference in a new issue