mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 06:53:59 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into render_voxels_optimization
This commit is contained in:
commit
de969891d8
23 changed files with 780 additions and 695 deletions
|
@ -60,7 +60,7 @@ const float DISTANCE_RATIO = 3.0f / 0.3f;
|
|||
const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5;
|
||||
const int PHASE_DELAY_AT_90 = 20;
|
||||
|
||||
const float MAX_OFF_AXIS_ATTENUATION = 0.5f;
|
||||
const float MAX_OFF_AXIS_ATTENUATION = 0.2f;
|
||||
const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f;
|
||||
|
||||
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
|
||||
|
@ -111,7 +111,6 @@ void *sendBuffer(void *args) {
|
|||
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData();
|
||||
float agentBearing = agentRingBuffer->getBearing();
|
||||
|
||||
int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {};
|
||||
|
||||
|
@ -120,76 +119,86 @@ void *sendBuffer(void *args) {
|
|||
AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData();
|
||||
|
||||
if (otherAgentBuffer->shouldBeAddedToMix()) {
|
||||
float *agentPosition = agentRingBuffer->getPosition();
|
||||
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
||||
|
||||
float bearingRelativeAngleToSource = 0.f;
|
||||
float attenuationCoefficient = 1.f;
|
||||
int numSamplesDelay = 0;
|
||||
float weakChannelAmplitudeRatio = 1.f;
|
||||
|
||||
// calculate the distance to the other agent
|
||||
|
||||
// use the distance to the other agent to calculate the change in volume for this frame
|
||||
int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex());
|
||||
int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex());
|
||||
|
||||
if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) {
|
||||
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
|
||||
powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
||||
powf(agentPosition[2] - otherAgentPosition[2], 2));
|
||||
if (otherAgent != agent) {
|
||||
float *agentPosition = agentRingBuffer->getPosition();
|
||||
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
||||
|
||||
float minCoefficient = std::min(1.0f,
|
||||
powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1));
|
||||
distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient;
|
||||
}
|
||||
|
||||
|
||||
// get the angle from the right-angle triangle
|
||||
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]),
|
||||
fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
|
||||
float absoluteAngleToSource = 0;
|
||||
float bearingRelativeAngleToSource = 0;
|
||||
|
||||
|
||||
// find the angle we need for calculation based on the orientation of the triangle
|
||||
if (otherAgentPosition[0] > agentPosition[0]) {
|
||||
if (otherAgentPosition[2] > agentPosition[2]) {
|
||||
absoluteAngleToSource = -90 + triangleAngle;
|
||||
} else {
|
||||
absoluteAngleToSource = -90 - triangleAngle;
|
||||
// calculate the distance to the other agent
|
||||
|
||||
// use the distance to the other agent to calculate the change in volume for this frame
|
||||
int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex());
|
||||
int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex());
|
||||
|
||||
if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) {
|
||||
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
|
||||
powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
||||
powf(agentPosition[2] - otherAgentPosition[2], 2));
|
||||
|
||||
float minCoefficient = std::min(1.0f,
|
||||
powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1));
|
||||
distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient;
|
||||
}
|
||||
} else {
|
||||
if (otherAgentPosition[2] > agentPosition[2]) {
|
||||
absoluteAngleToSource = 90 - triangleAngle;
|
||||
|
||||
|
||||
// get the angle from the right-angle triangle
|
||||
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]),
|
||||
fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
|
||||
float absoluteAngleToSource = 0;
|
||||
bearingRelativeAngleToSource = 0;
|
||||
|
||||
// find the angle we need for calculation based on the orientation of the triangle
|
||||
if (otherAgentPosition[0] > agentPosition[0]) {
|
||||
if (otherAgentPosition[2] > agentPosition[2]) {
|
||||
absoluteAngleToSource = -90 + triangleAngle;
|
||||
} else {
|
||||
absoluteAngleToSource = -90 - triangleAngle;
|
||||
}
|
||||
} else {
|
||||
absoluteAngleToSource = 90 + triangleAngle;
|
||||
if (otherAgentPosition[2] > agentPosition[2]) {
|
||||
absoluteAngleToSource = 90 - triangleAngle;
|
||||
} else {
|
||||
absoluteAngleToSource = 90 + triangleAngle;
|
||||
}
|
||||
}
|
||||
|
||||
bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing();
|
||||
|
||||
if (bearingRelativeAngleToSource > 180) {
|
||||
bearingRelativeAngleToSource -= 360;
|
||||
} else if (bearingRelativeAngleToSource < -180) {
|
||||
bearingRelativeAngleToSource += 360;
|
||||
}
|
||||
|
||||
float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing();
|
||||
|
||||
if (angleOfDelivery > 180) {
|
||||
angleOfDelivery -= 360;
|
||||
} else if (angleOfDelivery < -180) {
|
||||
angleOfDelivery += 360;
|
||||
}
|
||||
|
||||
float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION +
|
||||
(OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f));
|
||||
|
||||
attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex]
|
||||
* otherAgentBuffer->getAttenuationRatio()
|
||||
* offAxisCoefficient;
|
||||
|
||||
bearingRelativeAngleToSource *= (M_PI / 180);
|
||||
|
||||
float sinRatio = fabsf(sinf(bearingRelativeAngleToSource));
|
||||
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
||||
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
|
||||
}
|
||||
|
||||
if (absoluteAngleToSource > 180) {
|
||||
absoluteAngleToSource -= 360;
|
||||
} else if (absoluteAngleToSource < -180) {
|
||||
absoluteAngleToSource += 360;
|
||||
}
|
||||
|
||||
bearingRelativeAngleToSource = absoluteAngleToSource - agentBearing;
|
||||
bearingRelativeAngleToSource *= (M_PI / 180);
|
||||
|
||||
float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing();
|
||||
|
||||
if (angleOfDelivery < -180) {
|
||||
angleOfDelivery += 360;
|
||||
}
|
||||
|
||||
float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION +
|
||||
(OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f));
|
||||
|
||||
float attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex]
|
||||
* otherAgentBuffer->getAttenuationRatio()
|
||||
* offAxisCoefficient;
|
||||
|
||||
float sinRatio = fabsf(sinf(bearingRelativeAngleToSource));
|
||||
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
||||
float weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
|
||||
|
||||
int16_t* goodChannel = bearingRelativeAngleToSource > 0 ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix;
|
||||
int16_t* delayedChannel = bearingRelativeAngleToSource > 0 ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix;
|
||||
int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
|
||||
int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer()
|
||||
? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay
|
||||
|
@ -199,9 +208,7 @@ void *sendBuffer(void *args) {
|
|||
|
||||
if (s < numSamplesDelay) {
|
||||
// pull the earlier sample for the delayed channel
|
||||
|
||||
int earlierSample = delaySamplePointer[s] * attenuationCoefficient;
|
||||
|
||||
plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio);
|
||||
}
|
||||
|
||||
|
@ -210,8 +217,7 @@ void *sendBuffer(void *args) {
|
|||
|
||||
if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||
plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay],
|
||||
currentSample *
|
||||
weakChannelAmplitudeRatio);
|
||||
currentSample * weakChannelAmplitudeRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,8 +282,8 @@ int main(int argc, const char* argv[]) {
|
|||
if(agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
||||
if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) {
|
||||
|
||||
if (agentList->addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList->getLastAgentId())) {
|
||||
agentList->increaseAgentId();
|
||||
if (agentList->addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList->getLastAgentID())) {
|
||||
agentList->increaseAgentID();
|
||||
}
|
||||
|
||||
agentList->updateAgentWithData(agentAddress, packetData, receivedBytes);
|
||||
|
|
|
@ -51,8 +51,7 @@ void attachAvatarDataToAgent(Agent *newAgent) {
|
|||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
int main(int argc, const char* argv[]) {
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT);
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
|
@ -69,32 +68,32 @@ int main(int argc, const char* argv[])
|
|||
*broadcastPacket = PACKET_HEADER_BULK_AVATAR_DATA;
|
||||
|
||||
unsigned char* currentBufferPosition = NULL;
|
||||
|
||||
uint16_t agentID = 0;
|
||||
|
||||
while (true) {
|
||||
if (agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
||||
switch (packetData[0]) {
|
||||
case PACKET_HEADER_HEAD_DATA:
|
||||
// add this agent if we don't have them yet
|
||||
if (agentList->addOrUpdateAgent(agentAddress, agentAddress, AGENT_TYPE_AVATAR, agentList->getLastAgentId())) {
|
||||
agentList->increaseAgentId();
|
||||
}
|
||||
// grab the agent ID from the packet
|
||||
unpackAgentId(packetData + 1, &agentID);
|
||||
|
||||
// this is positional data from an agent
|
||||
// add or update the agent in our list
|
||||
agentList->addOrUpdateAgent(agentAddress, agentAddress, AGENT_TYPE_AVATAR, agentID);
|
||||
|
||||
// parse positional data from an agent
|
||||
agentList->updateAgentWithData(agentAddress, packetData, receivedBytes);
|
||||
|
||||
currentBufferPosition = broadcastPacket + 1;
|
||||
|
||||
// send back a packet with other active agent data to this agent
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL
|
||||
&& !socketMatch(agentAddress, agent->getActiveSocket())) {
|
||||
if (agent->getLinkedData() && !socketMatch(agentAddress, agent->getActiveSocket())) {
|
||||
currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*agent);
|
||||
}
|
||||
}
|
||||
|
||||
agentList->getAgentSocket().send(agentAddress,
|
||||
broadcastPacket,
|
||||
currentBufferPosition - broadcastPacket);
|
||||
agentList->getAgentSocket().send(agentAddress, broadcastPacket, currentBufferPosition - broadcastPacket);
|
||||
|
||||
break;
|
||||
case PACKET_HEADER_DOMAIN:
|
||||
|
|
|
@ -86,7 +86,6 @@ int main(int argc, const char * argv[])
|
|||
|
||||
unsigned char* currentBufferPos;
|
||||
unsigned char* startPointer;
|
||||
int packetBytesWithoutLeadingChar;
|
||||
|
||||
sockaddr_in agentPublicAddress, agentLocalAddress;
|
||||
agentLocalAddress.sin_family = AF_INET;
|
||||
|
@ -95,6 +94,8 @@ int main(int argc, const char * argv[])
|
|||
|
||||
agentList->startSilentAgentRemovalThread();
|
||||
|
||||
uint16_t packetAgentID = 0;
|
||||
|
||||
while (true) {
|
||||
if (agentList->getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes) &&
|
||||
(packetData[0] == PACKET_HEADER_DOMAIN_RFD || packetData[0] == PACKET_HEADER_DOMAIN_LIST_REQUEST)) {
|
||||
|
@ -117,8 +118,8 @@ int main(int argc, const char * argv[])
|
|||
if (agentList->addOrUpdateAgent((sockaddr*) &agentPublicAddress,
|
||||
(sockaddr*) &agentLocalAddress,
|
||||
agentType,
|
||||
agentList->getLastAgentId())) {
|
||||
agentList->increaseAgentId();
|
||||
agentList->getLastAgentID())) {
|
||||
agentList->increaseAgentID();
|
||||
}
|
||||
|
||||
currentBufferPos = broadcastPacket + 1;
|
||||
|
@ -143,13 +144,17 @@ int main(int argc, const char * argv[])
|
|||
}
|
||||
} else {
|
||||
double timeNow = usecTimestampNow();
|
||||
|
||||
// this is the agent, just update last receive to now
|
||||
agent->setLastHeardMicrostamp(timeNow);
|
||||
|
||||
// grab the ID for this agent so we can send it back with the packet
|
||||
packetAgentID = agent->getAgentId();
|
||||
|
||||
if (packetData[0] == PACKET_HEADER_DOMAIN_RFD
|
||||
&& memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) {
|
||||
agent->setWakeMicrostamp(timeNow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,11 +165,13 @@ int main(int argc, const char * argv[])
|
|||
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, soloAgent->second);
|
||||
}
|
||||
|
||||
if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) {
|
||||
agentList->getAgentSocket().send((sockaddr*) &agentPublicAddress,
|
||||
broadcastPacket,
|
||||
packetBytesWithoutLeadingChar + 1);
|
||||
}
|
||||
// add the agent ID to the end of the pointer
|
||||
currentBufferPos += packAgentId(currentBufferPos, packetAgentID);
|
||||
|
||||
// send the constructed list back to this agent
|
||||
agentList->getAgentSocket().send((sockaddr*) &agentPublicAddress,
|
||||
broadcastPacket,
|
||||
(currentBufferPos - startPointer) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
const int EVE_AGENT_LISTEN_PORT = 55441;
|
||||
|
||||
const float RANDOM_POSITION_MAX_DIMENSION = 5.0f;
|
||||
const float RANDOM_POSITION_MAX_DIMENSION = 10.0f;
|
||||
|
||||
const float DATA_SEND_INTERVAL_MSECS = 15;
|
||||
const float MIN_AUDIO_SEND_INTERVAL_SECS = 10;
|
||||
|
@ -25,6 +25,12 @@ const int MIN_ITERATIONS_BETWEEN_AUDIO_SENDS = (MIN_AUDIO_SEND_INTERVAL_SECS * 1
|
|||
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;
|
||||
|
||||
const int ITERATIONS_BEFORE_HAND_GRAB = 100;
|
||||
const int HAND_GRAB_DURATION_ITERATIONS = 50;
|
||||
const int HAND_TIMER_SLEEP_ITERATIONS = 50;
|
||||
|
||||
const float EVE_PELVIS_HEIGHT = 0.5f;
|
||||
|
||||
bool stopReceiveAgentDataThread;
|
||||
bool injectAudioThreadRunning = false;
|
||||
|
||||
|
@ -48,7 +54,7 @@ void *receiveAgentData(void *args) {
|
|||
// avatar mixer - this makes sure it won't be killed during silent agent removal
|
||||
avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER);
|
||||
|
||||
if (avatarMixer != NULL) {
|
||||
if (avatarMixer) {
|
||||
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||
}
|
||||
|
||||
|
@ -73,9 +79,9 @@ void *injectAudio(void *args) {
|
|||
// look for an audio mixer in our agent list
|
||||
Agent* audioMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER);
|
||||
|
||||
if (audioMixer != NULL) {
|
||||
if (audioMixer) {
|
||||
// until the audio mixer is setup for ping-reply, activate the public socket if it's not active
|
||||
if (audioMixer->getActiveSocket() == NULL) {
|
||||
if (!audioMixer->getActiveSocket()) {
|
||||
audioMixer->activatePublicSocket();
|
||||
}
|
||||
|
||||
|
@ -113,9 +119,9 @@ int main(int argc, const char* argv[]) {
|
|||
// move eve away from the origin
|
||||
// pick a random point inside a 10x10 grid
|
||||
|
||||
eve.setPosition(glm::vec3(randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION),
|
||||
1.33, // this should be the same as the avatar's pelvis standing height
|
||||
randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION)));
|
||||
eve.setPosition(glm::vec3(randFloatInRange(0, RANDOM_POSITION_MAX_DIMENSION),
|
||||
EVE_PELVIS_HEIGHT, // this should be the same as the avatar's pelvis standing height
|
||||
randFloatInRange(0, RANDOM_POSITION_MAX_DIMENSION)));
|
||||
|
||||
// face any instance of eve down the z-axis
|
||||
eve.setBodyYaw(0);
|
||||
|
@ -130,8 +136,6 @@ int main(int argc, const char* argv[]) {
|
|||
unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
||||
broadcastPacket[0] = PACKET_HEADER_HEAD_DATA;
|
||||
|
||||
int numBytesToSend = 0;
|
||||
|
||||
timeval thisSend;
|
||||
double numMicrosecondsSleep = 0;
|
||||
|
||||
|
@ -145,16 +149,19 @@ int main(int argc, const char* argv[]) {
|
|||
gettimeofday(&thisSend, NULL);
|
||||
|
||||
// find the current avatar mixer
|
||||
Agent *avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER);
|
||||
Agent* avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER);
|
||||
|
||||
// make sure we actually have an avatar mixer with an active socket
|
||||
if (avatarMixer != NULL && avatarMixer->getActiveSocket() != NULL) {
|
||||
if (agentList->getOwnerID() != UNKNOWN_AGENT_ID && avatarMixer && avatarMixer->getActiveSocket() != NULL) {
|
||||
unsigned char* packetPosition = broadcastPacket + sizeof(PACKET_HEADER);
|
||||
packetPosition += packAgentId(packetPosition, agentList->getOwnerID());
|
||||
|
||||
// use the getBroadcastData method in the AvatarData class to populate the broadcastPacket buffer
|
||||
numBytesToSend = eve.getBroadcastData((broadcastPacket + 1));
|
||||
packetPosition += eve.getBroadcastData(packetPosition);
|
||||
|
||||
// use the UDPSocket instance attached to our agent list to send avatar data to mixer
|
||||
agentList->getAgentSocket().send(avatarMixer->getActiveSocket(), broadcastPacket, numBytesToSend);
|
||||
}
|
||||
agentList->getAgentSocket().send(avatarMixer->getActiveSocket(), broadcastPacket, packetPosition - broadcastPacket);
|
||||
}
|
||||
|
||||
// temporarily disable Eve's audio sending until the file is actually available on EC2 box
|
||||
if (numIterationsLeftBeforeAudioSend == 0) {
|
||||
|
@ -175,13 +182,12 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
// simulate the effect of pressing and un-pressing the mouse button/pad
|
||||
handStateTimer++;
|
||||
if ( handStateTimer == 100 ) {
|
||||
|
||||
if (handStateTimer == ITERATIONS_BEFORE_HAND_GRAB) {
|
||||
eve.setHandState(1);
|
||||
}
|
||||
if ( handStateTimer == 150 ) {
|
||||
} else if (handStateTimer == ITERATIONS_BEFORE_HAND_GRAB + HAND_GRAB_DURATION_ITERATIONS) {
|
||||
eve.setHandState(0);
|
||||
}
|
||||
if ( handStateTimer >= 200 ) {
|
||||
} else if (handStateTimer >= ITERATIONS_BEFORE_HAND_GRAB + HAND_GRAB_DURATION_ITERATIONS + HAND_TIMER_SLEEP_ITERATIONS) {
|
||||
handStateTimer = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,10 +34,6 @@ const float BODY_ROLL_WHILE_TURNING = 0.1;
|
|||
const float LIN_VEL_DECAY = 5.0;
|
||||
const float MY_HAND_HOLDING_PULL = 0.2;
|
||||
const float YOUR_HAND_HOLDING_PULL = 1.0;
|
||||
|
||||
//const float BODY_SPRING_DEFAULT_TIGHTNESS = 20.0f;
|
||||
//const float BODY_SPRING_FORCE = 6.0f;
|
||||
|
||||
const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f;
|
||||
const float BODY_SPRING_FORCE = 300.0f;
|
||||
|
||||
|
@ -66,8 +62,8 @@ bool usingBigSphereCollisionTest = true;
|
|||
|
||||
char iris_texture_file[] = "resources/images/green_eye.png";
|
||||
|
||||
float chatMessageScale = 0.001;
|
||||
float chatMessageHeight = 0.4;
|
||||
float chatMessageScale = 0.0015;
|
||||
float chatMessageHeight = 0.45;
|
||||
|
||||
vector<unsigned char> iris_texture;
|
||||
unsigned int iris_texture_width = 512;
|
||||
|
@ -144,13 +140,14 @@ Avatar::Avatar(bool isMine) {
|
|||
_renderYaw = 0.0;
|
||||
_renderPitch = 0.0;
|
||||
_sphere = NULL;
|
||||
_interactingOther = NULL;
|
||||
_handHoldingPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||
_gravity = glm::vec3(0.0f, -1.0f, 0.0f); // default
|
||||
|
||||
initializeSkeleton();
|
||||
|
||||
_avatarTouch.setReachableRadius(0.6);
|
||||
|
||||
if (iris_texture.size() == 0) {
|
||||
switchToResourcesParentIfRequired();
|
||||
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
|
||||
|
@ -295,7 +292,6 @@ void Avatar::UpdateGyros(float frametime, SerialInterface* serialInterface, glm:
|
|||
if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) {
|
||||
addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float Avatar::getAbsoluteHeadYaw() const {
|
||||
|
@ -316,28 +312,31 @@ void Avatar::setLeanSideways(float dist){
|
|||
_head.leanSideways = dist;
|
||||
}
|
||||
|
||||
void Avatar::setMousePressed(bool d) {
|
||||
_mousePressed = d;
|
||||
void Avatar::setMousePressed(bool mousePressed) {
|
||||
_mousePressed = mousePressed;
|
||||
}
|
||||
|
||||
|
||||
bool Avatar::getIsNearInteractingOther() {
|
||||
return _avatarTouch.getAbleToReachOtherAvatar();
|
||||
}
|
||||
|
||||
|
||||
void Avatar::simulate(float deltaTime) {
|
||||
|
||||
|
||||
// update balls
|
||||
if (_balls) { _balls->simulate(deltaTime); }
|
||||
|
||||
// update avatar skeleton
|
||||
updateSkeleton();
|
||||
|
||||
//detect and respond to collisions with other avatars...
|
||||
if (_isMine) {
|
||||
updateAvatarCollisions(deltaTime);
|
||||
}
|
||||
|
||||
//update the movement of the hand and process handshaking with other avatars...
|
||||
updateHandMovementAndTouching(deltaTime);
|
||||
|
||||
|
||||
_avatarTouch.simulate(deltaTime);
|
||||
|
||||
// apply gravity and collision with the ground/floor
|
||||
if (USING_AVATAR_GRAVITY) {
|
||||
|
@ -381,7 +380,7 @@ void Avatar::simulate(float deltaTime) {
|
|||
|
||||
// decay body rotation momentum
|
||||
float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime;
|
||||
if ( bodySpinMomentum < 0.0f ) { bodySpinMomentum = 0.0f; }
|
||||
if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; }
|
||||
_bodyPitchDelta *= bodySpinMomentum;
|
||||
_bodyYawDelta *= bodySpinMomentum;
|
||||
_bodyRollDelta *= bodySpinMomentum;
|
||||
|
@ -430,8 +429,6 @@ void Avatar::simulate(float deltaTime) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//update the movement of the hand and process handshaking with other avatars...
|
||||
void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||
|
||||
// reset hand and arm positions according to hand movement
|
||||
|
@ -441,108 +438,72 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
|||
+ _orientation.getFront() * -_movedHandOffset.y * 1.0f;
|
||||
|
||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement;
|
||||
|
||||
if (_isMine) {
|
||||
_handState = _mousePressed;
|
||||
}
|
||||
|
||||
//reset these for the next go-round
|
||||
_avatarTouch.setAbleToReachOtherAvatar (false);
|
||||
_avatarTouch.setHandsCloseEnoughToGrasp(false);
|
||||
|
||||
// if the avatar being simulated is mine, then loop through
|
||||
// all the other avatars for potential interactions...
|
||||
|
||||
if (_isMine)
|
||||
{
|
||||
// Reset detector for nearest avatar
|
||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||
_avatarTouch.setMyBodyPosition(_position);
|
||||
|
||||
Avatar * _interactingOther = NULL;
|
||||
float closestDistance = std::numeric_limits<float>::max();
|
||||
|
||||
//loop through all the other avatars for potential interactions...
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
// check for collisions with other avatars and respond
|
||||
updateCollisionWithOtherAvatar(otherAvatar, deltaTime );
|
||||
|
||||
// test other avatar hand position for proximity
|
||||
glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position);
|
||||
v -= otherAvatar->getJointPosition(AVATAR_JOINT_RIGHT_SHOULDER);
|
||||
/*
|
||||
// Test: Show angle between your fwd vector and nearest avatar
|
||||
glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) -
|
||||
getJointPosition(AVATAR_JOINT_PELVIS);
|
||||
glm::vec3 myForwardVector = _orientation.getFront();
|
||||
printLog("Angle between: %f\n", angleBetween(&vectorBetweenUs, &myForwardVector));
|
||||
*/
|
||||
|
||||
// test whether shoulders are close enough to allow for reaching to touch hands
|
||||
glm::vec3 v(_position - otherAvatar->_position);
|
||||
float distance = glm::length(v);
|
||||
if (distance < _distanceToNearestAvatar) {_distanceToNearestAvatar = distance;}
|
||||
|
||||
if (distance < _maxArmLength + _maxArmLength) {
|
||||
|
||||
if (distance < closestDistance) {
|
||||
closestDistance = distance;
|
||||
_interactingOther = otherAvatar;
|
||||
|
||||
if (! _avatarTouch.getAbleToReachOtherAvatar()) {
|
||||
//initialize _handHolding
|
||||
_handHoldingPosition = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position;
|
||||
_avatarTouch.setAbleToReachOtherAvatar(true);
|
||||
}
|
||||
|
||||
glm::vec3 vectorBetweenHands(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||
vectorBetweenHands -= otherAvatar->getJointPosition(AVATAR_JOINT_RIGHT_FINGERTIPS);
|
||||
float distanceBetweenHands = glm::length(vectorBetweenHands);
|
||||
|
||||
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) {
|
||||
_avatarTouch.setHandsCloseEnoughToGrasp(true);
|
||||
}
|
||||
|
||||
// if I am holding hands with another avatar, a force is applied
|
||||
if ((_handState == 1) || (_interactingOther->_handState == 1)) {
|
||||
|
||||
// if the hands are close enough to grasp...
|
||||
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP)
|
||||
{
|
||||
// apply the forces...
|
||||
glm::vec3 vectorToOtherHand = _interactingOther->_handPosition - _handHoldingPosition;
|
||||
glm::vec3 vectorToMyHand = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - _handHoldingPosition;
|
||||
|
||||
_handHoldingPosition += vectorToOtherHand * YOUR_HAND_HOLDING_PULL;
|
||||
_handHoldingPosition += vectorToMyHand * MY_HAND_HOLDING_PULL;
|
||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handHoldingPosition;
|
||||
|
||||
// apply a force to the avatar body
|
||||
if (glm::length(vectorToOtherHand) > _maxArmLength * 0.9) {
|
||||
_velocity += vectorToOtherHand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the vector we send for hand position to other people to be our right hand
|
||||
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||
|
||||
if (_interactingOther) {
|
||||
_avatarTouch.setYourBodyPosition(_interactingOther->_position);
|
||||
_avatarTouch.setYourHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
|
||||
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
||||
}
|
||||
|
||||
}//if (_isMine)
|
||||
|
||||
//constrain right arm length and re-adjust elbow position as it bends
|
||||
// NOTE - the following must be called on all avatars - not just _isMine
|
||||
updateArmIKAndConstraints(deltaTime);
|
||||
|
||||
// set hand positions for _avatarTouch.setMyHandPosition AFTER calling updateArmIKAndConstraints
|
||||
if (_interactingOther) {
|
||||
if (_isMine) {
|
||||
_avatarTouch.setMyHandPosition (_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||
_avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||
_avatarTouch.setMyHandState (_handState);
|
||||
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
||||
_avatarTouch.simulate(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_avatarTouch.getAbleToReachOtherAvatar() ) {
|
||||
_interactingOther = NULL;
|
||||
if (_isMine) {
|
||||
//Set the vector we send for hand position to other people to be our right hand
|
||||
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||
|
||||
if (_mousePressed) {
|
||||
_handState = 1;
|
||||
} else {
|
||||
_handState = 0;
|
||||
}
|
||||
|
||||
_avatarTouch.setMyHandState(_handState);
|
||||
|
||||
if (_handState == 1) {
|
||||
_avatarTouch.setMyHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Avatar::updateHead(float deltaTime) {
|
||||
|
||||
//apply the head lean values to the springy position...
|
||||
if (fabs( _head.leanSideways + _head.leanForward ) > 0.0f) {
|
||||
if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) {
|
||||
glm::vec3 headLean =
|
||||
_orientation.getRight() * _head.leanSideways +
|
||||
_orientation.getFront() * _head.leanForward;
|
||||
|
@ -560,7 +521,7 @@ void Avatar::updateHead(float deltaTime) {
|
|||
if (_head.noise) {
|
||||
// Move toward new target
|
||||
_headPitch += (_head.pitchTarget - _headPitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ;
|
||||
_headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime);
|
||||
_headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime);
|
||||
_headRoll *= 1.f - (DECAY * deltaTime);
|
||||
}
|
||||
|
||||
|
@ -690,69 +651,99 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d
|
|||
}
|
||||
|
||||
|
||||
//detect collisions with other avatars and respond
|
||||
void Avatar::updateCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
|
||||
|
||||
// check if the bounding spheres of the two avatars are colliding
|
||||
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
|
||||
if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
|
||||
|
||||
void Avatar::updateAvatarCollisions(float deltaTime) {
|
||||
|
||||
// Reset detector for nearest avatar
|
||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||
|
||||
//loop through all the other avatars for potential interactions...
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
// check if the bounding spheres of the two avatars are colliding
|
||||
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
|
||||
if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
|
||||
//apply forces from collision
|
||||
applyCollisionWithOtherAvatar(otherAvatar, deltaTime);
|
||||
}
|
||||
|
||||
// test other avatar hand position for proximity
|
||||
glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position);
|
||||
v -= otherAvatar->getPosition();
|
||||
|
||||
float distance = glm::length(v);
|
||||
if (distance < _distanceToNearestAvatar) {
|
||||
_distanceToNearestAvatar = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//detect collisions with other avatars and respond
|
||||
void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
|
||||
|
||||
float bodyMomentum = 1.0f;
|
||||
glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// loop through the joints of each avatar to check for every possible collision
|
||||
for (int b=1; b<NUM_AVATAR_JOINTS; b++) {
|
||||
if (_joint[b].isCollidable) {
|
||||
// loop through the joints of each avatar to check for every possible collision
|
||||
for (int b=1; b<NUM_AVATAR_JOINTS; b++) {
|
||||
if (_joint[b].isCollidable) {
|
||||
|
||||
for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) {
|
||||
if (otherAvatar->_joint[o].isCollidable) {
|
||||
for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) {
|
||||
if (otherAvatar->_joint[o].isCollidable) {
|
||||
|
||||
glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition);
|
||||
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
|
||||
|
||||
glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition);
|
||||
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
|
||||
|
||||
if (distanceBetweenJoints > 0.0 ) { // to avoid divide by zero
|
||||
float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius;
|
||||
if (distanceBetweenJoints > 0.0) { // to avoid divide by zero
|
||||
float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius;
|
||||
|
||||
// check for collision
|
||||
if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
||||
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
|
||||
// check for collision
|
||||
if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
||||
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
|
||||
|
||||
// push balls away from each other and apply friction
|
||||
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime;
|
||||
|
||||
float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime;
|
||||
if (ballMomentum < 0.0 ) { ballMomentum = 0.0;}
|
||||
|
||||
_joint[b].springyVelocity += ballPushForce;
|
||||
otherAvatar->_joint[o].springyVelocity -= ballPushForce;
|
||||
|
||||
_joint[b].springyVelocity *= ballMomentum;
|
||||
otherAvatar->_joint[o].springyVelocity *= ballMomentum;
|
||||
|
||||
// accumulate forces and frictions to apply to the velocities of avatar bodies
|
||||
bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime;
|
||||
bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime;
|
||||
if (bodyMomentum < 0.0 ) { bodyMomentum = 0.0;}
|
||||
|
||||
}// check for collision
|
||||
} // to avoid divide by zero
|
||||
} // o loop
|
||||
} // collidable
|
||||
} // b loop
|
||||
} // collidable
|
||||
|
||||
|
||||
//apply forces and frictions on the bodies of both avatars
|
||||
_velocity += bodyPushForce;
|
||||
otherAvatar->_velocity -= bodyPushForce;
|
||||
_velocity *= bodyMomentum;
|
||||
otherAvatar->_velocity *= bodyMomentum;
|
||||
|
||||
} // bounding sphere collision
|
||||
} //method
|
||||
// push balls away from each other and apply friction
|
||||
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime;
|
||||
|
||||
float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime;
|
||||
if (ballMomentum < 0.0) { ballMomentum = 0.0;}
|
||||
|
||||
_joint[b].springyVelocity += ballPushForce;
|
||||
otherAvatar->_joint[o].springyVelocity -= ballPushForce;
|
||||
|
||||
_joint[b].springyVelocity *= ballMomentum;
|
||||
otherAvatar->_joint[o].springyVelocity *= ballMomentum;
|
||||
|
||||
// accumulate forces and frictions to apply to the velocities of avatar bodies
|
||||
bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime;
|
||||
bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime;
|
||||
if (bodyMomentum < 0.0) { bodyMomentum = 0.0;}
|
||||
|
||||
}// check for collision
|
||||
} // to avoid divide by zero
|
||||
} // o loop
|
||||
} // collidable
|
||||
} // b loop
|
||||
} // collidable
|
||||
|
||||
|
||||
//apply forces and frictions on the bodies of both avatars
|
||||
_velocity += bodyPushForce;
|
||||
otherAvatar->_velocity -= bodyPushForce;
|
||||
_velocity *= bodyMomentum;
|
||||
otherAvatar->_velocity *= bodyMomentum;
|
||||
}
|
||||
|
||||
|
||||
void Avatar::setDisplayingHead(bool displayingHead ) {
|
||||
|
||||
void Avatar::setDisplayingHead(bool displayingHead) {
|
||||
_displayingHead = displayingHead;
|
||||
}
|
||||
|
||||
|
@ -768,28 +759,28 @@ void Avatar::setGravity(glm::vec3 gravity) {
|
|||
}
|
||||
|
||||
|
||||
void Avatar::render(bool lookingInMirror) {
|
||||
void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) {
|
||||
|
||||
// render a simple round on the ground projected down from the avatar's position
|
||||
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f ), 0.1f, 0.2f );
|
||||
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), 0.1f, 0.2f);
|
||||
|
||||
/*
|
||||
// show avatar position
|
||||
glColor4f(0.5f, 0.5f, 0.5f, 0.6 );
|
||||
glColor4f(0.5f, 0.5f, 0.5f, 0.6);
|
||||
glPushMatrix();
|
||||
glTranslatef(_position.x, _position.y, _position.z);
|
||||
glScalef(0.03, 0.03, 0.03 );
|
||||
glutSolidSphere(1, 10, 10 );
|
||||
glScalef(0.03, 0.03, 0.03);
|
||||
glutSolidSphere(1, 10, 10);
|
||||
glPopMatrix();
|
||||
*/
|
||||
|
||||
if (usingBigSphereCollisionTest ) {
|
||||
if (usingBigSphereCollisionTest) {
|
||||
// show TEST big sphere
|
||||
glColor4f(0.5f, 0.6f, 0.8f, 0.7 );
|
||||
glColor4f(0.5f, 0.6f, 0.8f, 0.7);
|
||||
glPushMatrix();
|
||||
glTranslatef(_TEST_bigSpherePosition.x, _TEST_bigSpherePosition.y, _TEST_bigSpherePosition.z);
|
||||
glScalef(_TEST_bigSphereRadius, _TEST_bigSphereRadius, _TEST_bigSphereRadius );
|
||||
glutSolidSphere(1, 20, 20 );
|
||||
glScalef(_TEST_bigSphereRadius, _TEST_bigSphereRadius, _TEST_bigSphereRadius);
|
||||
glutSolidSphere(1, 20, 20);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -802,8 +793,8 @@ void Avatar::render(bool lookingInMirror) {
|
|||
}
|
||||
|
||||
// if this is my avatar, then render my interactions with the other avatar
|
||||
if (_isMine ) {
|
||||
_avatarTouch.render();
|
||||
if (_isMine) {
|
||||
_avatarTouch.render(cameraPosition);
|
||||
}
|
||||
|
||||
// Render the balls
|
||||
|
@ -863,7 +854,7 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
// show head orientation
|
||||
//renderOrientationDirections(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, _joint[ AVATAR_JOINT_HEAD_BASE ].orientation, 0.2f );
|
||||
//renderOrientationDirections(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, _joint[ AVATAR_JOINT_HEAD_BASE ].orientation, 0.2f);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
|
@ -891,7 +882,7 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
//glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
|
||||
//glRotatef(_bodyRoll - _headRoll, 0, 0, 1);
|
||||
// don't let body pitch and roll affect the head..
|
||||
glRotatef( _headPitch, 1, 0, 0);
|
||||
glRotatef(_headPitch, 1, 0, 0);
|
||||
glRotatef(-_headRoll, 0, 0, 1);
|
||||
} else {
|
||||
glRotatef(_bodyYaw + _headYaw, 0, 1, 0);
|
||||
|
@ -1028,7 +1019,7 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
void Avatar::setHandMovementValues(glm::vec3 handOffset ) {
|
||||
void Avatar::setHandMovementValues(glm::vec3 handOffset) {
|
||||
_movedHandOffset = handOffset;
|
||||
}
|
||||
|
||||
|
@ -1041,11 +1032,11 @@ void Avatar::initializeSkeleton() {
|
|||
for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
|
||||
_joint[b].isCollidable = true;
|
||||
_joint[b].parent = AVATAR_JOINT_NULL;
|
||||
_joint[b].position = glm::vec3(0.0, 0.0, 0.0 );
|
||||
_joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0 );
|
||||
_joint[b].springyPosition = glm::vec3(0.0, 0.0, 0.0 );
|
||||
_joint[b].springyVelocity = glm::vec3(0.0, 0.0, 0.0 );
|
||||
_joint[b].rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f );
|
||||
_joint[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||
_joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0);
|
||||
_joint[b].springyPosition = glm::vec3(0.0, 0.0, 0.0);
|
||||
_joint[b].springyVelocity = glm::vec3(0.0, 0.0, 0.0);
|
||||
_joint[b].rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
_joint[b].yaw = 0.0;
|
||||
_joint[b].pitch = 0.0;
|
||||
_joint[b].roll = 0.0;
|
||||
|
@ -1082,19 +1073,19 @@ void Avatar::initializeSkeleton() {
|
|||
_joint[ AVATAR_JOINT_RIGHT_TOES ].parent = AVATAR_JOINT_RIGHT_HEEL;
|
||||
|
||||
// specify the default pose position
|
||||
_joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 );
|
||||
_joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.0 );
|
||||
_joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.1, -0.01 );
|
||||
_joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 );
|
||||
_joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3(-0.06, 0.04, -0.01 );
|
||||
_joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3(-0.03, 0.0, -0.01 );
|
||||
_joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 );
|
||||
_joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 );
|
||||
_joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, -0.01 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, -0.01 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 );
|
||||
_joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 );
|
||||
_joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.0 );
|
||||
_joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.1, -0.01 );
|
||||
_joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 );
|
||||
_joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, -0.01 );
|
||||
_joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.03, 0.0, -0.01 );
|
||||
_joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 );
|
||||
_joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 );
|
||||
_joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, -0.01 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, -0.01 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 );
|
||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 );
|
||||
_joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.04, 0.0, -0.02 );
|
||||
|
@ -1189,15 +1180,18 @@ void Avatar::initializeSkeleton() {
|
|||
_joint[ AVATAR_JOINT_HEAD_BASE ].length +
|
||||
_joint[ AVATAR_JOINT_HEAD_BASE ].radius
|
||||
);
|
||||
//printf( "_height = %f\n", _height );
|
||||
//printf("_height = %f\n", _height);
|
||||
|
||||
// generate world positions
|
||||
updateSkeleton();
|
||||
|
||||
//set spring positions to be in the skeleton bone positions
|
||||
initializeBodySprings();
|
||||
}
|
||||
|
||||
void Avatar::calculateBoneLengths() {
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
_joint[b].length = glm::length( _joint[b].defaultPosePosition );
|
||||
_joint[b].length = glm::length(_joint[b].defaultPosePosition);
|
||||
}
|
||||
|
||||
_maxArmLength
|
||||
|
@ -1210,35 +1204,35 @@ void Avatar::updateSkeleton() {
|
|||
|
||||
// rotate body...
|
||||
_orientation.setToIdentity();
|
||||
_orientation.yaw ( _bodyYaw );
|
||||
_orientation.pitch( _bodyPitch );
|
||||
_orientation.roll ( _bodyRoll );
|
||||
_orientation.yaw (_bodyYaw );
|
||||
_orientation.pitch(_bodyPitch);
|
||||
_orientation.roll (_bodyRoll );
|
||||
|
||||
// calculate positions of all bones by traversing the skeleton tree:
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
if ( _joint[b].parent == AVATAR_JOINT_NULL ) {
|
||||
_joint[b].orientation.set( _orientation );
|
||||
if (_joint[b].parent == AVATAR_JOINT_NULL) {
|
||||
_joint[b].orientation.set(_orientation);
|
||||
_joint[b].position = _position;
|
||||
}
|
||||
else {
|
||||
_joint[b].orientation.set( _joint[ _joint[b].parent ].orientation );
|
||||
_joint[b].orientation.set(_joint[ _joint[b].parent ].orientation);
|
||||
_joint[b].position = _joint[ _joint[b].parent ].position;
|
||||
}
|
||||
|
||||
// if this is not my avatar, then hand position comes from transmitted data
|
||||
if ( ! _isMine ) {
|
||||
if (! _isMine) {
|
||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition;
|
||||
}
|
||||
|
||||
// the following will be replaced by a proper rotation...close
|
||||
float xx = glm::dot( _joint[b].defaultPosePosition, _joint[b].orientation.getRight() );
|
||||
float yy = glm::dot( _joint[b].defaultPosePosition, _joint[b].orientation.getUp () );
|
||||
float zz = glm::dot( _joint[b].defaultPosePosition, _joint[b].orientation.getFront() );
|
||||
float xx = glm::dot(_joint[b].defaultPosePosition, _joint[b].orientation.getRight());
|
||||
float yy = glm::dot(_joint[b].defaultPosePosition, _joint[b].orientation.getUp ());
|
||||
float zz = glm::dot(_joint[b].defaultPosePosition, _joint[b].orientation.getFront());
|
||||
|
||||
glm::vec3 rotatedJointVector( xx, yy, zz );
|
||||
glm::vec3 rotatedJointVector(xx, yy, zz);
|
||||
|
||||
//glm::vec3 myEuler ( 0.0f, 0.0f, 0.0f );
|
||||
//glm::quat myQuat ( myEuler );
|
||||
//glm::vec3 myEuler (0.0f, 0.0f, 0.0f);
|
||||
//glm::quat myQuat (myEuler);
|
||||
|
||||
_joint[b].position += rotatedJointVector;
|
||||
}
|
||||
|
@ -1247,31 +1241,31 @@ void Avatar::updateSkeleton() {
|
|||
void Avatar::initializeBodySprings() {
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
_joint[b].springyPosition = _joint[b].position;
|
||||
_joint[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::updateBodySprings( float deltaTime ) {
|
||||
void Avatar::updateBodySprings(float deltaTime) {
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
glm::vec3 springVector( _joint[b].springyPosition );
|
||||
glm::vec3 springVector(_joint[b].springyPosition);
|
||||
|
||||
if ( _joint[b].parent == AVATAR_JOINT_NULL ) {
|
||||
if (_joint[b].parent == AVATAR_JOINT_NULL) {
|
||||
springVector -= _position;
|
||||
}
|
||||
else {
|
||||
springVector -= _joint[ _joint[b].parent ].springyPosition;
|
||||
}
|
||||
|
||||
float length = glm::length( springVector );
|
||||
float length = glm::length(springVector);
|
||||
|
||||
if ( length > 0.0f ) {
|
||||
if (length > 0.0f) {
|
||||
glm::vec3 springDirection = springVector / length;
|
||||
|
||||
float force = (length - _joint[b].length) * BODY_SPRING_FORCE * deltaTime;
|
||||
|
||||
_joint[b].springyVelocity -= springDirection * force;
|
||||
|
||||
if ( _joint[b].parent != AVATAR_JOINT_NULL ) {
|
||||
if (_joint[b].parent != AVATAR_JOINT_NULL) {
|
||||
_joint[_joint[b].parent].springyVelocity += springDirection * force;
|
||||
}
|
||||
}
|
||||
|
@ -1284,7 +1278,7 @@ void Avatar::updateBodySprings( float deltaTime ) {
|
|||
_joint[b].springyVelocity *= decay;
|
||||
}
|
||||
else {
|
||||
_joint[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
_joint[b].springyPosition += _joint[b].springyVelocity * deltaTime;
|
||||
|
@ -1303,17 +1297,17 @@ const glm::vec3& Avatar::getHeadPosition() const {
|
|||
|
||||
|
||||
|
||||
void Avatar::updateArmIKAndConstraints( float deltaTime ) {
|
||||
void Avatar::updateArmIKAndConstraints(float deltaTime) {
|
||||
|
||||
// determine the arm vector
|
||||
glm::vec3 armVector = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position;
|
||||
armVector -= _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position;
|
||||
|
||||
// test to see if right hand is being dragged beyond maximum arm length
|
||||
float distance = glm::length( armVector );
|
||||
float distance = glm::length(armVector);
|
||||
|
||||
// don't let right hand get dragged beyond maximum arm length...
|
||||
if ( distance > _maxArmLength ) {
|
||||
if (distance > _maxArmLength) {
|
||||
// reset right hand to be constrained to maximum arm length
|
||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position;
|
||||
glm::vec3 armNormal = armVector / distance;
|
||||
|
@ -1328,13 +1322,13 @@ void Avatar::updateArmIKAndConstraints( float deltaTime ) {
|
|||
glm::vec3 newElbowPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position;
|
||||
newElbowPosition += armVector * ONE_HALF;
|
||||
|
||||
glm::vec3 perpendicular = glm::cross( _orientation.getFront(), armVector );
|
||||
glm::vec3 perpendicular = glm::cross(_orientation.getFront(), armVector);
|
||||
|
||||
newElbowPosition += perpendicular * ( 1.0f - ( _maxArmLength / distance ) ) * ONE_HALF;
|
||||
newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF;
|
||||
_joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition;
|
||||
|
||||
// set wrist position
|
||||
glm::vec3 vv( _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position );
|
||||
glm::vec3 vv(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||
vv -= _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position;
|
||||
glm::vec3 newWristPosition = _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position + vv * 0.7f;
|
||||
_joint[ AVATAR_JOINT_RIGHT_WRIST ].position = newWristPosition;
|
||||
|
@ -1346,53 +1340,53 @@ void Avatar::renderBody() {
|
|||
// Render joint positions as spheres
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
|
||||
if ( b != AVATAR_JOINT_HEAD_BASE ) { // the head is rendered as a special case in "renderHead"
|
||||
if (b != AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case in "renderHead"
|
||||
|
||||
//render bone orientation
|
||||
//renderOrientationDirections( _joint[b].springyPosition, _joint[b].orientation, _joint[b].radius * 2.0 );
|
||||
//renderOrientationDirections(_joint[b].springyPosition, _joint[b].orientation, _joint[b].radius * 2.0);
|
||||
|
||||
if ( _usingBodySprings ) {
|
||||
glColor3fv( skinColor );
|
||||
if (_usingBodySprings) {
|
||||
glColor3fv(skinColor);
|
||||
glPushMatrix();
|
||||
glTranslatef( _joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z );
|
||||
glutSolidSphere( _joint[b].radius, 20.0f, 20.0f );
|
||||
glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z);
|
||||
glutSolidSphere(_joint[b].radius, 20.0f, 20.0f);
|
||||
glPopMatrix();
|
||||
}
|
||||
else {
|
||||
glColor3fv( skinColor );
|
||||
glColor3fv(skinColor);
|
||||
glPushMatrix();
|
||||
glTranslatef( _joint[b].position.x, _joint[b].position.y, _joint[b].position.z );
|
||||
glutSolidSphere( _joint[b].radius, 20.0f, 20.0f );
|
||||
glTranslatef(_joint[b].position.x, _joint[b].position.y, _joint[b].position.z);
|
||||
glutSolidSphere(_joint[b].radius, 20.0f, 20.0f);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render lines connecting the joint positions
|
||||
if ( _usingBodySprings ) {
|
||||
glColor3f( 0.4f, 0.5f, 0.6f );
|
||||
if (_usingBodySprings) {
|
||||
glColor3f(0.4f, 0.5f, 0.6f);
|
||||
glLineWidth(3.0);
|
||||
|
||||
for (int b = 1; b < NUM_AVATAR_JOINTS; b++) {
|
||||
if ( _joint[b].parent != AVATAR_JOINT_NULL )
|
||||
if ( b != AVATAR_JOINT_HEAD_TOP ) {
|
||||
glBegin( GL_LINE_STRIP );
|
||||
glVertex3fv( &_joint[ _joint[ b ].parent ].springyPosition.x );
|
||||
glVertex3fv( &_joint[ b ].springyPosition.x );
|
||||
if (_joint[b].parent != AVATAR_JOINT_NULL)
|
||||
if (b != AVATAR_JOINT_HEAD_TOP) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(&_joint[ _joint[ b ].parent ].springyPosition.x);
|
||||
glVertex3fv(&_joint[ b ].springyPosition.x);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
else {
|
||||
glColor3fv( skinColor );
|
||||
glColor3fv(skinColor);
|
||||
glLineWidth(3.0);
|
||||
|
||||
for (int b = 1; b < NUM_AVATAR_JOINTS; b++) {
|
||||
if ( _joint[b].parent != AVATAR_JOINT_NULL ) {
|
||||
glBegin( GL_LINE_STRIP );
|
||||
glVertex3fv( &_joint[ _joint[ b ].parent ].position.x );
|
||||
glVertex3fv( &_joint[ b ].position.x);
|
||||
if (_joint[b].parent != AVATAR_JOINT_NULL) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(&_joint[ _joint[ b ].parent ].position.x);
|
||||
glVertex3fv(&_joint[ b ].position.x);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
@ -1455,9 +1449,7 @@ void Avatar::processTransmitterData(unsigned char* packetData, int numBytes) {
|
|||
//printLog("Packet: [%s]\n", packetData);
|
||||
//printLog("Version: %s\n", device);
|
||||
|
||||
_transmitterInitialReading = glm::vec3( rot3,
|
||||
rot2,
|
||||
rot1 );
|
||||
_transmitterInitialReading = glm::vec3(rot3, rot2, rot1);
|
||||
}
|
||||
const int TRANSMITTER_COUNT = 100;
|
||||
if (_transmitterPackets % TRANSMITTER_COUNT == 0) {
|
||||
|
@ -1465,7 +1457,7 @@ void Avatar::processTransmitterData(unsigned char* packetData, int numBytes) {
|
|||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
double msecsElapsed = diffclock(&_transmitterTimer, &now);
|
||||
_transmitterHz = static_cast<float>( (double)TRANSMITTER_COUNT / (msecsElapsed / 1000.0) );
|
||||
_transmitterHz = static_cast<float>((double)TRANSMITTER_COUNT / (msecsElapsed / 1000.0));
|
||||
_transmitterTimer = now;
|
||||
printLog("Transmitter Hz: %3.1f\n", _transmitterHz);
|
||||
}
|
||||
|
@ -1482,12 +1474,12 @@ void Avatar::processTransmitterData(unsigned char* packetData, int numBytes) {
|
|||
glm::vec3 angularVelocity;
|
||||
if (deviceType != DEVICE_GLASS) {
|
||||
angularVelocity = glm::vec3(glm::degrees(gyrZ), glm::degrees(-gyrX), glm::degrees(gyrY));
|
||||
setHeadFromGyros( &eulerAngles, &angularVelocity,
|
||||
setHeadFromGyros(&eulerAngles, &angularVelocity,
|
||||
(_transmitterHz == 0.f) ? 0.f : 1.f / _transmitterHz, 1.0);
|
||||
|
||||
} else {
|
||||
angularVelocity = glm::vec3(glm::degrees(gyrY), glm::degrees(-gyrX), glm::degrees(-gyrZ));
|
||||
setHeadFromGyros( &eulerAngles, &angularVelocity,
|
||||
setHeadFromGyros(&eulerAngles, &angularVelocity,
|
||||
(_transmitterHz == 0.f) ? 0.f : 1.f / _transmitterHz, 1000.0);
|
||||
|
||||
}
|
||||
|
|
|
@ -101,13 +101,6 @@ public:
|
|||
void setLeanForward(float dist);
|
||||
void setLeanSideways(float dist);
|
||||
void addLean(float x, float z);
|
||||
|
||||
/*
|
||||
const glm::vec3& getHeadRightDirection() const { return _orientation.getRight(); };
|
||||
const glm::vec3& getHeadUpDirection () const { return _orientation.getUp (); };
|
||||
const glm::vec3& getHeadFrontDirection() const { return _orientation.getFront(); };
|
||||
*/
|
||||
|
||||
const glm::vec3& getHeadPosition() const ;
|
||||
const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].position; };
|
||||
const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); };
|
||||
|
@ -117,8 +110,8 @@ public:
|
|||
|
||||
AvatarMode getMode();
|
||||
|
||||
void setMousePressed( bool pressed );
|
||||
void render(bool lookingInMirror);
|
||||
void setMousePressed(bool pressed);
|
||||
void render(bool lookingInMirrorm, glm::vec3 cameraPosition);
|
||||
void renderBody();
|
||||
void renderHead(bool lookingInMirror);
|
||||
void simulate(float);
|
||||
|
@ -241,7 +234,6 @@ private:
|
|||
float _transmitterHz;
|
||||
int _transmitterPackets;
|
||||
glm::vec3 _transmitterInitialReading;
|
||||
Avatar* _interactingOther;
|
||||
float _pelvisStandingHeight;
|
||||
float _height;
|
||||
Balls* _balls;
|
||||
|
@ -260,8 +252,9 @@ private:
|
|||
void readSensors();
|
||||
void updateHead( float deltaTime );
|
||||
void updateHandMovementAndTouching(float deltaTime);
|
||||
void updateAvatarCollisions(float deltaTime);
|
||||
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
|
||||
void updateCollisionWithOtherAvatar( Avatar * other, float deltaTime );
|
||||
void applyCollisionWithOtherAvatar( Avatar * other, float deltaTime );
|
||||
void setHeadFromGyros(glm::vec3 * eulerAngles, glm::vec3 * angularVelocity, float deltaTime, float smoothingTime);
|
||||
void setHeadSpringScale(float s) { _head.returnSpringScale = s; }
|
||||
};
|
||||
|
|
|
@ -16,13 +16,4 @@ AvatarRenderer::AvatarRenderer() {
|
|||
|
||||
// this method renders the avatar
|
||||
void AvatarRenderer::render(Avatar *avatar, bool lookingInMirror) {
|
||||
/*
|
||||
// show avatar position
|
||||
glColor4f( 0.5f, 0.5f, 0.5f, 0.6 );
|
||||
glPushMatrix();
|
||||
glTranslatef(avatar->_position.x, avatar->_position.y, avatar->_position.z);
|
||||
glScalef( 0.03, 0.03, 0.03 );
|
||||
glutSolidSphere( 1, 10, 10 );
|
||||
glPopMatrix();
|
||||
*/
|
||||
}
|
|
@ -10,94 +10,130 @@
|
|||
#include <SharedUtil.h>
|
||||
#include "AvatarTouch.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "Util.h"
|
||||
|
||||
const float THREAD_RADIUS = 0.012;
|
||||
|
||||
AvatarTouch::AvatarTouch() {
|
||||
|
||||
_myHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_yourHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_myHandPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
_yourHandPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
_myBodyPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
_yourBodyPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
_myHandState = 0;
|
||||
_yourHandState = 0;
|
||||
_yourHandState = 0;
|
||||
_reachableRadius = 0.0f;
|
||||
|
||||
_canReachToOtherAvatar = false;
|
||||
_handsCloseEnoughToGrasp = false;
|
||||
|
||||
for (int p=0; p<NUM_POINTS; p++) {
|
||||
_point[p] = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_point[p] = glm::vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarTouch::setMyHandPosition( glm::vec3 position ) {
|
||||
void AvatarTouch::setMyHandPosition(glm::vec3 position) {
|
||||
_myHandPosition = position;
|
||||
}
|
||||
|
||||
void AvatarTouch::setYourHandPosition( glm::vec3 position ) {
|
||||
void AvatarTouch::setYourHandPosition(glm::vec3 position) {
|
||||
_yourHandPosition = position;
|
||||
}
|
||||
|
||||
void AvatarTouch::setMyHandState( int state ) {
|
||||
void AvatarTouch::setMyBodyPosition(glm::vec3 position) {
|
||||
_myBodyPosition = position;
|
||||
}
|
||||
|
||||
void AvatarTouch::setYourBodyPosition(glm::vec3 position) {
|
||||
_yourBodyPosition = position;
|
||||
}
|
||||
|
||||
void AvatarTouch::setMyHandState(int state) {
|
||||
_myHandState = state;
|
||||
}
|
||||
|
||||
void AvatarTouch::setYourHandState( int state ) {
|
||||
void AvatarTouch::setYourHandState(int state) {
|
||||
_yourHandState = state;
|
||||
}
|
||||
|
||||
void AvatarTouch::render() {
|
||||
void AvatarTouch::setReachableRadius(float r) {
|
||||
_reachableRadius = r;
|
||||
}
|
||||
|
||||
glm::vec3 v1( _myHandPosition );
|
||||
glm::vec3 v2( _yourHandPosition );
|
||||
|
||||
void AvatarTouch::render(glm::vec3 cameraPosition) {
|
||||
|
||||
if (_canReachToOtherAvatar) {
|
||||
// if my hand is grasping, show it...
|
||||
if ( _myHandState == 1 ) {
|
||||
glPushMatrix();
|
||||
glTranslatef(_myHandPosition.x, _myHandPosition.y, _myHandPosition.z);
|
||||
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();
|
||||
}
|
||||
|
||||
glColor4f(0.3, 0.4, 0.5, 0.5);
|
||||
glm::vec3 p(_yourBodyPosition);
|
||||
p.y = 0.0005f;
|
||||
renderCircle(p, _reachableRadius, glm::vec3(0.0f, 1.0f, 0.0f), 30);
|
||||
|
||||
// if your hand is grasping, show it...
|
||||
if ( _yourHandState == 1 ) {
|
||||
if (_yourHandState == 1) {
|
||||
glPushMatrix();
|
||||
glTranslatef(_yourHandPosition.x, _yourHandPosition.y, _yourHandPosition.z);
|
||||
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 );
|
||||
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();
|
||||
}
|
||||
|
||||
//show beam
|
||||
glm::vec3 v1(_myHandPosition);
|
||||
glm::vec3 v2(_yourHandPosition);
|
||||
|
||||
if (_handsCloseEnoughToGrasp) {
|
||||
glLineWidth(2.0);
|
||||
glColor4f(0.7f, 0.4f, 0.1f, 0.3);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(v1.x, v1.y, v1.z);
|
||||
glVertex3f(v2.x, v2.y, v2.z);
|
||||
glEnd();
|
||||
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 0.8);
|
||||
|
||||
for (int p=0; p<NUM_POINTS; p++) {
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(_point[p].x, _point[p].y, _point[p].z);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//show beam
|
||||
if (_handsCloseEnoughToGrasp) {
|
||||
glLineWidth( 2.0 );
|
||||
glColor4f( 0.7f, 0.4f, 0.1f, 0.3 );
|
||||
glBegin( GL_LINE_STRIP );
|
||||
glVertex3f( v1.x, v1.y, v1.z );
|
||||
glVertex3f( v2.x, v2.y, v2.z );
|
||||
glEnd();
|
||||
|
||||
glColor4f( 1.0f, 1.0f, 0.0f, 0.8 );
|
||||
|
||||
for (int p=0; p<NUM_POINTS; p++) {
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(_point[p].x, _point[p].y, _point[p].z);
|
||||
glEnd();
|
||||
}
|
||||
// if my hand is grasping, show it...
|
||||
if (_myHandState == 1) {
|
||||
glPushMatrix();
|
||||
glTranslatef(_myHandPosition.x, _myHandPosition.y, _myHandPosition.z);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AvatarTouch::simulate (float deltaTime) {
|
||||
|
||||
glm::vec3 v = _yourHandPosition - _myHandPosition;
|
||||
for (int p=0; p<NUM_POINTS; p++) {
|
||||
_point[p] = _myHandPosition + v * ( (float)p / (float)NUM_POINTS );
|
||||
_point[p].x += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS );
|
||||
_point[p].y += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS );
|
||||
_point[p].z += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS );
|
||||
glm::vec3 v = _yourBodyPosition - _myBodyPosition;
|
||||
|
||||
float distance = glm::length(v);
|
||||
|
||||
if (distance < _reachableRadius) {
|
||||
_canReachToOtherAvatar = true;
|
||||
} else {
|
||||
_canReachToOtherAvatar = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
for (int p=0; p<NUM_POINTS; p++) {
|
||||
_point[p] = _myHandPosition + v * ((float)p / (float)NUM_POINTS);
|
||||
_point[p].x += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
|
||||
_point[p].y += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
|
||||
_point[p].z += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -19,30 +19,35 @@ public:
|
|||
AvatarTouch();
|
||||
|
||||
void simulate(float deltaTime);
|
||||
void render();
|
||||
void render(glm::vec3 cameraPosition);
|
||||
|
||||
void setMyHandPosition ( glm::vec3 position );
|
||||
void setYourHandPosition( glm::vec3 position );
|
||||
void setMyHandState ( int state );
|
||||
void setYourHandState ( int state );
|
||||
void setMyHandPosition (glm::vec3 position);
|
||||
void setYourHandPosition(glm::vec3 position);
|
||||
void setMyBodyPosition (glm::vec3 position);
|
||||
void setYourBodyPosition(glm::vec3 position);
|
||||
void setMyHandState (int state);
|
||||
void setYourHandState (int state);
|
||||
void setReachableRadius (float r);
|
||||
void setAbleToReachOtherAvatar (bool a) {_canReachToOtherAvatar = a;}
|
||||
void setHandsCloseEnoughToGrasp(bool h) {_handsCloseEnoughToGrasp = h;}
|
||||
|
||||
void setAbleToReachOtherAvatar ( bool a ) { _canReachToOtherAvatar = a; }
|
||||
void setHandsCloseEnoughToGrasp( bool h ) { _handsCloseEnoughToGrasp = h; }
|
||||
|
||||
bool getAbleToReachOtherAvatar () { return _canReachToOtherAvatar; }
|
||||
bool getHandsCloseEnoughToGrasp() { return _handsCloseEnoughToGrasp; }
|
||||
bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar;}
|
||||
bool getHandsCloseEnoughToGrasp() const {return _handsCloseEnoughToGrasp;}
|
||||
|
||||
private:
|
||||
|
||||
static const int NUM_POINTS = 100;
|
||||
|
||||
glm::vec3 _point [NUM_POINTS];
|
||||
glm::vec3 _myBodyPosition;
|
||||
glm::vec3 _yourBodyPosition;
|
||||
glm::vec3 _myHandPosition;
|
||||
glm::vec3 _yourHandPosition;
|
||||
int _myHandState;
|
||||
int _yourHandState;
|
||||
bool _canReachToOtherAvatar;
|
||||
bool _handsCloseEnoughToGrasp;
|
||||
float _reachableRadius;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,24 +26,24 @@ Camera::Camera() {
|
|||
_rightShift = 0.0;
|
||||
_distance = 0.0;
|
||||
_idealYaw = 0.0;
|
||||
_targetPosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_position = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_idealPosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_targetPosition = glm::vec3(0.0, 0.0, 0.0);
|
||||
_position = glm::vec3(0.0, 0.0, 0.0);
|
||||
_idealPosition = glm::vec3(0.0, 0.0, 0.0);
|
||||
_orientation.setToIdentity();
|
||||
}
|
||||
|
||||
|
||||
void Camera::update( float deltaTime ) {
|
||||
void Camera::update(float deltaTime) {
|
||||
|
||||
if ( _mode == CAMERA_MODE_NULL ) {
|
||||
if (_mode == CAMERA_MODE_NULL) {
|
||||
_modeShift = 0.0;
|
||||
} else {
|
||||
// use iterative forces to keep the camera at the desired position and angle
|
||||
updateFollowMode( deltaTime );
|
||||
updateFollowMode(deltaTime);
|
||||
|
||||
if ( _modeShift < 1.0f ) {
|
||||
if (_modeShift < 1.0f) {
|
||||
_modeShift += MODE_SHIFT_RATE * deltaTime;
|
||||
if ( _modeShift > 1.0f ) {
|
||||
if (_modeShift > 1.0f) {
|
||||
_modeShift = 1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -53,22 +53,19 @@ void Camera::update( float deltaTime ) {
|
|||
generateOrientation();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// generate the ortho-normals for the orientation based on the three Euler angles
|
||||
void Camera::generateOrientation() {
|
||||
_orientation.setToIdentity();
|
||||
_orientation.pitch( _pitch );
|
||||
_orientation.yaw ( _yaw );
|
||||
_orientation.roll ( _roll );
|
||||
_orientation.pitch(_pitch);
|
||||
_orientation.yaw (_yaw );
|
||||
_orientation.roll (_roll );
|
||||
}
|
||||
|
||||
|
||||
// use iterative forces to keep the camera at the desired position and angle
|
||||
void Camera::updateFollowMode( float deltaTime ) {
|
||||
void Camera::updateFollowMode(float deltaTime) {
|
||||
// derive t from tightness
|
||||
float t = _tightness * deltaTime;
|
||||
if ( t > 1.0 ) {
|
||||
if (t > 1.0) {
|
||||
t = 1.0;
|
||||
}
|
||||
|
||||
|
@ -114,8 +111,6 @@ void Camera::setFarClip (float f) {
|
|||
_frustumNeedsReshape = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// call to find out if the view frustum needs to be reshaped
|
||||
bool Camera::getFrustumNeedsReshape() {
|
||||
return _frustumNeedsReshape;
|
||||
|
|
|
@ -33,14 +33,14 @@ HandControl::HandControl() {
|
|||
_envelope = 0.0f;
|
||||
}
|
||||
|
||||
void HandControl::setScreenDimensions( int width, int height ) {
|
||||
void HandControl::setScreenDimensions(int width, int height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_startX = _width / 2;
|
||||
_startY = _height / 2;
|
||||
}
|
||||
|
||||
void HandControl::update( int x, int y ) {
|
||||
void HandControl::update(int x, int y) {
|
||||
_lastX = _x;
|
||||
_lastY = _y;
|
||||
_x = x;
|
||||
|
@ -49,22 +49,22 @@ void HandControl::update( int x, int y ) {
|
|||
_velocityY = _y - _lastY;
|
||||
|
||||
// if the mouse is moving, ramp up the envelope to increase amplitude of hand movement...
|
||||
if (( _velocityX != 0 )
|
||||
|| ( _velocityY != 0 )) {
|
||||
if ((_velocityX != 0)
|
||||
|| (_velocityY != 0)) {
|
||||
_enabled = true;
|
||||
if ( _envelope < 1.0 ) {
|
||||
if (_envelope < 1.0) {
|
||||
_envelope += _rampUpRate;
|
||||
if ( _envelope >= 1.0 ) {
|
||||
if (_envelope >= 1.0) {
|
||||
_envelope = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if not enabled ramp down the envelope to decrease amplitude of hand movement...
|
||||
if ( ! _enabled ) {
|
||||
if ( _envelope > 0.0 ) {
|
||||
if (! _enabled) {
|
||||
if (_envelope > 0.0) {
|
||||
_envelope -= _rampDownRate;
|
||||
if ( _envelope <= 0.0 ) {
|
||||
if (_envelope <= 0.0) {
|
||||
_startX = _width / 2;
|
||||
_startY = _height / 2;
|
||||
_envelope = 0.0;
|
||||
|
@ -77,14 +77,14 @@ void HandControl::update( int x, int y ) {
|
|||
_backFront = 0.0;
|
||||
|
||||
// if envelope is greater than zero, apply mouse movement to values to be output
|
||||
if ( _envelope > 0.0 ) {
|
||||
_leftRight += ( ( _x - _startX ) / (float)_width ) * _envelope;
|
||||
_downUp += ( ( _y - _startY ) / (float)_height ) * _envelope;
|
||||
if (_envelope > 0.0) {
|
||||
_leftRight += ((_x - _startX) / (float)_width ) * _envelope;
|
||||
_downUp += ((_y - _startY) / (float)_height) * _envelope;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 HandControl::getValues() {
|
||||
return glm::vec3( _leftRight, _downUp, _backFront );
|
||||
return glm::vec3(_leftRight, _downUp, _backFront);
|
||||
}
|
||||
|
||||
void HandControl::stop() {
|
||||
|
|
|
@ -33,12 +33,6 @@ const int GRAVITY_SAMPLES = 200; // Use the first samples to
|
|||
|
||||
const bool USING_INVENSENSE_MPU9150 = 1;
|
||||
|
||||
SerialInterface::~SerialInterface() {
|
||||
#ifdef __APPLE__
|
||||
close(_serialDescriptor);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SerialInterface::pair() {
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
|
|
@ -38,7 +38,6 @@ class SerialInterface {
|
|||
public:
|
||||
SerialInterface() : active(false),
|
||||
_failedOpenAttempts(0) {}
|
||||
~SerialInterface();
|
||||
|
||||
void pair();
|
||||
void readData();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/noise.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -65,81 +66,108 @@ float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float
|
|||
return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180.0f / PIf + render_yaw + head_yaw;
|
||||
}
|
||||
|
||||
void render_vector(glm::vec3 * vec)
|
||||
{
|
||||
// Show edge of world
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glLineWidth(1.0);
|
||||
glBegin(GL_LINES);
|
||||
// Draw axes
|
||||
glColor3f(1,0,0);
|
||||
glVertex3f(-1,0,0);
|
||||
glVertex3f(1,0,0);
|
||||
glColor3f(0,1,0);
|
||||
glVertex3f(0,-1,0);
|
||||
glVertex3f(0, 1, 0);
|
||||
glColor3f(0,0,1);
|
||||
glVertex3f(0,0,-1);
|
||||
glVertex3f(0, 0, 1);
|
||||
// Draw vector
|
||||
glColor3f(1,1,1);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(vec->x, vec->y, vec->z);
|
||||
// Draw marker dots for magnitude
|
||||
glEnd();
|
||||
float particleAttenuationQuadratic[] = { 0.0f, 0.0f, 2.0f }; // larger Z = smaller particles
|
||||
float particleAttenuationConstant[] = { 1.0f, 0.0f, 0.0f };
|
||||
|
||||
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, particleAttenuationQuadratic );
|
||||
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glPointSize(10.0);
|
||||
glBegin(GL_POINTS);
|
||||
glColor3f(1,0,0);
|
||||
glVertex3f(vec->x,0,0);
|
||||
glColor3f(0,1,0);
|
||||
glVertex3f(0,vec->y,0);
|
||||
glColor3f(0,0,1);
|
||||
glVertex3f(0,0,vec->z);
|
||||
glEnd();
|
||||
|
||||
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, particleAttenuationConstant );
|
||||
// Helper function returns the positive angle in degrees between two 3D vectors
|
||||
float angleBetween(glm::vec3 * v1, glm::vec3 * v2) {
|
||||
return acos((glm::dot(*v1, *v2)) / (glm::length(*v1) * glm::length(*v2))) * 180.f / PI;
|
||||
}
|
||||
|
||||
void render_world_box()
|
||||
{
|
||||
// Draw a 3D vector floating in space
|
||||
void drawVector(glm::vec3 * vector) {
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glPointSize(3.0);
|
||||
glLineWidth(2.0);
|
||||
|
||||
// Draw axes
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(1,0,0);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(1,0,0);
|
||||
glColor3f(0,1,0);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(0, 1, 0);
|
||||
glColor3f(0,0,1);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(0, 0, 1);
|
||||
glEnd();
|
||||
|
||||
// Draw the vector itself
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(1,1,1);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(vector->x, vector->y, vector->z);
|
||||
glEnd();
|
||||
|
||||
// Draw spheres for magnitude
|
||||
glPushMatrix();
|
||||
glColor3f(1,0,0);
|
||||
glTranslatef(vector->x, 0, 0);
|
||||
glutSolidSphere(0.02, 10, 10);
|
||||
glColor3f(0,1,0);
|
||||
glTranslatef(-vector->x, vector->y, 0);
|
||||
glutSolidSphere(0.02, 10, 10);
|
||||
glColor3f(0,0,1);
|
||||
glTranslatef(0, -vector->y, vector->z);
|
||||
glutSolidSphere(0.02, 10, 10);
|
||||
glPopMatrix();
|
||||
|
||||
}
|
||||
|
||||
// Render a 2D set of squares using perlin/fractal noise
|
||||
void noiseTest(int w, int h) {
|
||||
const float CELLS = 500;
|
||||
const float NOISE_SCALE = 10.0;
|
||||
float xStep = (float) w / CELLS;
|
||||
float yStep = (float) h / CELLS;
|
||||
glBegin(GL_QUADS);
|
||||
for (float x = 0; x < (float)w; x += xStep) {
|
||||
for (float y = 0; y < (float)h; y += yStep) {
|
||||
// Generate a vector varying between 0-1 corresponding to the screen location
|
||||
glm::vec2 position(NOISE_SCALE * x / (float) w, NOISE_SCALE * y / (float) h);
|
||||
// Set the cell color using the noise value at that location
|
||||
float color = glm::perlin(position);
|
||||
glColor4f(color, color, color, 1.0);
|
||||
glVertex2f(x, y);
|
||||
glVertex2f(x + xStep, y);
|
||||
glVertex2f(x + xStep, y + yStep);
|
||||
glVertex2f(x, y + yStep);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void render_world_box() {
|
||||
// Show edge of world
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glLineWidth(1.0);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(1,0,0);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(WORLD_SIZE,0,0);
|
||||
glColor3f(0,1,0);
|
||||
glVertex3f(0,0,0);
|
||||
glColor3f(1, 0, 0);
|
||||
glVertex3f(0, 0, 0);
|
||||
glVertex3f(WORLD_SIZE, 0, 0);
|
||||
glColor3f(0, 1, 0);
|
||||
glVertex3f(0, 0, 0);
|
||||
glVertex3f(0, WORLD_SIZE, 0);
|
||||
glColor3f(0,0,1);
|
||||
glVertex3f(0,0,0);
|
||||
glColor3f(0, 0, 1);
|
||||
glVertex3f(0, 0, 0);
|
||||
glVertex3f(0, 0, WORLD_SIZE);
|
||||
glEnd();
|
||||
// Draw little marker dots along the axis
|
||||
glEnable(GL_LIGHTING);
|
||||
glPushMatrix();
|
||||
glTranslatef(WORLD_SIZE,0,0);
|
||||
glColor3f(1,0,0);
|
||||
glutSolidSphere(0.125,10,10);
|
||||
glTranslatef(WORLD_SIZE, 0, 0);
|
||||
glColor3f(1, 0, 0);
|
||||
glutSolidSphere(0.125, 10, 10);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef(0,WORLD_SIZE,0);
|
||||
glColor3f(0,1,0);
|
||||
glutSolidSphere(0.125,10,10);
|
||||
glTranslatef(0, WORLD_SIZE, 0);
|
||||
glColor3f(0, 1, 0);
|
||||
glutSolidSphere(0.125, 10, 10);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef(0,0,WORLD_SIZE);
|
||||
glColor3f(0,0,1);
|
||||
glutSolidSphere(0.125,10,10);
|
||||
glTranslatef(0, 0, WORLD_SIZE);
|
||||
glColor3f(0, 0, 1);
|
||||
glutSolidSphere(0.125, 10, 10);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -166,13 +194,12 @@ float widthChar(float scale, int mono, char ch) {
|
|||
}
|
||||
|
||||
void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
|
||||
char const* string, float r, float g, float b)
|
||||
{
|
||||
char const* string, float r, float g, float b) {
|
||||
//
|
||||
// Draws text on screen as stroked so it can be resized
|
||||
//
|
||||
glPushMatrix();
|
||||
glTranslatef( static_cast<float>(x), static_cast<float>(y), 0.0f);
|
||||
glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f);
|
||||
glColor3f(r,g,b);
|
||||
glRotated(rotate,0,0,1);
|
||||
// glLineWidth(thick);
|
||||
|
@ -184,10 +211,7 @@ void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
|
|||
|
||||
}
|
||||
|
||||
|
||||
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec,
|
||||
float r, float g, float b)
|
||||
{
|
||||
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, float r, float g, float b) {
|
||||
//
|
||||
// Draws text on screen as stroked so it can be resized
|
||||
//
|
||||
|
@ -202,19 +226,16 @@ void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, gl
|
|||
glLineWidth(thick);
|
||||
glScalef(scale, scale, 1.0);
|
||||
len = (int) strlen(vectext);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!mono) glutStrokeCharacter(GLUT_STROKE_ROMAN, int(vectext[i]));
|
||||
else glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int(vectext[i]));
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
}
|
||||
|
||||
void drawGroundPlaneGrid(float size)
|
||||
{
|
||||
|
||||
glColor3f( 0.4f, 0.5f, 0.3f );
|
||||
void drawGroundPlaneGrid(float size) {
|
||||
glColor3f(0.4f, 0.5f, 0.3f);
|
||||
glLineWidth(2.0);
|
||||
|
||||
for (float x = 0; x <= size; x++) {
|
||||
|
@ -240,7 +261,7 @@ void drawGroundPlaneGrid(float size)
|
|||
|
||||
void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness) {
|
||||
|
||||
glColor4f( 0.0f, 0.0f, 0.0f, darkness );
|
||||
glColor4f(0.0f, 0.0f, 0.0f, darkness);
|
||||
|
||||
int num = 20;
|
||||
float y = 0.001f;
|
||||
|
@ -267,27 +288,72 @@ void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, f
|
|||
}
|
||||
|
||||
|
||||
void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) {
|
||||
|
||||
void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::vec3 cameraPosition) {
|
||||
glm::vec3 vectorToPosition(glm::normalize(position - cameraPosition));
|
||||
glm::vec3 right = glm::cross(vectorToPosition, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
glm::vec3 up = glm::cross(right, vectorToPosition);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int i=0; i<numSides+1; i++) {
|
||||
float r = ((float)i / (float)numSides) * PI * 2.0;
|
||||
float s = radius * sin(r);
|
||||
float c = radius * cos(r);
|
||||
|
||||
glVertex3f
|
||||
(
|
||||
position.x + right.x * s + up.x * c,
|
||||
position.y + right.y * s + up.y * c,
|
||||
position.z + right.z * s + up.z * c
|
||||
);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides) {
|
||||
glm::vec3 perp1 = glm::vec3(surfaceNormal.y, surfaceNormal.z, surfaceNormal.x);
|
||||
glm::vec3 perp2 = glm::vec3(surfaceNormal.z, surfaceNormal.x, surfaceNormal.y);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
||||
for (int i=0; i<numSides+1; i++) {
|
||||
float r = ((float)i / (float)numSides) * PI * 2.0;
|
||||
float s = radius * sin(r);
|
||||
float c = radius * cos(r);
|
||||
glVertex3f
|
||||
(
|
||||
position.x + perp1.x * s + perp2.x * c,
|
||||
position.y + perp1.y * s + perp2.y * c,
|
||||
position.z + perp1.z * s + perp2.z * c
|
||||
);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
void renderOrientationDirections(glm::vec3 position, Orientation orientation, float size) {
|
||||
glm::vec3 pRight = position + orientation.getRight() * size;
|
||||
glm::vec3 pUp = position + orientation.getUp() * size;
|
||||
glm::vec3 pUp = position + orientation.getUp () * size;
|
||||
glm::vec3 pFront = position + orientation.getFront() * 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 );
|
||||
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 );
|
||||
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 );
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,13 +33,19 @@ float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float
|
|||
|
||||
float randFloat();
|
||||
void render_world_box();
|
||||
void render_vector(glm::vec3 * vec);
|
||||
int widthText(float scale, int mono, char const* string);
|
||||
float widthChar(float scale, int mono, char ch);
|
||||
void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
|
||||
char const* string, float r=1.0, float g=1.0, float b=1.0);
|
||||
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec,
|
||||
float r=1.0, float g=1.0, float b=1.0);
|
||||
|
||||
void noiseTest(int w, int h);
|
||||
|
||||
void drawVector(glm::vec3* vector);
|
||||
|
||||
float angleBetween(glm::vec3 * v1, glm::vec3 * v2);
|
||||
|
||||
double diffclock(timeval *clock1,timeval *clock2);
|
||||
|
||||
void drawGroundPlaneGrid(float size);
|
||||
|
@ -48,6 +54,9 @@ void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, f
|
|||
|
||||
void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size );
|
||||
|
||||
void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::vec3 cameraPosition);
|
||||
void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides );
|
||||
|
||||
|
||||
class oTestCase {
|
||||
public:
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
//
|
||||
// Welcome Aboard!
|
||||
//
|
||||
//
|
||||
// Keyboard Commands:
|
||||
//
|
||||
// / = toggle stats display
|
||||
// spacebar = reset gyros/head position
|
||||
// h = render Head facing yourself (mirror)
|
||||
// l = show incoming gyro levels
|
||||
//
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
#include <math.h>
|
||||
|
@ -436,17 +428,22 @@ void updateAvatar(float frametime) {
|
|||
myAvatar.setCameraAspectRatio(::viewFrustum.getAspectRatio());
|
||||
myAvatar.setCameraNearClip(::viewFrustum.getNearClip());
|
||||
myAvatar.setCameraFarClip(::viewFrustum.getFarClip());
|
||||
|
||||
// Send my stream of head/hand data to the avatar mixer and voxel server
|
||||
unsigned char broadcastString[200];
|
||||
*broadcastString = PACKET_HEADER_HEAD_DATA;
|
||||
|
||||
int broadcastBytes = myAvatar.getBroadcastData(broadcastString + 1);
|
||||
broadcastBytes++;
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
|
||||
const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER};
|
||||
|
||||
AgentList::getInstance()->broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2);
|
||||
if (agentList->getOwnerID() != UNKNOWN_AGENT_ID) {
|
||||
// if I know my ID, send head/hand data to the avatar mixer and voxel server
|
||||
unsigned char broadcastString[200];
|
||||
unsigned char* endOfBroadcastStringWrite = broadcastString;
|
||||
|
||||
*(endOfBroadcastStringWrite++) = PACKET_HEADER_HEAD_DATA;
|
||||
endOfBroadcastStringWrite += packAgentId(endOfBroadcastStringWrite, agentList->getOwnerID());
|
||||
|
||||
endOfBroadcastStringWrite += myAvatar.getBroadcastData(endOfBroadcastStringWrite);
|
||||
|
||||
const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER};
|
||||
AgentList::getInstance()->broadcastToAgents(broadcastString, endOfBroadcastStringWrite - broadcastString, broadcastReceivers, sizeof(broadcastReceivers));
|
||||
}
|
||||
|
||||
// If I'm in paint mode, send a voxel out to VOXEL server agents.
|
||||
if (::paintOn) {
|
||||
|
@ -454,9 +451,9 @@ void updateAvatar(float frametime) {
|
|||
glm::vec3 avatarPos = myAvatar.getPosition();
|
||||
|
||||
// For some reason, we don't want to flip X and Z here.
|
||||
::paintingVoxel.x = avatarPos.x/10.0;
|
||||
::paintingVoxel.y = avatarPos.y/10.0;
|
||||
::paintingVoxel.z = avatarPos.z/10.0;
|
||||
::paintingVoxel.x = avatarPos.x / 10.0;
|
||||
::paintingVoxel.y = avatarPos.y / 10.0;
|
||||
::paintingVoxel.z = avatarPos.z / 10.0;
|
||||
|
||||
unsigned char* bufferOut;
|
||||
int sizeOut;
|
||||
|
@ -692,15 +689,14 @@ void displaySide(Camera& whichCamera) {
|
|||
float sphereRadius = 0.25f;
|
||||
glColor3f(1,0,0);
|
||||
glPushMatrix();
|
||||
glutSolidSphere( sphereRadius, 15, 15 );
|
||||
glutSolidSphere(sphereRadius, 15, 15);
|
||||
glPopMatrix();
|
||||
|
||||
//draw a grid ground plane....
|
||||
drawGroundPlaneGrid(10.f);
|
||||
|
||||
// Draw voxels
|
||||
if ( showingVoxels )
|
||||
{
|
||||
if (showingVoxels) {
|
||||
voxels.render();
|
||||
}
|
||||
|
||||
|
@ -710,7 +706,7 @@ void displaySide(Camera& whichCamera) {
|
|||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->render(0);
|
||||
avatar->render(0, ::myCamera.getPosition());
|
||||
}
|
||||
}
|
||||
agentList->unlock();
|
||||
|
@ -722,7 +718,7 @@ void displaySide(Camera& whichCamera) {
|
|||
if (::frustumOn) renderViewFrustum(::viewFrustum);
|
||||
|
||||
//Render my own avatar
|
||||
myAvatar.render(::lookingInMirror);
|
||||
myAvatar.render(::lookingInMirror, ::myCamera.getPosition());
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
@ -893,6 +889,8 @@ void displayOverlay() {
|
|||
audioScope.render();
|
||||
#endif
|
||||
|
||||
//noiseTest(WIDTH, HEIGHT);
|
||||
|
||||
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);
|
||||
|
@ -984,15 +982,15 @@ void display(void)
|
|||
glMateriali(GL_FRONT, GL_SHININESS, 96);
|
||||
|
||||
// camera settings
|
||||
if ( ::lookingInMirror ) {
|
||||
if (::lookingInMirror) {
|
||||
// set the camera to looking at my own face
|
||||
myCamera.setTargetPosition ( myAvatar.getHeadPosition() );
|
||||
myCamera.setTargetYaw ( myAvatar.getBodyYaw() - 180.0f ); // 180 degrees from body yaw
|
||||
myCamera.setPitch ( 0.0 );
|
||||
myCamera.setRoll ( 0.0 );
|
||||
myCamera.setUpShift ( 0.0 );
|
||||
myCamera.setDistance ( 0.2 );
|
||||
myCamera.setTightness ( 100.0f );
|
||||
myCamera.setTargetPosition (myAvatar.getHeadPosition());
|
||||
myCamera.setTargetYaw (myAvatar.getBodyYaw() - 180.0f); // 180 degrees from body yaw
|
||||
myCamera.setPitch (0.0);
|
||||
myCamera.setRoll (0.0);
|
||||
myCamera.setUpShift (0.0);
|
||||
myCamera.setDistance (0.2);
|
||||
myCamera.setTightness (100.0f);
|
||||
} else {
|
||||
|
||||
//float firstPersonPitch = 20.0f;
|
||||
|
@ -1010,59 +1008,47 @@ void display(void)
|
|||
float thirdPersonDistance = 1.2f;
|
||||
float thirdPersonTightness = 8.0f;
|
||||
|
||||
if ( USING_FIRST_PERSON_EFFECT ) {
|
||||
if (USING_FIRST_PERSON_EFFECT) {
|
||||
float ff = 0.0;
|
||||
float min = 0.1;
|
||||
float max = 0.5;
|
||||
|
||||
if ( myAvatar.getIsNearInteractingOther()){
|
||||
if ( myAvatar.getSpeed() < max ) {
|
||||
if (myAvatar.getIsNearInteractingOther()){
|
||||
if (myAvatar.getSpeed() < max) {
|
||||
|
||||
float s = (myAvatar.getSpeed()- min)/max ;
|
||||
ff = 1.0 - s;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if ( ff < 0.8 ) {
|
||||
myAvatar.setDisplayingHead( true );
|
||||
} else {
|
||||
myAvatar.setDisplayingHead( false );
|
||||
}
|
||||
*/
|
||||
|
||||
//printf( "ff = %f\n", ff );
|
||||
|
||||
myCamera.setPitch ( thirdPersonPitch + ff * ( firstPersonPitch - thirdPersonPitch ));
|
||||
myCamera.setUpShift ( thirdPersonUpShift + ff * ( firstPersonUpShift - thirdPersonUpShift ));
|
||||
myCamera.setDistance ( thirdPersonDistance + ff * ( firstPersonDistance - thirdPersonDistance ));
|
||||
myCamera.setTightness ( thirdPersonTightness + ff * ( firstPersonTightness - thirdPersonTightness ));
|
||||
myCamera.setPitch (thirdPersonPitch + ff * (firstPersonPitch - thirdPersonPitch ));
|
||||
myCamera.setUpShift (thirdPersonUpShift + ff * (firstPersonUpShift - thirdPersonUpShift ));
|
||||
myCamera.setDistance (thirdPersonDistance + ff * (firstPersonDistance - thirdPersonDistance ));
|
||||
myCamera.setTightness (thirdPersonTightness + ff * (firstPersonTightness - thirdPersonTightness));
|
||||
|
||||
|
||||
|
||||
// this version uses a ramp-up/ramp-down timer in the camera to determine shift between first and thirs-person view
|
||||
/*
|
||||
if ( myAvatar.getSpeed() < 0.02 ) {
|
||||
if (myAvatar.getSpeed() < 0.02) {
|
||||
|
||||
if (myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
|
||||
if (myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
|
||||
myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
}
|
||||
|
||||
//printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
|
||||
myCamera.setPitch ( thirdPersonPitch + myCamera.getModeShift() * ( firstPersonPitch - thirdPersonPitch ));
|
||||
myCamera.setUpShift ( thirdPersonUpShift + myCamera.getModeShift() * ( firstPersonUpShift - thirdPersonUpShift ));
|
||||
myCamera.setDistance ( thirdPersonDistance + myCamera.getModeShift() * ( firstPersonDistance - thirdPersonDistance ));
|
||||
myCamera.setTightness ( thirdPersonTightness + myCamera.getModeShift() * ( firstPersonTightness - thirdPersonTightness ));
|
||||
//printf("myCamera.getModeShift() = %f\n", myCamera.getModeShift());
|
||||
myCamera.setPitch (thirdPersonPitch + myCamera.getModeShift() * (firstPersonPitch - thirdPersonPitch ));
|
||||
myCamera.setUpShift (thirdPersonUpShift + myCamera.getModeShift() * (firstPersonUpShift - thirdPersonUpShift ));
|
||||
myCamera.setDistance (thirdPersonDistance + myCamera.getModeShift() * (firstPersonDistance - thirdPersonDistance ));
|
||||
myCamera.setTightness (thirdPersonTightness + myCamera.getModeShift() * (firstPersonTightness - thirdPersonTightness));
|
||||
} else {
|
||||
if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON ) {
|
||||
if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
|
||||
myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||
}
|
||||
|
||||
//printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
|
||||
myCamera.setPitch ( firstPersonPitch + myCamera.getModeShift() * ( thirdPersonPitch - firstPersonPitch ));
|
||||
myCamera.setUpShift ( firstPersonUpShift + myCamera.getModeShift() * ( thirdPersonUpShift - firstPersonUpShift ));
|
||||
myCamera.setDistance ( firstPersonDistance + myCamera.getModeShift() * ( thirdPersonDistance - firstPersonDistance ));
|
||||
myCamera.setTightness ( firstPersonTightness + myCamera.getModeShift() * ( thirdPersonTightness - firstPersonTightness ));
|
||||
//printf("myCamera.getModeShift() = %f\n", myCamera.getModeShift());
|
||||
myCamera.setPitch (firstPersonPitch + myCamera.getModeShift() * (thirdPersonPitch - firstPersonPitch ));
|
||||
myCamera.setUpShift (firstPersonUpShift + myCamera.getModeShift() * (thirdPersonUpShift - firstPersonUpShift ));
|
||||
myCamera.setDistance (firstPersonDistance + myCamera.getModeShift() * (thirdPersonDistance - firstPersonDistance ));
|
||||
myCamera.setTightness (firstPersonTightness + myCamera.getModeShift() * (thirdPersonTightness - firstPersonTightness));
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -1073,13 +1059,23 @@ void display(void)
|
|||
myCamera.setTightness(thirdPersonTightness);
|
||||
}
|
||||
|
||||
myCamera.setTargetPosition( myAvatar.getHeadPosition() );
|
||||
myCamera.setTargetYaw ( myAvatar.getBodyYaw() );
|
||||
myCamera.setRoll ( 0.0 );
|
||||
myCamera.setTargetPosition(myAvatar.getHeadPosition());
|
||||
myCamera.setTargetYaw (myAvatar.getBodyYaw());
|
||||
myCamera.setRoll (0.0);
|
||||
}
|
||||
|
||||
// important...
|
||||
|
||||
myCamera.update( 1.f/FPS );
|
||||
|
||||
// Render anything (like HUD items) that we want to be in 3D but not in worldspace
|
||||
const float HUD_Z_OFFSET = -5.f;
|
||||
glPushMatrix();
|
||||
glm::vec3 test(0.5, 0.5, 0.5);
|
||||
glTranslatef(1, 1, HUD_Z_OFFSET);
|
||||
drawVector(&test);
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
||||
// main camera, vs, an alternate camera. The alternate camera we support right now
|
||||
|
@ -1095,11 +1091,11 @@ void display(void)
|
|||
if (::viewFrustumFromOffset && ::frustumOn) {
|
||||
|
||||
// set the camera to third-person view but offset so we can see the frustum
|
||||
viewFrustumOffsetCamera.setTargetYaw( ::viewFrustumOffsetYaw + myAvatar.getBodyYaw() );
|
||||
viewFrustumOffsetCamera.setPitch ( ::viewFrustumOffsetPitch );
|
||||
viewFrustumOffsetCamera.setRoll ( ::viewFrustumOffsetRoll );
|
||||
viewFrustumOffsetCamera.setUpShift ( ::viewFrustumOffsetUp );
|
||||
viewFrustumOffsetCamera.setDistance ( ::viewFrustumOffsetDistance );
|
||||
viewFrustumOffsetCamera.setTargetYaw(::viewFrustumOffsetYaw + myAvatar.getBodyYaw());
|
||||
viewFrustumOffsetCamera.setPitch (::viewFrustumOffsetPitch );
|
||||
viewFrustumOffsetCamera.setRoll (::viewFrustumOffsetRoll );
|
||||
viewFrustumOffsetCamera.setUpShift (::viewFrustumOffsetUp );
|
||||
viewFrustumOffsetCamera.setDistance (::viewFrustumOffsetDistance);
|
||||
viewFrustumOffsetCamera.update(1.f/FPS);
|
||||
whichCamera = viewFrustumOffsetCamera;
|
||||
}
|
||||
|
@ -1109,11 +1105,11 @@ void display(void)
|
|||
// or could be viewFrustumOffsetCamera if in offset mode
|
||||
// I changed the ordering here - roll is FIRST (JJV)
|
||||
|
||||
glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z );
|
||||
glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z );
|
||||
glRotatef ( 180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z );
|
||||
glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z);
|
||||
glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z);
|
||||
glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z );
|
||||
|
||||
glTranslatef( -whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z );
|
||||
glTranslatef(-whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z);
|
||||
|
||||
if (::oculusOn) {
|
||||
displayOculus(whichCamera);
|
||||
|
@ -1380,8 +1376,7 @@ void initMenu() {
|
|||
menuColumnDebug->addRow("Show TRUE Colors", doTrueVoxelColors);
|
||||
}
|
||||
|
||||
void testPointToVoxel()
|
||||
{
|
||||
void testPointToVoxel() {
|
||||
float y=0;
|
||||
float z=0;
|
||||
float s=0.1;
|
||||
|
@ -1486,7 +1481,6 @@ void specialkey(int k, int x, int y) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void keyUp(unsigned char k, int x, int y) {
|
||||
if (::chatEntryOn) {
|
||||
myAvatar.setKeyState(NO_KEY_DOWN);
|
||||
|
@ -1501,8 +1495,7 @@ void keyUp(unsigned char k, int x, int y) {
|
|||
if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 0);
|
||||
}
|
||||
|
||||
void key(unsigned char k, int x, int y)
|
||||
{
|
||||
void key(unsigned char k, int x, int y) {
|
||||
if (::chatEntryOn) {
|
||||
if (chatEntry.key(k)) {
|
||||
myAvatar.setKeyState(k == '\b' || k == 127 ? // backspace or delete
|
||||
|
@ -1647,18 +1640,16 @@ void idle(void) {
|
|||
|
||||
// update behaviors for avatar hand movement: handControl takes mouse values as input,
|
||||
// and gives back 3D values modulated for smooth transitioning between interaction modes.
|
||||
handControl.update( mouseX, mouseY );
|
||||
myAvatar.setHandMovementValues( handControl.getValues() );
|
||||
handControl.update(mouseX, mouseY);
|
||||
myAvatar.setHandMovementValues(handControl.getValues());
|
||||
|
||||
// tell my avatar if the mouse is being pressed...
|
||||
if ( mousePressed == 1 ) {
|
||||
myAvatar.setMousePressed( true );
|
||||
} else {
|
||||
myAvatar.setMousePressed( false );
|
||||
}
|
||||
|
||||
if (mousePressed) {
|
||||
myAvatar.setMousePressed(mousePressed);
|
||||
}
|
||||
|
||||
// walking triggers the handControl to stop
|
||||
if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) {
|
||||
if (myAvatar.getMode() == AVATAR_MODE_WALKING) {
|
||||
handControl.stop();
|
||||
}
|
||||
|
||||
|
@ -1748,10 +1739,6 @@ void reshape(int width, int height) {
|
|||
glLoadIdentity();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Find and return the gravity vector at this location
|
||||
glm::vec3 getGravity(glm::vec3 pos) {
|
||||
//
|
||||
|
@ -1773,7 +1760,7 @@ glm::vec3 getGravity(glm::vec3 pos) {
|
|||
}
|
||||
|
||||
void mouseFunc(int button, int state, int x, int y) {
|
||||
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
|
||||
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
|
||||
if (state == GLUT_DOWN && !menu.mouseClick(x, y)) {
|
||||
mouseX = x;
|
||||
mouseY = y;
|
||||
|
@ -1810,8 +1797,7 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
int main(int argc, const char * argv[]) {
|
||||
voxels.setViewFrustum(&::viewFrustum);
|
||||
|
||||
shared_lib::printLog = & ::printLog;
|
||||
|
@ -1851,7 +1837,7 @@ int main(int argc, const char * argv[])
|
|||
|
||||
#ifdef _WIN32
|
||||
WSADATA WsaData;
|
||||
int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData );
|
||||
int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData);
|
||||
#endif
|
||||
|
||||
// start the agentList threads
|
||||
|
|
|
@ -129,14 +129,17 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
|
||||
// increment to push past the packet header
|
||||
sourceBuffer++;
|
||||
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
|
||||
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
// push past the agent ID
|
||||
sourceBuffer += + sizeof(uint16_t);
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -62,9 +62,10 @@ AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) :
|
|||
_agentBuckets(),
|
||||
_numAgents(0),
|
||||
agentSocket(newSocketListenPort),
|
||||
ownerType(newOwnerType),
|
||||
_ownerType(newOwnerType),
|
||||
socketListenPort(newSocketListenPort),
|
||||
lastAgentId(0) {
|
||||
_ownerID(UNKNOWN_AGENT_ID),
|
||||
_lastAgentID(0) {
|
||||
pthread_mutex_init(&mutex, 0);
|
||||
}
|
||||
|
||||
|
@ -81,10 +82,6 @@ UDPSocket& AgentList::getAgentSocket() {
|
|||
return agentSocket;
|
||||
}
|
||||
|
||||
char AgentList::getOwnerType() {
|
||||
return ownerType;
|
||||
}
|
||||
|
||||
unsigned int AgentList::getSocketListenPort() {
|
||||
return socketListenPort;
|
||||
}
|
||||
|
@ -92,7 +89,7 @@ unsigned int AgentList::getSocketListenPort() {
|
|||
void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) {
|
||||
switch (((char *)packetData)[0]) {
|
||||
case PACKET_HEADER_DOMAIN: {
|
||||
updateList(packetData, dataBytes);
|
||||
processDomainServerList(packetData, dataBytes);
|
||||
break;
|
||||
}
|
||||
case PACKET_HEADER_PING: {
|
||||
|
@ -126,7 +123,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
|
|||
uint16_t agentID = -1;
|
||||
|
||||
while ((currentPosition - startPosition) < numTotalBytes) {
|
||||
currentPosition += unpackAgentId(currentPosition, &agentID);
|
||||
unpackAgentId(currentPosition, &agentID);
|
||||
memcpy(packetHolder + 1, currentPosition, numTotalBytes - (currentPosition - startPosition));
|
||||
|
||||
Agent* matchingAgent = agentWithID(agentID);
|
||||
|
@ -195,15 +192,7 @@ Agent* AgentList::agentWithID(uint16_t agentID) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t AgentList::getLastAgentId() {
|
||||
return lastAgentId;
|
||||
}
|
||||
|
||||
void AgentList::increaseAgentId() {
|
||||
++lastAgentId;
|
||||
}
|
||||
|
||||
int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
||||
int AgentList::processDomainServerList(unsigned char *packetData, size_t dataBytes) {
|
||||
int readAgents = 0;
|
||||
|
||||
char agentType;
|
||||
|
@ -218,14 +207,17 @@ int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
|||
unsigned char *readPtr = packetData + 1;
|
||||
unsigned char *startPtr = packetData;
|
||||
|
||||
while((readPtr - startPtr) < dataBytes) {
|
||||
while((readPtr - startPtr) < dataBytes - sizeof(uint16_t)) {
|
||||
agentType = *readPtr++;
|
||||
readPtr += unpackAgentId(readPtr, (uint16_t *)&agentId);
|
||||
readPtr += unpackSocket(readPtr, (sockaddr *)&agentPublicSocket);
|
||||
readPtr += unpackSocket(readPtr, (sockaddr *)&agentLocalSocket);
|
||||
|
||||
addOrUpdateAgent((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType, agentId);
|
||||
}
|
||||
}
|
||||
|
||||
// read out our ID from the packet
|
||||
unpackAgentId(readPtr, &_ownerID);
|
||||
|
||||
return readAgents;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ extern char DOMAIN_HOSTNAME[];
|
|||
extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup
|
||||
extern const int DOMAINSERVER_PORT;
|
||||
|
||||
const int UNKNOWN_AGENT_ID = -1;
|
||||
|
||||
class AgentListIterator;
|
||||
|
||||
class AgentList {
|
||||
|
@ -50,13 +52,10 @@ public:
|
|||
|
||||
UDPSocket& getAgentSocket();
|
||||
|
||||
uint16_t getLastAgentId();
|
||||
void increaseAgentId();
|
||||
|
||||
void lock() { pthread_mutex_lock(&mutex); }
|
||||
void unlock() { pthread_mutex_unlock(&mutex); }
|
||||
|
||||
int updateList(unsigned char *packetData, size_t dataBytes);
|
||||
int processDomainServerList(unsigned char *packetData, size_t dataBytes);
|
||||
|
||||
Agent* agentWithAddress(sockaddr *senderAddress);
|
||||
Agent* agentWithID(uint16_t agentID);
|
||||
|
@ -70,9 +69,16 @@ public:
|
|||
int updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes);
|
||||
|
||||
void broadcastToAgents(unsigned char *broadcastData, size_t dataBytes, const char* agentTypes, int numAgentTypes);
|
||||
char getOwnerType();
|
||||
unsigned int getSocketListenPort();
|
||||
|
||||
char getOwnerType() const { return _ownerType; }
|
||||
|
||||
uint16_t getLastAgentID() const { return _lastAgentID; }
|
||||
void increaseAgentID() { ++_lastAgentID; }
|
||||
|
||||
uint16_t getOwnerID() const { return _ownerID; }
|
||||
void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; }
|
||||
|
||||
Agent* soloAgentOfType(char agentType);
|
||||
|
||||
void startSilentAgentRemovalThread();
|
||||
|
@ -96,9 +102,10 @@ private:
|
|||
Agent** _agentBuckets[MAX_NUM_AGENTS / AGENTS_PER_BUCKET];
|
||||
int _numAgents;
|
||||
UDPSocket agentSocket;
|
||||
char ownerType;
|
||||
char _ownerType;
|
||||
unsigned int socketListenPort;
|
||||
uint16_t lastAgentId;
|
||||
uint16_t _ownerID;
|
||||
uint16_t _lastAgentID;
|
||||
pthread_t removeSilentAgentsThread;
|
||||
pthread_t checkInWithDomainServerThread;
|
||||
pthread_t pingUnknownAgentsThread;
|
||||
|
|
|
@ -113,6 +113,7 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
attenuationRatio = attenuationByte / 255.0f;
|
||||
|
||||
memcpy(&bearing, dataPtr, sizeof(float));
|
||||
dataPtr += sizeof(bearing);
|
||||
|
||||
if (bearing > 180 || bearing < -180) {
|
||||
// we were passed an invalid bearing because this agent wants loopback (pressed the H key)
|
||||
|
@ -122,9 +123,9 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
bearing = bearing > 0
|
||||
? bearing - AGENT_LOOPBACK_MODIFIER
|
||||
: bearing + AGENT_LOOPBACK_MODIFIER;
|
||||
}
|
||||
|
||||
dataPtr += sizeof(float);
|
||||
} else {
|
||||
_shouldLoopbackForAgent = false;
|
||||
}
|
||||
|
||||
sourceBuffer = dataPtr;
|
||||
}
|
||||
|
|
|
@ -13,18 +13,19 @@
|
|||
#ifndef hifi_PacketHeaders_h
|
||||
#define hifi_PacketHeaders_h
|
||||
|
||||
const char PACKET_HEADER_DOMAIN = 'D';
|
||||
const char PACKET_HEADER_PING = 'P';
|
||||
const char PACKET_HEADER_PING_REPLY = 'R';
|
||||
const char PACKET_HEADER_HEAD_DATA = 'H';
|
||||
const char PACKET_HEADER_Z_COMMAND = 'Z';
|
||||
const char PACKET_HEADER_INJECT_AUDIO = 'I';
|
||||
const char PACKET_HEADER_SET_VOXEL = 'S';
|
||||
const char PACKET_HEADER_ERASE_VOXEL = 'E';
|
||||
const char PACKET_HEADER_VOXEL_DATA = 'V';
|
||||
const char PACKET_HEADER_BULK_AVATAR_DATA = 'X';
|
||||
const char PACKET_HEADER_TRANSMITTER_DATA = 't';
|
||||
const char PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L';
|
||||
const char PACKET_HEADER_DOMAIN_RFD = 'C';
|
||||
typedef char PACKET_HEADER;
|
||||
const PACKET_HEADER PACKET_HEADER_DOMAIN = 'D';
|
||||
const PACKET_HEADER PACKET_HEADER_PING = 'P';
|
||||
const PACKET_HEADER PACKET_HEADER_PING_REPLY = 'R';
|
||||
const PACKET_HEADER PACKET_HEADER_HEAD_DATA = 'H';
|
||||
const PACKET_HEADER PACKET_HEADER_Z_COMMAND = 'Z';
|
||||
const PACKET_HEADER PACKET_HEADER_INJECT_AUDIO = 'I';
|
||||
const PACKET_HEADER PACKET_HEADER_SET_VOXEL = 'S';
|
||||
const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E';
|
||||
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V';
|
||||
const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X';
|
||||
const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA = 't';
|
||||
const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L';
|
||||
const PACKET_HEADER PACKET_HEADER_DOMAIN_RFD = 'C';
|
||||
|
||||
#endif
|
||||
|
|
0
libraries/voxels/src/AABox.cpp
Executable file → Normal file
0
libraries/voxels/src/AABox.cpp
Executable file → Normal file
|
@ -445,12 +445,9 @@ int main(int argc, const char * argv[])
|
|||
// If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_AVATAR, and we
|
||||
// need to make sure we have it in our agentList.
|
||||
if (packetData[0] == PACKET_HEADER_HEAD_DATA) {
|
||||
if (agentList->addOrUpdateAgent(&agentPublicAddress,
|
||||
&agentPublicAddress,
|
||||
AGENT_TYPE_AVATAR,
|
||||
agentList->getLastAgentId())) {
|
||||
agentList->increaseAgentId();
|
||||
}
|
||||
uint16_t agentID = 0;
|
||||
unpackAgentId(packetData + sizeof(PACKET_HEADER_HEAD_DATA), &agentID);
|
||||
agentList->addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, AGENT_TYPE_AVATAR, agentID);
|
||||
|
||||
agentList->updateAgentWithData(&agentPublicAddress, packetData, receivedBytes);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue