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

Conflicts:
	interface/src/Head.cpp
	interface/src/Util.cpp
	interface/src/main.cpp
	libraries/avatars/src/Orientation.cpp
This commit is contained in:
tosh 2013-04-18 12:38:35 +02:00
commit 1e6352593a
43 changed files with 1185 additions and 1208 deletions

View file

@ -445,8 +445,8 @@ Audio::Audio(Oscilloscope *s, Head *linkedHead)
// read the walking sound from the raw file and store it // read the walking sound from the raw file and store it
// in the in memory array // in the in memory array
switchToResourcesIfRequired(); switchToResourcesParentIfRequired();
FILE *soundFile = fopen("audio/walking.raw", "r"); FILE *soundFile = fopen("resources/audio/walking.raw", "r");
// get length of file: // get length of file:
std::fseek(soundFile, 0, SEEK_END); std::fseek(soundFile, 0, SEEK_END);

View file

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

View file

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

View file

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

View file

@ -1,126 +0,0 @@
//
// FieldOfView.cpp
// interface
//
// Created by Tobias Schwinger on 3/21/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "FieldOfView.h"
#include <math.h>
#include <algorithm>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_inverse.hpp>
using namespace glm;
FieldOfView::FieldOfView() :
_matOrientation(mat4(1.0f)),
_vecBoundsLow(vec3(-1.0f,-1.0f,-1.0f)),
_vecBoundsHigh(vec3(1.0f,1.0f,1.0f)),
_valWidth(256.0f),
_valHeight(256.0f),
_valAngle(0.61),
_valZoom(1.0f),
_enmAspectBalancing(expose_less) {
}
mat4 FieldOfView::getViewerScreenXform() const {
mat4 projection;
vec3 low, high;
getFrustum(low, high);
// perspective projection? determine correct near distance
if (_valAngle != 0.0f) {
projection = translate(
frustum(low.x, high.x, low.y, high.y, low.z, high.z),
vec3(0.f, 0.f, -low.z) );
} else {
projection = ortho(low.x, high.x, low.y, high.y, low.z, high.z);
}
return projection;
}
mat4 FieldOfView::getWorldViewerXform() const {
return translate(affineInverse(_matOrientation),
vec3(0.0f, 0.0f, -_vecBoundsHigh.z) );
}
mat4 FieldOfView::getWorldScreenXform() const {
return translate(
getViewerScreenXform() * affineInverse(_matOrientation),
vec3(0.0f, 0.0f, -_vecBoundsHigh.z) );
}
mat4 FieldOfView::getViewerWorldXform() const {
vec3 n_translate = vec3(0.0f, 0.0f, _vecBoundsHigh.z);
return translate(
translate(mat4(1.0f), n_translate)
* _matOrientation, -n_translate );
}
float FieldOfView::getPixelSize() const {
vec3 low, high;
getFrustum(low, high);
return std::min(
abs(high.x - low.x) / _valWidth,
abs(high.y - low.y) / _valHeight);
}
void FieldOfView::getFrustum(vec3& low, vec3& high) const {
low = _vecBoundsLow;
high = _vecBoundsHigh;
// start with uniform zoom
float inv_zoom = 1.0f / _valZoom;
float adj_x = inv_zoom, adj_y = inv_zoom;
// balance aspect
if (_enmAspectBalancing != stretch) {
float f_aspect = (high.x - low.x) / (high.y - low.y);
float vp_aspect = _valWidth / _valHeight;
if ((_enmAspectBalancing == expose_more)
!= (f_aspect > vp_aspect)) {
// expose_more -> f_aspect <= vp_aspect <=> adj >= 1
// expose_less -> f_aspect > vp_aspect <=> adj < 1
adj_x = vp_aspect / f_aspect;
} else {
// expose_more -> f_aspect > vp_aspect <=> adj > 1
// expose_less -> f_aspect <= vp_aspect <=> adj <= 1
adj_y = f_aspect / vp_aspect;
}
}
// scale according to zoom / aspect correction
float ax = (low.x + high.x) / 2.0f, ay = (low.y + high.y) / 2.0f;
low.x = (low.x - ax) * adj_x + ax;
high.x = (high.x - ax) * adj_x + ax;
low.y = (low.y - ay) * adj_y + ay;
high.y = (high.y - ay) * adj_y + ay;
low.z = (low.z - high.z) * inv_zoom + high.z;
// calc and apply near distance based on near diagonal and perspective
float w = high.x - low.x, h = high.y - low.y;
high.z -= low.z;
low.z = _valAngle == 0.0f ? 0.0f :
sqrt(w*w+h*h) * 0.5f / tan(_valAngle * 0.5f);
high.z += low.z;
}

View file

