mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
Merge branch 'master' of git://github.com/worklist/hifi into 19188
This commit is contained in:
commit
225188a6f9
17 changed files with 633 additions and 406 deletions
|
@ -133,7 +133,7 @@ int main(int argc, const char * argv[])
|
|||
|
||||
if (DEBUG_TO_SELF ||
|
||||
!agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) {
|
||||
if (memchr(SOLO_AGENT_TYPES_STRING, agent->getType(), 1) == NULL) {
|
||||
if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) {
|
||||
// this is an agent of which there can be multiple, just add them to the packet
|
||||
// don't send avatar agents to other avatars, that will come from avatar mixer
|
||||
if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) {
|
||||
|
|
|
@ -13,20 +13,31 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include <AgentList.h>
|
||||
#include <AvatarData.h>
|
||||
#include <AudioInjector.h>
|
||||
|
||||
const int EVE_AGENT_LIST_PORT = 55441;
|
||||
const float DATA_SEND_INTERVAL_MSECS = 10;
|
||||
const int EVE_AGENT_LISTEN_PORT = 55441;
|
||||
|
||||
const float RANDOM_POSITION_MAX_DIMENSION = 5.0f;
|
||||
|
||||
const float DATA_SEND_INTERVAL_MSECS = 15;
|
||||
const float MIN_AUDIO_SEND_INTERVAL_SECS = 10;
|
||||
const int MIN_ITERATIONS_BETWEEN_AUDIO_SENDS = (MIN_AUDIO_SEND_INTERVAL_SECS * 1000) / DATA_SEND_INTERVAL_MSECS;
|
||||
const int MAX_AUDIO_SEND_INTERVAL_SECS = 15;
|
||||
const float MAX_ITERATIONS_BETWEEN_AUDIO_SENDS = (MAX_AUDIO_SEND_INTERVAL_SECS * 1000) / DATA_SEND_INTERVAL_MSECS;
|
||||
|
||||
bool stopReceiveAgentDataThread;
|
||||
bool injectAudioThreadRunning = false;
|
||||
|
||||
void *receiveAgentData(void *args)
|
||||
{
|
||||
int TEMP_AUDIO_LISTEN_PORT = 55439;
|
||||
// UDPSocket audioSocket(TEMP_AUDIO_LISTEN_PORT);
|
||||
|
||||
void *receiveAgentData(void *args) {
|
||||
sockaddr senderAddress;
|
||||
ssize_t bytesReceived;
|
||||
unsigned char incomingPacket[MAX_PACKET_SIZE];
|
||||
|
||||
AgentList *agentList = AgentList::getInstance();
|
||||
Agent *avatarMixer = NULL;
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
Agent* avatarMixer = NULL;
|
||||
|
||||
while (!::stopReceiveAgentDataThread) {
|
||||
if (agentList->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||
|
@ -54,9 +65,35 @@ void *receiveAgentData(void *args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
void *injectAudio(void *args) {
|
||||
::injectAudioThreadRunning = true;
|
||||
|
||||
AudioInjector* eveAudioInjector = (AudioInjector *)args;
|
||||
|
||||
// look for an audio mixer in our agent list
|
||||
Agent* audioMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER);
|
||||
|
||||
if (audioMixer != NULL) {
|
||||
// until the audio mixer is setup for ping-reply, activate the public socket if it's not active
|
||||
if (audioMixer->getActiveSocket() == NULL) {
|
||||
audioMixer->activatePublicSocket();
|
||||
}
|
||||
|
||||
// we have an active audio mixer we can send data to
|
||||
// eveAudioInjector->injectAudio(&::audioSocket, audioMixer->getActiveSocket());
|
||||
}
|
||||
|
||||
::injectAudioThreadRunning = false;
|
||||
pthread_exit(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
// new seed for random audio sleep times
|
||||
srand(time(0));
|
||||
|
||||
// create an AgentList instance to handle communication with other agents
|
||||
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AVATAR, EVE_AGENT_LIST_PORT);
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR, EVE_AGENT_LISTEN_PORT);
|
||||
|
||||
// start telling the domain server that we are alive
|
||||
agentList->startDomainServerCheckInThread();
|
||||
|
@ -74,15 +111,22 @@ int main(int argc, char* argv[]) {
|
|||
AvatarData eve = AvatarData();
|
||||
|
||||
// move eve away from the origin
|
||||
eve.setBodyPosition(glm::vec3(3, 0, -3));
|
||||
// pick a random point inside a 10x10 grid
|
||||
|
||||
// turn her back towards the origin
|
||||
eve.setBodyYaw(-45);
|
||||
eve.setPosition(glm::vec3(randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION),
|
||||
0,
|
||||
randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION)));
|
||||
|
||||
// face any instance of eve down the z-axis
|
||||
eve.setBodyYaw(0);
|
||||
|
||||
// put her hand out so somebody can shake it
|
||||
eve.setHandPosition(glm::vec3(eve.getBodyPosition()[0] - 0.2,
|
||||
eve.setHandPosition(glm::vec3(eve.getPosition()[0] - 0.2,
|
||||
0.25,
|
||||
eve.getBodyPosition()[2] + 0.1));
|
||||
eve.getPosition()[2] + 0.1));
|
||||
|
||||
// read eve's audio data
|
||||
AudioInjector eveAudioInjector("eve.raw");
|
||||
|
||||
unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
||||
broadcastPacket[0] = PACKET_HEADER_HEAD_DATA;
|
||||
|
@ -92,6 +136,9 @@ int main(int argc, char* argv[]) {
|
|||
timeval thisSend;
|
||||
double numMicrosecondsSleep = 0;
|
||||
|
||||
// int numIterationsLeftBeforeAudioSend = 0;
|
||||
// pthread_t injectAudioThread;
|
||||
|
||||
while (true) {
|
||||
// update the thisSend timeval to the current time
|
||||
gettimeofday(&thisSend, NULL);
|
||||
|
@ -104,10 +151,21 @@ int main(int argc, char* argv[]) {
|
|||
// use the getBroadcastData method in the AvatarData class to populate the broadcastPacket buffer
|
||||
numBytesToSend = eve.getBroadcastData((broadcastPacket + 1));
|
||||
|
||||
|
||||
// use the UDPSocket instance attached to our agent list to send avatar data to mixer
|
||||
agentList->getAgentSocket().send(avatarMixer->getActiveSocket(), broadcastPacket, numBytesToSend);
|
||||
}
|
||||
|
||||
// temporarily disable Eve's audio sending until the file is actually available on EC2 box
|
||||
// if (numIterationsLeftBeforeAudioSend == 0) {
|
||||
// if (!::injectAudioThreadRunning) {
|
||||
// pthread_create(&injectAudioThread, NULL, injectAudio, (void*) &eveAudioInjector);
|
||||
//
|
||||
// numIterationsLeftBeforeAudioSend = randIntInRange(MIN_ITERATIONS_BETWEEN_AUDIO_SENDS,
|
||||
// MAX_ITERATIONS_BETWEEN_AUDIO_SENDS);
|
||||
// }
|
||||
// } else {
|
||||
// numIterationsLeftBeforeAudioSend--;
|
||||
// }
|
||||
|
||||
// sleep for the correct amount of time to have data send be consistently timed
|
||||
if ((numMicrosecondsSleep = (DATA_SEND_INTERVAL_MSECS * 1000) - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) {
|
||||
|
|
|
@ -14,4 +14,4 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|||
|
||||
# link the threads library
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(injector ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// injector.cpp
|
||||
// main.cpp
|
||||
// Audio Injector
|
||||
//
|
||||
// Created by Leonardo Murillo on 3/5/13.
|
||||
|
@ -11,39 +11,27 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include "UDPSocket.h"
|
||||
#include "UDPSocket.cpp"
|
||||
|
||||
|
||||
#include <SharedUtil.h>
|
||||
#include <PacketHeaders.h>
|
||||
|
||||
#include <UDPSocket.h>
|
||||
#include <AudioInjector.h>
|
||||
|
||||
char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53";
|
||||
const int AUDIO_UDP_LISTEN_PORT = 55443;
|
||||
const int BUFFER_LENGTH_BYTES = 512;
|
||||
const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t);
|
||||
const float SAMPLE_RATE = 22050.0;
|
||||
const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES / SAMPLE_RATE) * 1000000;
|
||||
|
||||
// Command line parameter defaults
|
||||
bool loopAudio = true;
|
||||
float sleepIntervalMin = 1.00;
|
||||
float sleepIntervalMax = 2.00;
|
||||
float positionInUniverse[] = {0, 0, 0, 0};
|
||||
unsigned char attenuationModifier = 255;
|
||||
char *sourceAudioFile;
|
||||
char *sourceAudioFile = NULL;
|
||||
const char *allowedParameters = ":rb::t::c::a::f:";
|
||||
|
||||
char *charBuffer;
|
||||
int16_t *buffer;
|
||||
long length;
|
||||
|
||||
UDPSocket *streamSocket;
|
||||
float floatArguments[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
unsigned char attenuationModifier = 255;
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
|
@ -62,19 +50,19 @@ bool processParameters(int parameterCount, char* parameterData[])
|
|||
while ((p = getopt(parameterCount, parameterData, allowedParameters)) != -1) {
|
||||
switch (p) {
|
||||
case 'r':
|
||||
loopAudio = false;
|
||||
::loopAudio = false;
|
||||
std::cout << "[DEBUG] Random sleep mode enabled" << std::endl;
|
||||
break;
|
||||
case 'b':
|
||||
sleepIntervalMin = atof(optarg);
|
||||
::sleepIntervalMin = atof(optarg);
|
||||
std::cout << "[DEBUG] Min delay between plays " << sleepIntervalMin << "sec" << std::endl;
|
||||
break;
|
||||
case 't':
|
||||
sleepIntervalMax = atof(optarg);
|
||||
::sleepIntervalMax = atof(optarg);
|
||||
std::cout << "[DEBUG] Max delay between plays " << sleepIntervalMax << "sec" << std::endl;
|
||||
break;
|
||||
case 'f':
|
||||
sourceAudioFile = optarg;
|
||||
::sourceAudioFile = optarg;
|
||||
std::cout << "[DEBUG] Opening file: " << sourceAudioFile << std::endl;
|
||||
break;
|
||||
case 'c':
|
||||
|
@ -84,7 +72,7 @@ bool processParameters(int parameterCount, char* parameterData[])
|
|||
|
||||
int i = 0;
|
||||
while (std::getline(ss, token, ',')) {
|
||||
positionInUniverse[i] = atof(token.c_str());
|
||||
::floatArguments[i] = atof(token.c_str());
|
||||
++i;
|
||||
if (i == 4) {
|
||||
break;
|
||||
|
@ -94,7 +82,7 @@ bool processParameters(int parameterCount, char* parameterData[])
|
|||
break;
|
||||
}
|
||||
case 'a':
|
||||
attenuationModifier = atoi(optarg);
|
||||
::attenuationModifier = atoi(optarg);
|
||||
std::cout << "[DEBUG] Attenuation modifier: " << optarg << std::endl;
|
||||
break;
|
||||
default:
|
||||
|
@ -103,79 +91,44 @@ bool processParameters(int parameterCount, char* parameterData[])
|
|||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
};_Position
|
||||
|
||||
void loadFile(void) {
|
||||
std::fstream sourceFile;
|
||||
sourceFile.open(sourceAudioFile, std::ios::in | std::ios::binary);
|
||||
sourceFile.seekg(0, std::ios::end);
|
||||
length = sourceFile.tellg();
|
||||
sourceFile.seekg(0, std::ios::beg);
|
||||
long sizeOfShortArray = length / 2;
|
||||
buffer = new int16_t[sizeOfShortArray];
|
||||
sourceFile.read((char *)buffer, length);
|
||||
}
|
||||
|
||||
void stream(void)
|
||||
{
|
||||
timeval startTime;
|
||||
|
||||
int leadingBytes = 1 + (sizeof(float) * 4);
|
||||
unsigned char dataPacket[BUFFER_LENGTH_BYTES + leadingBytes];
|
||||
|
||||
dataPacket[0] = PACKET_HEADER_INJECT_AUDIO;
|
||||
unsigned char *currentPacketPtr = dataPacket + 1;
|
||||
|
||||
for (int p = 0; p < 4; p++) {
|
||||
memcpy(currentPacketPtr, &positionInUniverse[p], sizeof(float));
|
||||
currentPacketPtr += sizeof(float);
|
||||
}
|
||||
|
||||
*currentPacketPtr = attenuationModifier;
|
||||
currentPacketPtr++;
|
||||
|
||||
for (int i = 0; i < length; i += BUFFER_LENGTH_SAMPLES) {
|
||||
gettimeofday(&startTime, NULL);
|
||||
memcpy(currentPacketPtr, &buffer[i], BUFFER_LENGTH_BYTES);
|
||||
streamSocket->send(EC2_WEST_AUDIO_SERVER, AUDIO_UDP_LISTEN_PORT, dataPacket, sizeof(dataPacket));
|
||||
double usecToSleep = usecTimestamp(&startTime) + BUFFER_SEND_INTERVAL_USECS - usecTimestampNow();
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int main(int argc, const char* argv[]) {
|
||||
|
||||
srand(time(0));
|
||||
int AUDIO_UDP_SEND_PORT = 1500 + (rand() % (int)(1500 - 2000 + 1));
|
||||
|
||||
streamSocket = new UDPSocket(AUDIO_UDP_SEND_PORT);
|
||||
UDPSocket streamSocket(AUDIO_UDP_SEND_PORT);
|
||||
|
||||
if (processParameters(argc, argv)) {
|
||||
if (sourceAudioFile) {
|
||||
loadFile();
|
||||
} else {
|
||||
sockaddr_in mixerSocket;
|
||||
mixerSocket.sin_family = AF_INET;
|
||||
mixerSocket.sin_addr.s_addr = inet_addr(EC2_WEST_AUDIO_SERVER);
|
||||
mixerSocket.sin_port = htons((uint16_t)AUDIO_UDP_LISTEN_PORT);
|
||||
|
||||
if (processParameters(argc, argv)) {
|
||||
if (::sourceAudioFile == NULL) {
|
||||
std::cout << "[FATAL] Source audio file not specified" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(positionInUniverse)/sizeof(positionInUniverse[0]); ++i) {
|
||||
std::cout << "Position " << positionInUniverse[i] << std::endl;
|
||||
}
|
||||
|
||||
float delay;
|
||||
int usecDelay;
|
||||
while (true) {
|
||||
stream();
|
||||
} else {
|
||||
AudioInjector injector(sourceAudioFile);
|
||||
|
||||
if (loopAudio) {
|
||||
delay = 0;
|
||||
} else {
|
||||
delay = randFloatInRange(sleepIntervalMin, sleepIntervalMax);
|
||||
injector.setPosition(::floatArguments);
|
||||
injector.setBearing(*(::floatArguments + 3));
|
||||
injector.setAttenuationModifier(::attenuationModifier);
|
||||
|
||||
float delay = 0;
|
||||
int usecDelay = 0;
|
||||
|
||||
while (true) {
|
||||
injector.injectAudio(&streamSocket, (sockaddr*) &mixerSocket);
|
||||
|
||||
if (!::loopAudio) {
|
||||
delay = randFloatInRange(::sleepIntervalMin, ::sleepIntervalMax);
|
||||
usecDelay = delay * 1000 * 1000;
|
||||
usleep(usecDelay);
|
||||
}
|
||||
}
|
||||
usecDelay = delay * 1000 * 1000;
|
||||
usleep(usecDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -157,7 +157,7 @@ int audioCallback (const void *inputBuffer,
|
|||
|
||||
// memcpy the three float positions
|
||||
for (int p = 0; p < 3; p++) {
|
||||
memcpy(currentPacketPtr, &data->linkedHead->getBodyPosition()[p], sizeof(float));
|
||||
memcpy(currentPacketPtr, &data->linkedHead->getPosition()[p], sizeof(float));
|
||||
currentPacketPtr += sizeof(float);
|
||||
}
|
||||
|
||||
|
@ -250,8 +250,16 @@ int audioCallback (const void *inputBuffer,
|
|||
}
|
||||
// play whatever we have in the audio buffer
|
||||
|
||||
//
|
||||
// if we haven't fired off the flange effect, check if we should
|
||||
int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredYaw());
|
||||
//
|
||||
|
||||
//
|
||||
// NOTE: PER - LastMeasuredHeadYaw is now relative to body position, represents the local
|
||||
// rotation of the head relative to body, this may effect flange effect!
|
||||
//
|
||||
//
|
||||
int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredHeadYaw());
|
||||
|
||||
if (!samplesLeftForFlange && lastYawMeasured > MIN_FLANGE_EFFECT_THRESHOLD) {
|
||||
// we should flange for one second
|
||||
|
|
|
@ -35,8 +35,6 @@ float browThickness = 0.16;
|
|||
|
||||
bool usingBigSphereCollisionTest = true;
|
||||
|
||||
|
||||
|
||||
char iris_texture_file[] = "resources/images/green_eye.png";
|
||||
|
||||
vector<unsigned char> iris_texture;
|
||||
|
@ -50,7 +48,7 @@ Head::Head(bool isMine) {
|
|||
_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;
|
||||
_nearOtherAvatar = false;
|
||||
_bodyYaw = -90.0;
|
||||
_bodyPitch = 0.0;
|
||||
_bodyRoll = 0.0;
|
||||
|
@ -62,7 +60,7 @@ Head::Head(bool isMine) {
|
|||
//_transmitterTimer = 0;
|
||||
_transmitterHz = 0.0;
|
||||
_transmitterPackets = 0;
|
||||
_numOtherAvatarsInView = 0;
|
||||
//_numOtherAvatars = 0;
|
||||
|
||||
initializeSkeleton();
|
||||
|
||||
|
@ -75,9 +73,9 @@ Head::Head(bool isMine) {
|
|||
_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.yaw = 0.0;
|
||||
//_head.pitch = 0.0;
|
||||
//_head.roll = 0.0;
|
||||
_head.pitchRate = 0.0;
|
||||
_head.yawRate = 0.0;
|
||||
_head.rollRate = 0.0;
|
||||
|
@ -106,7 +104,6 @@ Head::Head(bool isMine) {
|
|||
_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;
|
||||
|
@ -120,7 +117,11 @@ Head::Head(bool isMine) {
|
|||
_renderPitch = 0.0;
|
||||
|
||||
_sphere = NULL;
|
||||
|
||||
|
||||
_handHolding.position = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_handHolding.velocity = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_handHolding.force = 10.0f;
|
||||
|
||||
if (iris_texture.size() == 0) {
|
||||
switchToResourcesParentIfRequired();
|
||||
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
|
||||
|
@ -128,23 +129,19 @@ Head::Head(bool isMine) {
|
|||
printLog("error %u: %s\n", error, lodepng_error_text(error));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// test... just slam them into random positions...
|
||||
//--------------------------------------------------
|
||||
_otherAvatarHandPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f );
|
||||
_otherAvatarHandPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f );
|
||||
_otherAvatarHandPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f );
|
||||
_otherAvatarHandPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f );
|
||||
_otherAvatarHandPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f );
|
||||
|
||||
_otherAvatar.handPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_otherAvatar.handState = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Head::Head(const Head &otherAvatar) {
|
||||
|
||||
_velocity = otherAvatar._velocity;
|
||||
_thrust = otherAvatar._thrust;
|
||||
_rotation = otherAvatar._rotation;
|
||||
_closestOtherAvatar = otherAvatar._closestOtherAvatar;
|
||||
_nearOtherAvatar = otherAvatar._nearOtherAvatar;
|
||||
_bodyYaw = otherAvatar._bodyYaw;
|
||||
_bodyPitch = otherAvatar._bodyPitch;
|
||||
_bodyRoll = otherAvatar._bodyRoll;
|
||||
|
@ -176,9 +173,9 @@ Head::Head(const Head &otherAvatar) {
|
|||
_head.interPupilDistance = otherAvatar._head.interPupilDistance;
|
||||
_head.interBrowDistance = otherAvatar._head.interBrowDistance;
|
||||
_head.nominalPupilSize = otherAvatar._head.nominalPupilSize;
|
||||
_head.yaw = otherAvatar._head.yaw;
|
||||
_head.pitch = otherAvatar._head.pitch;
|
||||
_head.roll = otherAvatar._head.roll;
|
||||
//_head.yaw = otherAvatar._head.yaw;
|
||||
//_head.pitch = otherAvatar._head.pitch;
|
||||
//_head.roll = otherAvatar._head.roll;
|
||||
_head.yawRate = otherAvatar._head.yawRate;
|
||||
_head.pitchRate = otherAvatar._head.pitchRate;
|
||||
_head.rollRate = otherAvatar._head.rollRate;
|
||||
|
@ -207,7 +204,6 @@ Head::Head(const Head &otherAvatar) {
|
|||
_head.eyeContactTarget = otherAvatar._head.eyeContactTarget;
|
||||
_head.scale = otherAvatar._head.scale;
|
||||
_head.audioAttack = otherAvatar._head.audioAttack;
|
||||
_head.loudness = otherAvatar._head.loudness;
|
||||
_head.averageLoudness = otherAvatar._head.averageLoudness;
|
||||
_head.lastLoudness = otherAvatar._head.lastLoudness;
|
||||
_head.browAudioLift = otherAvatar._head.browAudioLift;
|
||||
|
@ -234,14 +230,14 @@ Head* Head::clone() const {
|
|||
}
|
||||
|
||||
void Head::reset() {
|
||||
_head.pitch = _head.yaw = _head.roll = 0;
|
||||
_headPitch = _headYaw = _headRoll = 0;
|
||||
_head.leanForward = _head.leanSideways = 0;
|
||||
}
|
||||
|
||||
|
||||
//this pertains to moving the head with the glasses
|
||||
//---------------------------------------------------
|
||||
void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity)
|
||||
void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity)
|
||||
// Using serial data, update avatar/render position and angles
|
||||
{
|
||||
const float PITCH_ACCEL_COUPLING = 0.5;
|
||||
|
@ -269,20 +265,15 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h
|
|||
const float MAX_YAW = 85;
|
||||
const float MIN_YAW = -85;
|
||||
|
||||
if ((_head.pitch < MAX_PITCH) && (_head.pitch > MIN_PITCH))
|
||||
addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime);
|
||||
if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH))
|
||||
addHeadPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime);
|
||||
|
||||
addRoll(-measured_roll_rate * HEAD_ROLL_SCALE * frametime);
|
||||
addHeadRoll(measured_roll_rate * HEAD_ROLL_SCALE * frametime);
|
||||
|
||||
if (head_mirror) {
|
||||
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 ((_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);
|
||||
}
|
||||
if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW))
|
||||
addHeadYaw(_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) {
|
||||
|
@ -304,7 +295,6 @@ void Head::setMousePressed( bool d ) {
|
|||
_mousePressed = d;
|
||||
}
|
||||
|
||||
|
||||
void Head::simulate(float deltaTime) {
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
@ -313,15 +303,12 @@ void Head::simulate(float deltaTime) {
|
|||
//-------------------------------------------------------------
|
||||
if ( _isMine )
|
||||
{
|
||||
//-------------------------------------
|
||||
// DEBUG - other avatars...
|
||||
//-------------------------------------
|
||||
_closestOtherAvatar = -1;
|
||||
_nearOtherAvatar = false;
|
||||
float closestDistance = 10000.0f;
|
||||
|
||||
AgentList * agentList = AgentList::getInstance();
|
||||
|
||||
_numOtherAvatarsInView =0;
|
||||
//_numOtherAvatars = 0;
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
|
||||
agent != agentList->getAgents().end();
|
||||
|
@ -329,63 +316,63 @@ void Head::simulate(float deltaTime) {
|
|||
if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_AVATAR ) )) {
|
||||
Head *otherAvatar = (Head *)agent->getLinkedData();
|
||||
|
||||
if ( _numOtherAvatarsInView < MAX_OTHER_AVATARS ) {
|
||||
// if ( _numOtherAvatars < MAX_OTHER_AVATARS )
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// test other avatar hand position for proximity...
|
||||
//-----------------------------------------------------------
|
||||
_otherAvatarHandPosition[ _numOtherAvatarsInView ] = otherAvatar->getBonePosition( AVATAR_BONE_RIGHT_HAND );
|
||||
//------------------------------------------------------
|
||||
// check for collisions with other avatars and respond
|
||||
//------------------------------------------------------
|
||||
updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
otherAvatar->getPosition(),
|
||||
otherAvatar->getGirth(),
|
||||
otherAvatar->getHeight(),
|
||||
otherAvatar->getBodyUpDirection(),
|
||||
deltaTime
|
||||
);
|
||||
|
||||
//-------------------------------------------------
|
||||
// test other avatar hand position for proximity
|
||||
//------------------------------------------------
|
||||
glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
|
||||
v -= _otherAvatarHandPosition[ _numOtherAvatarsInView ];
|
||||
v -= otherAvatar->getBonePosition( AVATAR_BONE_RIGHT_HAND );
|
||||
|
||||
float distance = glm::length( v );
|
||||
if ( distance < _maxArmLength ) {
|
||||
if ( distance < closestDistance ) {
|
||||
closestDistance = distance;
|
||||
_closestOtherAvatar = _numOtherAvatarsInView;
|
||||
_numOtherAvatarsInView++;
|
||||
_nearOtherAvatar = true;
|
||||
_otherAvatar.handPosition = otherAvatar->getBonePosition( AVATAR_BONE_RIGHT_HAND );
|
||||
_otherAvatar.handState = (int)otherAvatar->getHandState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
///for testing only (prior to having real avs working)
|
||||
for (int o=0; o<NUM_OTHER_AVATARS; o++) {
|
||||
//-------------------------------------
|
||||
// test other avs for proximity...
|
||||
//-------------------------------------
|
||||
glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
|
||||
v -= _DEBUG_otherAvatarListPosition[o];
|
||||
|
||||
float distance = glm::length( v );
|
||||
|
||||
if ( distance < _maxArmLength ) {
|
||||
if ( distance < closestDistance ) {
|
||||
closestDistance = distance;
|
||||
_closestOtherAvatar = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}//if ( _isMine )
|
||||
|
||||
if ( usingBigSphereCollisionTest ) {
|
||||
//--------------------------------------------------------------
|
||||
// test for avatar collision response (using a big sphere :)
|
||||
//--------------------------------------------------------------
|
||||
updateBigSphereCollisionTest(deltaTime);
|
||||
updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
_TEST_bigSpherePosition,
|
||||
_TEST_bigSphereRadius,
|
||||
_TEST_bigSphereRadius,
|
||||
glm::vec3( 0.0, 1.0, 0.0 ),
|
||||
deltaTime
|
||||
);
|
||||
}
|
||||
|
||||
if ( AVATAR_GRAVITY ) {
|
||||
if ( _bodyPosition.y > _bone[ AVATAR_BONE_RIGHT_FOOT ].radius * 2.0 ) {
|
||||
if ( _position.y > _bone[ AVATAR_BONE_RIGHT_FOOT ].radius * 2.0 ) {
|
||||
_velocity += glm::dvec3( 0.0, -1.0, 0.0 ) * ( 6.0 * deltaTime );
|
||||
}
|
||||
else {
|
||||
if ( _bodyPosition.y < _bone[ AVATAR_BONE_RIGHT_FOOT ].radius ) {
|
||||
_bodyPosition.y = _bone[ AVATAR_BONE_RIGHT_FOOT ].radius;
|
||||
if ( _position.y < _bone[ AVATAR_BONE_RIGHT_FOOT ].radius ) {
|
||||
_position.y = _bone[ AVATAR_BONE_RIGHT_FOOT ].radius;
|
||||
_velocity.y = 0.0;
|
||||
}
|
||||
}
|
||||
|
@ -400,7 +387,7 @@ void Head::simulate(float deltaTime) {
|
|||
// reset hand and arm positions according to hand movement
|
||||
//------------------------------------------------------------
|
||||
if (_usingBodySprings) {
|
||||
updateHandMovement();
|
||||
updateHandMovement( deltaTime );
|
||||
updateBodySprings( deltaTime );
|
||||
}
|
||||
|
||||
|
@ -462,10 +449,6 @@ void Head::simulate(float deltaTime) {
|
|||
_bodyYaw += _bodyYawDelta * deltaTime;
|
||||
}
|
||||
|
||||
// we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation
|
||||
_head.yaw = _bodyYaw;
|
||||
_head.pitch = _bodyPitch;
|
||||
_head.roll = _bodyRoll;
|
||||
|
||||
//----------------------------------------------------------
|
||||
// decay body yaw delta
|
||||
|
@ -480,28 +463,37 @@ void Head::simulate(float deltaTime) {
|
|||
//----------------------------------------------------------
|
||||
// update position by velocity
|
||||
//----------------------------------------------------------
|
||||
_bodyPosition += (glm::vec3)_velocity * deltaTime;
|
||||
_position += (glm::vec3)_velocity * deltaTime;
|
||||
|
||||
//----------------------------------------------------------
|
||||
// decay velocity
|
||||
//----------------------------------------------------------
|
||||
_velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime );
|
||||
|
||||
//
|
||||
// Update Head information
|
||||
//
|
||||
|
||||
// we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation
|
||||
//_head.yaw = _bodyYaw;
|
||||
//_head.pitch = _bodyPitch;
|
||||
//_head.roll = _bodyRoll;
|
||||
|
||||
if (!_head.noise) {
|
||||
// Decay back toward center
|
||||
_head.pitch *= (1.0f - DECAY*2*deltaTime);
|
||||
_head.yaw *= (1.0f - DECAY*2*deltaTime);
|
||||
_head.roll *= (1.0f - DECAY*2*deltaTime);
|
||||
_headPitch *= (1.0f - DECAY * 2 * deltaTime);
|
||||
_headYaw *= (1.0f - DECAY * 2 * deltaTime);
|
||||
_headRoll *= (1.0f - DECAY * 2 * deltaTime);
|
||||
}
|
||||
else {
|
||||
// Move toward new target
|
||||
_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);
|
||||
_headPitch += (_head.pitchTarget - _headPitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ;
|
||||
_headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime);
|
||||
_headRoll *= 1.f - (DECAY * deltaTime);
|
||||
}
|
||||
|
||||
_head.leanForward *= (1.f - DECAY*30.f*deltaTime);
|
||||
_head.leanSideways *= (1.f - DECAY*30.f*deltaTime);
|
||||
_head.leanForward *= (1.f - DECAY * 30 * deltaTime);
|
||||
_head.leanSideways *= (1.f - DECAY * 30 * deltaTime);
|
||||
|
||||
// Update where the avatar's eyes are
|
||||
//
|
||||
|
@ -511,8 +503,8 @@ void Head::simulate(float deltaTime) {
|
|||
_head.eyeContact = 1;
|
||||
if (!_head.eyeContact) {
|
||||
// If we just stopped making eye contact,move the eyes markedly away
|
||||
_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;
|
||||
_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);
|
||||
|
@ -539,63 +531,75 @@ void Head::simulate(float deltaTime) {
|
|||
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;
|
||||
|
||||
_head.eyeballPitch[0] = _head.eyeballPitch[1] = -_head.pitch + eye_target_pitch_adjust;
|
||||
_head.eyeballYaw[0] = _head.eyeballYaw[1] = -_head.yaw + eye_target_yaw_adjust;
|
||||
_head.eyeballPitch[0] = _head.eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust;
|
||||
_head.eyeballYaw[0] = _head.eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust;
|
||||
}
|
||||
|
||||
|
||||
if (_head.noise)
|
||||
{
|
||||
_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;
|
||||
_headPitch += (randFloat() - 0.5) * 0.2 * _head.noiseEnvelope;
|
||||
_headYaw += (randFloat() - 0.5) * 0.3 *_head.noiseEnvelope;
|
||||
//PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope;
|
||||
|
||||
if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3];
|
||||
|
||||
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.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(_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 ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _headPitch) < 1.0) && (fabs(_head.yawTarget - _headYaw) < 1.0)) {
|
||||
SetNewHeadTarget((randFloat()-0.5) * 20.0, (randFloat()-0.5) * 45.0);
|
||||
}
|
||||
|
||||
if (0) {
|
||||
|
||||
// Pick new target
|
||||
_head.pitchTarget = (randFloat() - 0.5)*45;
|
||||
_head.yawTarget = (randFloat() - 0.5)*22;
|
||||
_head.pitchTarget = (randFloat() - 0.5) * 45;
|
||||
_head.yawTarget = (randFloat() - 0.5) * 22;
|
||||
}
|
||||
if (randFloat() < 0.01)
|
||||
{
|
||||
_head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3];
|
||||
_head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5];
|
||||
_head.eyebrowRoll [1]*=-1;
|
||||
_head.eyebrowRoll [1] *=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float Head::getGirth() {
|
||||
return COLLISION_BODY_RADIUS;
|
||||
}
|
||||
|
||||
float Head::getHeight() {
|
||||
return COLLISION_HEIGHT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
glm::vec3 Head::getBodyUpDirection() {
|
||||
return _orientation.getUp();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// This is a workspace for testing avatar body collision detection and response
|
||||
//--------------------------------------------------------------------------------
|
||||
void Head::updateBigSphereCollisionTest( float deltaTime ) {
|
||||
void Head::updateAvatarCollisionDetectionAndResponse
|
||||
( glm::vec3 collisionPosition, float collisionGirth, float collisionHeight, glm::vec3 collisionUpVector, float deltaTime ) {
|
||||
|
||||
float myBodyApproximateBoundingRadius = 1.0f;
|
||||
glm::vec3 vectorFromMyBodyToBigSphere(_bodyPosition - _TEST_bigSpherePosition);
|
||||
glm::vec3 vectorFromMyBodyToBigSphere(_position - collisionPosition);
|
||||
bool jointCollision = false;
|
||||
|
||||
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
|
||||
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + _TEST_bigSphereRadius)
|
||||
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + collisionGirth )
|
||||
{
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++)
|
||||
{
|
||||
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - _TEST_bigSpherePosition);
|
||||
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - collisionPosition);
|
||||
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
|
||||
float combinedRadius = _bone[b].radius + _TEST_bigSphereRadius;
|
||||
float combinedRadius = _bone[b].radius + collisionGirth;
|
||||
if ( distanceToBigSphereCenter < combinedRadius )
|
||||
{
|
||||
jointCollision = true;
|
||||
|
@ -608,7 +612,7 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) {
|
|||
|
||||
_bone[b].springyVelocity += collisionForce * 30.0f * deltaTime;
|
||||
_velocity += collisionForce * 100.0f * deltaTime;
|
||||
_bone[b].springyPosition = _TEST_bigSpherePosition + directionVector * combinedRadius;
|
||||
_bone[b].springyPosition = collisionPosition + directionVector * combinedRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -621,23 +625,22 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Head::render(int faceToFace) {
|
||||
void Head::render(bool lookingInMirror) {
|
||||
|
||||
//---------------------------------------------------
|
||||
// show avatar position
|
||||
//---------------------------------------------------
|
||||
glColor4f( 0.5f, 0.5f, 0.5f, 0.6 );
|
||||
glPushMatrix();
|
||||
glTranslatef(_bodyPosition.x, _bodyPosition.y, _bodyPosition.z);
|
||||
glTranslatef(_position.x, _position.y, _position.z);
|
||||
glScalef( 0.03, 0.03, 0.03 );
|
||||
glutSolidSphere( 1, 10, 10 );
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
if ( usingBigSphereCollisionTest ) {
|
||||
//---------------------------------------------------
|
||||
// show TEST big sphere
|
||||
|
@ -658,31 +661,18 @@ void Head::render(int faceToFace) {
|
|||
//---------------------------------------------------
|
||||
// render head
|
||||
//---------------------------------------------------
|
||||
renderHead(faceToFace);
|
||||
renderHead(lookingInMirror);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// if this is my avatar, then render my interactions with the other avatars
|
||||
//---------------------------------------------------------------------------
|
||||
if ( _isMine )
|
||||
{
|
||||
/*
|
||||
//---------------------------------------------------
|
||||
// render other avatars (DEBUG TEST)
|
||||
//---------------------------------------------------
|
||||
for (int o=0; o<_numOtherAvatarsInView; o++) {
|
||||
glPushMatrix();
|
||||
glTranslatef( _otherAvatarHandPosition[o].x, _otherAvatarHandPosition[o].y, _otherAvatarHandPosition[o].z );
|
||||
glScalef( 0.03, 0.03, 0.03 );
|
||||
glutSolidSphere( 1, 10, 10 );
|
||||
glPopMatrix();
|
||||
}
|
||||
*/
|
||||
|
||||
if (_usingBodySprings) {
|
||||
if ( _closestOtherAvatar != -1 ) {
|
||||
if ( _nearOtherAvatar ) {
|
||||
|
||||
glm::vec3 v1( _bone[ AVATAR_BONE_RIGHT_HAND ].position );
|
||||
glm::vec3 v2( _otherAvatarHandPosition[ _closestOtherAvatar ] );
|
||||
glm::vec3 v2( _otherAvatar.handPosition );
|
||||
|
||||
glLineWidth( 8.0 );
|
||||
glColor4f( 0.7f, 0.4f, 0.1f, 0.6 );
|
||||
|
@ -695,9 +685,9 @@ void Head::render(int faceToFace) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Head::renderHead(int faceToFace) {
|
||||
void Head::renderHead(bool lookingInMirror) {
|
||||
int side = 0;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -723,9 +713,15 @@ void Head::renderHead(int faceToFace) {
|
|||
|
||||
glScalef( 0.03, 0.03, 0.03 );
|
||||
|
||||
glRotatef(_head.yaw, 0, 1, 0);
|
||||
glRotatef(_head.pitch, 1, 0, 0);
|
||||
glRotatef(_head.roll, 0, 0, 1);
|
||||
if (lookingInMirror) {
|
||||
glRotatef(_bodyYaw - _headYaw, 0, 1, 0);
|
||||
glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
|
||||
glRotatef(_bodyRoll - _headRoll, 0, 0, 1);
|
||||
} else {
|
||||
glRotatef(_bodyYaw + _headYaw, 0, 1, 0);
|
||||
glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
|
||||
glRotatef(_bodyRoll + _headRoll, 0, 0, 1);
|
||||
}
|
||||
|
||||
glScalef(2.0, 2.0, 2.0);
|
||||
glColor3fv(skinColor);
|
||||
|
@ -745,17 +741,17 @@ void Head::renderHead(int faceToFace) {
|
|||
glPopMatrix();
|
||||
|
||||
// _eyebrows
|
||||
_head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_head.loudness - _head.lastLoudness);
|
||||
_head.lastLoudness = _head.loudness;
|
||||
_head.audioAttack = 0.9 * _head.audioAttack + 0.1 * fabs(_audioLoudness - _head.lastLoudness);
|
||||
_head.lastLoudness = _audioLoudness;
|
||||
|
||||
const float BROW_LIFT_THRESHOLD = 100;
|
||||
if (_head.audioAttack > BROW_LIFT_THRESHOLD)
|
||||
_head.browAudioLift += sqrt(_head.audioAttack)/1000.0;
|
||||
_head.browAudioLift += sqrt(_head.audioAttack) / 1000.0;
|
||||
|
||||
_head.browAudioLift *= .90;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-_head.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();
|
||||
|
@ -809,7 +805,7 @@ void Head::renderHead(int faceToFace) {
|
|||
glPushMatrix();
|
||||
{
|
||||
glRotatef(_head.eyeballPitch[1], 1, 0, 0);
|
||||
glRotatef(_head.eyeballYaw[1] + _head.yaw + _head.pupilConverge, 0, 1, 0);
|
||||
glRotatef(_head.eyeballYaw[1] + _headYaw + _head.pupilConverge, 0, 1, 0);
|
||||
glTranslatef(0,0,.35);
|
||||
glRotatef(-75,1,0,0);
|
||||
glScalef(1.0, 0.4, 1.0);
|
||||
|
@ -835,7 +831,7 @@ void Head::renderHead(int faceToFace) {
|
|||
glPushMatrix();
|
||||
{
|
||||
glRotatef(_head.eyeballPitch[0], 1, 0, 0);
|
||||
glRotatef(_head.eyeballYaw[0] + _head.yaw - _head.pupilConverge, 0, 1, 0);
|
||||
glRotatef(_head.eyeballYaw[0] + _headYaw - _head.pupilConverge, 0, 1, 0);
|
||||
glTranslatef(0, 0, .35);
|
||||
glRotatef(-75, 1, 0, 0);
|
||||
glScalef(1.0, 0.4, 1.0);
|
||||
|
@ -979,9 +975,6 @@ void Head::initializeSkeleton() {
|
|||
updateSkeleton();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Head::calculateBoneLengths() {
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||
_bone[b].length = glm::length( _bone[b].defaultPosePosition );
|
||||
|
@ -1006,7 +999,7 @@ void Head::updateSkeleton() {
|
|||
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||
if ( _bone[b].parent == AVATAR_BONE_NULL ) {
|
||||
_bone[b].orientation.set( _orientation );
|
||||
_bone[b].position = _bodyPosition;
|
||||
_bone[b].position = _position;
|
||||
}
|
||||
else {
|
||||
_bone[b].orientation.set( _bone[ _bone[b].parent ].orientation );
|
||||
|
@ -1045,7 +1038,7 @@ void Head::updateBodySprings( float deltaTime ) {
|
|||
glm::vec3 springVector( _bone[b].springyPosition );
|
||||
|
||||
if ( _bone[b].parent == AVATAR_BONE_NULL ) {
|
||||
springVector -= _bodyPosition;
|
||||
springVector -= _position;
|
||||
}
|
||||
else {
|
||||
springVector -= _bone[ _bone[b].parent ].springyPosition;
|
||||
|
@ -1123,7 +1116,7 @@ glm::vec3 Head::getBonePosition( AvatarBoneID b ) {
|
|||
|
||||
|
||||
|
||||
void Head::updateHandMovement() {
|
||||
void Head::updateHandMovement( float deltaTime ) {
|
||||
glm::vec3 transformedHandMovement;
|
||||
|
||||
transformedHandMovement
|
||||
|
@ -1133,28 +1126,45 @@ void Head::updateHandMovement() {
|
|||
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement;
|
||||
|
||||
//if holding hands, add a pull to the hand...
|
||||
if ( _usingBodySprings ) {
|
||||
if ( _closestOtherAvatar != -1 ) {
|
||||
if ( _mousePressed ) {
|
||||
setHandState(_mousePressed);
|
||||
|
||||
bool atLeastOneAvatarIsGrasping = false;
|
||||
|
||||
if ( getHandState() == 1 ) { atLeastOneAvatarIsGrasping = true; }
|
||||
|
||||
//if ( _isMine ) {
|
||||
//if ( _otherAvatar.handState == 1 ) {
|
||||
if ( _nearOtherAvatar ) {
|
||||
atLeastOneAvatarIsGrasping = true;
|
||||
}
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
glm::vec3 handToHandVector( _otherAvatarHandPosition[ _closestOtherAvatar ]);
|
||||
handToHandVector -= _bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||
|
||||
//_bone[ AVATAR_BONE_RIGHT_HAND ].springyVelocity -= handPull;
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position = _otherAvatarHandPosition[ _closestOtherAvatar ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// if holding hands with another avatar, add a force to the hand...
|
||||
//---------------------------------------------------------------------
|
||||
if ( atLeastOneAvatarIsGrasping ) {
|
||||
|
||||
glm::vec3 vectorToOtherHand = _otherAvatar.handPosition - _handHolding.position;
|
||||
glm::vec3 vectorToMyHand = _bone[ AVATAR_BONE_RIGHT_HAND ].position - _handHolding.position;
|
||||
|
||||
_handHolding.velocity *= 0.7;
|
||||
_handHolding.velocity += ( vectorToOtherHand + vectorToMyHand ) * _handHolding.force * deltaTime;
|
||||
_handHolding.position += _handHolding.velocity;
|
||||
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position = _handHolding.position;
|
||||
}
|
||||
else {
|
||||
_handHolding.position = _bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||
_handHolding.velocity = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// determine the arm vector
|
||||
//-------------------------------------------------------------------------------
|
||||
glm::vec3 armVector = _bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||
armVector -= _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// test to see if right hand is being dragged beyond maximum arm length
|
||||
//-------------------------------------------------------------------------------
|
||||
|
@ -1175,30 +1185,13 @@ void Head::updateHandMovement() {
|
|||
constrainedPosition += armVector;
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position = constrainedPosition;
|
||||
}
|
||||
|
||||
/*
|
||||
//-------------------------------------------------------------------------------
|
||||
// keep arm from going through av body...
|
||||
//-------------------------------------------------------------------------------
|
||||
glm::vec3 adjustedArmVector = _bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||
adjustedArmVector -= _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
|
||||
|
||||
float rightComponent = glm::dot( adjustedArmVector, avatar.orientation.getRight() );
|
||||
|
||||
if ( rightComponent < 0.0 )
|
||||
{
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position -= avatar.orientation.getRight() * rightComponent;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// set elbow position
|
||||
//-----------------------------------------------------------------------------
|
||||
glm::vec3 newElbowPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
|
||||
newElbowPosition += armVector * ONE_HALF;
|
||||
//glm::vec3 perpendicular = glm::cross( frontDirection, armVector );
|
||||
glm::vec3 perpendicular = glm::cross( _orientation.getFront(), armVector );
|
||||
|
||||
newElbowPosition += perpendicular * ( 1.0f - ( _maxArmLength / distance ) ) * ONE_HALF;
|
||||
_bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position = newElbowPosition;
|
||||
|
||||
|
@ -1226,7 +1219,7 @@ void Head::renderBody() {
|
|||
//renderBoneAsBlock( (AvatarBoneID)b);
|
||||
|
||||
//render bone orientation
|
||||
renderOrientationDirections( _bone[b].springyPosition, _bone[b].orientation, _bone[b].radius * 2.0 );
|
||||
//renderOrientationDirections( _bone[b].springyPosition, _bone[b].orientation, _bone[b].radius * 2.0 );
|
||||
|
||||
if ( _usingBodySprings ) {
|
||||
glColor3fv( skinColor );
|
||||
|
@ -1274,8 +1267,10 @@ void Head::renderBody() {
|
|||
}
|
||||
}
|
||||
|
||||
if (( _usingBodySprings ) && ( _mousePressed )) {
|
||||
glColor4f( 1.0, 1.0, 0.5, 0.5 );
|
||||
//---------------------------------------------------------
|
||||
// if the hand is grasping, show it...
|
||||
//---------------------------------------------------------
|
||||
if (( _usingBodySprings ) && ( getHandState() == 1 )) {
|
||||
glPushMatrix();
|
||||
glTranslatef
|
||||
(
|
||||
|
@ -1283,7 +1278,10 @@ void Head::renderBody() {
|
|||
_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.y,
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.z
|
||||
);
|
||||
glutSolidSphere( 0.03f, 10.0f, 5.0f );
|
||||
glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.4, 0.2 ); glutSolidSphere( 0.025f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
@ -1302,9 +1300,6 @@ void Head::renderBoneAsBlock( AvatarBoneID b ) {
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Head::SetNewHeadTarget(float pitch, float yaw) {
|
||||
_head.pitchTarget = pitch;
|
||||
_head.yawTarget = yaw;
|
||||
|
|
|
@ -29,6 +29,9 @@ const float YAW_MAG = 300.0;
|
|||
const float TEST_YAW_DECAY = 5.0;
|
||||
const float LIN_VEL_DECAY = 5.0;
|
||||
|
||||
const float COLLISION_BODY_RADIUS = 0.1;
|
||||
const float COLLISION_HEIGHT = 1.5;
|
||||
|
||||
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
||||
|
||||
#define FWD 0
|
||||
|
@ -41,7 +44,7 @@ enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
|||
#define ROT_RIGHT 7
|
||||
#define MAX_DRIVE_KEYS 8
|
||||
|
||||
#define MAX_OTHER_AVATARS 50 // temporary - for testing purposes!
|
||||
#define MAX_OTHER_AVATARS 10 // temporary - for testing purposes!
|
||||
|
||||
enum AvatarMode
|
||||
{
|
||||
|
@ -81,6 +84,29 @@ enum AvatarBoneID
|
|||
NUM_AVATAR_BONES
|
||||
};
|
||||
|
||||
struct AvatarCollisionElipsoid
|
||||
{
|
||||
bool colliding;
|
||||
glm::vec3 position;
|
||||
float girth;
|
||||
float height;
|
||||
glm::vec3 upVector;
|
||||
};
|
||||
|
||||
struct AvatarHandHolding
|
||||
{
|
||||
glm::vec3 position;
|
||||
glm::vec3 velocity;
|
||||
float force;
|
||||
};
|
||||
|
||||
struct OtherAvatar
|
||||
{
|
||||
glm::vec3 handPosition;
|
||||
int handState;
|
||||
};
|
||||
|
||||
|
||||
struct AvatarBone
|
||||
{
|
||||
AvatarBoneID parent; // which bone is this bone connected to?
|
||||
|
@ -100,9 +126,6 @@ struct AvatarBone
|
|||
|
||||
struct AvatarHead
|
||||
{
|
||||
float pitch;
|
||||
float yaw;
|
||||
float roll;
|
||||
float pitchRate;
|
||||
float yawRate;
|
||||
float rollRate;
|
||||
|
@ -134,7 +157,7 @@ struct AvatarHead
|
|||
eyeContactTargets eyeContactTarget;
|
||||
|
||||
// Sound loudness information
|
||||
float loudness, lastLoudness;
|
||||
float lastLoudness;
|
||||
float averageLoudness;
|
||||
float audioAttack;
|
||||
};
|
||||
|
@ -148,11 +171,8 @@ class Head : public AvatarData {
|
|||
Head* clone() const;
|
||||
|
||||
void reset();
|
||||
void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity);
|
||||
void UpdateGyros(float frametime, SerialInterface * serialInterface, 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;}
|
||||
|
@ -160,14 +180,8 @@ class Head : public AvatarData {
|
|||
float getRenderPitch() {return _renderPitch;}
|
||||
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 getLastMeasuredHeadYaw() const {return _head.yawRate;}
|
||||
float getBodyYaw() {return _bodyYaw;};
|
||||
void addBodyYaw(float y) {_bodyYaw += y;};
|
||||
|
||||
|
@ -175,25 +189,27 @@ class Head : public AvatarData {
|
|||
glm::vec3 getHeadLookatDirectionUp();
|
||||
glm::vec3 getHeadLookatDirectionRight();
|
||||
glm::vec3 getHeadPosition();
|
||||
glm::vec3 getBonePosition( AvatarBoneID b );
|
||||
|
||||
glm::vec3 getBonePosition( AvatarBoneID b );
|
||||
glm::vec3 getBodyUpDirection();
|
||||
//int getHandState();
|
||||
float getGirth();
|
||||
float getHeight();
|
||||
|
||||
AvatarMode getMode();
|
||||
|
||||
void setMousePressed( bool pressed );
|
||||
void render(int faceToFace);
|
||||
void render(bool lookingInMirror);
|
||||
void renderBody();
|
||||
void renderHead( int faceToFace);
|
||||
void renderHead(bool lookingInMirror);
|
||||
void simulate(float);
|
||||
void startHandMovement();
|
||||
void stopHandMovement();
|
||||
void setHandMovementValues( glm::vec3 movement );
|
||||
void updateHandMovement();
|
||||
void updateHandMovement( float deltaTime );
|
||||
|
||||
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);
|
||||
|
||||
// Set what driving keys are being pressed to control thrust levels
|
||||
|
@ -205,45 +221,38 @@ class Head : public AvatarData {
|
|||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||
glm::vec3 getThrust() { return _thrust; };
|
||||
|
||||
//
|
||||
// Related to getting transmitter UDP data used to animate the avatar hand
|
||||
//
|
||||
|
||||
void processTransmitterData(unsigned char * packetData, int numBytes);
|
||||
float getTransmitterHz() { return _transmitterHz; };
|
||||
|
||||
private:
|
||||
AvatarHead _head;
|
||||
bool _isMine;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
float _TEST_bigSphereRadius;
|
||||
glm::vec3 _otherAvatarHandPosition[ MAX_OTHER_AVATARS ];
|
||||
bool _mousePressed;
|
||||
float _bodyYawDelta;
|
||||
int _closestOtherAvatar;
|
||||
bool _usingBodySprings;
|
||||
glm::vec3 _movedHandOffset;
|
||||
float _springVelocityDecay;
|
||||
float _springForce;
|
||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||
AvatarBone _bone[ NUM_AVATAR_BONES ];
|
||||
AvatarMode _mode;
|
||||
glm::dvec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
float _maxArmLength;
|
||||
Orientation _orientation;
|
||||
int _numOtherAvatarsInView;
|
||||
int _driveKeys[MAX_DRIVE_KEYS];
|
||||
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
|
||||
//
|
||||
timeval _transmitterTimer;
|
||||
float _transmitterHz;
|
||||
int _transmitterPackets;
|
||||
AvatarHead _head;
|
||||
bool _isMine;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
float _TEST_bigSphereRadius;
|
||||
OtherAvatar _otherAvatar;
|
||||
bool _mousePressed;
|
||||
float _bodyYawDelta;
|
||||
bool _nearOtherAvatar;
|
||||
bool _usingBodySprings;
|
||||
glm::vec3 _movedHandOffset;
|
||||
float _springVelocityDecay;
|
||||
float _springForce;
|
||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||
AvatarBone _bone[ NUM_AVATAR_BONES ];
|
||||
AvatarMode _mode;
|
||||
AvatarHandHolding _handHolding;
|
||||
glm::dvec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
float _maxArmLength;
|
||||
Orientation _orientation;
|
||||
int _driveKeys[MAX_DRIVE_KEYS];
|
||||
GLUquadric* _sphere;
|
||||
float _renderYaw;
|
||||
float _renderPitch; // Pitch from view frustum when this is own head
|
||||
timeval _transmitterTimer;
|
||||
float _transmitterHz;
|
||||
int _transmitterPackets;
|
||||
|
||||
//-----------------------------
|
||||
// private methods...
|
||||
|
@ -253,10 +262,16 @@ class Head : public AvatarData {
|
|||
void initializeBodySprings();
|
||||
void updateBodySprings( float deltaTime );
|
||||
void calculateBoneLengths();
|
||||
void updateBigSphereCollisionTest( float deltaTime );
|
||||
void readSensors();
|
||||
void renderBoneAsBlock( AvatarBoneID b );
|
||||
|
||||
void updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
glm::vec3 collisionPosition,
|
||||
float collisionGirth,
|
||||
float collisionHeight,
|
||||
glm::vec3 collisionUpVector,
|
||||
float deltaTime
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -185,7 +185,7 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, const glm::vec3& nodePosi
|
|||
int voxelsAdded = 0;
|
||||
|
||||
float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
|
||||
glm::vec3 viewerPosition = viewerHead->getBodyPosition();
|
||||
glm::vec3 viewerPosition = viewerHead->getPosition();
|
||||
|
||||
// debug LOD code
|
||||
glm::vec3 debugNodePosition;
|
||||
|
|
|
@ -96,8 +96,6 @@ int packetsPerSecond = 0;
|
|||
int bytesPerSecond = 0;
|
||||
int bytesCount = 0;
|
||||
|
||||
int headMirror = 1; // Whether to mirror own head when viewing it
|
||||
|
||||
int WIDTH = 1200; // Window size
|
||||
int HEIGHT = 800;
|
||||
int fullscreen = 0;
|
||||
|
@ -163,7 +161,7 @@ int noiseOn = 0; // Whether to add random noise
|
|||
float noise = 1.0; // Overall magnitude scaling for random noise levels
|
||||
|
||||
int displayLevels = 0;
|
||||
int displayHead = 0;
|
||||
bool lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror?
|
||||
int displayField = 0;
|
||||
|
||||
int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement
|
||||
|
@ -306,7 +304,7 @@ void displayStats(void)
|
|||
char legend2[] = "* - toggle stars, & - toggle paint mode, '-' - send erase all, '%' - send add scene";
|
||||
drawtext(10, statsVerticalOffset + 32, 0.10f, 0, 1.0, 0, legend2);
|
||||
|
||||
glm::vec3 avatarPos = myAvatar.getBodyPosition();
|
||||
glm::vec3 avatarPos = myAvatar.getPosition();
|
||||
|
||||
char stats[200];
|
||||
sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)= %4.2f, %4.2f, %4.2f ",
|
||||
|
@ -398,8 +396,8 @@ void init(void)
|
|||
if (noiseOn) {
|
||||
myAvatar.setNoise(noise);
|
||||
}
|
||||
myAvatar.setBodyPosition(start_location);
|
||||
myCamera.setPosition( start_location );
|
||||
myAvatar.setPosition(start_location);
|
||||
myCamera.setPosition(start_location);
|
||||
|
||||
|
||||
#ifdef MARKER_CAPTURE
|
||||
|
@ -440,7 +438,7 @@ void reset_sensors()
|
|||
|
||||
renderYawRate = 0;
|
||||
renderPitchRate = 0;
|
||||
myAvatar.setBodyPosition(start_location);
|
||||
myAvatar.setPosition(start_location);
|
||||
headMouseX = WIDTH/2;
|
||||
headMouseY = HEIGHT/2;
|
||||
|
||||
|
@ -459,7 +457,7 @@ void updateAvatar(float frametime)
|
|||
float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE);
|
||||
float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE );
|
||||
|
||||
myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity);
|
||||
myAvatar.UpdateGyros(frametime, &serialPort, &gravity);
|
||||
|
||||
//
|
||||
// Update gyro-based mouse (X,Y on screen)
|
||||
|
@ -553,7 +551,7 @@ void updateAvatar(float frametime)
|
|||
// If I'm in paint mode, send a voxel out to VOXEL server agents.
|
||||
if (::paintOn) {
|
||||
|
||||
glm::vec3 avatarPos = myAvatar.getBodyPosition();
|
||||
glm::vec3 avatarPos = myAvatar.getPosition();
|
||||
|
||||
// For some reason, we don't want to flip X and Z here.
|
||||
::paintingVoxel.x = avatarPos.x/10.0;
|
||||
|
@ -819,7 +817,7 @@ void display(void)
|
|||
//--------------------------------------------------------
|
||||
// camera settings
|
||||
//--------------------------------------------------------
|
||||
if ( displayHead ) {
|
||||
if ( ::lookingInMirror ) {
|
||||
//-----------------------------------------------
|
||||
// set the camera to looking at my own face
|
||||
//-----------------------------------------------
|
||||
|
@ -835,7 +833,7 @@ void display(void)
|
|||
//----------------------------------------------------
|
||||
// set the camera to third-person view behind my av
|
||||
//----------------------------------------------------
|
||||
myCamera.setTargetPosition ( myAvatar.getBodyPosition() );
|
||||
myCamera.setTargetPosition ( myAvatar.getPosition() );
|
||||
myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() );
|
||||
myCamera.setPitch ( 0.0 ); // temporarily, this must be 0.0 or else bad juju
|
||||
myCamera.setRoll ( 0.0 );
|
||||
|
@ -913,7 +911,7 @@ void display(void)
|
|||
drawGroundPlaneGrid( 5.0f, 9 );
|
||||
|
||||
// Draw cloud of dots
|
||||
if (!displayHead) cloud.render();
|
||||
if (!::lookingInMirror) cloud.render();
|
||||
|
||||
// Draw voxels
|
||||
if ( showingVoxels )
|
||||
|
@ -935,16 +933,16 @@ void display(void)
|
|||
}
|
||||
}
|
||||
|
||||
if ( !displayHead ) balls.render();
|
||||
if ( !::lookingInMirror ) balls.render();
|
||||
|
||||
// Render the world box
|
||||
if (!displayHead && statsOn) render_world_box();
|
||||
if (!::lookingInMirror && statsOn) render_world_box();
|
||||
|
||||
// brad's frustum for debugging
|
||||
if (::frustumOn) renderViewFrustum(::viewFrustum);
|
||||
|
||||
//Render my own avatar
|
||||
myAvatar.render(true);
|
||||
myAvatar.render(::lookingInMirror);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
@ -962,7 +960,7 @@ void display(void)
|
|||
if (audioScope.getState()) audioScope.render();
|
||||
#endif
|
||||
|
||||
if (displayHeadMouse && !displayHead && statsOn) {
|
||||
if (displayHeadMouse && !::lookingInMirror && statsOn) {
|
||||
// Display small target box at center or head mouse target that can also be used to measure LOD
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
|
@ -1058,7 +1056,7 @@ int setValue(int state, bool *value) {
|
|||
}
|
||||
|
||||
int setHead(int state) {
|
||||
return setValue(state, &displayHead);
|
||||
return setValue(state, &::lookingInMirror);
|
||||
}
|
||||
|
||||
int setField(int state) {
|
||||
|
@ -1091,10 +1089,6 @@ int setMenu(int state) {
|
|||
return setValue(state, &::menuOn);
|
||||
}
|
||||
|
||||
int setMirror(int state) {
|
||||
return setValue(state, &headMirror);
|
||||
}
|
||||
|
||||
int setDisplayFrustum(int state) {
|
||||
return setValue(state, &::frustumOn);
|
||||
}
|
||||
|
@ -1200,10 +1194,9 @@ void initMenu() {
|
|||
MenuColumn *menuColumnOptions, *menuColumnTools, *menuColumnDebug, *menuColumnFrustum;
|
||||
// Options
|
||||
menuColumnOptions = menu.addColumn("Options");
|
||||
menuColumnOptions->addRow("(H)ead", setHead);
|
||||
menuColumnOptions->addRow("Mirror (h)", setHead);
|
||||
menuColumnOptions->addRow("Field (f)", setField);
|
||||
menuColumnOptions->addRow("(N)oise", setNoise);
|
||||
menuColumnOptions->addRow("Mirror", setMirror);
|
||||
menuColumnOptions->addRow("(V)oxels", setVoxels);
|
||||
menuColumnOptions->addRow("Stars (*)", setStars);
|
||||
menuColumnOptions->addRow("(Q)uit", quitApp);
|
||||
|
@ -1273,7 +1266,7 @@ void shiftPaintingColor()
|
|||
}
|
||||
|
||||
void setupPaintingVoxel() {
|
||||
glm::vec3 avatarPos = myAvatar.getBodyPosition();
|
||||
glm::vec3 avatarPos = myAvatar.getPosition();
|
||||
|
||||
::paintingVoxel.x = avatarPos.z/-10.0; // voxel space x is negative z head space
|
||||
::paintingVoxel.y = avatarPos.y/-10.0; // voxel space y is negative y head space
|
||||
|
@ -1412,9 +1405,9 @@ void key(unsigned char k, int x, int y)
|
|||
}
|
||||
|
||||
if (k == 'h') {
|
||||
displayHead = !displayHead;
|
||||
::lookingInMirror = !::lookingInMirror;
|
||||
#ifndef _WIN32
|
||||
audio.setMixerLoopbackFlag(displayHead);
|
||||
audio.setMixerLoopbackFlag(::lookingInMirror);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1502,7 +1495,7 @@ void idle(void) {
|
|||
//
|
||||
updateAvatar(deltaTime);
|
||||
|
||||
//loop through all the other avatars and simulate them.
|
||||
//loop through all the other avatars and simulate them...
|
||||
AgentList * agentList = AgentList::getInstance();
|
||||
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++)
|
||||
{
|
||||
|
@ -1520,7 +1513,6 @@ void idle(void) {
|
|||
|
||||
glutPostRedisplay();
|
||||
lastTimeIdle = check;
|
||||
|
||||
}
|
||||
|
||||
// Read serial data
|
||||
|
|
|
@ -34,9 +34,14 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
|
|||
}
|
||||
|
||||
AvatarData::AvatarData() :
|
||||
_handPosition(0,0,0),
|
||||
_bodyYaw(-90.0),
|
||||
_bodyPitch(0.0),
|
||||
_bodyRoll(0.0),
|
||||
_headYaw(0),
|
||||
_headPitch(0),
|
||||
_headRoll(0),
|
||||
_handState(0),
|
||||
_cameraPosition(0,0,0),
|
||||
_cameraDirection(0,0,0),
|
||||
_cameraUp(0,0,0),
|
||||
|
@ -63,15 +68,31 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
// that can pack any type given the number of bytes
|
||||
// and return the number of bytes to push the pointer
|
||||
|
||||
memcpy(destinationBuffer, &_bodyPosition, sizeof(float) * 3);
|
||||
// Body world position
|
||||
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
|
||||
destinationBuffer += sizeof(float) * 3;
|
||||
|
||||
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
|
||||
|
||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headYaw);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headPitch);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headRoll);
|
||||
|
||||
// Hand Position
|
||||
memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3);
|
||||
destinationBuffer += sizeof(float) * 3;
|
||||
|
||||
// Hand State (0 = not grabbing, 1 = grabbing)
|
||||
memcpy(destinationBuffer, &_handState, sizeof(char));
|
||||
destinationBuffer += sizeof(char);
|
||||
|
||||
// Instantaneous audio loudness (used to drive facial animation)
|
||||
memcpy(destinationBuffer, &_audioLoudness, sizeof(float));
|
||||
destinationBuffer += sizeof(float);
|
||||
|
||||
// camera details
|
||||
memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition));
|
||||
|
@ -91,6 +112,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip));
|
||||
destinationBuffer += sizeof(_cameraFarClip);
|
||||
|
||||
|
||||
return destinationBuffer - bufferStart;
|
||||
}
|
||||
|
||||
|
@ -102,16 +124,32 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
memcpy(&_bodyPosition, sourceBuffer, sizeof(float) * 3);
|
||||
// Body world position
|
||||
memcpy(&_position, sourceBuffer, sizeof(float) * 3);
|
||||
sourceBuffer += sizeof(float) * 3;
|
||||
|
||||
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll);
|
||||
|
||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headYaw);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headPitch);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headRoll);
|
||||
|
||||
// Hand Position
|
||||
memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3);
|
||||
sourceBuffer += sizeof(float) * 3;
|
||||
|
||||
// Hand State
|
||||
memcpy(&_handState, sourceBuffer, sizeof(char));
|
||||
sourceBuffer += sizeof(char);
|
||||
|
||||
// Instantaneous audio loudness (used to drive facial animation)
|
||||
memcpy(&_audioLoudness, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
|
||||
// camera details
|
||||
memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition));
|
||||
sourceBuffer += sizeof(_cameraPosition);
|
||||
|
@ -133,14 +171,14 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
||||
glm::vec3 AvatarData::getBodyPosition() {
|
||||
return glm::vec3(_bodyPosition.x,
|
||||
_bodyPosition.y,
|
||||
_bodyPosition.z);
|
||||
glm::vec3 AvatarData::getPosition() {
|
||||
return glm::vec3(_position.x,
|
||||
_position.y,
|
||||
_position.z);
|
||||
}
|
||||
|
||||
void AvatarData::setBodyPosition(glm::vec3 bodyPosition) {
|
||||
_bodyPosition = bodyPosition;
|
||||
void AvatarData::setPosition(glm::vec3 position) {
|
||||
_position = position;
|
||||
}
|
||||
|
||||
void AvatarData::setHandPosition(glm::vec3 handPosition) {
|
||||
|
|
|
@ -20,23 +20,41 @@ public:
|
|||
|
||||
AvatarData* clone() const;
|
||||
|
||||
glm::vec3 getBodyPosition();
|
||||
void setBodyPosition(glm::vec3 bodyPosition);
|
||||
glm::vec3 getPosition();
|
||||
void setPosition(glm::vec3 position);
|
||||
void setHandPosition(glm::vec3 handPosition);
|
||||
|
||||
int getBroadcastData(unsigned char* destinationBuffer);
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
// Body Rotation
|
||||
float getBodyYaw();
|
||||
void setBodyYaw(float bodyYaw);
|
||||
|
||||
float getBodyPitch();
|
||||
void setBodyPitch(float bodyPitch);
|
||||
|
||||
float getBodyRoll();
|
||||
void setBodyYaw(float bodyYaw);
|
||||
void setBodyPitch(float bodyPitch);
|
||||
void setBodyRoll(float bodyRoll);
|
||||
|
||||
// getters for camera details
|
||||
// Head Rotation
|
||||
void setHeadPitch(float p) {_headPitch = p; }
|
||||
void setHeadYaw(float y) {_headYaw = y; }
|
||||
void setHeadRoll(float r) {_headRoll = r; };
|
||||
const float getHeadPitch() const { return _headPitch; };
|
||||
const float getHeadYaw() const { return _headYaw; };
|
||||
const float getHeadRoll() const { return _headRoll; };
|
||||
void addHeadPitch(float p) {_headPitch -= p; }
|
||||
void addHeadYaw(float y){_headYaw -= y; }
|
||||
void addHeadRoll(float r){_headRoll += r; }
|
||||
|
||||
// Hand State
|
||||
void setHandState(char s) { _handState = s; };
|
||||
const float getHandState() const {return _handState; }; //@Philip - shouldn't this be an int or a char?
|
||||
|
||||
// Instantaneous audio loudness to drive mouth/facial animation
|
||||
void setLoudness(float l) { _audioLoudness = l; };
|
||||
const float getLoudness() const {return _audioLoudness; };
|
||||
|
||||
// getters for camera details
|
||||
const glm::vec3& getCameraPosition() const { return _cameraPosition; };
|
||||
const glm::vec3& getCameraDirection() const { return _cameraDirection; }
|
||||
const glm::vec3& getCameraUp() const { return _cameraUp; }
|
||||
|
@ -57,13 +75,25 @@ public:
|
|||
void setCameraFarClip(float farClip) { _cameraFarClip = farClip; }
|
||||
|
||||
protected:
|
||||
glm::vec3 _bodyPosition;
|
||||
glm::vec3 _position;
|
||||
glm::vec3 _handPosition;
|
||||
|
||||
// Body rotation
|
||||
float _bodyYaw;
|
||||
float _bodyPitch;
|
||||
float _bodyRoll;
|
||||
|
||||
// Head rotation (relative to body)
|
||||
float _headYaw;
|
||||
float _headPitch;
|
||||
float _headRoll;
|
||||
|
||||
// Audio loudness (used to drive facial animation)
|
||||
float _audioLoudness;
|
||||
|
||||
// Hand state (are we grabbing something or not)
|
||||
char _handState;
|
||||
|
||||
// camera details for the avatar
|
||||
glm::vec3 _cameraPosition;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
using shared_lib::printLog;
|
||||
|
||||
const char SOLO_AGENT_TYPES_STRING[] = {
|
||||
const char SOLO_AGENT_TYPES[3] = {
|
||||
AGENT_TYPE_AVATAR_MIXER,
|
||||
AGENT_TYPE_AUDIO_MIXER,
|
||||
AGENT_TYPE_VOXEL
|
||||
|
@ -305,8 +305,8 @@ void AgentList::handlePingReply(sockaddr *agentAddress) {
|
|||
}
|
||||
}
|
||||
|
||||
Agent* AgentList::soloAgentOfType(char agentType) {
|
||||
if (memchr(SOLO_AGENT_TYPES_STRING, agentType, 1)) {
|
||||
Agent* AgentList::soloAgentOfType(char agentType) {
|
||||
if (memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES)) != NULL) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
if (agent->getType() == agentType) {
|
||||
return &*agent;
|
||||
|
@ -428,7 +428,7 @@ void *checkInWithDomainServer(void *args) {
|
|||
sockaddr_in tempAddress;
|
||||
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
||||
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
||||
printLog("Domain server: %s \n", DOMAIN_HOSTNAME);
|
||||
printLog("Domain server: %s - %s\n", DOMAIN_HOSTNAME, DOMAIN_IP);
|
||||
|
||||
} else {
|
||||
printLog("Failed lookup domainserver\n");
|
||||
|
|
|
@ -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[3];
|
||||
|
||||
extern char DOMAIN_HOSTNAME[];
|
||||
extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup
|
||||
|
|
103
libraries/shared/src/AudioInjector.cpp
Normal file
103
libraries/shared/src/AudioInjector.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
//
|
||||
// AudioInjector.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/23/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
#include "PacketHeaders.h"
|
||||
|
||||
#include "AudioInjector.h"
|
||||
|
||||
const int BUFFER_LENGTH_BYTES = 512;
|
||||
const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t);
|
||||
const float SAMPLE_RATE = 22050.0f;
|
||||
const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES / SAMPLE_RATE) * 1000000;
|
||||
|
||||
AudioInjector::AudioInjector(const char* filename) :
|
||||
_numTotalBytesAudio(0),
|
||||
_bearing(0),
|
||||
_attenuationModifier(255)
|
||||
{
|
||||
_position[0] = 0.0f;
|
||||
_position[1] = 0.0f;
|
||||
_position[2] = 0.0f;
|
||||
|
||||
std::fstream sourceFile;
|
||||
|
||||
sourceFile.open(filename, std::ios::in | std::ios::binary);
|
||||
sourceFile.seekg(0, std::ios::end);
|
||||
|
||||
_numTotalBytesAudio = sourceFile.tellg();
|
||||
if (_numTotalBytesAudio == -1) {
|
||||
printf("Error reading audio data from file %s\n", filename);
|
||||
_audioSampleArray = NULL;
|
||||
} else {
|
||||
printf("Read %d bytes from audio file\n", _numTotalBytesAudio);
|
||||
sourceFile.seekg(0, std::ios::beg);
|
||||
long sizeOfShortArray = _numTotalBytesAudio / 2;
|
||||
_audioSampleArray = new int16_t[sizeOfShortArray];
|
||||
|
||||
sourceFile.read((char *)_audioSampleArray, _numTotalBytesAudio);
|
||||
}
|
||||
}
|
||||
|
||||
AudioInjector::~AudioInjector() {
|
||||
delete[] _audioSampleArray;
|
||||
}
|
||||
|
||||
void AudioInjector::setPosition(float* position) {
|
||||
_position[0] = position[0];
|
||||
_position[1] = position[1];
|
||||
_position[2] = position[2];
|
||||
}
|
||||
|
||||
void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket) const {
|
||||
if (_audioSampleArray != NULL) {
|
||||
timeval startTime;
|
||||
|
||||
// one byte for header, 3 positional floats, 1 bearing float, 1 attenuation modifier byte
|
||||
int leadingBytes = 1 + (sizeof(float) * 4) + 1;
|
||||
unsigned char dataPacket[BUFFER_LENGTH_BYTES + leadingBytes];
|
||||
|
||||
dataPacket[0] = PACKET_HEADER_INJECT_AUDIO;
|
||||
unsigned char *currentPacketPtr = dataPacket + 1;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
memcpy(currentPacketPtr, &_position[i], sizeof(float));
|
||||
currentPacketPtr += sizeof(float);
|
||||
}
|
||||
|
||||
*currentPacketPtr = _attenuationModifier;
|
||||
currentPacketPtr++;
|
||||
|
||||
memcpy(currentPacketPtr, &_bearing, sizeof(float));
|
||||
currentPacketPtr += sizeof(float);
|
||||
|
||||
for (int i = 0; i < _numTotalBytesAudio; i += BUFFER_LENGTH_BYTES) {
|
||||
gettimeofday(&startTime, NULL);
|
||||
|
||||
int numBytesToCopy = BUFFER_LENGTH_BYTES;
|
||||
|
||||
if (_numTotalBytesAudio - i < BUFFER_LENGTH_BYTES) {
|
||||
numBytesToCopy = _numTotalBytesAudio - i;
|
||||
memset(currentPacketPtr + numBytesToCopy, 0, BUFFER_LENGTH_BYTES - numBytesToCopy);
|
||||
}
|
||||
|
||||
memcpy(currentPacketPtr, _audioSampleArray + (i / 2), numBytesToCopy);
|
||||
|
||||
injectorSocket->send(destinationSocket, dataPacket, sizeof(dataPacket));
|
||||
|
||||
double usecToSleep = BUFFER_SEND_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&startTime));
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
libraries/shared/src/AudioInjector.h
Normal file
35
libraries/shared/src/AudioInjector.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// AudioInjector.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/23/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__AudioInjector__
|
||||
#define __hifi__AudioInjector__
|
||||
|
||||
#include <iostream>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "UDPSocket.h"
|
||||
|
||||
class AudioInjector {
|
||||
public:
|
||||
AudioInjector(const char* filename);
|
||||
~AudioInjector();
|
||||
|
||||
void setPosition(float* position);
|
||||
void setBearing(float bearing) { _bearing = bearing; }
|
||||
void setAttenuationModifier(unsigned char attenuationModifier) { _attenuationModifier = attenuationModifier; }
|
||||
|
||||
void injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket) const;
|
||||
private:
|
||||
int16_t* _audioSampleArray;
|
||||
int _numTotalBytesAudio;
|
||||
float _position[3];
|
||||
float _bearing;
|
||||
unsigned char _attenuationModifier;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AudioInjector__) */
|
|
@ -19,7 +19,7 @@ VoxelAgentData::~VoxelAgentData() {
|
|||
}
|
||||
|
||||
VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
|
||||
memcpy(&_bodyPosition, &otherAgentData._bodyPosition, sizeof(_bodyPosition));
|
||||
memcpy(&_position, &otherAgentData._position, sizeof(_position));
|
||||
rootMarkerNode = new MarkerNode();
|
||||
}
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd,
|
||||
randomTree.rootNode,
|
||||
agentData->rootMarkerNode,
|
||||
agentData->getBodyPosition(),
|
||||
agentData->getPosition(),
|
||||
treeRoot,
|
||||
viewFrustum,
|
||||
::viewFrustumCulling,
|
||||
|
|
Loading…
Reference in a new issue