Merge branch 'master' of https://github.com/worklist/hifi into render_voxels_optimization

This commit is contained in:
ZappoMan 2013-05-08 01:19:35 -07:00
commit de969891d8
23 changed files with 780 additions and 695 deletions

View file

@ -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,6 +119,13 @@ void *sendBuffer(void *args) {
AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData();
if (otherAgentBuffer->shouldBeAddedToMix()) {
float bearingRelativeAngleToSource = 0.f;
float attenuationCoefficient = 1.f;
int numSamplesDelay = 0;
float weakChannelAmplitudeRatio = 1.f;
if (otherAgent != agent) {
float *agentPosition = agentRingBuffer->getPosition();
float *otherAgentPosition = otherAgentBuffer->getPosition();
@ -144,8 +150,7 @@ void *sendBuffer(void *args) {
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]),
fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
float absoluteAngleToSource = 0;
float bearingRelativeAngleToSource = 0;
bearingRelativeAngleToSource = 0;
// find the angle we need for calculation based on the orientation of the triangle
if (otherAgentPosition[0] > agentPosition[0]) {
@ -162,34 +167,38 @@ void *sendBuffer(void *args) {
}
}
if (absoluteAngleToSource > 180) {
absoluteAngleToSource -= 360;
} else if (absoluteAngleToSource < -180) {
absoluteAngleToSource += 360;
}
bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing();
bearingRelativeAngleToSource = absoluteAngleToSource - agentBearing;
bearingRelativeAngleToSource *= (M_PI / 180);
if (bearingRelativeAngleToSource > 180) {
bearingRelativeAngleToSource -= 360;
} else if (bearingRelativeAngleToSource < -180) {
bearingRelativeAngleToSource += 360;
}
float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing();
if (angleOfDelivery < -180) {
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));
float attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex]
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);
bearingRelativeAngleToSource *= (M_PI / 180);
int16_t* goodChannel = bearingRelativeAngleToSource > 0 ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix;
int16_t* delayedChannel = bearingRelativeAngleToSource > 0 ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
float sinRatio = fabsf(sinf(bearingRelativeAngleToSource));
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
}
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);

View file

@ -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);
@ -70,31 +69,31 @@ int main(int argc, const char* argv[])
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:

View file

@ -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,9 +144,13 @@ 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))) {
// 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,
packetBytesWithoutLeadingChar + 1);
}
(currentBufferPos - startPointer) + 1);
}
}

View file

@ -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;
@ -148,12 +152,15 @@ int main(int argc, const char* argv[]) {
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
@ -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;
}
}

View file

@ -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) {
@ -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
@ -442,102 +439,66 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
_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);
//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);
_avatarTouch.setYourHandState (_interactingOther->_handState);
_avatarTouch.simulate(deltaTime);
}
}
if (!_avatarTouch.getAbleToReachOtherAvatar() ) {
_interactingOther = NULL;
if (_handState == 1) {
_avatarTouch.setMyHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
}
}
}
void Avatar::updateHead(float deltaTime) {
@ -690,12 +651,43 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d
}
//detect collisions with other avatars and respond
void Avatar::updateCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
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);
@ -747,9 +739,8 @@ void Avatar::updateCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTim
otherAvatar->_velocity -= bodyPushForce;
_velocity *= bodyMomentum;
otherAvatar->_velocity *= bodyMomentum;
}
} // bounding sphere collision
} //method
void Avatar::setDisplayingHead(bool displayingHead) {
@ -768,7 +759,7 @@ 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);
@ -803,7 +794,7 @@ void Avatar::render(bool lookingInMirror) {
// if this is my avatar, then render my interactions with the other avatar
if (_isMine) {
_avatarTouch.render();
_avatarTouch.render(cameraPosition);
}
// Render the balls
@ -1193,6 +1184,9 @@ void Avatar::initializeSkeleton() {
// generate world positions
updateSkeleton();
//set spring positions to be in the skeleton bone positions
initializeBodySprings();
}
void Avatar::calculateBoneLengths() {
@ -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) {

View file

@ -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(); };
@ -118,7 +111,7 @@ public:
AvatarMode getMode();
void setMousePressed(bool pressed);
void render(bool lookingInMirror);
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; }
};