@ -1,123 +0,0 @@
//
// FieldOfView.h
// interface
//
// Created by Tobias Schwinger on 3/21/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__FieldOfView__
#define __interface__FieldOfView__
#include <glm/glm.hpp>
//
// Viewing parameter encapsulation.
//
class FieldOfView {
glm::mat4 _matOrientation;
glm::vec3 _vecBoundsLow;
glm::vec3 _vecBoundsHigh;
float _valWidth;
float _valHeight;
float _valAngle;
float _valZoom;
int _enmAspectBalancing;
public:
FieldOfView();
// mutators
FieldOfView& setBounds(glm::vec3 const& low, glm::vec3 const& high) {
_vecBoundsLow = low; _vecBoundsHigh = high; return *this; }
FieldOfView& setOrientation(glm::mat4 const& matrix) { _matOrientation = matrix; return *this; }
FieldOfView& setPerspective(float angle) { _valAngle = angle; return *this; }
FieldOfView& setResolution(unsigned width, unsigned height) { _valWidth = width; _valHeight = height; return *this; }
FieldOfView& setZoom(float factor) { _valZoom = factor; return *this; }
enum aspect_balancing
{
expose_more,
expose_less,
stretch
};
FieldOfView& setAspectBalancing(aspect_balancing v) { _enmAspectBalancing = v; return *this; }
// dumb accessors
glm::mat4 const& getOrientation() const { return _matOrientation; }
float getWidthInPixels() const { return _valWidth; }
float getHeightInPixels() const { return _valHeight; }
float getPerspective() const { return _valAngle; }
// matrices
//
// Returns a full transformation matrix to project world coordinates
// onto the screen.
//
glm::mat4 getWorldScreenXform() const;
//
// Transforms world coordinates to viewer-relative coordinates.
//
// This matrix can be used as the modelview matrix in legacy GL code
// where the projection matrix is kept separately.
//
glm::mat4 getWorldViewerXform() const;
//
// Returns the transformation to of viewer-relative coordinates back
// to world space.
//
// This matrix can be used to set up a coordinate system for avatar
// rendering.
//
glm::mat4 getViewerWorldXform() const;
//
// Returns the transformation of viewer-relative coordinates to the
// screen.
//
// This matrix can be used as the projection matrix in legacy GL code.
//
glm::mat4 getViewerScreenXform() const;
// other useful information
//
// Returns the size of a pixel in world space, that is the minimum
// in respect to x/y screen directions.
//
float getPixelSize() const;
//
// Returns the frustum as used for the projection matrices.
// The result depdends on the bounds, eventually aspect correction
// for the current resolution, the perspective angle (specified in
// respect to diagonal) and zoom.
//
void getFrustum(glm::vec3& low, glm::vec3& high) const;
//
// Returns the z-offset from the origin to where orientation ia
// applied.
//
float getTransformOffset() const { return _vecBoundsHigh.z; }
//
// Returns the aspect ratio.
//
float getAspectRatio() const { return _valHeight / _valWidth; }
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -9,8 +9,6 @@
#ifndef __interface__head__ #ifndef __interface__head__
#define __interface__head__ #define __interface__head__
#include <iostream>
#include <AvatarData.h> #include <AvatarData.h>
#include <Orientation.h> #include <Orientation.h>
@ -20,6 +18,10 @@
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include "SerialInterface.h" #include "SerialInterface.h"
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp> //looks like we might not need this
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
#define FWD 0 #define FWD 0
@ -80,11 +82,13 @@ struct AvatarBone
glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) 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) 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 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 orientation)
float yaw; // the yaw Euler angle of the bone rotation off the parent 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 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 float roll; // the roll Euler angle of the bone rotation off the parent
Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll
float length; // the length of the bone float length; // the length of the bone
float radius; // used for detecting collisions for certain physical effects
}; };
struct Avatar struct Avatar
@ -97,17 +101,17 @@ struct Avatar
class Head : public AvatarData { class Head : public AvatarData {
public: public:
Head(); Head(bool isMine);
~Head(); ~Head();
Head(const Head &otherHead); Head(const Head &otherHead);
Head* clone() const; Head* clone() const;
void reset(); void reset();
void UpdatePos(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity);
void setNoise (float mag) { noise = mag; } void setNoise (float mag) { noise = mag; }
void setPitch(float p) {Pitch = p; } void setPitch(float p) {_headPitch = p; }
void setYaw(float y) {Yaw = y; } void setYaw(float y) {_headYaw = y; }
void setRoll(float r) {Roll = r; }; void setRoll(float r) {_headRoll = r; };
void setScale(float s) {scale = s; }; void setScale(float s) {scale = s; };
void setRenderYaw(float y) {renderYaw = y;} void setRenderYaw(float y) {renderYaw = y;}
void setRenderPitch(float p) {renderPitch = p;} void setRenderPitch(float p) {renderPitch = p;}
@ -115,16 +119,18 @@ class Head : public AvatarData {
float getRenderPitch() {return renderPitch;} float getRenderPitch() {return renderPitch;}
void setLeanForward(float dist); void setLeanForward(float dist);
void setLeanSideways(float dist); void setLeanSideways(float dist);
void addPitch(float p) {Pitch -= p; } void addPitch(float p) {_headPitch -= p; }
void addYaw(float y){Yaw -= y; } void addYaw(float y){_headYaw -= y; }
void addRoll(float r){Roll += r; } void addRoll(float r){_headRoll += r; }
void addLean(float x, float z); void addLean(float x, float z);
float getPitch() {return Pitch;} float getPitch() {return _headPitch;}
float getRoll() {return Roll;} float getRoll() {return _headRoll;}
float getYaw() {return Yaw;} float getYaw() {return _headYaw;}
float getLastMeasuredYaw() {return YawRate;} float getLastMeasuredYaw() {return _headYawRate;}
float getBodyYaw(); float getBodyYaw() {return _bodyYaw;};
void addBodyYaw(float y) {_bodyYaw += y;};
glm::vec3 getHeadLookatDirection(); glm::vec3 getHeadLookatDirection();
glm::vec3 getHeadLookatDirectionUp(); glm::vec3 getHeadLookatDirectionUp();
glm::vec3 getHeadLookatDirectionRight(); glm::vec3 getHeadLookatDirectionRight();
@ -135,10 +141,10 @@ class Head : public AvatarData {
void setTriggeringAction( bool trigger ); void setTriggeringAction( bool trigger );
void render(int faceToFace, int isMine); void render(int faceToFace);
void renderBody(); void renderBody();
void renderHead( int faceToFace, int isMine ); void renderHead( int faceToFace);
//void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); //void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size );
void simulate(float); void simulate(float);
@ -158,9 +164,9 @@ class Head : public AvatarData {
bool getDriveKeys(int key) { return driveKeys[key]; }; bool getDriveKeys(int key) { return driveKeys[key]; };
// Set/Get update the thrust that will move the avatar around // Set/Get update the thrust that will move the avatar around
void setThrust(glm::vec3 newThrust) { avatar.thrust = newThrust; }; void setThrust(glm::vec3 newThrust) { _avatar.thrust = newThrust; };
void addThrust(glm::vec3 newThrust) { avatar.thrust += newThrust; }; void addThrust(glm::vec3 newThrust) { _avatar.thrust += newThrust; };
glm::vec3 getThrust() { return avatar.thrust; }; glm::vec3 getThrust() { return _avatar.thrust; };
// //
// Related to getting transmitter UDP data used to animate the avatar hand // Related to getting transmitter UDP data used to animate the avatar hand
@ -170,13 +176,14 @@ class Head : public AvatarData {
float getTransmitterHz() { return transmitterHz; }; float getTransmitterHz() { return transmitterHz; };
private: private:
bool _isMine;
float noise; float noise;
float Pitch; float _headPitch;
float Yaw; float _headYaw;
float Roll; float _headRoll;
float PitchRate; float _headPitchRate;
float YawRate; float _headYawRate;
float RollRate; float _headRollRate;
float EyeballPitch[2]; float EyeballPitch[2];
float EyeballYaw[2]; float EyeballYaw[2];
float EyebrowPitch[2]; float EyebrowPitch[2];
@ -203,38 +210,36 @@ class Head : public AvatarData {
float averageLoudness; float averageLoudness;
float audioAttack; float audioAttack;
float browAudioLift; float browAudioLift;
bool triggeringAction; glm::vec3 _TEST_bigSpherePosition;
float _TEST_bigSphereRadius;
float bodyYawDelta;
float closeEnoughToInteract;
int closestOtherAvatar;
//temporary - placeholder for real other avs //temporary - placeholder for real other avs
glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ]; glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ];
float DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ]; float DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ];
bool usingSprings; bool _triggeringAction;
float _bodyYawDelta;
bool handBeingMoved; float _closeEnoughToInteract;
bool previousHandBeingMoved; int _closestOtherAvatar;
glm::vec3 movedHandOffset; bool _usingSprings;
bool _handBeingMoved;
bool _previousHandBeingMoved;
glm::vec3 _movedHandOffset;
float _springVelocityDecay;
float _springForce;
glm::quat _rotation; // the rotation of the avatar body as a whole
AvatarBone _bone[ NUM_AVATAR_BONES ];
AvatarMode _mode;
Avatar _avatar;
int driveKeys[MAX_DRIVE_KEYS]; int driveKeys[MAX_DRIVE_KEYS];
float springVelocityDecay;
float springForce;
int eyeContact; int eyeContact;
eyeContactTargets eyeContactTarget; eyeContactTargets eyeContactTarget;
GLUquadric *sphere; GLUquadric *sphere;
Avatar avatar;
AvatarBone bone[ NUM_AVATAR_BONES ];
AvatarMode mode;
float renderYaw, renderPitch; // Pitch from view frustum when this is own head. float renderYaw, renderPitch; // Pitch from view frustum when this is own head.
@ -244,18 +249,16 @@ class Head : public AvatarData {
timeval transmitterTimer; timeval transmitterTimer;
float transmitterHz; float transmitterHz;
int transmitterPackets; int transmitterPackets;
//------------------------------------------- //-----------------------------
// private methods... // private methods...
//------------------------------------------- //-----------------------------
void initializeAvatar();
void initializeSkeleton(); void initializeSkeleton();
void updateSkeleton(); void updateSkeleton();
void initializeBodySprings(); void initializeBodySprings();
void updateBodySprings( float deltaTime ); void updateBodySprings( float deltaTime );
void calculateBoneLengths(); void calculateBoneLengths();
void updateBigSphereCollisionTest( float deltaTime );
void readSensors(); void readSensors();
}; };

View file

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

View file

@ -167,14 +167,14 @@ void SerialInterface::readData() {
int initialSamples = totalSamples; int initialSamples = totalSamples;
while (read(serialFd, &bufchar, 1) > 0) { while (read(serialFd, &bufchar, 1) > 0) {
//std::cout << bufchar[0]; //printLof("%c", bufchar[0]);
serialBuffer[serialBufferPos] = bufchar[0]; serialBuffer[serialBufferPos] = bufchar[0];
serialBufferPos++; serialBufferPos++;
// Have we reached end of a line of input? // Have we reached end of a line of input?
if ((bufchar[0] == '\n') || (serialBufferPos >= MAX_BUFFER)) { if ((bufchar[0] == '\n') || (serialBufferPos >= MAX_BUFFER)) {
std::string serialLine(serialBuffer, serialBufferPos-1); std::string serialLine(serialBuffer, serialBufferPos-1);
//std::cout << serialLine << "\n"; //printLog("%s\n", serialLine.c_str());
int spot; int spot;
//int channel = 0; //int channel = 0;
std::string val; std::string val;
@ -182,7 +182,7 @@ void SerialInterface::readData() {
spot = serialLine.find_first_of(" ", 0); spot = serialLine.find_first_of(" ", 0);
if (spot != std::string::npos) { if (spot != std::string::npos) {
val = serialLine.substr(0,spot); 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()); if (i < NUM_CHANNELS) lastMeasured[i] = atoi(val.c_str());
else samplesAveraged = atoi(val.c_str()); else samplesAveraged = atoi(val.c_str());
} else LED = atoi(serialLine.c_str()); } else LED = atoi(serialLine.c_str());
@ -208,8 +208,7 @@ void SerialInterface::readData() {
} }
if (totalSamples == GRAVITY_SAMPLES) { if (totalSamples == GRAVITY_SAMPLES) {
gravity = glm::normalize(gravity); gravity = glm::normalize(gravity);
std::cout << "gravity: " << gravity.x << "," << printLof("gravity: %f,%f,%f\n", gravity.x, gravity.y, gravity.z);
gravity.y << "," << gravity.z << "\n";
} }
totalSamples++; totalSamples++;
@ -222,7 +221,7 @@ void SerialInterface::readData() {
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
if (diffclock(&lastGoodRead, &now) > NO_READ_MAXIMUM_MSECS) { if (diffclock(&lastGoodRead, &now) > NO_READ_MAXIMUM_MSECS) {
std::cout << "No data - Shutting down SerialInterface.\n"; printLog("No data - Shutting down SerialInterface.\n");
resetSerial(); resetSerial();
} }
} else { } else {

View file

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

View file

@ -7,7 +7,6 @@
// //
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include "FieldOfView.h"
#include "Stars.h" #include "Stars.h"
#define __interface__Starfield_impl__ #define __interface__Starfield_impl__
@ -23,8 +22,8 @@ Stars::~Stars() {
delete _ptrController; delete _ptrController;
} }
bool Stars::readInput(const char* url, unsigned limit) { bool Stars::readInput(const char* url, const char* cacheFile, unsigned limit) {
return _ptrController->readInput(url, limit); return _ptrController->readInput(url, cacheFile, limit);
} }
bool Stars::setResolution(unsigned k) { bool Stars::setResolution(unsigned k) {
@ -35,8 +34,9 @@ float Stars::changeLOD(float fraction, float overalloc, float realloc) {
return float(_ptrController->changeLOD(fraction, overalloc, realloc)); return float(_ptrController->changeLOD(fraction, overalloc, realloc));
} }
void Stars::render(FieldOfView const& fov) { void Stars::render(float fovDiagonal, float aspect, glm::mat4 const& view) {
_ptrController->render(fov.getPerspective(), fov.getAspectRatio(), fov.getOrientation());
_ptrController->render(fovDiagonal, aspect, glm::affineInverse(view));
} }

View file

@ -9,7 +9,7 @@
#ifndef __interface__Stars__ #ifndef __interface__Stars__
#define __interface__Stars__ #define __interface__Stars__
#include "FieldOfView.h" #include <glm/glm.hpp>
namespace starfield { class Controller; } namespace starfield { class Controller; }
@ -31,13 +31,13 @@ class Stars {
* The limit parameter allows to reduce the number of stars * The limit parameter allows to reduce the number of stars
* that are loaded, keeping the brightest ones. * that are loaded, keeping the brightest ones.
*/ */
bool readInput(const char* url, unsigned limit = 200000); bool readInput(const char* url, const char* cacheFile = 0l, unsigned limit = 200000);
/** /**
* Renders the starfield from a local viewer's perspective. * Renders the starfield from a local viewer's perspective.
* The parameter specifies the field of view. * The parameter specifies the field of view.
*/ */
void render(FieldOfView const& fov); void render(float fovDiagonal, float aspect, glm::mat4 const& view);
/** /**
* Sets the resolution for FOV culling. * Sets the resolution for FOV culling.

View file

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

View file

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

View file

@ -11,6 +11,7 @@
#include <cstring> #include <cstring>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <SharedUtil.h> #include <SharedUtil.h>
#include "Log.h" #include "Log.h"
@ -24,6 +25,37 @@ using namespace std;
// see http://www.opengl.org/resources/libraries/glut/spec3/node78.html // see http://www.opengl.org/resources/libraries/glut/spec3/node78.html
static float MONO_STROKE_WIDTH_GLUT = 104.76; 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. // Return the azimuth angle in degrees between two points.
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) { float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) {
return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180.0f / PIf; return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180.0f / PIf;
@ -166,7 +198,7 @@ void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
float scale = MONO_STROKE_WIDTH_GLUT / glutStrokeLength(GLUT_STROKE_ROMAN, tmpStr); float scale = MONO_STROKE_WIDTH_GLUT / glutStrokeLength(GLUT_STROKE_ROMAN, tmpStr);
glScalef(scale, 1.0f, 1.0f); glScalef(scale, 1.0f, 1.0f);
glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i])); glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i]));
// stay humble on the stack - might be in projection mode // staying humble on the stack - might be in projection mode
glScalef(1.0f / scale, 1.0f, 1.0f); glScalef(1.0f / scale, 1.0f, 1.0f);
} }
#endif #endif
@ -258,6 +290,13 @@ void renderOrientationDirections( glm::vec3 position, Orientation orientation, f
glEnd(); 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() { void testOrientationClass() {
printLog("\n----------\ntestOrientationClass()\n----------\n\n"); printLog("\n----------\ntestOrientationClass()\n----------\n\n");
@ -267,14 +306,45 @@ void testOrientationClass() {
// ( yaw , pitch, roll , front.x , front.y , front.z , up.x , up.y , up.z , right.x , right.y , right.z ) // ( yaw , pitch, roll , front.x , front.y , front.z , up.x , up.y , up.z , right.x , right.y , right.z )
// simple yaw tests // 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( 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(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(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( 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(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(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 // 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; int failedCount = 0;
@ -298,33 +368,43 @@ void testOrientationClass() {
glm::vec3 up = o1.getUp(); glm::vec3 up = o1.getUp();
glm::vec3 right = o1.getRight(); glm::vec3 right = o1.getRight();
printLog("\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);
printLog(" +front.x=%f, front.y=%f, front.z=%f\n",front.x,front.y,front.z); printLog("\nFRONT\n");
if (front.x == tests[i].frontX && front.y == tests[i].frontY && front.z == tests[i].frontZ) { 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"); printLog(" front vector PASSES!\n");
} else { } else {
printLog(" front vector FAILED! expected: \n"); printLog(" expected: front.x=%f, front.y=%f, front.z=%f\n",tests[i].frontX,tests[i].frontY,tests[i].frontZ);
printLog(" 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; passed = false;
} }
printLog(" +up.x=%f, up.y=%f, up.z=%f\n",up.x,up.y,up.z); printLog("\nUP\n");
if (up.x == tests[i].upX && up.y == tests[i].upY && up.z == tests[i].upZ) { 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"); printLog(" up vector PASSES!\n");
} else { } else {
printLog(" up vector FAILED! expected: \n"); printLog(" expected: up.x=%f, up.y=%f, up.z=%f\n",tests[i].upX,tests[i].upY,tests[i].upZ);
printLog(" 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; passed = false;
} }
printLog(" +right.x=%f, right.y=%f, right.z=%f\n",right.x,right.y,right.z); printLog("\nRIGHT\n");
if (right.x == tests[i].rightX && right.y == tests[i].rightY && right.z == tests[i].rightZ) { 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"); printLog(" right vector PASSES!\n");
} else { } else {
printLog(" right vector FAILED! expected: \n"); printLog(" expected: right.x=%f, right.y=%f, right.z=%f\n",tests[i].rightX,tests[i].rightY,tests[i].rightZ);
printLog(" 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; passed = false;
} }
@ -340,5 +420,3 @@ void testOrientationClass() {

View file

@ -19,6 +19,7 @@
#include <Orientation.h> #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 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); float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw);

View file

@ -11,7 +11,6 @@
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <iostream>
#include <UDPSocket.h> #include <UDPSocket.h>
#include <AgentData.h> #include <AgentData.h>
#include <VoxelTree.h> #include <VoxelTree.h>

View file

@ -24,8 +24,6 @@
// //
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include <iostream>
#include <fstream>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <sstream> #include <sstream>
@ -59,7 +57,7 @@
#include "Audio.h" #include "Audio.h"
#endif #endif
#include "FieldOfView.h" #include "AngleUtil.h"
#include "Stars.h" #include "Stars.h"
#include "MenuRow.h" #include "MenuRow.h"
@ -79,6 +77,7 @@
#include <PerfStat.h> #include <PerfStat.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <AvatarData.h>
#include "ViewFrustum.h" #include "ViewFrustum.h"
@ -100,6 +99,7 @@ int headMirror = 1; // Whether to mirror own head when viewing
int WIDTH = 1200; // Window size int WIDTH = 1200; // Window size
int HEIGHT = 800; int HEIGHT = 800;
int fullscreen = 0; int fullscreen = 0;
float aspectRatio = 1.0f;
bool wantColorRandomizer = true; // for addSphere and load file bool wantColorRandomizer = true; // for addSphere and load file
@ -107,18 +107,14 @@ Oscilloscope audioScope(256,200,true);
ViewFrustum viewFrustum; // current state of view frustum, perspective, orientation, etc. ViewFrustum viewFrustum; // current state of view frustum, perspective, orientation, etc.
Head myAvatar; // The rendered avatar of oneself Head myAvatar(true); // The rendered avatar of oneself
Camera myCamera; // My view onto the world (sometimes on myself :) Camera myCamera; // My view onto the world (sometimes on myself :)
Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
// Starfield information // Starfield information
char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
FieldOfView fov; char starCacheFile[] = "cachedStars.txt";
Stars stars; Stars stars;
#ifdef STARFIELD_KEYS
int starsTiles = 20;
double starsLod = 1.0;
#endif
bool showingVoxels = true; bool showingVoxels = true;
@ -154,11 +150,11 @@ float renderPitchRate = 0.f;
// Where one's own agent begins in the world (needs to become a dynamic thing passed to the program) // 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); glm::vec3 start_location(6.1f, 0, 1.4f);
bool statsOn = true; // Whether to show onscreen text overlay with stats bool statsOn = false; // Whether to show onscreen text overlay with stats
bool starsOn = false; // Whether to display the stars bool starsOn = false; // Whether to display the stars
bool paintOn = false; // Whether to paint voxels as you fly around bool paintOn = false; // Whether to paint voxels as you fly around
VoxelDetail paintingVoxel; // The voxel we're painting if we're painting VoxelDetail paintingVoxel; // The voxel we're painting if we're painting
unsigned char dominantColor = 0; // The dominant color of the voxel 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? bool perfStatsOn = false; // Do we want to display perfStats?
int noiseOn = 0; // Whether to add random noise int noiseOn = 0; // Whether to add random noise
@ -174,8 +170,8 @@ int headMouseX, headMouseY;
int mouseX, mouseY; // Where is the mouse int mouseX, mouseY; // Where is the mouse
// Mouse location at start of last down click // Mouse location at start of last down click
int mouseStartX;// = WIDTH / 2; int mouseStartX = WIDTH / 2;
int mouseStartY;// = HEIGHT / 2; int mouseStartY = HEIGHT / 2;
int mousePressed = 0; // true if mouse has been pressed (clear when finished) int mousePressed = 0; // true if mouse has been pressed (clear when finished)
Menu menu; // main menu Menu menu; // main menu
@ -238,12 +234,7 @@ void displayStats(void)
char stats[200]; char stats[200];
sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)= %4.2f, %4.2f, %4.2f ", sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)= %4.2f, %4.2f, %4.2f ",
FPS, packetsPerSecond, bytesPerSecond, avatarPos.x,avatarPos.y,avatarPos.z); FPS, packetsPerSecond, bytesPerSecond, avatarPos.x,avatarPos.y,avatarPos.z);
drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats);
if (serialPort.active) {
sprintf(stats, "ADC samples = %d, LED = %d",
serialPort.getNumSamples(), serialPort.getLED());
drawtext(300, statsVerticalOffset + 30, 0.10f, 0, 1.0, 0, stats);
}
std::stringstream voxelStats; std::stringstream voxelStats;
voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered(); voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered();
@ -311,7 +302,7 @@ void init(void)
headMouseX = WIDTH/2; headMouseX = WIDTH/2;
headMouseY = HEIGHT/2; headMouseY = HEIGHT/2;
stars.readInput(starFile, 0); stars.readInput(starFile, starCacheFile, 0);
// Initialize Field values // Initialize Field values
field = Field(); field = Field();
@ -391,10 +382,10 @@ void updateAvatarHand(float deltaTime) {
// //
void updateAvatar(float frametime) void updateAvatar(float frametime)
{ {
float gyroPitchRate = serialPort.getRelativeValue(PITCH_RATE); float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE);
float gyroYawRate = serialPort.getRelativeValue(YAW_RATE); float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE );
myAvatar.UpdatePos(frametime, &serialPort, headMirror, &gravity); myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity);
// //
// Update gyro-based mouse (X,Y on screen) // Update gyro-based mouse (X,Y on screen)
@ -463,6 +454,8 @@ void updateAvatar(float frametime)
*broadcastString = PACKET_HEADER_HEAD_DATA; *broadcastString = PACKET_HEADER_HEAD_DATA;
int broadcastBytes = myAvatar.getBroadcastData(broadcastString + 1); int broadcastBytes = myAvatar.getBroadcastData(broadcastString + 1);
broadcastBytes++;
const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER}; const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER};
AgentList::getInstance()->broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2); AgentList::getInstance()->broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2);
@ -732,7 +725,7 @@ void display(void)
//---------------------------------------------------- //----------------------------------------------------
myCamera.setTargetPosition ( myAvatar.getBodyPosition() ); myCamera.setTargetPosition ( myAvatar.getBodyPosition() );
myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() ); 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.setRoll ( 0.0 );
myCamera.setUp ( 0.45); myCamera.setUp ( 0.45);
myCamera.setDistance ( 1.0 ); myCamera.setDistance ( 1.0 );
@ -772,18 +765,12 @@ void display(void)
glRotatef ( whichCamera.getYaw(), 0, 1, 0 ); glRotatef ( whichCamera.getYaw(), 0, 1, 0 );
glTranslatef( -whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z ); glTranslatef( -whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z );
//quick test for camera ortho-normal sanity check...
if (::starsOn) { if (::starsOn) {
// should be the first rendering pass - w/o depth buffer / lighting // should be the first rendering pass - w/o depth buffer / lighting
stars.render(fov);
glm::mat4 view;
glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view));
stars.render(angleConvert<Degrees,Radians>(whichCamera.getFieldOfView()), aspectRatio, view);
} }
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
@ -835,8 +822,8 @@ void display(void)
Head *agentHead = (Head *)agent->getLinkedData(); Head *agentHead = (Head *)agent->getLinkedData();
glPushMatrix(); glPushMatrix();
glm::vec3 pos = agentHead->getBodyPosition(); glm::vec3 pos = agentHead->getBodyPosition();
glTranslatef(-pos.x, -pos.y, -pos.z); glTranslatef(pos.x, pos.y, pos.z);
agentHead->render(0, 0); agentHead->render(0);
glPopMatrix(); glPopMatrix();
} }
} }
@ -849,9 +836,8 @@ void display(void)
// brad's frustum for debugging // brad's frustum for debugging
if (::frustumOn) render_view_frustum(); if (::frustumOn) render_view_frustum();
//Render my own avatar //Render my own avatar
myAvatar.render( true, 1 ); myAvatar.render(true);
} }
glPopMatrix(); glPopMatrix();
@ -1092,7 +1078,7 @@ void testPointToVoxel()
float s=0.1; float s=0.1;
for (float x=0; x<=1; x+= 0.05) for (float x=0; x<=1; x+= 0.05)
{ {
std::cout << " x=" << x << " "; printLog(" x=%f");
unsigned char red = 200; //randomColorValue(65); unsigned char red = 200; //randomColorValue(65);
unsigned char green = 200; //randomColorValue(65); unsigned char green = 200; //randomColorValue(65);
@ -1101,7 +1087,7 @@ void testPointToVoxel()
unsigned char* voxelCode = pointToVoxel(x, y, z, s,red,green,blue); unsigned char* voxelCode = pointToVoxel(x, y, z, s,red,green,blue);
printVoxelCode(voxelCode); printVoxelCode(voxelCode);
delete voxelCode; delete voxelCode;
std::cout << std::endl; printLog("\n");
} }
} }
@ -1286,13 +1272,6 @@ void key(unsigned char k, int x, int y)
if (k == ' ') reset_sensors(); if (k == ' ') reset_sensors();
if (k == 't') renderPitchRate -= KEYBOARD_PITCH_RATE; if (k == 't') renderPitchRate -= KEYBOARD_PITCH_RATE;
if (k == 'g') renderPitchRate += KEYBOARD_PITCH_RATE; if (k == 'g') renderPitchRate += KEYBOARD_PITCH_RATE;
#ifdef STARFIELD_KEYS
if (k == 'u') stars.setResolution(starsTiles += 1);
if (k == 'j') stars.setResolution(starsTiles = max(starsTiles-1,1));
if (k == 'i') if (starsLod < 1.0) starsLod = stars.changeLOD(1.01);
if (k == 'k') if (starsLod > 0.01) starsLod = stars.changeLOD(0.99);
if (k == 'r') stars.readInput(starFile, 0);
#endif
if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 1); if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 1);
if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 1); if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 1);
} }
@ -1322,7 +1301,7 @@ void *networkReceive(void *args)
AgentList::getInstance()->processBulkAgentData(&senderAddress, AgentList::getInstance()->processBulkAgentData(&senderAddress,
incomingPacket, incomingPacket,
bytesReceived, bytesReceived,
(sizeof(float) * 3) + (sizeof(uint16_t) * 2)); BYTES_PER_AVATAR);
break; break;
default: default:
AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived);
@ -1343,22 +1322,21 @@ void idle(void) {
// Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time // Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time
if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) { 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 leftRight = ( mouseX - mouseStartX ) / (float)WIDTH;
float downUp = ( mouseY - mouseStartY ) / (float)HEIGHT; float downUp = ( mouseY - mouseStartY ) / (float)HEIGHT;
float backFront = 0.0; float backFront = 0.0;
glm::vec3 handMovement( leftRight, downUp, backFront ); glm::vec3 handMovement( leftRight, downUp, backFront );
myAvatar.setHandMovement( handMovement ); myAvatar.setHandMovement( handMovement );
} /*}
else { else {
mouseStartX = mouseX; mouseStartX = mouseX;
mouseStartY = mouseY; mouseStartY = mouseY;
//mouseStartX = (float)WIDTH / 2.0f; //mouseStartX = (float)WIDTH / 2.0f;
//mouseStartY = (float)HEIGHT / 2.0f; //mouseStartY = (float)HEIGHT / 2.0f;
} }
*/
//-------------------------------------------------------- //--------------------------------------------------------
// when the mouse is being pressed, an 'action' is being // when the mouse is being pressed, an 'action' is being
@ -1372,14 +1350,13 @@ void idle(void) {
} }
// //
// 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 ); updateAvatar( 1.f/FPS );
//loop through all the other avatars and simulate them.
//test AgentList * agentList = AgentList::getInstance();
/* for(std::vector<Agent>::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++)
for(std::vector<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++)
{ {
if (agent->getLinkedData() != NULL) if (agent->getLinkedData() != NULL)
{ {
@ -1387,7 +1364,7 @@ void idle(void) {
agentHead->simulate(1.f/FPS); agentHead->simulate(1.f/FPS);
} }
} }
*/
updateAvatarHand(1.f/FPS); updateAvatarHand(1.f/FPS);
@ -1412,7 +1389,7 @@ void reshape(int width, int height)
{ {
WIDTH = width; WIDTH = width;
HEIGHT = height; HEIGHT = height;
float aspectRatio = ((float)width/(float)height); // based on screen resize aspectRatio = ((float)width/(float)height); // based on screen resize
float fov; float fov;
float nearClip; float nearClip;
@ -1440,14 +1417,6 @@ void reshape(int width, int height)
glMatrixMode(GL_PROJECTION); //hello glMatrixMode(GL_PROJECTION); //hello
// XXXBHG - Note: this is Tobias's code for loading the perspective matrix. At Philip's suggestion, I'm removing
// it and putting back our old code that simply loaded the fov, ratio, and near/far clips. But I'm keeping this here
// for reference for now.
//fov.setResolution(width, height)
// .setBounds(glm::vec3(-0.5f,-0.5f,-500.0f), glm::vec3(0.5f, 0.5f, 0.1f) )
// .setPerspective(0.7854f);
//glLoadMatrixf(glm::value_ptr(fov.getViewerScreenXform()));
glLoadIdentity(); glLoadIdentity();
// XXXBHG - If we're in view frustum mode, then we need to do this little bit of hackery so that // XXXBHG - If we're in view frustum mode, then we need to do this little bit of hackery so that
@ -1505,7 +1474,7 @@ void mouseoverFunc( int x, int y)
void attachNewHeadToAgent(Agent *newAgent) { void attachNewHeadToAgent(Agent *newAgent) {
if (newAgent->getLinkedData() == NULL) { if (newAgent->getLinkedData() == NULL) {
newAgent->setLinkedData(new Head()); newAgent->setLinkedData(new Head(false));
} }
} }
@ -1522,7 +1491,10 @@ int main(int argc, const char * argv[])
avatars_lib::printLog = & ::printLog; avatars_lib::printLog = & ::printLog;
// Quick test of the Orientation class on startup! // Quick test of the Orientation class on startup!
testOrientationClass(); if (cmdOptionExists(argc, argv, "--testOrientation")) {
testOrientationClass();
return EXIT_SUCCESS;
}
AgentList::createInstance(AGENT_TYPE_INTERFACE); AgentList::createInstance(AGENT_TYPE_INTERFACE);

View file

@ -25,8 +25,8 @@
#define STARFIELD_LOW_MEMORY 0 // set to 1 not to use 16-bit types #define STARFIELD_LOW_MEMORY 0 // set to 1 not to use 16-bit types
#endif #endif
#ifndef STARFIELD_DEBUG_LOD #ifndef STARFIELD_DEBUG_CULLING
#define STARFIELD_DEBUG_LOD 0 // set to 1 to peek behind the scenes #define STARFIELD_DEBUG_CULLING 0 // set to 1 to peek behind the scenes
#endif #endif
#ifndef STARFIELD_MULTITHREADING #ifndef STARFIELD_MULTITHREADING
@ -65,7 +65,6 @@
#include <glm/gtc/matrix_inverse.hpp> #include <glm/gtc/matrix_inverse.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_access.hpp> #include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/swizzle.hpp>
#include "UrlReader.h" #include "UrlReader.h"
#include "AngleUtil.h" #include "AngleUtil.h"
@ -81,13 +80,11 @@ namespace starfield {
using glm::vec4; using glm::vec4;
using glm::dot; using glm::dot;
using glm::normalize; using glm::normalize;
using glm::swizzle;
using glm::X; using glm::X;
using glm::Y; using glm::Y;
using glm::Z; using glm::Z;
using glm::W; using glm::W;
using glm::mat4; using glm::mat4;
using glm::column;
using glm::row; using glm::row;
using namespace std; using namespace std;

View file

@ -109,11 +109,11 @@ namespace starfield {
_ptrRenderer(0l) { _ptrRenderer(0l) {
} }
bool readInput(const char* url, unsigned limit) bool readInput(const char* url, const char* cacheFile, unsigned limit)
{ {
InputVertices vertices; InputVertices vertices;
if (! Loader().loadVertices(vertices, url, limit)) if (! Loader().loadVertices(vertices, url, cacheFile, limit))
return false; return false;
BrightnessLevels brightness; BrightnessLevels brightness;

View file

@ -33,7 +33,7 @@ namespace starfield {
public: public:
bool loadVertices( bool loadVertices(
InputVertices& destination, char const* url, unsigned limit) InputVertices& destination, char const* url, char const* cacheFile, unsigned limit)
{ {
_ptrVertices = & destination; _ptrVertices = & destination;
_valLimit = limit; _valLimit = limit;
@ -43,7 +43,7 @@ namespace starfield {
#endif #endif
_strUrl = url; // in case we fail early _strUrl = url; // in case we fail early
if (! UrlReader::readUrl(url, *this)) if (! UrlReader::readUrl(url, *this, cacheFile))
{ {
printLog("%s:%d: %s\n", printLog("%s:%d: %s\n",
_strUrl, _valLineNo, getError()); _strUrl, _valLineNo, getError());

View file

@ -149,7 +149,7 @@ namespace starfield {
matrix[3][2] = 0.0f; matrix[3][2] = 0.0f;
// extract local z vector // extract local z vector
vec3 ahead = swizzle<X,Y,Z>( column(matrix, 2) ); vec3 ahead = vec3(matrix[2]);
float azimuth = atan2(ahead.x,-ahead.z) + Radians::pi(); float azimuth = atan2(ahead.x,-ahead.z) + Radians::pi();
float altitude = atan2(-ahead.y, hypotf(ahead.x, ahead.z)); float altitude = atan2(-ahead.y, hypotf(ahead.x, ahead.z));
@ -163,7 +163,7 @@ namespace starfield {
// printLog("Stars.cpp: starting on tile #%d\n", tileIndex); // printLog("Stars.cpp: starting on tile #%d\n", tileIndex);
#if STARFIELD_DEBUG_LOD #if STARFIELD_DEBUG_CULLING
mat4 matrix_debug = glm::translate( mat4 matrix_debug = glm::translate(
glm::frustum(-hw, hw, -hh, hh, nearClip, 10.0f), glm::frustum(-hw, hw, -hh, hh, nearClip, 10.0f),
vec3(0.0f, 0.0f, -4.0f)) * glm::affineInverse(matrix); vec3(0.0f, 0.0f, -4.0f)) * glm::affineInverse(matrix);
@ -173,7 +173,7 @@ namespace starfield {
* glm::affineInverse(matrix); * glm::affineInverse(matrix);
this->_itrOutIndex = (unsigned*) _arrBatchOffs; this->_itrOutIndex = (unsigned*) _arrBatchOffs;
this->_vecWxform = swizzle<X,Y,Z>(row(matrix, 3)); this->_vecWxform = vec3(row(matrix, 3));
this->_valHalfPersp = halfPersp; this->_valHalfPersp = halfPersp;
this->_valMinBright = minBright; this->_valMinBright = minBright;
@ -181,13 +181,13 @@ namespace starfield {
_arrTile, _arrTile + _objTiling.getTileCount(), _arrTile, _arrTile + _objTiling.getTileCount(),
(Tile**) _arrBatchCount)); (Tile**) _arrBatchCount));
#if STARFIELD_DEBUG_LOD #if STARFIELD_DEBUG_CULLING
# define matrix matrix_debug # define matrix matrix_debug
#endif #endif
this->glBatch(glm::value_ptr(matrix), prepareBatch( this->glBatch(glm::value_ptr(matrix), prepareBatch(
(unsigned*) _arrBatchOffs, _itrOutIndex) ); (unsigned*) _arrBatchOffs, _itrOutIndex) );
#if STARFIELD_DEBUG_LOD #if STARFIELD_DEBUG_CULLING
# undef matrix # undef matrix
#endif #endif
} }

View file

@ -10,9 +10,14 @@
#include <cstring> #include <cstring>
#include <stdint.h> #include <stdint.h>
#include <SharedUtil.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include "AvatarData.h" #include "AvatarData.h"
#include "avatars_Log.h"
using avatars_lib::printLog;
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) { int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0); 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); return sizeof(uint16_t);
} }
int unpackFloatAngleFromTwoByte(uint16_t *byteAnglePointer, float *destinationPointer) { int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer) {
*destinationPointer = (*byteAnglePointer / std::numeric_limits<uint16_t>::max()) * 360.0 - 180; *destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.0 - 180;
return sizeof(uint16_t); return sizeof(uint16_t);
} }
@ -43,14 +48,13 @@ AvatarData* AvatarData::clone() const {
return new AvatarData(*this); return new AvatarData(*this);
} }
// transmit data to agents requesting it
// called on me just prior to sending data to others (continuasly called)
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
unsigned char* bufferStart = destinationBuffer; unsigned char* bufferStart = destinationBuffer;
// TODO: DRY this up to a shared method // TODO: DRY this up to a shared method
// that can pack any type given the number of bytes // that can pack any type given the number of bytes
// and return the number of bytes to push the pointer // and return the number of bytes to push the pointer
memcpy(destinationBuffer, &_bodyPosition, sizeof(float) * 3); memcpy(destinationBuffer, &_bodyPosition, sizeof(float) * 3);
destinationBuffer += sizeof(float) * 3; destinationBuffer += sizeof(float) * 3;
@ -58,12 +62,18 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
//printLog( "_bodyYaw = %f", _bodyYaw );
memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3);
destinationBuffer += sizeof(float) * 3;
printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z);
return destinationBuffer - bufferStart; return destinationBuffer - bufferStart;
} }
// called on the other agents - assigns it to my views of the others // called on the other agents - assigns it to my views of the others
void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
// increment to push past the packet header // increment to push past the packet header
sourceBuffer++; sourceBuffer++;
@ -73,6 +83,14 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll);
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() { glm::vec3 AvatarData::getBodyPosition() {
@ -85,6 +103,10 @@ void AvatarData::setBodyPosition(glm::vec3 bodyPosition) {
_bodyPosition = bodyPosition; _bodyPosition = bodyPosition;
} }
void AvatarData::setHandPosition(glm::vec3 handPosition) {
_handPosition = handPosition;
}
float AvatarData::getBodyYaw() { float AvatarData::getBodyYaw() {
return _bodyYaw; return _bodyYaw;
} }

View file

@ -9,12 +9,12 @@
#ifndef __hifi__AvatarData__ #ifndef __hifi__AvatarData__
#define __hifi__AvatarData__ #define __hifi__AvatarData__
#include <iostream>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <AgentData.h> #include <AgentData.h>
const int BYTES_PER_AVATAR = 30;
class AvatarData : public AgentData { class AvatarData : public AgentData {
public: public:
AvatarData(); AvatarData();
@ -24,6 +24,7 @@ public:
glm::vec3 getBodyPosition(); glm::vec3 getBodyPosition();
void setBodyPosition(glm::vec3 bodyPosition); void setBodyPosition(glm::vec3 bodyPosition);
void setHandPosition(glm::vec3 handPosition);
int getBroadcastData(unsigned char* destinationBuffer); int getBroadcastData(unsigned char* destinationBuffer);
void parseData(unsigned char* sourceBuffer, int numBytes); void parseData(unsigned char* sourceBuffer, int numBytes);
@ -39,6 +40,7 @@ public:
protected: protected:
glm::vec3 _bodyPosition; glm::vec3 _bodyPosition;
glm::vec3 _handPosition;
float _bodyYaw; float _bodyYaw;
float _bodyPitch; float _bodyPitch;

View file

@ -9,94 +9,107 @@
#include <SharedUtil.h> #include <SharedUtil.h>
#include "avatars_Log.h" #include "avatars_Log.h"
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
//#include "Util.h"
using avatars_lib::printLog; using avatars_lib::printLog;
static bool testingForNormalizationAndOrthogonality = true; // 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... :-)
//
static bool testingForNormalizationAndOrthogonality = false;
Orientation::Orientation() { Orientation::Orientation() {
setToIdentity(); setToIdentity();
} }
void Orientation::setToIdentity() { void Orientation::setToIdentity() {
right = glm::vec3( 1.0, 0.0, 0.0 ); _yaw = 0.0;
up = glm::vec3( 0.0, 1.0, 0.0 ); _pitch = 0.0;
front = glm::vec3( 0.0, 0.0, 1.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 ) { void Orientation::set( Orientation o ) {
right = o.right; right = o.right;
up = o.up; up = o.up;
front = o.front; front = o.front;
} }
void Orientation::update() {
void Orientation::yaw( float angle ) { float pitchRads = _pitch * PI_OVER_180;
float r = angle * PI_OVER_180; float yawRads = _yaw * PI_OVER_180;
float s = sin(r); float rollRads = _roll * PI_OVER_180;
float c = cos(r);
glm::quat q(glm::vec3(pitchRads, -(yawRads), rollRads));
glm::vec3 cosineFront = front * c;
glm::vec3 cosineRight = right * c; // Next, create a rotation matrix from that quaternion
glm::vec3 sineFront = front * s; glm::mat4 rotation;
glm::vec3 sineRight = right * s; rotation = glm::mat4_cast(q);
front = cosineFront + sineRight; // Transform the original vectors by the rotation matrix to get the new vectors
right = cosineRight - sineFront; 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 ); } 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 ) { void Orientation::pitch( float angle ) {
float r = angle * PI_OVER_180; // remember the value for any future changes to other angles
float s = sin(r); _pitch = angle;
float c = cos(r); update();
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 ); }
} }
void Orientation::roll( float angle ) { void Orientation::roll( float angle ) {
float r = angle * PI_OVER_180; _roll = angle;
float s = sin(r); update();
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 ); }
} }
void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) { void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) {
right = r; right = r;
up = u; up = u;
front = f; front = f;
} }
//----------------------------------------------------------------------
void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) { 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) // make sure vectors are normalized (or close enough to length 1.0)
//------------------------------------------------------------------
float rightLength = glm::length( right ); float rightLength = glm::length( right );
float upLength = glm::length( up ); float upLength = glm::length( up );
float frontLength = glm::length( front ); float frontLength = glm::length( front );
@ -125,10 +138,7 @@ void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) {
assert ( frontLength < 1.0f + epsilon ); assert ( frontLength < 1.0f + epsilon );
// make sure vectors are orthogonal (or close enough)
//----------------------------------------------------------------
// make sure vectors are orthoginal (or close enough)
//----------------------------------------------------------------
glm::vec3 rightCross = glm::cross( up, front ); glm::vec3 rightCross = glm::cross( up, front );
glm::vec3 upCross = glm::cross( front, right ); glm::vec3 upCross = glm::cross( front, right );
glm::vec3 frontCross = glm::cross( right, up ); glm::vec3 frontCross = glm::cross( right, up );

View file

@ -20,6 +20,13 @@ enum Axis
class Orientation class Orientation
{ {
private:
float _yaw;
float _pitch;
float _roll;
void update(); // actually updates the vectors from yaw, pitch, roll
public: public:
Orientation(); Orientation();

View file

@ -10,6 +10,7 @@
#include "Agent.h" #include "Agent.h"
#include "AgentTypes.h" #include "AgentTypes.h"
#include <cstring> #include <cstring>
#include "shared_Log.h"
#include "UDPSocket.h" #include "UDPSocket.h"
#include "SharedUtil.h" #include "SharedUtil.h"
@ -19,6 +20,8 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
using shared_lib::printLog;
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) { Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) {
publicSocket = new sockaddr; publicSocket = new sockaddr;
memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr)); memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr));
@ -71,7 +74,6 @@ Agent::Agent(const Agent &otherAgent) {
} }
Agent& Agent::operator=(Agent otherAgent) { Agent& Agent::operator=(Agent otherAgent) {
std::cout << "Agent swap constructor called on resize?\n";
swap(*this, otherAgent); swap(*this, otherAgent);
return *this; return *this;
} }
@ -209,6 +211,16 @@ bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, cha
&& socketMatch(localSocket, otherLocalSocket); && socketMatch(localSocket, otherLocalSocket);
} }
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: %8x:%d LA: %8x:%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) { std::ostream& operator<<(std::ostream& os, const Agent* agent) {
sockaddr_in *agentPublicSocket = (sockaddr_in *)agent->publicSocket; sockaddr_in *agentPublicSocket = (sockaddr_in *)agent->publicSocket;
sockaddr_in *agentLocalSocket = (sockaddr_in *)agent->localSocket; sockaddr_in *agentLocalSocket = (sockaddr_in *)agent->localSocket;
@ -217,4 +229,4 @@ std::ostream& operator<<(std::ostream& os, const Agent* agent) {
":" << ntohs(agentPublicSocket->sin_port) << " LA: " << inet_ntoa(agentLocalSocket->sin_addr) << ":" << ntohs(agentPublicSocket->sin_port) << " LA: " << inet_ntoa(agentLocalSocket->sin_addr) <<
":" << ntohs(agentLocalSocket->sin_port); ":" << ntohs(agentLocalSocket->sin_port);
return os; return os;
} }

View file

@ -9,8 +9,8 @@
#ifndef __hifi__Agent__ #ifndef __hifi__Agent__
#define __hifi__Agent__ #define __hifi__Agent__
#include <iostream>
#include <stdint.h> #include <stdint.h>
#include <ostream>
#include "AgentData.h" #include "AgentData.h"
#ifdef _WIN32 #ifdef _WIN32
@ -50,6 +50,7 @@ public:
AgentData* getLinkedData(); AgentData* getLinkedData();
void setLinkedData(AgentData *newData); void setLinkedData(AgentData *newData);
static void printLog(Agent const&);
friend std::ostream& operator<<(std::ostream& os, const Agent* agent); friend std::ostream& operator<<(std::ostream& os, const Agent* agent);
private: private:
void swap(Agent &first, Agent &second); void swap(Agent &first, Agent &second);

View file

@ -110,9 +110,9 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow()); bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow());
} }
unsigned char *startPosition = (unsigned char *)packetData; unsigned char *startPosition = packetData;
unsigned char *currentPosition = startPosition + 1; unsigned char *currentPosition = startPosition + 1;
unsigned char *packetHolder = new unsigned char[numBytesPerAgent + 1]; unsigned char packetHolder[numBytesPerAgent + 1];
packetHolder[0] = PACKET_HEADER_HEAD_DATA; packetHolder[0] = PACKET_HEADER_HEAD_DATA;
@ -125,13 +125,12 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
int matchingAgentIndex = indexOfMatchingAgent(agentID); int matchingAgentIndex = indexOfMatchingAgent(agentID);
if (matchingAgentIndex >= 0) { if (matchingAgentIndex >= 0) {
updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1); updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1);
} }
currentPosition += numBytesPerAgent; currentPosition += numBytesPerAgent;
} }
delete[] packetHolder;
} }
void AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { void AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) {
@ -151,7 +150,7 @@ void AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int
linkedDataCreateCallback(agent); linkedDataCreateCallback(agent);
} }
} }
agent->getLinkedData()->parseData(packetData, dataBytes); agent->getLinkedData()->parseData(packetData, dataBytes);
} }
@ -241,7 +240,8 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
newAgent.activatePublicSocket(); newAgent.activatePublicSocket();
} }
std::cout << "Added agent - " << &newAgent << "\n"; printLog("Added agent - ");
Agent::printLog(newAgent);
pthread_mutex_lock(&vectorChangeMutex); pthread_mutex_lock(&vectorChangeMutex);
agents.push_back(newAgent); agents.push_back(newAgent);
@ -340,7 +340,8 @@ void *removeSilentAgents(void *args) {
&& agent->getType() != AGENT_TYPE_VOXEL && agent->getType() != AGENT_TYPE_VOXEL
&& pthread_mutex_trylock(agentDeleteMutex) == 0) { && 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 // make sure the vector isn't currently adding an agent
pthread_mutex_lock(&vectorChangeMutex); pthread_mutex_lock(&vectorChangeMutex);

View file

@ -9,7 +9,6 @@
#ifndef __hifi__AgentList__ #ifndef __hifi__AgentList__
#define __hifi__AgentList__ #define __hifi__AgentList__
#include <iostream>
#include <vector> #include <vector>
#include <stdint.h> #include <stdint.h>

View file

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

View file

@ -77,7 +77,7 @@ bool oneAtBit(unsigned char byte, int bitIndex) {
return (byte >> (7 - bitIndex) & 1); return (byte >> (7 - bitIndex) & 1);
} }
void switchToResourcesIfRequired() { void switchToResourcesParentIfRequired() {
#ifdef __APPLE__ #ifdef __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle(); CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
@ -88,6 +88,7 @@ void switchToResourcesIfRequired() {
CFRelease(resourcesURL); CFRelease(resourcesURL);
chdir(path); chdir(path);
chdir("..");
#endif #endif
} }

View file

@ -47,7 +47,7 @@ void printVoxelCode(unsigned char* voxelCode);
int numberOfOnes(unsigned char byte); int numberOfOnes(unsigned char byte);
bool oneAtBit(unsigned char byte, int bitIndex); bool oneAtBit(unsigned char byte, int bitIndex);
void switchToResourcesIfRequired(); void switchToResourcesParentIfRequired();
const char* getCmdOption(int argc, const char * argv[],const char* option); const char* getCmdOption(int argc, const char * argv[],const char* option);
bool cmdOptionExists(int argc, const char * argv[],const char* option); bool cmdOptionExists(int argc, const char * argv[],const char* option);

View file

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

View file

@ -18,6 +18,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ifaddrs.h> #include <ifaddrs.h>
#include <unistd.h>
#endif #endif
#include "shared_Log.h" #include "shared_Log.h"

View file

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

View file

@ -6,13 +6,17 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
// //
#include "UrlReader.h" #include "UrlReader.h"
#include <new> #include <new>
#ifdef _WIN32 #ifdef _WIN32
#define NOCURL_IN_WINDOWS #define NOCURL_IN_WINDOWS
#endif #endif
#include <sys/types.h>
#include <sys/stat.h>
#ifndef NOCURL_IN_WINDOWS #ifndef NOCURL_IN_WINDOWS
#include <curl/curl.h> #include <curl/curl.h>
size_t const UrlReader::max_read_ahead = CURL_MAX_WRITE_SIZE; size_t const UrlReader::max_read_ahead = CURL_MAX_WRITE_SIZE;
@ -21,6 +25,7 @@ size_t const UrlReader::max_read_ahead = 0;
#endif #endif
char const* const UrlReader::success = "UrlReader: Success!"; char const* const UrlReader::success = "UrlReader: Success!";
char const* const UrlReader::success_cached = "UrlReader:: Using local file.";
char const* const UrlReader::error_init_failed = "UrlReader: Initialization failed."; char const* const UrlReader::error_init_failed = "UrlReader: Initialization failed.";
char const* const UrlReader::error_aborted = "UrlReader: Processing error."; char const* const UrlReader::error_aborted = "UrlReader: Processing error.";
char const* const UrlReader::error_buffer_overflow = "UrlReader: Buffer overflow."; char const* const UrlReader::error_buffer_overflow = "UrlReader: Buffer overflow.";
@ -29,7 +34,7 @@ char const* const UrlReader::error_leftover_input = "UrlReader: Incomplete pro
#define hnd_curl static_cast<CURL*>(_ptrImpl) #define hnd_curl static_cast<CURL*>(_ptrImpl)
UrlReader::UrlReader() UrlReader::UrlReader()
: _ptrImpl(0l), _arrXtra(0l), _strError(0l) { : _ptrImpl(0l), _arrXtra(0l), _strError(0l), _arrCacheRdBuf(0l) {
_arrXtra = new(std::nothrow) char[max_read_ahead]; _arrXtra = new(std::nothrow) char[max_read_ahead];
if (! _arrXtra) { _strError = error_init_failed; return; } if (! _arrXtra) { _strError = error_init_failed; return; }
@ -39,12 +44,14 @@ UrlReader::UrlReader()
curl_easy_setopt(hnd_curl, CURLOPT_NOSIGNAL, 1l); curl_easy_setopt(hnd_curl, CURLOPT_NOSIGNAL, 1l);
curl_easy_setopt(hnd_curl, CURLOPT_FAILONERROR, 1l); curl_easy_setopt(hnd_curl, CURLOPT_FAILONERROR, 1l);
curl_easy_setopt(hnd_curl, CURLOPT_FILETIME, 1l); curl_easy_setopt(hnd_curl, CURLOPT_FILETIME, 1l);
curl_easy_setopt(hnd_curl, CURLOPT_ENCODING, "");
#endif #endif
} }
UrlReader::~UrlReader() { UrlReader::~UrlReader() {
delete _arrXtra; delete[] _arrXtra;
delete[] _arrCacheRdBuf;
#ifndef NOCURL_IN_WINDOWS #ifndef NOCURL_IN_WINDOWS
if (! hnd_curl) return; if (! hnd_curl) return;
curl_easy_cleanup(hnd_curl); curl_easy_cleanup(hnd_curl);
@ -78,14 +85,42 @@ void UrlReader::getinfo(char const*& url,
char const*& type, int64_t& length, int64_t& stardate) { char const*& type, int64_t& length, int64_t& stardate) {
#ifndef NOCURL_IN_WINDOWS #ifndef NOCURL_IN_WINDOWS
double clen;
long time;
curl_easy_getinfo(hnd_curl, CURLINFO_FILETIME, & time);
// check caching file time whether we actually want to download anything
if (_strCacheFile != 0l) {
struct stat s;
stat(_strCacheFile, & s);
if (time > s.st_mtime) {
// file on server is newer -> update cache file
_ptrCacheFile = fopen(_strCacheFile, "wb");
if (_ptrCacheFile != 0l) {
_valCacheMode = cache_write;
}
} else {
// file on server is older -> use cache file
if (! _arrCacheRdBuf) {
_arrCacheRdBuf = new (std::nothrow) char[max_read_ahead];
if (! _arrCacheRdBuf) {
_valCacheMode = no_cache;
}
}
_ptrCacheFile = fopen(_strCacheFile, "rb");
if (_ptrCacheFile != 0l) {
_valCacheMode = cache_read;
}
_strError = success_cached;
}
}
curl_easy_getinfo(hnd_curl, CURLINFO_EFFECTIVE_URL, & url); curl_easy_getinfo(hnd_curl, CURLINFO_EFFECTIVE_URL, & url);
curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_TYPE, & type); curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_TYPE, & type);
double clen;
curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, & clen); curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, & clen);
length = static_cast<int64_t>(clen); length = static_cast<int64_t>(clen);
long time;
curl_easy_getinfo(hnd_curl, CURLINFO_FILETIME, & time); curl_easy_getinfo(hnd_curl, CURLINFO_FILETIME, & time);
stardate = time; stardate = time;
#endif #endif

