From 9ce1683c50efe75aa1dcf33ffdba56e74e3d0fd4 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 14:45:54 -0700 Subject: [PATCH 01/15] reversed strafe left right, and commented-out updateAvatarHand --- interface/src/Head.cpp | 6 +++--- interface/src/main.cpp | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 91a227a72a..6f77ee66dc 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -33,7 +33,7 @@ float MouthWidthChoices[3] = {0.5, 0.77, 0.3}; float browWidth = 0.8; float browThickness = 0.16; -bool usingBigSphereCollisionTest = true; +bool usingBigSphereCollisionTest = false; const float DECAY = 0.1; const float THRUST_MAG = 10.0; @@ -381,11 +381,11 @@ void Head::simulate(float deltaTime) { } if (_driveKeys[RIGHT]) { glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); - _avatar.thrust -= right * THRUST_MAG; + _avatar.thrust += right * THRUST_MAG; } if (_driveKeys[LEFT]) { glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); - _avatar.thrust += right * THRUST_MAG; + _avatar.thrust -= right * THRUST_MAG; } if (_driveKeys[UP]) { glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index d81838287e..82bc1d0bbd 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -363,6 +363,7 @@ void reset_sensors() } } +/* void updateAvatarHand(float deltaTime) { // If mouse is being dragged, send current force to the hand controller if (mousePressed == 1) @@ -376,6 +377,7 @@ void updateAvatarHand(float deltaTime) { //myAvatar.hand->addVelocity(vel*deltaTime); } } +*/ // // Using gyro data, update both view frustum and avatar head position @@ -1357,30 +1359,33 @@ void idle(void) { else { myAvatar.setTriggeringAction( false ); } + + float deltaTime = 1.f/FPS; // // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // updateAvatar( 1.f/FPS ); + //loop through all the other avatars and simulate them. AgentList * agentList = AgentList::getInstance(); for(std::vector::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; From b9a1faf2848697ade81f426b939f8718b7a95003 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 14:46:39 -0700 Subject: [PATCH 02/15] add a new SimpleMovingAverage class, replaces CounterStats --- interface/src/VoxelSystem.cpp | 12 +- interface/src/VoxelSystem.h | 6 +- interface/src/main.cpp | 34 +---- libraries/shared/src/CounterStats.cpp | 142 ------------------- libraries/shared/src/CounterStats.h | 65 --------- libraries/shared/src/SimpleMovingAverage.cpp | 51 +++++++ libraries/shared/src/SimpleMovingAverage.h | 34 +++++ libraries/voxels/src/VoxelTree.cpp | 27 ++-- libraries/voxels/src/VoxelTree.h | 12 +- 9 files changed, 116 insertions(+), 267 deletions(-) delete mode 100644 libraries/shared/src/CounterStats.cpp delete mode 100644 libraries/shared/src/CounterStats.h create mode 100644 libraries/shared/src/SimpleMovingAverage.cpp create mode 100644 libraries/shared/src/SimpleMovingAverage.h diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 412c0aac75..cf88a199d0 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -93,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 tree->voxelsColoredStats.getEventDeltaAverage(); } long int VoxelSystem::getVoxelsBytesRead() { return tree->voxelsBytesRead; } -long int VoxelSystem::getVoxelsBytesReadRunningAverage() { - return tree->voxelsBytesReadStats.getRunningAverage(); +float VoxelSystem::getVoxelsBytesReadAverage() { + return tree->voxelsBytesReadStats.getAverage(); } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 5395ce700a..3ca39d75bf 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -40,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 getVoxelsBytesReadAverage(); private: int voxelsRendered; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 4aa20f8b91..4e43381edc 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -74,10 +74,11 @@ #include "Oscilloscope.h" #include "UDPSocket.h" #include "SerialInterface.h" -#include #include #include #include +#include +#include #include "ViewFrustum.h" @@ -235,35 +236,6 @@ void displayStats(void) 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); drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); - - 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) "; - 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) "; - 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) "; - 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) "; - drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - if (::perfStatsOn) { // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups @@ -1297,7 +1269,7 @@ void *networkReceive(void *args) case PACKET_HEADER_ERASE_VOXEL: voxels.parseData(incomingPacket, bytesReceived); break; - case PACKET_HEADER_BULK_AVATAR_DATA: + case PACKET_HEADER_BULK_AVATAR_DATA: AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, diff --git a/libraries/shared/src/CounterStats.cpp b/libraries/shared/src/CounterStats.cpp deleted file mode 100644 index 51d991f0f1..0000000000 --- a/libraries/shared/src/CounterStats.cpp +++ /dev/null @@ -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 - -#ifdef _WIN32 -#include "Systime.h" -#else -#include -#endif -#include -#include -#include "shared_Log.h" - -//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; - - //printLog("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->sampleCountsampleCount++; - } - this->countSamples[this->sampleAt]=thisCount; - this->timeSamples[this->sampleAt]=thisTime; - this->deltaSamples[this->sampleAt]=thisDelta; - - //printLog("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; -} diff --git a/libraries/shared/src/CounterStats.h b/libraries/shared/src/CounterStats.h deleted file mode 100644 index 81e34853ef..0000000000 --- a/libraries/shared/src/CounterStats.h +++ /dev/null @@ -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 -#include -#include - -// 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__) */ diff --git a/libraries/shared/src/SimpleMovingAverage.cpp b/libraries/shared/src/SimpleMovingAverage.cpp new file mode 100644 index 0000000000..94ae96f5d2 --- /dev/null +++ b/libraries/shared/src/SimpleMovingAverage.cpp @@ -0,0 +1,51 @@ +// +// SimpleMovingAverage.cpp +// hifi +// +// Created by Stephen Birarda on 4/18/13. +// +// + +#include "SharedUtil.h" +#include "SimpleMovingAverage.h" + +SimpleMovingAverage::SimpleMovingAverage(float numSamplesToAverage) : + _numSamples(0), + _numSamplesToAverage(numSamplesToAverage), + _average(0), + _eventDeltaAverage(0) { +} + +int SimpleMovingAverage::updateAverage(float sample) { + if (_numSamples > 0) { + + float firstCoefficient = 1 - (1.0f / _numSamplesToAverage); + float secondCoefficient = (1.0f / _numSamplesToAverage); + + _average = (firstCoefficient * _average) + (secondCoefficient * sample); + + float eventDelta = (usecTimestampNow() - _lastEventTimestamp) / 1000000; + + if (_numSamples > 1) { + _eventDeltaAverage = (firstCoefficient * _eventDeltaAverage) + + (secondCoefficient * eventDelta); + } else { + _eventDeltaAverage = eventDelta; + } + } else { + _average = sample; + _eventDeltaAverage = 0; + } + + _lastEventTimestamp = usecTimestampNow(); + + return ++_numSamples; +} + +void SimpleMovingAverage::reset() { + _numSamples = 0; +} + +float SimpleMovingAverage::getAverageSampleValuePerSecond() { + return _average * (1 / _eventDeltaAverage); +} \ No newline at end of file diff --git a/libraries/shared/src/SimpleMovingAverage.h b/libraries/shared/src/SimpleMovingAverage.h new file mode 100644 index 0000000000..33366ed48c --- /dev/null +++ b/libraries/shared/src/SimpleMovingAverage.h @@ -0,0 +1,34 @@ +// +// SimpleMovingAverage.h +// hifi +// +// Created by Stephen Birarda on 4/18/13. +// Based heavily on Brad Hefta-Gaub's CounterStats class (RIP) +// +// + +#ifndef __hifi__Stats__ +#define __hifi__Stats__ + +#include + +class SimpleMovingAverage { +public: + SimpleMovingAverage(float numSamplesToAverage); + + int updateAverage(float sample); + void reset(); + + int getSampleCount() { return _numSamples; }; + float getAverage() { return _average; }; + float getEventDeltaAverage() { return _eventDeltaAverage; }; + float getAverageSampleValuePerSecond(); +private: + int _numSamples; + int _numSamplesToAverage; + double _lastEventTimestamp; + float _average; + float _eventDeltaAverage; +}; + +#endif /* defined(__hifi__Stats__) */ diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 173fe1a38b..2c2599bc80 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -15,7 +15,6 @@ #include "SharedUtil.h" #include "voxels_Log.h" #include "PacketHeaders.h" -#include "CounterStats.h" #include "OctalCode.h" #include "VoxelTree.h" #include // to load voxels from file @@ -46,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() { @@ -126,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; } @@ -156,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 @@ -184,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 diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 618a3710ae..4c18a23028 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -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(); From 588fc67cb944c69803cfaaabc328cd0dad88e274 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 15:02:26 -0700 Subject: [PATCH 03/15] add SimpleMovingAverage to each Agent, collect bytes received stats --- interface/src/main.cpp | 2 +- libraries/shared/src/Agent.cpp | 35 ++++++++++++++++++++++ libraries/shared/src/Agent.h | 19 ++++++++++-- libraries/shared/src/AgentList.cpp | 2 ++ libraries/shared/src/SimpleMovingAverage.h | 2 +- 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 4e43381edc..09486a9c90 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1269,7 +1269,7 @@ void *networkReceive(void *args) case PACKET_HEADER_ERASE_VOXEL: voxels.parseData(incomingPacket, bytesReceived); break; - case PACKET_HEADER_BULK_AVATAR_DATA: + case PACKET_HEADER_BULK_AVATAR_DATA: AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index e50392c96f..93925a04a5 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -37,6 +37,7 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent activeSocket = NULL; linkedData = NULL; + _movingAverage = NULL; deleteMutex = new pthread_mutex_t; pthread_mutex_init(deleteMutex, NULL); @@ -69,6 +70,13 @@ Agent::Agent(const Agent &otherAgent) { linkedData = NULL; } + if (otherAgent._movingAverage != NULL) { + _movingAverage = new SimpleMovingAverage(100); + memcpy(_movingAverage, otherAgent._movingAverage, sizeof(SimpleMovingAverage)); + } else { + _movingAverage = NULL; + } + deleteMutex = new pthread_mutex_t; pthread_mutex_init(deleteMutex, NULL); } @@ -89,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._movingAverage, second._movingAverage); swap(first.deleteMutex, second.deleteMutex); } @@ -99,6 +108,7 @@ Agent::~Agent() { delete publicSocket; delete localSocket; delete linkedData; + delete _movingAverage; } char Agent::getType() const { @@ -211,6 +221,31 @@ bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, cha && socketMatch(localSocket, otherLocalSocket); } +void Agent::recordBytesReceived(int bytesReceived) { + if (_movingAverage == NULL) { + printf("Setting up the moving average for agent\n"); + _movingAverage = new SimpleMovingAverage(100); + } + + _movingAverage->updateAverage((float) bytesReceived); +} + +float Agent::getAveragePacketsPerSecond() { + if (_movingAverage != NULL) { + return (1 / _movingAverage->getEventDeltaAverage()); + } else { + return 0; + } +} + +float Agent::getAverageKilobitsPerSecond() { + if (_movingAverage != NULL) { + return (_movingAverage->getAverageSampleValuePerSecond() * (8.0f / 1000)); + } else { + return 0; + } +} + void Agent::printLog(Agent const& agent) { sockaddr_in *agentPublicSocket = (sockaddr_in *) agent.publicSocket; diff --git a/libraries/shared/src/Agent.h b/libraries/shared/src/Agent.h index 601df8d1f0..99773633b5 100644 --- a/libraries/shared/src/Agent.h +++ b/libraries/shared/src/Agent.h @@ -11,7 +11,6 @@ #include #include -#include "AgentData.h" #ifdef _WIN32 #include "Syssocket.h" @@ -19,6 +18,9 @@ #include #endif +#include "SimpleMovingAverage.h" +#include "AgentData.h" + class Agent { public: Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId); @@ -34,32 +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* _movingAverage; + AgentData* linkedData; + }; std::ostream& operator<<(std::ostream& os, const Agent* agent); diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 36627d409e..9749e390c0 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -108,6 +108,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac if (bulkSendAgentIndex >= 0) { Agent *bulkSendAgent = &agents[bulkSendAgentIndex]; bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow()); + bulkSendAgent->recordBytesReceived(numTotalBytes); } unsigned char *startPosition = packetData; @@ -144,6 +145,7 @@ 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) { diff --git a/libraries/shared/src/SimpleMovingAverage.h b/libraries/shared/src/SimpleMovingAverage.h index 33366ed48c..e653e89d85 100644 --- a/libraries/shared/src/SimpleMovingAverage.h +++ b/libraries/shared/src/SimpleMovingAverage.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 4/18/13. -// Based heavily on Brad Hefta-Gaub's CounterStats class (RIP) +// Replaces Brad Hefta-Gaub's CounterStats class (RIP) // // From 44cb57afad7000428facd629ad886d410eca9355 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 15:33:17 -0700 Subject: [PATCH 04/15] put back brad's voxel stats, he loves them too much --- interface/src/VoxelSystem.cpp | 6 +++--- interface/src/VoxelSystem.h | 2 +- interface/src/main.cpp | 27 +++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index cf88a199d0..7b22525fde 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -102,15 +102,15 @@ long int VoxelSystem::getVoxelsColored() { } float VoxelSystem::getVoxelsColoredPerSecondAverage() { - return tree->voxelsColoredStats.getEventDeltaAverage(); + return (1 / tree->voxelsColoredStats.getEventDeltaAverage()); } long int VoxelSystem::getVoxelsBytesRead() { return tree->voxelsBytesRead; } -float VoxelSystem::getVoxelsBytesReadAverage() { - return tree->voxelsBytesReadStats.getAverage(); +float VoxelSystem::getVoxelsBytesReadPerSecondAverage() { + return tree->voxelsBytesReadStats.getAverageSampleValuePerSecond(); } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 3ca39d75bf..76aaf57a4e 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -42,7 +42,7 @@ public: long int getVoxelsBytesRead(); float getVoxelsCreatedPerSecondAverage(); float getVoxelsColoredPerSecondAverage(); - float getVoxelsBytesReadAverage(); + float getVoxelsBytesReadPerSecondAverage(); private: int voxelsRendered; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 09486a9c90..5adea8abff 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -236,6 +236,33 @@ void displayStats(void) 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); drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); + + 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.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.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.getVoxelsBytesReadPerSecondAverage() << " Bps)"; + drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + + voxelStats.str(""); + 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()); if (::perfStatsOn) { // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups From cf1254f53b5e1bb3980f71c275b1f7e320d166a9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 15:45:20 -0700 Subject: [PATCH 05/15] rename the _movingAverage variable so it is more descriptive --- libraries/shared/src/Agent.cpp | 29 ++++++++++++++--------------- libraries/shared/src/Agent.h | 2 +- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 93925a04a5..b329b7faaa 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -37,7 +37,7 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent activeSocket = NULL; linkedData = NULL; - _movingAverage = NULL; + _bytesReceivedMovingAverage = NULL; deleteMutex = new pthread_mutex_t; pthread_mutex_init(deleteMutex, NULL); @@ -70,11 +70,11 @@ Agent::Agent(const Agent &otherAgent) { linkedData = NULL; } - if (otherAgent._movingAverage != NULL) { - _movingAverage = new SimpleMovingAverage(100); - memcpy(_movingAverage, otherAgent._movingAverage, sizeof(SimpleMovingAverage)); + if (otherAgent._bytesReceivedMovingAverage != NULL) { + _bytesReceivedMovingAverage = new SimpleMovingAverage(100); + memcpy(_bytesReceivedMovingAverage, otherAgent._bytesReceivedMovingAverage, sizeof(SimpleMovingAverage)); } else { - _movingAverage = NULL; + _bytesReceivedMovingAverage = NULL; } deleteMutex = new pthread_mutex_t; @@ -97,7 +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._movingAverage, second._movingAverage); + swap(first._bytesReceivedMovingAverage, second._bytesReceivedMovingAverage); swap(first.deleteMutex, second.deleteMutex); } @@ -108,7 +108,7 @@ Agent::~Agent() { delete publicSocket; delete localSocket; delete linkedData; - delete _movingAverage; + delete _bytesReceivedMovingAverage; } char Agent::getType() const { @@ -209,7 +209,6 @@ void Agent::setLinkedData(AgentData *newData) { linkedData = newData; } - bool Agent::operator==(const Agent& otherAgent) { return matches(otherAgent.publicSocket, otherAgent.localSocket, otherAgent.type); } @@ -222,25 +221,25 @@ bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, cha } void Agent::recordBytesReceived(int bytesReceived) { - if (_movingAverage == NULL) { + if (_bytesReceivedMovingAverage == NULL) { printf("Setting up the moving average for agent\n"); - _movingAverage = new SimpleMovingAverage(100); + _bytesReceivedMovingAverage = new SimpleMovingAverage(100); } - _movingAverage->updateAverage((float) bytesReceived); + _bytesReceivedMovingAverage->updateAverage((float) bytesReceived); } float Agent::getAveragePacketsPerSecond() { - if (_movingAverage != NULL) { - return (1 / _movingAverage->getEventDeltaAverage()); + if (_bytesReceivedMovingAverage != NULL) { + return (1 / _bytesReceivedMovingAverage->getEventDeltaAverage()); } else { return 0; } } float Agent::getAverageKilobitsPerSecond() { - if (_movingAverage != NULL) { - return (_movingAverage->getAverageSampleValuePerSecond() * (8.0f / 1000)); + if (_bytesReceivedMovingAverage != NULL) { + return (_bytesReceivedMovingAverage->getAverageSampleValuePerSecond() * (8.0f / 1000)); } else { return 0; } diff --git a/libraries/shared/src/Agent.h b/libraries/shared/src/Agent.h index 99773633b5..14942defcb 100644 --- a/libraries/shared/src/Agent.h +++ b/libraries/shared/src/Agent.h @@ -72,7 +72,7 @@ private: uint16_t agentId; double firstRecvTimeUsecs; double lastRecvTimeUsecs; - SimpleMovingAverage* _movingAverage; + SimpleMovingAverage* _bytesReceivedMovingAverage; AgentData* linkedData; }; From 6e540d166b5b4040f27dd08e635b241bd0a7b0f8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 16:30:38 -0700 Subject: [PATCH 06/15] add a decay to the event delta average --- libraries/shared/src/SimpleMovingAverage.cpp | 25 +++++++++++--------- libraries/shared/src/SimpleMovingAverage.h | 8 ++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libraries/shared/src/SimpleMovingAverage.cpp b/libraries/shared/src/SimpleMovingAverage.cpp index 94ae96f5d2..db433c020f 100644 --- a/libraries/shared/src/SimpleMovingAverage.cpp +++ b/libraries/shared/src/SimpleMovingAverage.cpp @@ -9,26 +9,24 @@ #include "SharedUtil.h" #include "SimpleMovingAverage.h" -SimpleMovingAverage::SimpleMovingAverage(float numSamplesToAverage) : +SimpleMovingAverage::SimpleMovingAverage(int numSamplesToAverage) : _numSamples(0), - _numSamplesToAverage(numSamplesToAverage), _average(0), - _eventDeltaAverage(0) { + _eventDeltaAverage(0), + WEIGHTING(1.0f / numSamplesToAverage), + ONE_MINUS_WEIGHTING(1 - WEIGHTING) { + } int SimpleMovingAverage::updateAverage(float sample) { if (_numSamples > 0) { - - float firstCoefficient = 1 - (1.0f / _numSamplesToAverage); - float secondCoefficient = (1.0f / _numSamplesToAverage); - - _average = (firstCoefficient * _average) + (secondCoefficient * sample); + _average = (ONE_MINUS_WEIGHTING * _average) + (WEIGHTING * sample); float eventDelta = (usecTimestampNow() - _lastEventTimestamp) / 1000000; if (_numSamples > 1) { - _eventDeltaAverage = (firstCoefficient * _eventDeltaAverage) + - (secondCoefficient * eventDelta); + _eventDeltaAverage = (ONE_MINUS_WEIGHTING * _eventDeltaAverage) + + (WEIGHTING * eventDelta); } else { _eventDeltaAverage = eventDelta; } @@ -46,6 +44,11 @@ void SimpleMovingAverage::reset() { _numSamples = 0; } +float SimpleMovingAverage::getEventDeltaAverage() { + return (ONE_MINUS_WEIGHTING * _eventDeltaAverage) + + (WEIGHTING * ((usecTimestampNow() - _lastEventTimestamp) / 1000000)); +} + float SimpleMovingAverage::getAverageSampleValuePerSecond() { - return _average * (1 / _eventDeltaAverage); + return _average * (1 / getEventDeltaAverage()); } \ No newline at end of file diff --git a/libraries/shared/src/SimpleMovingAverage.h b/libraries/shared/src/SimpleMovingAverage.h index e653e89d85..e24b639133 100644 --- a/libraries/shared/src/SimpleMovingAverage.h +++ b/libraries/shared/src/SimpleMovingAverage.h @@ -14,21 +14,23 @@ class SimpleMovingAverage { public: - SimpleMovingAverage(float numSamplesToAverage); + SimpleMovingAverage(int numSamplesToAverage); int updateAverage(float sample); void reset(); int getSampleCount() { return _numSamples; }; float getAverage() { return _average; }; - float getEventDeltaAverage() { return _eventDeltaAverage; }; + float getEventDeltaAverage(); float getAverageSampleValuePerSecond(); private: int _numSamples; - int _numSamplesToAverage; double _lastEventTimestamp; float _average; float _eventDeltaAverage; + + const float WEIGHTING; + const float ONE_MINUS_WEIGHTING; }; #endif /* defined(__hifi__Stats__) */ From d937ef17f60d561a79aac9552ba2f05afe6fc976 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 16:38:46 -0700 Subject: [PATCH 07/15] remove extra debug line --- libraries/shared/src/Agent.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index b329b7faaa..d05afe5e26 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -222,7 +222,6 @@ bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, cha void Agent::recordBytesReceived(int bytesReceived) { if (_bytesReceivedMovingAverage == NULL) { - printf("Setting up the moving average for agent\n"); _bytesReceivedMovingAverage = new SimpleMovingAverage(100); } From daac10511e1a70506d23dc46ff265dba2fda5de2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Apr 2013 16:58:08 -0700 Subject: [PATCH 08/15] output avatar mixer stats below the voxel stats --- domain-server/src/main.cpp | 2 +- interface/src/main.cpp | 7 +++++++ libraries/shared/src/AgentList.cpp | 19 ++++++++++++++++++- libraries/shared/src/AgentList.h | 4 +++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 8ab62eaeeb..05e1583fca 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -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 { diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 9c548a5c33..17b8ad8ec3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -263,6 +263,13 @@ void displayStats(void) 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 diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 9749e390c0..5316eee79c 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -24,7 +24,12 @@ using shared_lib::printLog; -const char * SOLO_AGENT_TYPES_STRING = "MV"; +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; @@ -287,6 +292,18 @@ void AgentList::handlePingReply(sockaddr *agentAddress) { } } +Agent* AgentList::soloAgentOfType(char agentType) { + if (memchr(SOLO_AGENT_TYPES_STRING, agentType, 1)) { + for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { + if (agent->getType() == agentType) { + return &*agent; + } + } + } + + return NULL; +} + void *pingUnknownAgents(void *args) { AgentList *agentList = (AgentList *)args; diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index 4dfa9359bf..adc66333f9 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.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(); From 298bc7eee93fb3daaafeedff9b4ac451372c3a0f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 19:24:57 -0700 Subject: [PATCH 09/15] added more robust avatar hand movement algorithm in main.cpp --- interface/src/main.cpp | 123 ++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 44 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 6f5c1ed7d5..cbf280ce06 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -167,16 +167,73 @@ int displayField = 0; int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement int headMouseX, headMouseY; -int mouseX, mouseY; // Where is the mouse +int mouseX = 0; +int mouseY = 0; // Mouse location at start of last down click -int mouseStartX = WIDTH / 2; -int mouseStartY = HEIGHT / 2; int mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menu int menuOn = 1; // Whether to show onscreen menu +struct HandMovement +{ + bool enabled = false; + int startX = WIDTH / 2; + int startY = HEIGHT / 2; + int x = 0; + int y = 0; + int lastX = 0; + int lastY = 0; + int velocityX = 0; + int velocityY = 0; + float rampUpRate = 0.05; + float rampDownRate = 0.02; + float envelope = 0.0f; +}; + +HandMovement handMovement; + +void updateHandMovement( int x, int y ) { + handMovement.lastX = handMovement.x; + handMovement.lastY = handMovement.y; + handMovement.x = x; + handMovement.y = y; + handMovement.velocityX = handMovement.x - handMovement.lastX; + handMovement.velocityY = handMovement.y - handMovement.lastY; + + if (( handMovement.velocityX != 0 ) + || ( handMovement.velocityY != 0 )) { + handMovement.enabled = true; + if ( handMovement.envelope < 1.0 ) { + handMovement.envelope += handMovement.rampUpRate; + if ( handMovement.envelope >= 1.0 ) { + handMovement.envelope = 1.0; + } + } + } + + if ( ! handMovement.enabled ) { + if ( handMovement.envelope > 0.0 ) { + handMovement.envelope -= handMovement.rampDownRate; + if ( handMovement.envelope <= 0.0 ) { + handMovement.startX = WIDTH / 2; + handMovement.startY = HEIGHT / 2; + handMovement.envelope = 0.0; + } + } + } + + if ( handMovement.envelope > 0.0 ) { + float leftRight = ( ( handMovement.x - handMovement.startX ) / (float)WIDTH ) * handMovement.envelope; + float downUp = ( ( handMovement.y - handMovement.startY ) / (float)HEIGHT ) * handMovement.envelope; + float backFront = 0.0; + myAvatar.setHandMovement( glm::vec3( leftRight, downUp, backFront ) ); + } +} + + + // // Serial USB Variables // @@ -363,22 +420,6 @@ void reset_sensors() } } -/* -void updateAvatarHand(float deltaTime) { - // If mouse is being dragged, send current force to the hand controller - if (mousePressed == 1) - { - // NOTE--PER: Need to re-implement when ready for new avatar hand movements - - const float MOUSE_HAND_FORCE = 1.5; - float dx = mouseX - mouseStartX; - float dy = mouseY - mouseStartY; - glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); - //myAvatar.hand->addVelocity(vel*deltaTime); - } -} -*/ - // // Using gyro data, update both view frustum and avatar head position // @@ -830,10 +871,10 @@ void display(void) agent != agentList->getAgents().end(); agent++) { if (agent->getLinkedData() != NULL) { - Head *agentHead = (Head *)agent->getLinkedData(); - glPushMatrix(); - agentHead->render(0); - glPopMatrix(); + Head *avatar = (Head *)agent->getLinkedData(); + //glPushMatrix(); + avatar->render(0); + //glPopMatrix(); } } @@ -1332,25 +1373,13 @@ void idle(void) { if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) { - //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; - } - */ - - //-------------------------------------------------------- + float deltaTime = 1.f/FPS; + + // update behaviors for avatar hand movement + updateHandMovement( mouseX, mouseY ); + // when the mouse is being pressed, an 'action' is being // triggered in the avatar. The action is context-based. - //-------------------------------------------------------- if ( mousePressed == 1 ) { myAvatar.setTriggeringAction( true ); } @@ -1358,8 +1387,11 @@ void idle(void) { myAvatar.setTriggeringAction( false ); } - float deltaTime = 1.f/FPS; - + // walking triggers the handMovement to stop + if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) { + handMovement.enabled = false; + } + // // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // @@ -1457,8 +1489,6 @@ void mouseFunc( int button, int state, int x, int y ) mouseX = x; mouseY = y; mousePressed = 1; - //mouseStartX = x; - //mouseStartY = y; } } if( button == GLUT_LEFT_BUTTON && state == GLUT_UP ) { @@ -1478,12 +1508,17 @@ void motionFunc( int x, int y) void mouseoverFunc( int x, int y) { menu.mouseOver(x, y); + mouseX = x; mouseY = y; if (mousePressed == 0) {} } + + + + void attachNewHeadToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { newAgent->setLinkedData(new Head(false)); From 9dd423f5448ecd9724cf0185b727208b810c63f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 19:30:27 -0700 Subject: [PATCH 10/15] removed updateAvatarHand function --- interface/src/main.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 75b6132be6..80341e5f3b 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -426,6 +426,22 @@ void reset_sensors() } } +/* +void updateAvatarHand(float deltaTime) { + // If mouse is being dragged, send current force to the hand controller + if (mousePressed == 1) + { + // NOTE--PER: Need to re-implement when ready for new avatar hand movements + + const float MOUSE_HAND_FORCE = 1.5; + float dx = mouseX - mouseStartX; + float dy = mouseY - mouseStartY; + glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); + //myAvatar.hand->addVelocity(vel*deltaTime); + } +} +*/ + // // Using gyro data, update both view frustum and avatar head position // From 623c99843951b1d4d8a4be3d9741de7ad5bb6550 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 21:31:20 -0700 Subject: [PATCH 11/15] removed init values in HandMovement structure --- interface/src/main.cpp | 46 +++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 80341e5f3b..117c94a053 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -174,27 +174,43 @@ int mouseY = 0; // Mouse location at start of last down click int mousePressed = 0; // true if mouse has been pressed (clear when finished) -Menu menu; // main menu -int menuOn = 1; // Whether to show onscreen menu +Menu menu; // main menu +int menuOn = 1; // Whether to show onscreen menu struct HandMovement { - bool enabled = false; - int startX = WIDTH / 2; - int startY = HEIGHT / 2; - int x = 0; - int y = 0; - int lastX = 0; - int lastY = 0; - int velocityX = 0; - int velocityY = 0; - float rampUpRate = 0.05; - float rampDownRate = 0.02; - float envelope = 0.0f; + bool enabled; + int startX; + int startY; + int x; + int y; + int lastX; + int lastY; + int velocityX; + int velocityY; + float rampUpRate; + float rampDownRate; + float envelope; }; HandMovement handMovement; +void initializeHandMovement() { + handMovement.enabled = false; + handMovement.startX = WIDTH / 2; + handMovement.startY = HEIGHT / 2; + handMovement.x = 0; + handMovement.y = 0; + handMovement.lastX = 0; + handMovement.lastY = 0; + handMovement.velocityX = 0; + handMovement.velocityY = 0; + handMovement.rampUpRate = 0.05; + handMovement.rampDownRate = 0.02; + handMovement.envelope = 0.0f; + +} + void updateHandMovement( int x, int y ) { handMovement.lastX = handMovement.x; handMovement.lastY = handMovement.y; @@ -361,6 +377,8 @@ void init(void) voxels.init(); voxels.setViewerHead(&myAvatar); myAvatar.setRenderYaw(startYaw); + + initializeHandMovement(); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; From d962230556ccefd6e6edca73b496e6ea1956367c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Apr 2013 12:44:09 -0700 Subject: [PATCH 12/15] fixed sneaky array-out-of-bounds error in avatar bones and cleaned up some of the code for testing hand shake target positions --- interface/src/Head.cpp | 58 +++++++++++++++------------ interface/src/Head.h | 1 - libraries/avatars/src/Orientation.cpp | 3 +- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 6f77ee66dc..b191c454d6 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -120,20 +120,18 @@ Head::Head(bool isMine) { printLog("error %u: %s\n", error, lodepng_error_text(error)); } } - - for (int o=0; o Date: Fri, 19 Apr 2013 14:34:01 -0700 Subject: [PATCH 13/15] cleaned up logic for body springs mode and moving hand mode --- interface/src/Head.cpp | 75 +++++++++++++++-------------- interface/src/Head.h | 20 ++++++-- interface/src/main.cpp | 106 ++++++++++++++++++----------------------- 3 files changed, 99 insertions(+), 102 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index b191c454d6..442c5eefba 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -33,7 +33,7 @@ float MouthWidthChoices[3] = {0.5, 0.77, 0.3}; float browWidth = 0.8; float browThickness = 0.16; -bool usingBigSphereCollisionTest = false; +bool usingBigSphereCollisionTest = true; const float DECAY = 0.1; const float THRUST_MAG = 10.0; @@ -104,10 +104,8 @@ Head::Head(bool isMine) { _lastLoudness = 0.0; _browAudioLift = 0.0; _noise = 0; - _handBeingMoved = false; - _previousHandBeingMoved = false; _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - _usingSprings = false; + _usingBodySprings = false; _springForce = 6.0f; _springVelocityDecay = 16.0f; @@ -338,32 +336,15 @@ void Head::simulate(float deltaTime) { //------------------------ updateSkeleton(); - //------------------------------------------------------------------------ - // reset hand and elbow position according to hand movement - //------------------------------------------------------------------------ - if ( _handBeingMoved ){ - if (! _previousHandBeingMoved ){ - initializeBodySprings(); - _usingSprings = true; - //printLog( "just started moving hand\n" ); - } - } - else { - if ( _previousHandBeingMoved ){ - _usingSprings = false; - //printLog( "just stopped moving hand\n" ); - } - } - - if ( _handBeingMoved ) { + //------------------------------------------------------------ + // reset hand and arm positions according to hand movement + //------------------------------------------------------------ + if (_usingBodySprings) { updateHandMovement(); updateBodySprings( deltaTime ); } - - _previousHandBeingMoved = _handBeingMoved; - _handBeingMoved = false; - if ( _isMine ) { // driving the avatar around should only apply is this is my avatar (as opposed to an avatar being driven remotely) + if ( _isMine ) { // driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely) //------------------------------------------------- // this handles the avatar being driven around... //------------------------------------------------- @@ -411,7 +392,7 @@ void Head::simulate(float deltaTime) { } else { - _mode = AVATAR_MODE_COMMUNICATING; + _mode = AVATAR_MODE_INTERACTING; } //---------------------------------------------------------- @@ -571,6 +552,18 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { } if ( jointCollision ) { + if (!_usingBodySprings) { + _usingBodySprings = true; + initializeBodySprings(); + } + /* + else { + if (_usingSprings) { + _usingSprings = false; + } + } + */ + //---------------------------------------------------------- // add gravity to velocity //---------------------------------------------------------- @@ -648,7 +641,7 @@ void Head::render(int faceToFace) { glPopMatrix(); } - if ( _usingSprings ) { + if (_usingBodySprings) { if ( _closestOtherAvatar != -1 ) { glm::vec3 v1( _bone[ AVATAR_BONE_RIGHT_HAND ].position ); @@ -704,7 +697,7 @@ void Head::renderHead(int faceToFace) { glPushMatrix(); - if (_usingSprings) { + if (_usingBodySprings) { glTranslatef ( _bone[ AVATAR_BONE_HEAD ].springyPosition.x, @@ -862,10 +855,19 @@ void Head::renderHead(int faceToFace) { } - +void Head::startHandMovement() { -void Head::setHandMovement( glm::vec3 handOffset ) { - _handBeingMoved = true; + if (!_usingBodySprings) { + initializeBodySprings(); + _usingBodySprings = true; + } +} + +void Head::stopHandMovement() { + _usingBodySprings = false; +} + +void Head::setHandMovementValues( glm::vec3 handOffset ) { _movedHandOffset = handOffset; } @@ -873,7 +875,6 @@ AvatarMode Head::getMode() { return _mode; } - void Head::initializeSkeleton() { for (int b=0; b #include //looks like we might not need this + +// Note to self: +// modes I might need to implement for avatar +// +// walking usingSprings - ramping down +// bumping into sphere usingSprings is on +// moving hand usingSprings is on +// stuck to another hand usingSprings is on + + enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define FWD 0 @@ -40,7 +50,7 @@ enum AvatarMode { AVATAR_MODE_STANDING = 0, AVATAR_MODE_WALKING, - AVATAR_MODE_COMMUNICATING, + AVATAR_MODE_INTERACTING, NUM_AVATAR_MODES }; @@ -149,7 +159,9 @@ class Head : public AvatarData { void simulate(float); - void setHandMovement( glm::vec3 movement ); + void startHandMovement(); + void stopHandMovement(); + void setHandMovementValues( glm::vec3 movement ); void updateHandMovement(); float getLoudness() {return _loudness;}; @@ -218,9 +230,7 @@ class Head : public AvatarData { float _bodyYawDelta; float _closeEnoughToInteract; int _closestOtherAvatar; - bool _usingSprings; - bool _handBeingMoved; - bool _previousHandBeingMoved; + bool _usingBodySprings; glm::vec3 _movedHandOffset; float _springVelocityDecay; float _springForce; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 117c94a053..cf3745fc4c 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -177,7 +177,7 @@ int mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menu int menuOn = 1; // Whether to show onscreen menu -struct HandMovement +struct HandController { bool enabled; int startX; @@ -193,59 +193,61 @@ struct HandMovement float envelope; }; -HandMovement handMovement; +HandController handController; -void initializeHandMovement() { - handMovement.enabled = false; - handMovement.startX = WIDTH / 2; - handMovement.startY = HEIGHT / 2; - handMovement.x = 0; - handMovement.y = 0; - handMovement.lastX = 0; - handMovement.lastY = 0; - handMovement.velocityX = 0; - handMovement.velocityY = 0; - handMovement.rampUpRate = 0.05; - handMovement.rampDownRate = 0.02; - handMovement.envelope = 0.0f; +void initializeHandController() { + handController.enabled = false; + handController.startX = WIDTH / 2; + handController.startY = HEIGHT / 2; + handController.x = 0; + handController.y = 0; + handController.lastX = 0; + handController.lastY = 0; + handController.velocityX = 0; + handController.velocityY = 0; + handController.rampUpRate = 0.05; + handController.rampDownRate = 0.02; + handController.envelope = 0.0f; } -void updateHandMovement( int x, int y ) { - handMovement.lastX = handMovement.x; - handMovement.lastY = handMovement.y; - handMovement.x = x; - handMovement.y = y; - handMovement.velocityX = handMovement.x - handMovement.lastX; - handMovement.velocityY = handMovement.y - handMovement.lastY; +void updateHandController( int x, int y ) { + handController.lastX = handController.x; + handController.lastY = handController.y; + handController.x = x; + handController.y = y; + handController.velocityX = handController.x - handController.lastX; + handController.velocityY = handController.y - handController.lastY; - if (( handMovement.velocityX != 0 ) - || ( handMovement.velocityY != 0 )) { - handMovement.enabled = true; - if ( handMovement.envelope < 1.0 ) { - handMovement.envelope += handMovement.rampUpRate; - if ( handMovement.envelope >= 1.0 ) { - handMovement.envelope = 1.0; + if (( handController.velocityX != 0 ) + || ( handController.velocityY != 0 )) { + handController.enabled = true; + myAvatar.startHandMovement(); + if ( handController.envelope < 1.0 ) { + handController.envelope += handController.rampUpRate; + if ( handController.envelope >= 1.0 ) { + handController.envelope = 1.0; } } } - if ( ! handMovement.enabled ) { - if ( handMovement.envelope > 0.0 ) { - handMovement.envelope -= handMovement.rampDownRate; - if ( handMovement.envelope <= 0.0 ) { - handMovement.startX = WIDTH / 2; - handMovement.startY = HEIGHT / 2; - handMovement.envelope = 0.0; + if ( ! handController.enabled ) { + if ( handController.envelope > 0.0 ) { + handController.envelope -= handController.rampDownRate; + if ( handController.envelope <= 0.0 ) { + handController.startX = WIDTH / 2; + handController.startY = HEIGHT / 2; + handController.envelope = 0.0; + myAvatar.stopHandMovement(); } } } - if ( handMovement.envelope > 0.0 ) { - float leftRight = ( ( handMovement.x - handMovement.startX ) / (float)WIDTH ) * handMovement.envelope; - float downUp = ( ( handMovement.y - handMovement.startY ) / (float)HEIGHT ) * handMovement.envelope; + if ( handController.envelope > 0.0 ) { + float leftRight = ( ( handController.x - handController.startX ) / (float)WIDTH ) * handController.envelope; + float downUp = ( ( handController.y - handController.startY ) / (float)HEIGHT ) * handController.envelope; float backFront = 0.0; - myAvatar.setHandMovement( glm::vec3( leftRight, downUp, backFront ) ); + myAvatar.setHandMovementValues( glm::vec3( leftRight, downUp, backFront ) ); } } @@ -378,7 +380,7 @@ void init(void) voxels.setViewerHead(&myAvatar); myAvatar.setRenderYaw(startYaw); - initializeHandMovement(); + initializeHandController(); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; @@ -444,22 +446,6 @@ void reset_sensors() } } -/* -void updateAvatarHand(float deltaTime) { - // If mouse is being dragged, send current force to the hand controller - if (mousePressed == 1) - { - // NOTE--PER: Need to re-implement when ready for new avatar hand movements - - const float MOUSE_HAND_FORCE = 1.5; - float dx = mouseX - mouseStartX; - float dy = mouseY - mouseStartY; - glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); - //myAvatar.hand->addVelocity(vel*deltaTime); - } -} -*/ - // // Using gyro data, update both view frustum and avatar head position // @@ -1416,7 +1402,7 @@ void idle(void) { float deltaTime = 1.f/FPS; // update behaviors for avatar hand movement - updateHandMovement( mouseX, mouseY ); + updateHandController( mouseX, mouseY ); // when the mouse is being pressed, an 'action' is being // triggered in the avatar. The action is context-based. @@ -1427,9 +1413,9 @@ void idle(void) { myAvatar.setTriggeringAction( false ); } - // walking triggers the handMovement to stop + // walking triggers the handController to stop if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) { - handMovement.enabled = false; + handController.enabled = false; } // From 06f8990d42cab394477466ac525cdbc796eb8e58 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Apr 2013 14:52:06 -0700 Subject: [PATCH 14/15] removed avatar structure from Head class (leftover from the start of the prototyping phase) --- interface/src/Head.cpp | 131 ++++++++++++++++------------------------- interface/src/Head.h | 29 +++------ 2 files changed, 58 insertions(+), 102 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 442c5eefba..7cf053d0a0 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -47,9 +47,9 @@ unsigned int iris_texture_height = 256; Head::Head(bool isMine) { - _avatar.orientation.setToIdentity(); - _avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); - _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _orientation.setToIdentity(); + _velocity = glm::vec3( 0.0, 0.0, 0.0 ); + _thrust = glm::vec3( 0.0, 0.0, 0.0 ); _rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); _closestOtherAvatar = 0; _bodyYaw = -90.0; @@ -134,9 +134,9 @@ Head::Head(bool isMine) { Head::Head(const Head &otherHead) { - _avatar.orientation.set( otherHead._avatar.orientation ); - _avatar.velocity = otherHead._avatar.velocity; - _avatar.thrust = otherHead._avatar.thrust; + _orientation.set( otherHead._orientation ); + _velocity = otherHead._velocity; + _thrust = otherHead._thrust; _rotation = otherHead._rotation; _closestOtherAvatar = otherHead._closestOtherAvatar; _bodyYaw = otherHead._bodyYaw; @@ -314,7 +314,7 @@ void Head::simulate(float deltaTime) { float distance = glm::length( v ); - if ( distance < _avatar.maxArmLength ) { + if ( distance < _maxArmLength ) { if ( distance < closestDistance ) { closestDistance = distance; _closestOtherAvatar = o; @@ -348,31 +348,31 @@ void Head::simulate(float deltaTime) { //------------------------------------------------- // this handles the avatar being driven around... //------------------------------------------------- - _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _thrust = glm::vec3( 0.0, 0.0, 0.0 ); if (_driveKeys[FWD]) { - glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); - _avatar.thrust += front * THRUST_MAG; + glm::vec3 front( _orientation.getFront().x, _orientation.getFront().y, _orientation.getFront().z ); + _thrust += front * THRUST_MAG; } if (_driveKeys[BACK]) { - glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); - _avatar.thrust -= front * THRUST_MAG; + glm::vec3 front( _orientation.getFront().x, _orientation.getFront().y, _orientation.getFront().z ); + _thrust -= front * THRUST_MAG; } if (_driveKeys[RIGHT]) { - glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); - _avatar.thrust += right * THRUST_MAG; + glm::vec3 right( _orientation.getRight().x, _orientation.getRight().y, _orientation.getRight().z ); + _thrust += right * THRUST_MAG; } if (_driveKeys[LEFT]) { - glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); - _avatar.thrust -= right * THRUST_MAG; + glm::vec3 right( _orientation.getRight().x, _orientation.getRight().y, _orientation.getRight().z ); + _thrust -= right * THRUST_MAG; } if (_driveKeys[UP]) { - glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); - _avatar.thrust += up * THRUST_MAG; + glm::vec3 up( _orientation.getUp().x, _orientation.getUp().y, _orientation.getUp().z ); + _thrust += up * THRUST_MAG; } if (_driveKeys[DOWN]) { - glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); - _avatar.thrust -= up * THRUST_MAG; + glm::vec3 up( _orientation.getUp().x, _orientation.getUp().y, _orientation.getUp().z ); + _thrust -= up * THRUST_MAG; } if (_driveKeys[ROT_RIGHT]) { _bodyYawDelta -= YAW_MAG * deltaTime; @@ -384,7 +384,7 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- - float translationalSpeed = glm::length( _avatar.velocity ); + float translationalSpeed = glm::length( _velocity ); float rotationalSpeed = fabs( _bodyYawDelta ); if ( translationalSpeed + rotationalSpeed > 0.2 ) { @@ -416,18 +416,18 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- // add thrust to velocity //---------------------------------------------------------- - _avatar.velocity += glm::dvec3(_avatar.thrust * deltaTime); + _velocity += glm::dvec3(_thrust * deltaTime); //---------------------------------------------------------- // update position by velocity //---------------------------------------------------------- - _bodyPosition += (glm::vec3)_avatar.velocity * deltaTime; + _bodyPosition += (glm::vec3)_velocity * deltaTime; //---------------------------------------------------------- // decay velocity //---------------------------------------------------------- const float LIN_VEL_DECAY = 5.0; - _avatar.velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); + _velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); if (!_noise) { // Decay back toward center @@ -546,7 +546,7 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { float amp = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphere * amp; _bone[b].springyVelocity += collisionForce * 8.0f * deltaTime; - _avatar.velocity += collisionForce * 18.0f * deltaTime; + _velocity += collisionForce * 18.0f * deltaTime; } } } @@ -567,15 +567,15 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { //---------------------------------------------------------- // add gravity to velocity //---------------------------------------------------------- - _avatar.velocity += glm::dvec3( 0.0, -1.0, 0.0 ) * 0.05; + _velocity += glm::dvec3( 0.0, -1.0, 0.0 ) * 0.05; //---------------------------------------------------------- // ground collisions //---------------------------------------------------------- if ( _bodyPosition.y < 0.0 ) { _bodyPosition.y = 0.0; - if ( _avatar.velocity.y < 0.0 ) { - _avatar.velocity.y *= -0.7; + if ( _velocity.y < 0.0 ) { + _velocity.y *= -0.7; } } } @@ -658,35 +658,6 @@ void Head::render(int faceToFace) { } } - - -//this has been moved to Utils.cpp -/* -void Head::renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) { - glm::vec3 pRight = position + orientation.right * size; - glm::vec3 pUp = position + orientation.up * size; - glm::vec3 pFront = position + orientation.front * size; - - glColor3f( 1.0f, 0.0f, 0.0f ); - glBegin( GL_LINE_STRIP ); - glVertex3f( position.x, position.y, position.z ); - glVertex3f( pRight.x, pRight.y, pRight.z ); - glEnd(); - - glColor3f( 0.0f, 1.0f, 0.0f ); - glBegin( GL_LINE_STRIP ); - glVertex3f( position.x, position.y, position.z ); - glVertex3f( pUp.x, pUp.y, pUp.z ); - glEnd(); - - glColor3f( 0.0f, 0.0f, 1.0f ); - glBegin( GL_LINE_STRIP ); - glVertex3f( position.x, position.y, position.z ); - glVertex3f( pFront.x, pFront.y, pFront.z ); - glEnd(); -} -*/ - void Head::renderHead(int faceToFace) { @@ -986,7 +957,7 @@ void Head::calculateBoneLengths() { _bone[b].length = glm::length( _bone[b].defaultPosePosition ); } - _avatar.maxArmLength + _maxArmLength = _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].length + _bone[ AVATAR_BONE_RIGHT_FOREARM ].length + _bone[ AVATAR_BONE_RIGHT_HAND ].length; @@ -996,13 +967,13 @@ void Head::updateSkeleton() { //---------------------------------- // rotate body... //---------------------------------- - _avatar.orientation.setToIdentity(); - _avatar.orientation.yaw( _bodyYaw ); + _orientation.setToIdentity(); + _orientation.yaw( _bodyYaw ); //test! - make sure this does what expected: st rotation to be identity PLUS _bodyYaw - //_rotation = glm::angleAxis( _bodyYaw, _avatar.orientation.up ); + //_rotation = glm::angleAxis( _bodyYaw, _orientation.up ); - //glm::quat yaw_rotation = glm::angleAxis( _bodyYaw, _avatar.orientation.up ); + //glm::quat yaw_rotation = glm::angleAxis( _bodyYaw, _orientation.up ); //------------------------------------------------------------------------ @@ -1010,7 +981,7 @@ void Head::updateSkeleton() { //------------------------------------------------------------------------ for (int b=0; b _avatar.maxArmLength ) { + if ( distance > _maxArmLength ) { //------------------------------------------------------------------------------- // reset right hand to be constrained to maximum arm length //------------------------------------------------------------------------------- _bone[ AVATAR_BONE_RIGHT_HAND ].position = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; glm::vec3 armNormal = armVector / distance; - armVector = armNormal * _avatar.maxArmLength; - distance = _avatar.maxArmLength; + armVector = armNormal * _maxArmLength; + distance = _maxArmLength; glm::vec3 constrainedPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; constrainedPosition += armVector; _bone[ AVATAR_BONE_RIGHT_HAND ].position = constrainedPosition; @@ -1200,9 +1171,9 @@ void Head::updateHandMovement() { //----------------------------------------------------------------------------- glm::vec3 newElbowPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; newElbowPosition += armVector * ONE_HALF; - glm::vec3 perpendicular = glm::cross( _avatar.orientation.getFront(), armVector ); + glm::vec3 perpendicular = glm::cross( _orientation.getFront(), armVector ); - newElbowPosition += perpendicular * ( 1.0f - ( _avatar.maxArmLength / distance ) ) * ONE_HALF; + newElbowPosition += perpendicular * ( 1.0f - ( _maxArmLength / distance ) ) * ONE_HALF; _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position = newElbowPosition; //----------------------------------------------------------------------------- diff --git a/interface/src/Head.h b/interface/src/Head.h index 554ab3eafe..9ab60f2e73 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -22,16 +22,6 @@ #include #include //looks like we might not need this - -// Note to self: -// modes I might need to implement for avatar -// -// walking usingSprings - ramping down -// bumping into sphere usingSprings is on -// moving hand usingSprings is on -// stuck to another hand usingSprings is on - - enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define FWD 0 @@ -101,14 +91,6 @@ struct AvatarBone float radius; // used for detecting collisions for certain physical effects }; -struct Avatar -{ - glm::dvec3 velocity; - glm::vec3 thrust; - float maxArmLength; - Orientation orientation; -}; - class Head : public AvatarData { public: Head(bool isMine); @@ -176,9 +158,9 @@ class Head : public AvatarData { 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; }; - void addThrust(glm::vec3 newThrust) { _avatar.thrust += newThrust; }; - glm::vec3 getThrust() { return _avatar.thrust; }; + void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }; + void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; + glm::vec3 getThrust() { return _thrust; }; // // Related to getting transmitter UDP data used to animate the avatar hand @@ -237,7 +219,10 @@ class Head : public AvatarData { glm::quat _rotation; // the rotation of the avatar body as a whole AvatarBone _bone[ NUM_AVATAR_BONES ]; AvatarMode _mode; - Avatar _avatar; + glm::dvec3 _velocity; + glm::vec3 _thrust; + float _maxArmLength; + Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; int _eyeContact; eyeContactTargets _eyeContactTarget; From 08105c38985c3e833457ac1e684e2cec1cadfedd Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Apr 2013 17:09:28 -0700 Subject: [PATCH 15/15] I did a major cleanup of the Head class, including putting all the "head"-related members into a single structure. We may consider making a separate class just to handle the head. --- interface/src/Head.cpp | 408 ++++++++++++++++++++++------------------- interface/src/Head.h | 139 +++++++------- 2 files changed, 293 insertions(+), 254 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 7cf053d0a0..821ff2e111 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -48,8 +48,8 @@ unsigned int iris_texture_height = 256; Head::Head(bool isMine) { _orientation.setToIdentity(); - _velocity = glm::vec3( 0.0, 0.0, 0.0 ); - _thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _velocity = glm::vec3( 0.0, 0.0, 0.0 ); + _thrust = glm::vec3( 0.0, 0.0, 0.0 ); _rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); _closestOtherAvatar = 0; _bodyYaw = -90.0; @@ -59,6 +59,10 @@ Head::Head(bool isMine) { _triggeringAction = false; _mode = AVATAR_MODE_STANDING; _isMine = isMine; + _maxArmLength = 0.0; + //_transmitterTimer = 0; + _transmitterHz = 0.0; + _transmitterPackets = 0; initializeSkeleton(); @@ -67,47 +71,53 @@ Head::Head(bool isMine) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) _driveKeys[i] = false; - _pupilSize = 0.10; - _interPupilDistance = 0.6; - _interBrowDistance = 0.75; - _nominalPupilSize = 0.10; - _headYaw = 0.0; - _eyebrowPitch[0] = -30; - _eyebrowPitch[1] = -30; - _eyebrowRoll [0] = 20; - _eyebrowRoll [1] = -20; - _mouthPitch = 0; - _mouthYaw = 0; - _mouthWidth = 1.0; - _mouthHeight = 0.2; - _eyeballPitch[0] = 0; - _eyeballPitch[1] = 0; - _eyeballScaleX = 1.2; - _eyeballScaleY = 1.5; - _eyeballScaleZ = 1.0; - _eyeballYaw[0] = 0; - _eyeballYaw[1] = 0; - _pitchTarget = 0; - _yawTarget = 0; - _noiseEnvelope = 1.0; - _pupilConverge = 10.0; - _leanForward = 0.0; - _leanSideways = 0.0; - _eyeContact = 1; - _eyeContactTarget = LEFT_EYE; - _scale = 1.0; - _renderYaw = 0.0; - _renderPitch = 0.0; - _audioAttack = 0.0; - _loudness = 0.0; - _averageLoudness = 0.0; - _lastLoudness = 0.0; - _browAudioLift = 0.0; - _noise = 0; - _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - _usingBodySprings = false; - _springForce = 6.0f; - _springVelocityDecay = 16.0f; + _head.pupilSize = 0.10; + _head.interPupilDistance = 0.6; + _head.interBrowDistance = 0.75; + _head.nominalPupilSize = 0.10; + _head.yaw = 0.0; + _head.pitch = 0.0; + _head.roll = 0.0; + _head.pitchRate = 0.0; + _head.yawRate = 0.0; + _head.rollRate = 0.0; + _head.eyebrowPitch[0] = -30; + _head.eyebrowPitch[1] = -30; + _head.eyebrowRoll [0] = 20; + _head.eyebrowRoll [1] = -20; + _head.mouthPitch = 0; + _head.mouthYaw = 0; + _head.mouthWidth = 1.0; + _head.mouthHeight = 0.2; + _head.eyeballPitch[0] = 0; + _head.eyeballPitch[1] = 0; + _head.eyeballScaleX = 1.2; + _head.eyeballScaleY = 1.5; + _head.eyeballScaleZ = 1.0; + _head.eyeballYaw[0] = 0; + _head.eyeballYaw[1] = 0; + _head.pitchTarget = 0; + _head.yawTarget = 0; + _head.noiseEnvelope = 1.0; + _head.pupilConverge = 10.0; + _head.leanForward = 0.0; + _head.leanSideways = 0.0; + _head.eyeContact = 1; + _head.eyeContactTarget = LEFT_EYE; + _head.scale = 1.0; + _head.audioAttack = 0.0; + _head.loudness = 0.0; + _head.averageLoudness = 0.0; + _head.lastLoudness = 0.0; + _head.browAudioLift = 0.0; + _head.noise = 0; + + _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); + _usingBodySprings = false; + _springForce = 6.0f; + _springVelocityDecay = 16.0f; + _renderYaw = 0.0; + _renderPitch = 0.0; _sphere = NULL; @@ -119,77 +129,103 @@ Head::Head(bool isMine) { } } - if (_isMine) - { - //-------------------------------------------------- - // test... just slam them into random positions... - //-------------------------------------------------- - _DEBUG_otherAvatarListPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f ); - _DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f ); - } + //-------------------------------------------------- + // test... just slam them into random positions... + //-------------------------------------------------- + _DEBUG_otherAvatarListPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f ); + _DEBUG_otherAvatarListPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f ); + _DEBUG_otherAvatarListPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f ); + _DEBUG_otherAvatarListPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f ); + _DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f ); } -Head::Head(const Head &otherHead) { +Head::Head(const Head &otherAvatar) { + + _velocity = otherAvatar._velocity; + _thrust = otherAvatar._thrust; + _rotation = otherAvatar._rotation; + _closestOtherAvatar = otherAvatar._closestOtherAvatar; + _bodyYaw = otherAvatar._bodyYaw; + _bodyPitch = otherAvatar._bodyPitch; + _bodyRoll = otherAvatar._bodyRoll; + _bodyYawDelta = otherAvatar._bodyYawDelta; + _triggeringAction = otherAvatar._triggeringAction; + _mode = otherAvatar._mode; + _isMine = otherAvatar._isMine; + _renderYaw = otherAvatar._renderYaw; + _renderPitch = otherAvatar._renderPitch; + _maxArmLength = otherAvatar._maxArmLength; + _transmitterTimer = otherAvatar._transmitterTimer; + _transmitterHz = otherAvatar._transmitterHz; + _transmitterPackets = otherAvatar._transmitterPackets; + _TEST_bigSphereRadius = otherAvatar._TEST_bigSphereRadius; + _TEST_bigSpherePosition = otherAvatar._TEST_bigSpherePosition; + _movedHandOffset = otherAvatar._movedHandOffset; + _usingBodySprings = otherAvatar._usingBodySprings; + _springForce = otherAvatar._springForce; + _springVelocityDecay = otherAvatar._springVelocityDecay; + + _orientation.set( otherAvatar._orientation ); - _orientation.set( otherHead._orientation ); - _velocity = otherHead._velocity; - _thrust = otherHead._thrust; - _rotation = otherHead._rotation; - _closestOtherAvatar = otherHead._closestOtherAvatar; - _bodyYaw = otherHead._bodyYaw; - _bodyPitch = otherHead._bodyPitch; - _bodyRoll = otherHead._bodyRoll; - _bodyYawDelta = otherHead._bodyYawDelta; - _triggeringAction = otherHead._triggeringAction; - _mode = otherHead._mode; + //for (int o=0;ogetRelativeValue(HEAD_PITCH_RATE); - _headYawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); + _head.yawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); float measured_lateral_accel = serialInterface->getRelativeValue(ACCEL_X) - ROLL_ACCEL_COUPLING*serialInterface->getRelativeValue(HEAD_ROLL_RATE); float measured_fwd_accel = serialInterface->getRelativeValue(ACCEL_Z) - @@ -238,35 +274,35 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h const float MAX_YAW = 85; const float MIN_YAW = -85; - if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH)) + if ((_head.pitch < MAX_PITCH) && (_head.pitch > MIN_PITCH)) addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); addRoll(-measured_roll_rate * HEAD_ROLL_SCALE * frametime); if (head_mirror) { - if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) - addYaw(-_headYawRate * HEAD_ROTATION_SCALE * frametime); + if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) + addYaw(-_head.yawRate * HEAD_ROTATION_SCALE * frametime); addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } else { - if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) - addYaw(_headYawRate * -HEAD_ROTATION_SCALE * frametime); + if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) + addYaw(_head.yawRate * -HEAD_ROTATION_SCALE * frametime); addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } } void Head::addLean(float x, float z) { // Add Body lean as impulse - _leanSideways += x; - _leanForward += z; + _head.leanSideways += x; + _head.leanForward += z; } void Head::setLeanForward(float dist){ - _leanForward = dist; + _head.leanForward = dist; } void Head::setLeanSideways(float dist){ - _leanSideways = dist; + _head.leanSideways = dist; } void Head::setTriggeringAction( bool d ) { @@ -403,9 +439,9 @@ void Head::simulate(float deltaTime) { } // we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation - _headYaw = _bodyYaw; - _headPitch = _bodyPitch; - _headRoll = _bodyRoll; + _head.yaw = _bodyYaw; + _head.pitch = _bodyPitch; + _head.roll = _bodyRoll; //---------------------------------------------------------- // decay body yaw delta @@ -429,32 +465,32 @@ void Head::simulate(float deltaTime) { const float LIN_VEL_DECAY = 5.0; _velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); - if (!_noise) { + if (!_head.noise) { // Decay back toward center - _headPitch *= (1.0f - DECAY*2*deltaTime); - _headYaw *= (1.0f - DECAY*2*deltaTime); - _headRoll *= (1.0f - DECAY*2*deltaTime); + _head.pitch *= (1.0f - DECAY*2*deltaTime); + _head.yaw *= (1.0f - DECAY*2*deltaTime); + _head.roll *= (1.0f - DECAY*2*deltaTime); } else { // Move toward new target - _headPitch += (_pitchTarget - _headPitch)*10*deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; - _headYaw += (_yawTarget - _headYaw)*10*deltaTime; // (1.f - DECAY*deltaTime); - _headRoll *= (1.f - DECAY*deltaTime); + _head.pitch += (_head.pitchTarget - _head.pitch)*10*deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; + _head.yaw += (_head.yawTarget - _head.yaw )*10*deltaTime; // (1.f - DECAY*deltaTime); + _head.roll *= (1.f - DECAY*deltaTime); } - _leanForward *= (1.f - DECAY*30.f*deltaTime); - _leanSideways *= (1.f - DECAY*30.f*deltaTime); + _head.leanForward *= (1.f - DECAY*30.f*deltaTime); + _head.leanSideways *= (1.f - DECAY*30.f*deltaTime); // Update where the avatar's eyes are // // First, decide if we are making eye contact or not if (randFloat() < 0.005) { - _eyeContact = !_eyeContact; - _eyeContact = 1; - if (!_eyeContact) { + _head.eyeContact = !_head.eyeContact; + _head.eyeContact = 1; + if (!_head.eyeContact) { // If we just stopped making eye contact,move the eyes markedly away - _eyeballPitch[0] = _eyeballPitch[1] = _eyeballPitch[0] + 5.0 + (randFloat() - 0.5)*10; - _eyeballYaw[0] = _eyeballYaw[1] = _eyeballYaw[0] + 5.0 + (randFloat()- 0.5)*5; + _head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5)*10; + _head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5)*5; } else { // If now making eye contact, turn head to look right at viewer SetNewHeadTarget(0,0); @@ -464,56 +500,56 @@ void Head::simulate(float deltaTime) { const float DEGREES_BETWEEN_VIEWER_EYES = 3; const float DEGREES_TO_VIEWER_MOUTH = 7; - if (_eyeContact) { + if (_head.eyeContact) { // Should we pick a new eye contact target? if (randFloat() < 0.01) { // Choose where to look next if (randFloat() < 0.1) { - _eyeContactTarget = MOUTH; + _head.eyeContactTarget = MOUTH; } else { - if (randFloat() < 0.5) _eyeContactTarget = LEFT_EYE; else _eyeContactTarget = RIGHT_EYE; + if (randFloat() < 0.5) _head.eyeContactTarget = LEFT_EYE; else _head.eyeContactTarget = RIGHT_EYE; } } // Set eyeball pitch and yaw to make contact float eye_target_yaw_adjust = 0; float eye_target_pitch_adjust = 0; - if (_eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; - if (_eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; - if (_eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; + if (_head.eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; + if (_head.eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; + if (_head.eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; - _eyeballPitch[0] = _eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust; - _eyeballYaw[0] = _eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust; + _head.eyeballPitch[0] = _head.eyeballPitch[1] = -_head.pitch + eye_target_pitch_adjust; + _head.eyeballYaw[0] = _head.eyeballYaw[1] = -_head.yaw + eye_target_yaw_adjust; } - if (_noise) + if (_head.noise) { - _headPitch += (randFloat() - 0.5)*0.2*_noiseEnvelope; - _headYaw += (randFloat() - 0.5)*0.3*_noiseEnvelope; + _head.pitch += (randFloat() - 0.5)*0.2*_head.noiseEnvelope; + _head.yaw += (randFloat() - 0.5)*0.3*_head.noiseEnvelope; //PupilSize += (randFloat() - 0.5)*0.001*NoiseEnvelope; - if (randFloat() < 0.005) _mouthWidth = MouthWidthChoices[rand()%3]; + if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3]; - if (!_eyeContact) { - if (randFloat() < 0.01) _eyeballPitch[0] = _eyeballPitch[1] = (randFloat() - 0.5)*20; - if (randFloat() < 0.01) _eyeballYaw[0] = _eyeballYaw[1] = (randFloat()- 0.5)*10; + if (!_head.eyeContact) { + if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5)*20; + if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5)*10; } - if ((randFloat() < 0.005) && (fabs(_pitchTarget - _headPitch) < 1.0) && (fabs(_yawTarget - _headYaw) < 1.0)) { + if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _head.pitch) < 1.0) && (fabs(_head.yawTarget - _head.yaw) < 1.0)) { SetNewHeadTarget((randFloat()-0.5)*20.0, (randFloat()-0.5)*45.0); } if (0) { // Pick new target - _pitchTarget = (randFloat() - 0.5)*45; - _yawTarget = (randFloat() - 0.5)*22; + _head.pitchTarget = (randFloat() - 0.5)*45; + _head.yawTarget = (randFloat() - 0.5)*22; } if (randFloat() < 0.01) { - _eyebrowPitch[0] = _eyebrowPitch[1] = BrowPitchAngle[rand()%3]; - _eyebrowRoll[0] = _eyebrowRoll[1] = BrowRollAngle[rand()%5]; - _eyebrowRoll[1]*=-1; + _head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3]; + _head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5]; + _head.eyebrowRoll [1]*=-1; } } } @@ -688,9 +724,9 @@ void Head::renderHead(int faceToFace) { glScalef( 0.03, 0.03, 0.03 ); - glRotatef(_headYaw, 0, 1, 0); - glRotatef(_headPitch, 1, 0, 0); - glRotatef(_headRoll, 0, 0, 1); + glRotatef(_head.yaw, 0, 1, 0); + glRotatef(_head.pitch, 1, 0, 0); + glRotatef(_head.roll, 0, 0, 1); // Overall scale of head if (faceToFace) glScalef(2.0, 2.0, 2.0); @@ -719,27 +755,27 @@ void Head::renderHead(int faceToFace) { glPopMatrix(); // _eyebrows - _audioAttack = 0.9*_audioAttack + 0.1*fabs(_loudness - _lastLoudness); - _lastLoudness = _loudness; + _head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_head.loudness - _head.lastLoudness); + _head.lastLoudness = _head.loudness; const float BROW_LIFT_THRESHOLD = 100; - if (_audioAttack > BROW_LIFT_THRESHOLD) - _browAudioLift += sqrt(_audioAttack)/1000.0; + if (_head.audioAttack > BROW_LIFT_THRESHOLD) + _head.browAudioLift += sqrt(_head.audioAttack)/1000.0; - _browAudioLift *= .90; + _head.browAudioLift *= .90; glPushMatrix(); - glTranslatef(-_interBrowDistance/2.0,0.4,0.45); + glTranslatef(-_head.interBrowDistance/2.0,0.4,0.45); for(side = 0; side < 2; side++) { glColor3fv(browColor); glPushMatrix(); - glTranslatef(0, 0.35 + _browAudioLift, 0); - glRotatef(_eyebrowPitch[side]/2.0, 1, 0, 0); - glRotatef(_eyebrowRoll[side]/2.0, 0, 0, 1); + glTranslatef(0, 0.35 + _head.browAudioLift, 0); + glRotatef(_head.eyebrowPitch[side]/2.0, 1, 0, 0); + glRotatef(_head.eyebrowRoll[side]/2.0, 0, 0, 1); glScalef(browWidth, browThickness, 1); glutSolidCube(0.5); glPopMatrix(); - glTranslatef(_interBrowDistance, 0, 0); + glTranslatef(_head.interBrowDistance, 0, 0); } glPopMatrix(); @@ -749,23 +785,23 @@ void Head::renderHead(int faceToFace) { glPushMatrix(); glTranslatef(0,-0.35,0.75); glColor3f(0,0,0); - glRotatef(_mouthPitch, 1, 0, 0); - glRotatef(_mouthYaw, 0, 0, 1); - glScalef(_mouthWidth*(.7 + sqrt(_averageLoudness)/60.0), _mouthHeight*(1.0 + sqrt(_averageLoudness)/30.0), 1); + glRotatef(_head.mouthPitch, 1, 0, 0); + glRotatef(_head.mouthYaw, 0, 0, 1); + glScalef(_head.mouthWidth*(.7 + sqrt(_head.averageLoudness)/60.0), _head.mouthHeight*(1.0 + sqrt(_head.averageLoudness)/30.0), 1); glutSolidCube(0.5); glPopMatrix(); glTranslatef(0, 1.0, 0); - glTranslatef(-_interPupilDistance/2.0,-0.68,0.7); + glTranslatef(-_head.interPupilDistance/2.0,-0.68,0.7); // Right Eye glRotatef(-10, 1, 0, 0); glColor3fv(eyeColor); glPushMatrix(); { - glTranslatef(_interPupilDistance/10.0, 0, 0.05); + glTranslatef(_head.interPupilDistance/10.0, 0, 0.05); glRotatef(20, 0, 0, 1); - glScalef(_eyeballScaleX, _eyeballScaleY, _eyeballScaleZ); + glScalef(_head.eyeballScaleX, _head.eyeballScaleY, _head.eyeballScaleZ); glutSolidSphere(0.25, 30, 30); } glPopMatrix(); @@ -782,40 +818,40 @@ void Head::renderHead(int faceToFace) { glPushMatrix(); { - glRotatef(_eyeballPitch[1], 1, 0, 0); - glRotatef(_eyeballYaw[1] + _pupilConverge, 0, 1, 0); + glRotatef(_head.eyeballPitch[1], 1, 0, 0); + glRotatef(_head.eyeballYaw[1] + _head.yaw + _head.pupilConverge, 0, 1, 0); glTranslatef(0,0,.35); glRotatef(-75,1,0,0); glScalef(1.0, 0.4, 1.0); glEnable(GL_TEXTURE_2D); - gluSphere(_sphere, _pupilSize, 15, 15); + gluSphere(_sphere, _head.pupilSize, 15, 15); glDisable(GL_TEXTURE_2D); } glPopMatrix(); // Left Eye glColor3fv(eyeColor); - glTranslatef(_interPupilDistance, 0, 0); + glTranslatef(_head.interPupilDistance, 0, 0); glPushMatrix(); { - glTranslatef(-_interPupilDistance/10.0, 0, .05); + glTranslatef(-_head.interPupilDistance/10.0, 0, .05); glRotatef(-20, 0, 0, 1); - glScalef(_eyeballScaleX, _eyeballScaleY, _eyeballScaleZ); + glScalef(_head.eyeballScaleX, _head.eyeballScaleY, _head.eyeballScaleZ); glutSolidSphere(0.25, 30, 30); } glPopMatrix(); // Left Pupil glPushMatrix(); { - glRotatef(_eyeballPitch[0], 1, 0, 0); - glRotatef(_eyeballYaw[0] - _pupilConverge, 0, 1, 0); + glRotatef(_head.eyeballPitch[0], 1, 0, 0); + glRotatef(_head.eyeballYaw[0] + _head.yaw - _head.pupilConverge, 0, 1, 0); glTranslatef(0, 0, .35); glRotatef(-75, 1, 0, 0); glScalef(1.0, 0.4, 1.0); glEnable(GL_TEXTURE_2D); - gluSphere(_sphere, _pupilSize, 15, 15); + gluSphere(_sphere, _head.pupilSize, 15, 15); glDisable(GL_TEXTURE_2D); } @@ -1260,8 +1296,8 @@ void Head::renderBody() { } void Head::SetNewHeadTarget(float pitch, float yaw) { - _pitchTarget = pitch; - _yawTarget = yaw; + _head.pitchTarget = pitch; + _head.yawTarget = yaw; } // getting data from Android transmitte app diff --git a/interface/src/Head.h b/interface/src/Head.h index 9ab60f2e73..72cf750d69 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -91,6 +91,48 @@ struct AvatarBone float radius; // used for detecting collisions for certain physical effects }; +struct AvatarHead +{ + float pitch; + float yaw; + float roll; + float pitchRate; + float yawRate; + float rollRate; + float noise; + float eyeballPitch[2]; + float eyeballYaw [2]; + float eyebrowPitch[2]; + float eyebrowRoll [2]; + float eyeballScaleX; + float eyeballScaleY; + float 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; + int eyeContact; + float browAudioLift; + eyeContactTargets eyeContactTarget; + + // Sound loudness information + float loudness, lastLoudness; + float averageLoudness; + float audioAttack; +}; + + class Head : public AvatarData { public: Head(bool isMine); @@ -98,30 +140,29 @@ class Head : public AvatarData { Head(const Head &otherHead); Head* clone() const; - void reset(); - void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); - 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;} + void reset(); + void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); + void setNoise (float mag) { _head.noise = mag; } + void setPitch(float p) {_head.pitch = p; } + void setYaw(float y) {_head.yaw = y; } + void setRoll(float r) {_head.roll = r; }; + void setScale(float s) {_head.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) {_headPitch -= p; } - void addYaw(float y){_headYaw -= y; } - void addRoll(float r){_headRoll += r; } - void addLean(float x, float z); - float getPitch() {return _headPitch;} - float getRoll() {return _headRoll;} - float getYaw() {return _headYaw;} - float getLastMeasuredYaw() {return _headYawRate;} - + void setLeanForward(float dist); + void setLeanSideways(float dist); + void addPitch(float p) {_head.pitch -= p; } + void addYaw(float y){_head.yaw -= y; } + void addRoll(float r){_head.roll += r; } + void addLean(float x, float z); + float getPitch() {return _head.pitch;} + float getRoll() {return _head.roll;} + float getYaw() {return _head.yaw;} + float getLastMeasuredYaw() {return _head.yawRate;} float getBodyYaw() {return _bodyYaw;}; - void addBodyYaw(float y) {_bodyYaw += y;}; + void addBodyYaw(float y) {_bodyYaw += y;}; glm::vec3 getHeadLookatDirection(); glm::vec3 getHeadLookatDirectionUp(); @@ -137,7 +178,6 @@ class Head : public AvatarData { void renderBody(); void renderHead( int faceToFace); - //void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); void simulate(float); @@ -146,10 +186,10 @@ class Head : public AvatarData { void setHandMovementValues( 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 _head.loudness;}; + float getAverageLoudness() {return _head.averageLoudness;}; + void setAverageLoudness(float al) {_head.averageLoudness = al;}; + void setLoudness(float l) {_head.loudness = l;}; void SetNewHeadTarget(float, float); @@ -170,41 +210,8 @@ class Head : public AvatarData { float getTransmitterHz() { return _transmitterHz; }; private: - 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; - + AvatarHead _head; + bool _isMine; glm::vec3 _TEST_bigSpherePosition; float _TEST_bigSphereRadius; glm::vec3 _DEBUG_otherAvatarListPosition[ NUM_OTHER_AVATARS ]; @@ -224,13 +231,9 @@ class Head : public AvatarData { float _maxArmLength; Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; - int _eyeContact; - eyeContactTargets _eyeContactTarget; - - GLUquadric *_sphere; - - float _renderYaw; - float _renderPitch; // Pitch from view frustum when this is own head. + GLUquadric* _sphere; + 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