View file

@ -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();
*/
}

View file

@ -10,6 +10,7 @@
#include <SharedUtil.h>
#include "AvatarTouch.h"
#include "InterfaceConfig.h"
#include "Util.h"
const float THREAD_RADIUS = 0.012;
@ -17,8 +18,11 @@ AvatarTouch::AvatarTouch() {
_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;
_reachableRadius = 0.0f;
_canReachToOtherAvatar = false;
_handsCloseEnoughToGrasp = false;
@ -36,6 +40,14 @@ void AvatarTouch::setYourHandPosition( glm::vec3 position ) {
_yourHandPosition = position;
}
void AvatarTouch::setMyBodyPosition(glm::vec3 position) {
_myBodyPosition = position;
}
void AvatarTouch::setYourBodyPosition(glm::vec3 position) {
_yourBodyPosition = position;
}
void AvatarTouch::setMyHandState(int state) {
_myHandState = state;
}
@ -44,21 +56,19 @@ 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) {
@ -69,9 +79,11 @@ void AvatarTouch::render() {
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);
@ -90,14 +102,38 @@ void AvatarTouch::render() {
}
}
// 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;
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);
}
*/
}

View file

@ -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 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;}
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

View file

@ -53,8 +53,6 @@ void Camera::update( float deltaTime ) {
generateOrientation();
}
// generate the ortho-normals for the orientation based on the three Euler angles
void Camera::generateOrientation() {
_orientation.setToIdentity();
@ -63,7 +61,6 @@ void Camera::generateOrientation() {
_orientation.roll (_roll );
}
// use iterative forces to keep the camera at the desired position and angle
void Camera::updateFollowMode(float deltaTime) {
// derive t from tightness
@ -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;

View file

@ -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__

View file

@ -38,7 +38,6 @@ class SerialInterface {
public:
SerialInterface() : active(false),
_failedOpenAttempts(0) {}
~SerialInterface();
void pair();
void readData();

View file

@ -11,6 +11,7 @@
#include <cstring>
#include <glm/glm.hpp>
#include <glm/gtc/noise.hpp>
#include <glm/gtc/quaternion.hpp>
#include <SharedUtil.h>
@ -65,50 +66,77 @@ 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);
@ -166,8 +194,7 @@ 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
//
@ -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,18 +226,15 @@ 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)
{
void drawGroundPlaneGrid(float size) {
glColor3f(0.4f, 0.5f, 0.3f);
glLineWidth(2.0);
@ -267,6 +288,51 @@ void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, f
}
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;

View file

@ -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:

View file

@ -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>
@ -437,16 +429,21 @@ void updateAvatar(float frametime) {
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;
AgentList* agentList = AgentList::getInstance();
int broadcastBytes = myAvatar.getBroadcastData(broadcastString + 1);
broadcastBytes++;
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, broadcastBytes, broadcastReceivers, 2);
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) {
@ -699,8 +696,7 @@ void displaySide(Camera& whichCamera) {
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);
@ -1023,23 +1021,11 @@ void display(void)
}
}
/*
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));
// 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) {
@ -1079,8 +1065,18 @@ void display(void)
}
// 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
// is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism
@ -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
@ -1651,10 +1644,8 @@ void idle(void) {
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
@ -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) {
//
@ -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;

View file

@ -129,10 +129,13 @@ 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;

View file

@ -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,7 +207,7 @@ 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);
@ -227,6 +216,9 @@ int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
addOrUpdateAgent((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType, agentId);
}
// read out our ID from the packet
unpackAgentId(readPtr, &_ownerID);
return readAgents;
}

View file

@ -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;

View file

@ -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,10 +123,10 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
bearing = bearing > 0
? bearing - AGENT_LOOPBACK_MODIFIER
: bearing + AGENT_LOOPBACK_MODIFIER;
} else {
_shouldLoopbackForAgent = false;
}
dataPtr += sizeof(float);
sourceBuffer = dataPtr;
}

View file

@ -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
View file

View 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);
}