View file

@ -12,119 +12,132 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdio.h>
/**
* UrlReader class that encapsulates a context for sequential data retrieval //
* via URLs. Use one per thread. // UrlReader class that encapsulates a context for sequential data retrieval
*/ // via URLs. Use one per thread.
//
class UrlReader { class UrlReader {
enum CacheMode { no_cache, cache_write, cache_read };
void* _ptrImpl; void* _ptrImpl;
char* _arrXtra; char* _arrXtra;
char const* _strError; char const* _strError;
void* _ptrStream; void* _ptrStream;
char const* _strCacheFile;
FILE* _ptrCacheFile;
char* _arrCacheRdBuf;
CacheMode _valCacheMode;
size_t _valXtraSize; size_t _valXtraSize;
public: public:
/** //
* Constructor - performs initialization, never throws. // Constructor - performs initialization, never throws.
*/ //
UrlReader(); UrlReader();
/** //
* Destructor - frees resources, never throws. // Destructor - frees resources, never throws.
*/ //
~UrlReader(); ~UrlReader();
/** //
* Reads data from an URL and forwards it to the instance of a class // Reads data from an URL and forwards it to the instance of a class
* fulfilling the ContentStream concept. // fulfilling the ContentStream concept.
* //
* The call protocol on the ContentStream is detailed as follows: // The call protocol on the ContentStream is detailed as follows:
* //
* 1. begin(char const* url, // 1. begin(char const* url,
* char const* content_type, uint64_t bytes, uint64_t stardate) // char const* content_type, uint64_t bytes, uint64_t stardate)
* //
* All information except 'url' is optional; 'content_type' can // All information except 'url' is optional; 'content_type' can
* be a null pointer - 'bytes' and 'stardate' can be equal to // be a null pointer - 'bytes' and 'stardate' can be equal to
* to 'unavailable'. // to 'unavailable'.
* //
* 2. transfer(char* buffer, size_t bytes) // 2. transfer(char* buffer, size_t bytes)
* //
* Called until all data has been received. The number of bytes // Called until all data has been received. The number of bytes
* actually processed should be returned. // actually processed should be returned.
* Unprocessed data is stored in an extra buffer whose size is // Unprocessed data is stored in an extra buffer whose size is
* given by the constant UrlReader::max_read_ahead - it can be // given by the constant UrlReader::max_read_ahead - it can be
* assumed to be reasonably large for on-the-fly parsing. // assumed to be reasonably large for on-the-fly parsing.
* //
* 3. end(bool ok) // 3. end(bool ok)
* //
* Called at the end of the transfer. // Called at the end of the transfer.
* //
* Returns the same success code // Returns the same success code
*/ //
template< class ContentStream > template< class ContentStream >
bool readUrl(char const* url, ContentStream& s); bool readUrl(char const* url, ContentStream& s, char const* cacheFile = 0l);
/** //
* Returns a pointer to a static C-string that describes the error // Returns a pointer to a static C-string that describes the error
* condition. // condition.
*/ //
inline char const* getError() const; inline char const* getError() const;
/** //
* Can be called by the stream to set a user-defined error string. // Can be called by the stream to set a user-defined error string.
*/ //
inline void setError(char const* static_c_string); inline void setError(char const* static_c_string);
/** //
* Pointer to the C-string returned by a call to 'readUrl' when no // Pointer to the C-string returned by a call to 'readUrl' when no
* error occurred. // error occurred.
*/ //
static char const* const success; static char const* const success;
/** //
* Pointer to the C-string returned by a call to 'readUrl' when the // Pointer to the C-string returned by a call to 'readUrl' when no
* initialization has failed. // error occurred and a local file has been read instead of the
*/ // network stream.
//
static char const* const success_cached;
//
// Pointer to the C-string returned by a call to 'readUrl' when the
// initialization has failed.
//
static char const* const error_init_failed; static char const* const error_init_failed;
/** //
* Pointer to the C-string returned by a call to 'readUrl' when the // Pointer to the C-string returned by a call to 'readUrl' when the
* transfer has been aborted by the client. // transfer has been aborted by the client.
*/ //
static char const* const error_aborted; static char const* const error_aborted;
/** //
* Pointer to the C-string returned by a call to 'readUrl' when // Pointer to the C-string returned by a call to 'readUrl' when
* leftover input from incomplete processing caused a buffer // leftover input from incomplete processing caused a buffer
* overflow. // overflow.
*/ //
static char const* const error_buffer_overflow; static char const* const error_buffer_overflow;
/** //
* Pointer to the C-string return by a call to 'readUrl' when the // Pointer to the C-string return by a call to 'readUrl' when the
* input provided was not completely consumed. // input provided was not completely consumed.
*/ //
static char const* const error_leftover_input; static char const* const error_leftover_input;
/** //
* Constant of the maximum number of bytes that are buffered // Constant of the maximum number of bytes that are buffered
* between invocations of 'transfer'. // between invocations of 'transfer'.
*/ //
static size_t const max_read_ahead; static size_t const max_read_ahead;
/** //
* Constant representing absent information in the call to the // Constant representing absent information in the call to the
* 'begin' member function of the target stream. // 'begin' member function of the target stream.
*/ //
static int const unavailable = -1; static int const unavailable = -1;
/** //
* Constant for requesting to abort the current transfer when // Constant for requesting to abort the current transfer when
* returned by the 'transfer' member function of the target stream. // returned by the 'transfer' member function of the target stream.
*/ //
static size_t const abort = ~0u; static size_t const abort = ~0u;
private: private:
@ -143,38 +156,105 @@ class UrlReader {
// synthesized callback // synthesized callback
template< class Stream > template< class Stream > static size_t callback_template(char *input, size_t size,
static size_t callback_template( size_t nmemb, void* thiz);
char *input, size_t size, size_t nmemb, void* thiz);
template< class Stream > size_t feedBuffered(Stream* stream,
char* input, size_t size);
}; };
template< class ContentStream > template< class ContentStream >
bool UrlReader::readUrl(char const* url, ContentStream& s) { bool UrlReader::readUrl(char const* url, ContentStream& s, char const* cacheFile) {
if (! _ptrImpl) return false; if (! _ptrImpl) return false;
_strCacheFile = cacheFile;
_ptrCacheFile = 0l;
_valCacheMode = no_cache; // eventually set later
_strError = success; _strError = success;
_ptrStream = & s; _ptrStream = & s;
_valXtraSize = ~size_t(0); _valXtraSize = ~size_t(0);
this->perform(url, & callback_template<ContentStream>); this->perform(url, & callback_template<ContentStream>);
s.end(_strError == success); s.end(_strError == success);
return _strError == success; if (_ptrCacheFile != 0l) {
fclose(_ptrCacheFile);
}
return _strError == success || _strError == success_cached;
} }
inline char const* UrlReader::getError() const { return this->_strError; } inline char const* UrlReader::getError() const { return this->_strError; }
inline void UrlReader::setError(char const* static_c_string) { inline void UrlReader::setError(char const* staticCstring) {
if (this->_strError == success) if (this->_strError == success || this->_strError == success_cached)
this->_strError = static_c_string; this->_strError = staticCstring;
} }
template< class Stream > template< class Stream >
size_t UrlReader::callback_template( size_t UrlReader::feedBuffered(Stream* stream, char* input, size_t size) {
char *input, size_t size, size_t nmemb, void* thiz) { size_t inputOffset = 0u;
size *= nmemb; while (true) {
char* buffer = input + inputOffset;
size_t bytes = size - inputOffset;
// data in extra buffer?
if (_valXtraSize > 0) {
// fill extra buffer with beginning of input
size_t fill = max_read_ahead - _valXtraSize;
if (bytes < fill) fill = bytes;
memcpy(_arrXtra + _valXtraSize, buffer, fill);
// use extra buffer for next transfer
buffer = _arrXtra;
bytes = _valXtraSize + fill;
inputOffset += fill;
}
// call 'transfer'
size_t processed = stream->transfer(buffer, bytes);
if (processed == abort) {
setError(error_aborted);
return 0u;
} else if (! processed && ! input) {
setError(error_leftover_input);
return 0u;
}
size_t unprocessed = bytes - processed;
// can switch to input buffer, now?
if (buffer == _arrXtra && unprocessed <= inputOffset) {
_valXtraSize = 0u;
inputOffset -= unprocessed;
} else { // no? unprocessed data -> extra buffer
if (unprocessed > max_read_ahead) {
setError(error_buffer_overflow);
return 0;
}
_valXtraSize = unprocessed;
memmove(_arrXtra, buffer + processed, unprocessed);
if (inputOffset == size || buffer != _arrXtra) {
return size;
}
}
} // while
}
template< class Stream >
size_t UrlReader::callback_template(char *input, size_t size, size_t nmemb, void* thiz) {
size_t result = 0u;
UrlReader* me = static_cast<UrlReader*>(thiz); UrlReader* me = static_cast<UrlReader*>(thiz);
Stream* stream = static_cast<Stream*>(me->_ptrStream); Stream* stream = static_cast<Stream*>(me->_ptrStream);
size *= nmemb;
// first call? // first call?
if (me->_valXtraSize == ~size_t(0)) { if (me->_valXtraSize == ~size_t(0)) {
@ -184,65 +264,28 @@ size_t UrlReader::callback_template(
char const* url, * type; char const* url, * type;
int64_t length, stardate; int64_t length, stardate;
me->getinfo(url, type, length, stardate); me->getinfo(url, type, length, stardate);
stream->begin(url, type, length, stardate); if (me->_valCacheMode != cache_read) {
stream->begin(url, type, length, stardate);
}
} }
do {
// will have to repeat from here when reading a local file
size_t input_offset = 0u; // read from cache file?
if (me->_valCacheMode == cache_read) {
while (true) { // change input buffer and start
input = me->_arrCacheRdBuf;
char* buffer = input + input_offset; size = fread(input, 1, max_read_ahead, me->_ptrCacheFile);
size_t bytes = size - input_offset; nmemb = 1;
} else if (me->_valCacheMode == cache_write) {
// data in extra buffer? fwrite(input, 1, size, me->_ptrCacheFile);
if (me->_valXtraSize > 0) {
// fill extra buffer with beginning of input
size_t fill = max_read_ahead - me->_valXtraSize;
if (bytes < fill) fill = bytes;
memcpy(me->_arrXtra + me->_valXtraSize, buffer, fill);
// use extra buffer for next transfer
buffer = me->_arrXtra;
bytes = me->_valXtraSize + fill;
input_offset += fill;
} }
// call 'transfer' result = me->feedBuffered(stream, input, size);
size_t processed = stream->transfer(buffer, bytes);
if (processed == abort) {
me->setError(error_aborted); } while (me->_valCacheMode == cache_read && result != 0 && ! feof(me->_ptrCacheFile));
return 0u;
} else if (! processed && ! input) { return me->_valCacheMode != cache_read ? result : 0;
me->setError(error_leftover_input);
return 0u;
}
size_t unprocessed = bytes - processed;
// can switch to input buffer, now?
if (buffer == me->_arrXtra && unprocessed <= input_offset) {
me->_valXtraSize = 0u;
input_offset -= unprocessed;
} else { // no? unprocessed data -> extra buffer
if (unprocessed > max_read_ahead) {
me->setError(error_buffer_overflow);
return 0;
}
me->_valXtraSize = unprocessed;
memmove(me->_arrXtra, buffer + processed, unprocessed);
if (input_offset == size || buffer != me->_arrXtra) {
return size;
}
}
} // for
} }
#endif /* defined(__hifi__UrlReader__) */ #endif /* defined(__hifi__UrlReader__) */

View file

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

View file

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

View file

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

View file

@ -18,7 +18,6 @@
#include "CounterStats.h" #include "CounterStats.h"
#include "OctalCode.h" #include "OctalCode.h"
#include "VoxelTree.h" #include "VoxelTree.h"
#include <iostream> // to load voxels from file
#include <fstream> // to load voxels from file #include <fstream> // to load voxels from file
using voxels_lib::printLog; using voxels_lib::printLog;