mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into occlusion_culling
This commit is contained in:
commit
8320925add
22 changed files with 365 additions and 242 deletions
|
@ -244,7 +244,6 @@ static void renderMovingBug() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
float intensity = 0.5f;
|
||||
float intensityIncrement = 0.1f;
|
||||
const float MAX_INTENSITY = 1.0f;
|
||||
|
@ -644,14 +643,14 @@ void* animateVoxels(void* args) {
|
|||
sendDanceFloor();
|
||||
}
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedSeconds = (end - ::start) / 1000000.0;
|
||||
long long end = usecTimestampNow();
|
||||
long long elapsedSeconds = (end - ::start) / 1000000;
|
||||
if (::shouldShowPacketsPerSecond) {
|
||||
printf("packetsSent=%ld, bytesSent=%ld pps=%f bps=%f\n",packetsSent,bytesSent,
|
||||
(float)(packetsSent/elapsedSeconds),(float)(bytesSent/elapsedSeconds));
|
||||
}
|
||||
// dynamically sleep until we need to fire off the next set of voxels
|
||||
double usecToSleep = ANIMATE_VOXELS_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSendTime));
|
||||
long long usecToSleep = ANIMATE_VOXELS_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSendTime));
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
|
|
@ -318,7 +318,7 @@ int main(int argc, const char* argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
double usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||
long long usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
|
|
@ -133,37 +133,26 @@ int main(int argc, const char * argv[])
|
|||
if (numInterestTypes > 0) {
|
||||
// if the agent has sent no types of interest, assume they want nothing but their own ID back
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType)) {
|
||||
if (memchr(agentTypesOfInterest, agent->getType(), numInterestTypes)) {
|
||||
// this is not the agent themselves
|
||||
// and this is an agent of a type in the passed agent types of interest
|
||||
// or the agent did not pass us any specific types they are interested in
|
||||
|
||||
if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) {
|
||||
// this is an agent of which there can be multiple, just add them to the packet
|
||||
// don't send avatar agents to other avatars, that will come from avatar mixer
|
||||
if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) {
|
||||
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent));
|
||||
}
|
||||
|
||||
} else {
|
||||
// solo agent, we need to only send newest
|
||||
if (newestSoloAgents[agent->getType()] == NULL ||
|
||||
newestSoloAgents[agent->getType()]->getWakeMicrostamp() < agent->getWakeMicrostamp()) {
|
||||
// we have to set the newer solo agent to add it to the broadcast later
|
||||
newestSoloAgents[agent->getType()] = &(*agent);
|
||||
}
|
||||
if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType) &&
|
||||
memchr(agentTypesOfInterest, agent->getType(), numInterestTypes)) {
|
||||
// this is not the agent themselves
|
||||
// and this is an agent of a type in the passed agent types of interest
|
||||
// or the agent did not pass us any specific types they are interested in
|
||||
|
||||
if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) {
|
||||
// this is an agent of which there can be multiple, just add them to the packet
|
||||
// don't send avatar agents to other avatars, that will come from avatar mixer
|
||||
if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) {
|
||||
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
double timeNow = usecTimestampNow();
|
||||
|
||||
// this is the agent, just update last receive to now
|
||||
agent->setLastHeardMicrostamp(timeNow);
|
||||
|
||||
if (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY
|
||||
&& memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) {
|
||||
agent->setWakeMicrostamp(timeNow);
|
||||
} else {
|
||||
// solo agent, we need to only send newest
|
||||
if (newestSoloAgents[agent->getType()] == NULL ||
|
||||
newestSoloAgents[agent->getType()]->getWakeMicrostamp() < agent->getWakeMicrostamp()) {
|
||||
// we have to set the newer solo agent to add it to the broadcast later
|
||||
newestSoloAgents[agent->getType()] = &(*agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +164,15 @@ int main(int argc, const char * argv[])
|
|||
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, soloAgent->second);
|
||||
}
|
||||
}
|
||||
|
||||
// update last receive to now
|
||||
long long timeNow = usecTimestampNow();
|
||||
newAgent->setLastHeardMicrostamp(timeNow);
|
||||
|
||||
if (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY
|
||||
&& memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) {
|
||||
newAgent->setWakeMicrostamp(timeNow);
|
||||
}
|
||||
|
||||
// add the agent ID to the end of the pointer
|
||||
currentBufferPos += packAgentId(currentBufferPos, newAgent->getAgentID());
|
||||
|
|
|
@ -128,7 +128,7 @@ int main(int argc, const char* argv[]) {
|
|||
broadcastPacket[0] = PACKET_HEADER_HEAD_DATA;
|
||||
|
||||
timeval thisSend;
|
||||
double numMicrosecondsSleep = 0;
|
||||
long long numMicrosecondsSleep = 0;
|
||||
|
||||
int handStateTimer = 0;
|
||||
|
||||
|
@ -212,4 +212,4 @@ int main(int argc, const char* argv[]) {
|
|||
// stop the agent list's threads
|
||||
agentList->stopPingUnknownAgentsThread();
|
||||
agentList->stopSilentAgentRemovalThread();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ int main(int argc, char* argv[]) {
|
|||
unsigned char broadcastPacket = PACKET_HEADER_INJECT_AUDIO;
|
||||
|
||||
timeval thisSend;
|
||||
double numMicrosecondsSleep = 0;
|
||||
long long numMicrosecondsSleep = 0;
|
||||
|
||||
timeval lastDomainServerCheckIn = {};
|
||||
|
||||
|
|
|
@ -64,8 +64,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
const bool TESTING_AVATAR_TOUCH = false;
|
||||
|
||||
// Starfield information
|
||||
static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
|
||||
static char STAR_CACHE_FILE[] = "cachedStars.txt";
|
||||
|
@ -512,6 +510,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
|
||||
case Qt::Key_E:
|
||||
if (!_myAvatar.getDriveKeys(UP)) {
|
||||
_myAvatar.jump();
|
||||
}
|
||||
_myAvatar.setDriveKeys(UP, 1);
|
||||
break;
|
||||
|
||||
|
@ -722,6 +723,9 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
if (event->button() == Qt::LeftButton) {
|
||||
_mouseX = event->x();
|
||||
_mouseY = event->y();
|
||||
_mouseDragStartedX = _mouseX;
|
||||
_mouseDragStartedY = _mouseY;
|
||||
_mouseVoxelDragging = _mouseVoxel;
|
||||
_mousePressed = true;
|
||||
maybeEditVoxelUnderCursor();
|
||||
|
||||
|
@ -1018,6 +1022,12 @@ static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) {
|
|||
}
|
||||
}
|
||||
|
||||
const glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel) {
|
||||
return glm::vec3((_mouseVoxel.x + _mouseVoxel.s / 2.f) * TREE_SCALE,
|
||||
(_mouseVoxel.y + _mouseVoxel.s / 2.f) * TREE_SCALE,
|
||||
(_mouseVoxel.z + _mouseVoxel.s / 2.f) * TREE_SCALE);
|
||||
}
|
||||
|
||||
void Application::decreaseVoxelSize() {
|
||||
_mouseVoxelScale /= 2;
|
||||
}
|
||||
|
@ -1227,7 +1237,7 @@ void Application::initMenu() {
|
|||
(_gyroLook = optionsMenu->addAction("Gyro Look"))->setCheckable(true);
|
||||
_gyroLook->setChecked(false);
|
||||
(_mouseLook = optionsMenu->addAction("Mouse Look"))->setCheckable(true);
|
||||
_mouseLook->setChecked(false);
|
||||
_mouseLook->setChecked(true);
|
||||
(_showHeadMouse = optionsMenu->addAction("Head Mouse"))->setCheckable(true);
|
||||
_showHeadMouse->setChecked(false);
|
||||
(_transmitterDrives = optionsMenu->addAction("Transmitter Drive"))->setCheckable(true);
|
||||
|
@ -1251,7 +1261,6 @@ void Application::initMenu() {
|
|||
_renderAtmosphereOn->setShortcut(Qt::SHIFT | Qt::Key_A);
|
||||
(_renderGroundPlaneOn = renderMenu->addAction("Ground Plane"))->setCheckable(true);
|
||||
_renderGroundPlaneOn->setChecked(true);
|
||||
_renderGroundPlaneOn->setShortcut(Qt::SHIFT | Qt::Key_G);
|
||||
(_renderAvatarsOn = renderMenu->addAction("Avatars"))->setCheckable(true);
|
||||
_renderAvatarsOn->setChecked(true);
|
||||
(_renderAvatarBalls = renderMenu->addAction("Avatar as Balls"))->setCheckable(true);
|
||||
|
@ -1446,6 +1455,26 @@ void Application::update(float deltaTime) {
|
|||
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
|
||||
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
|
||||
|
||||
// If we are dragging on a voxel, add thrust according to the amount the mouse is dragging
|
||||
const float VOXEL_GRAB_THRUST = 5.0f;
|
||||
if (_mousePressed && (_mouseVoxel.s != 0)) {
|
||||
glm::vec2 mouseDrag(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY);
|
||||
glm::quat orientation = _myAvatar.getOrientation();
|
||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||
glm::vec3 up = orientation * IDENTITY_UP;
|
||||
glm::vec3 towardVoxel = getMouseVoxelWorldCoordinates(_mouseVoxelDragging)
|
||||
- _myAvatar.getCameraPosition();
|
||||
towardVoxel = front * glm::length(towardVoxel);
|
||||
glm::vec3 lateralToVoxel = glm::cross(up, glm::normalize(towardVoxel)) * glm::length(towardVoxel);
|
||||
_voxelThrust = glm::vec3(0, 0, 0);
|
||||
_voxelThrust += towardVoxel * VOXEL_GRAB_THRUST * deltaTime * mouseDrag.y;
|
||||
_voxelThrust += lateralToVoxel * VOXEL_GRAB_THRUST * deltaTime * mouseDrag.x;
|
||||
|
||||
// Add thrust from voxel grabbing to the avatar
|
||||
_myAvatar.addThrust(_voxelThrust);
|
||||
|
||||
}
|
||||
|
||||
_mouseVoxel.s = 0.0f;
|
||||
if (checkedVoxelModeAction() != 0 &&
|
||||
(fabs(_myAvatar.getVelocity().x) +
|
||||
|
@ -1574,30 +1603,27 @@ void Application::update(float deltaTime) {
|
|||
_myAvatar.simulate(deltaTime, NULL);
|
||||
}
|
||||
|
||||
if (TESTING_AVATAR_TOUCH) {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
|
||||
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||
_myCamera.setModeShiftRate(1.0f);
|
||||
}
|
||||
} else {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) {
|
||||
if (_manualFirstPerson->isChecked()) {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
|
||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
_myCamera.setModeShiftRate(1.0f);
|
||||
}
|
||||
} else {
|
||||
if (_myAvatar.getIsNearInteractingOther()) {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
|
||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
_myCamera.setModeShiftRate(1.0f);
|
||||
}
|
||||
} else {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
|
||||
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||
_myCamera.setModeShiftRate(1.0f);
|
||||
}
|
||||
} else {
|
||||
const float THIRD_PERSON_SHIFT_VELOCITY = 2.0f;
|
||||
const float TIME_BEFORE_SHIFT_INTO_FIRST_PERSON = 0.75f;
|
||||
const float TIME_BEFORE_SHIFT_INTO_THIRD_PERSON = 0.1f;
|
||||
|
||||
if ((_myAvatar.getElapsedTimeStopped() > TIME_BEFORE_SHIFT_INTO_FIRST_PERSON)
|
||||
&& (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON)) {
|
||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
_myCamera.setModeShiftRate(1.0f);
|
||||
}
|
||||
if ((_myAvatar.getSpeed() > THIRD_PERSON_SHIFT_VELOCITY)
|
||||
&& (_myAvatar.getElapsedTimeMoving() > TIME_BEFORE_SHIFT_INTO_THIRD_PERSON)
|
||||
&& (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON)) {
|
||||
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||
_myCamera.setModeShiftRate(1000.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2050,6 +2076,10 @@ void Application::displaySide(Camera& whichCamera) {
|
|||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Enable to show line from me to the voxel I am touching
|
||||
//renderLineToTouchedVoxel();
|
||||
//renderThrustAtVoxel(_voxelThrust);
|
||||
|
||||
// draw a red sphere
|
||||
float sphereRadius = 0.25f;
|
||||
glColor3f(1,0,0);
|
||||
|
@ -2169,9 +2199,8 @@ void Application::displayOverlay() {
|
|||
// Show on-screen msec timer
|
||||
if (_renderFrameTimerOn->isChecked()) {
|
||||
char frameTimer[10];
|
||||
double mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
|
||||
mSecsNow = mSecsNow - floor(mSecsNow / 1000.0) * 1000.0;
|
||||
sprintf(frameTimer, "%3.0f\n", mSecsNow);
|
||||
long long mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
|
||||
sprintf(frameTimer, "%d\n", (int)(mSecsNow % 1000));
|
||||
drawtext(_glWidget->width() - 100, _glWidget->height() - 20, 0.30, 0, 1.0, 0, frameTimer, 0, 0, 0);
|
||||
drawtext(_glWidget->width() - 102, _glWidget->height() - 22, 0.30, 0, 1.0, 0, frameTimer, 1, 1, 1);
|
||||
}
|
||||
|
@ -2271,6 +2300,32 @@ void Application::displayStats() {
|
|||
|
||||
}
|
||||
|
||||
void Application::renderThrustAtVoxel(const glm::vec3& thrust) {
|
||||
if (_mousePressed) {
|
||||
glColor3f(1, 0, 0);
|
||||
glLineWidth(2.0f);
|
||||
glBegin(GL_LINES);
|
||||
glm::vec3 voxelTouched = getMouseVoxelWorldCoordinates(_mouseVoxelDragging);
|
||||
glVertex3f(voxelTouched.x, voxelTouched.y, voxelTouched.z);
|
||||
glVertex3f(voxelTouched.x + thrust.x, voxelTouched.y + thrust.y, voxelTouched.z + thrust.z);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
void Application::renderLineToTouchedVoxel() {
|
||||
// Draw a teal line to the voxel I am currently dragging on
|
||||
if (_mousePressed) {
|
||||
glColor3f(0, 1, 1);
|
||||
glLineWidth(2.0f);
|
||||
glBegin(GL_LINES);
|
||||
glm::vec3 voxelTouched = getMouseVoxelWorldCoordinates(_mouseVoxelDragging);
|
||||
glVertex3f(voxelTouched.x, voxelTouched.y, voxelTouched.z);
|
||||
glm::vec3 headPosition = _myAvatar.getHeadJointPosition();
|
||||
glVertex3fv(&headPosition.x);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// renderViewFrustum()
|
||||
//
|
||||
|
@ -2547,6 +2602,8 @@ void Application::resetSensors() {
|
|||
QCursor::setPos(_headMouseX, _headMouseY);
|
||||
_myAvatar.reset();
|
||||
_myTransmitter.resetLevels();
|
||||
_myAvatar.setVelocity(glm::vec3(0,0,0));
|
||||
_myAvatar.setThrust(glm::vec3(0,0,0));
|
||||
}
|
||||
|
||||
static void setShortcutsEnabled(QWidget* widget, bool enabled) {
|
||||
|
|
|
@ -67,6 +67,8 @@ public:
|
|||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel);
|
||||
|
||||
Avatar* getAvatar() { return &_myAvatar; }
|
||||
Camera* getCamera() { return &_myCamera; }
|
||||
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
|
||||
|
@ -93,6 +95,9 @@ private slots:
|
|||
|
||||
void setRenderFirstPerson(bool firstPerson);
|
||||
|
||||
void renderThrustAtVoxel(const glm::vec3& thrust);
|
||||
void renderLineToTouchedVoxel();
|
||||
|
||||
void setFrustumOffset(bool frustumOffset);
|
||||
void cycleFrustumRenderMode();
|
||||
|
||||
|
@ -147,7 +152,7 @@ private:
|
|||
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
|
||||
|
||||
void renderViewFrustum(ViewFrustum& viewFrustum);
|
||||
|
||||
|
||||
void setupPaintingVoxel();
|
||||
void shiftPaintingColor();
|
||||
void maybeEditVoxelUnderCursor();
|
||||
|
@ -262,7 +267,12 @@ private:
|
|||
|
||||
int _mouseX;
|
||||
int _mouseY;
|
||||
int _mouseDragStartedX;
|
||||
int _mouseDragStartedY;
|
||||
VoxelDetail _mouseVoxelDragging;
|
||||
glm::vec3 _voxelThrust;
|
||||
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
||||
|
||||
|
||||
VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor
|
||||
float _mouseVoxelScale; // the scale for adding/removing voxels
|
||||
|
|
|
@ -77,6 +77,7 @@ Avatar::Avatar(Agent* owningAgent) :
|
|||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||
_velocity(0.0f, 0.0f, 0.0f),
|
||||
_thrust(0.0f, 0.0f, 0.0f),
|
||||
_shouldJump(false),
|
||||
_speed(0.0f),
|
||||
_maxArmLength(0.0f),
|
||||
_leanScale(0.5f),
|
||||
|
@ -89,6 +90,9 @@ Avatar::Avatar(Agent* owningAgent) :
|
|||
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||
_interactingOther(NULL),
|
||||
_isMouseTurningRight(false),
|
||||
_elapsedTimeMoving(0.0f),
|
||||
_elapsedTimeStopped(0.0f),
|
||||
_elapsedTimeSinceCollision(0.0f),
|
||||
_voxels(this)
|
||||
{
|
||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||
|
@ -316,40 +320,128 @@ glm::vec3 Avatar::getUprightHeadPosition() const {
|
|||
|
||||
void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight) {
|
||||
// Update head yaw and pitch based on mouse input
|
||||
const float MOUSE_MOVE_RADIUS = 0.3f;
|
||||
const float MOUSE_ROTATE_SPEED = 4.0f;
|
||||
const float MOUSE_PITCH_SPEED = 2.0f;
|
||||
const float MOUSE_ROTATE_SPEED = 0.01f;
|
||||
const float MOUSE_PITCH_SPEED = 0.02f;
|
||||
const int TITLE_BAR_HEIGHT = 46;
|
||||
float mouseLocationX = (float)mouseX / (float)screenWidth - 0.5f;
|
||||
float mouseLocationY = (float)mouseY / (float)screenHeight - 0.5f;
|
||||
|
||||
if ((mouseX > 1) && (mouseX < screenWidth) && (mouseY > TITLE_BAR_HEIGHT) && (mouseY < screenHeight)) {
|
||||
//
|
||||
// Mouse must be inside screen (not at edge) and not on title bar for movement to happen
|
||||
//
|
||||
if (mouseLocationX > MOUSE_MOVE_RADIUS) {
|
||||
_head.addYaw(-(mouseLocationX - MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_ROTATE_SPEED);
|
||||
} else if (mouseLocationX < -MOUSE_MOVE_RADIUS) {
|
||||
_head.addYaw(-(mouseLocationX + MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_ROTATE_SPEED);
|
||||
}
|
||||
|
||||
if (mouseLocationY > MOUSE_MOVE_RADIUS) {
|
||||
_head.addPitch(-(mouseLocationY - MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_PITCH_SPEED);
|
||||
} else if (mouseLocationY < -MOUSE_MOVE_RADIUS) {
|
||||
_head.addPitch(-(mouseLocationY + MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_PITCH_SPEED);
|
||||
int pixelMoveThreshold = screenWidth / 6;
|
||||
glm::vec2 mouseVector(mouseX - (screenWidth / 2), mouseY - (screenHeight / 2));
|
||||
if (glm::length(mouseVector) > pixelMoveThreshold) {
|
||||
mouseVector -= glm::normalize(mouseVector) * (float) pixelMoveThreshold;
|
||||
_head.addYaw(-mouseVector.x * MOUSE_ROTATE_SPEED);
|
||||
_head.addPitch(-mouseVector.y * MOUSE_PITCH_SPEED);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
||||
//
|
||||
// Gather thrust information from keyboard and sensors to apply to avatar motion
|
||||
//
|
||||
glm::quat orientation = getOrientation();
|
||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||
glm::vec3 right = orientation * IDENTITY_RIGHT;
|
||||
glm::vec3 up = orientation * IDENTITY_UP;
|
||||
|
||||
const float THRUST_MAG_UP = 800.0f;
|
||||
const float THRUST_MAG_DOWN = 200.f;
|
||||
const float THRUST_MAG_FWD = 300.f;
|
||||
const float THRUST_MAG_BACK = 150.f;
|
||||
const float THRUST_MAG_LATERAL = 200.f;
|
||||
const float THRUST_JUMP = 120.f;
|
||||
|
||||
// Add Thrusts from keyboard
|
||||
if (_driveKeys[FWD ]) {_thrust += THRUST_MAG_FWD * deltaTime * front;}
|
||||
if (_driveKeys[BACK ]) {_thrust -= THRUST_MAG_BACK * deltaTime * front;}
|
||||
if (_driveKeys[RIGHT ]) {_thrust += THRUST_MAG_LATERAL * deltaTime * right;}
|
||||
if (_driveKeys[LEFT ]) {_thrust -= THRUST_MAG_LATERAL * deltaTime * right;}
|
||||
if (_driveKeys[UP ]) {_thrust += THRUST_MAG_UP * deltaTime * up;}
|
||||
if (_driveKeys[DOWN ]) {_thrust -= THRUST_MAG_DOWN * deltaTime * up;}
|
||||
if (_driveKeys[ROT_RIGHT]) {_bodyYawDelta -= YAW_MAG * deltaTime;}
|
||||
if (_driveKeys[ROT_LEFT ]) {_bodyYawDelta += YAW_MAG * deltaTime;}
|
||||
|
||||
// Add one time jumping force if requested
|
||||
if (_shouldJump) {
|
||||
_thrust += THRUST_JUMP * up;
|
||||
_shouldJump = false;
|
||||
}
|
||||
|
||||
// Add thrusts from Transmitter
|
||||
if (transmitter) {
|
||||
transmitter->checkForLostTransmitter();
|
||||
glm::vec3 rotation = transmitter->getEstimatedRotation();
|
||||
const float TRANSMITTER_MIN_RATE = 1.f;
|
||||
const float TRANSMITTER_MIN_YAW_RATE = 4.f;
|
||||
const float TRANSMITTER_LATERAL_FORCE_SCALE = 5.f;
|
||||
const float TRANSMITTER_FWD_FORCE_SCALE = 25.f;
|
||||
const float TRANSMITTER_UP_FORCE_SCALE = 100.f;
|
||||
const float TRANSMITTER_YAW_SCALE = 10.0f;
|
||||
const float TRANSMITTER_LIFT_SCALE = 3.f;
|
||||
const float TOUCH_POSITION_RANGE_HALF = 32767.f;
|
||||
if (fabs(rotation.z) > TRANSMITTER_MIN_RATE) {
|
||||
_thrust += rotation.z * TRANSMITTER_LATERAL_FORCE_SCALE * deltaTime * right;
|
||||
}
|
||||
if (fabs(rotation.x) > TRANSMITTER_MIN_RATE) {
|
||||
_thrust += -rotation.x * TRANSMITTER_FWD_FORCE_SCALE * deltaTime * front;
|
||||
}
|
||||
if (fabs(rotation.y) > TRANSMITTER_MIN_YAW_RATE) {
|
||||
_bodyYawDelta += rotation.y * TRANSMITTER_YAW_SCALE * deltaTime;
|
||||
}
|
||||
if (transmitter->getTouchState()->state == 'D') {
|
||||
_thrust += TRANSMITTER_UP_FORCE_SCALE *
|
||||
(float)(transmitter->getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF *
|
||||
TRANSMITTER_LIFT_SCALE *
|
||||
deltaTime *
|
||||
up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||
|
||||
//figure out if the mouse cursor is over any body spheres...
|
||||
checkForMouseRayTouching();
|
||||
glm::quat orientation = getOrientation();
|
||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||
glm::vec3 right = orientation * IDENTITY_RIGHT;
|
||||
|
||||
// Update movement timers
|
||||
if (!_owningAgent) {
|
||||
_elapsedTimeSinceCollision += deltaTime;
|
||||
const float VELOCITY_MOVEMENT_TIMER_THRESHOLD = 0.2f;
|
||||
if (glm::length(_velocity) < VELOCITY_MOVEMENT_TIMER_THRESHOLD) {
|
||||
_elapsedTimeMoving = 0.f;
|
||||
_elapsedTimeStopped += deltaTime;
|
||||
} else {
|
||||
_elapsedTimeStopped = 0.f;
|
||||
_elapsedTimeMoving += deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect thrust forces from keyboard and devices
|
||||
if (!_owningAgent) {
|
||||
updateThrust(deltaTime, transmitter);
|
||||
}
|
||||
|
||||
// copy velocity so we can use it later for acceleration
|
||||
glm::vec3 oldVelocity = getVelocity();
|
||||
|
||||
if (!_owningAgent) {
|
||||
// update position by velocity
|
||||
_position += _velocity * deltaTime;
|
||||
|
||||
// calculate speed
|
||||
_speed = glm::length(_velocity);
|
||||
}
|
||||
|
||||
//figure out if the mouse cursor is over any body spheres...
|
||||
if (!_owningAgent) {
|
||||
checkForMouseRayTouching();
|
||||
}
|
||||
|
||||
// update balls
|
||||
if (_balls) { _balls->simulate(deltaTime); }
|
||||
|
||||
|
@ -391,12 +483,13 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
|
||||
//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 (!_owningAgent && USING_AVATAR_GRAVITY) {
|
||||
_velocity += _gravity * (GRAVITY_EARTH * deltaTime);
|
||||
}
|
||||
if (!_owningAgent) {
|
||||
updateCollisionWithEnvironment();
|
||||
}
|
||||
|
||||
|
@ -413,57 +506,11 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
updateCollisionWithVoxels();
|
||||
}
|
||||
|
||||
glm::quat orientation = getOrientation();
|
||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||
glm::vec3 right = orientation * IDENTITY_RIGHT;
|
||||
glm::vec3 up = orientation * IDENTITY_UP;
|
||||
|
||||
// driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely)
|
||||
const float THRUST_MAG = 600.0f;
|
||||
|
||||
if (!_owningAgent) {
|
||||
|
||||
_thrust = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Add Thrusts from keyboard
|
||||
if (_driveKeys[FWD ]) {_thrust += THRUST_MAG * deltaTime * front;}
|
||||
if (_driveKeys[BACK ]) {_thrust -= THRUST_MAG * deltaTime * front;}
|
||||
if (_driveKeys[RIGHT ]) {_thrust += THRUST_MAG * deltaTime * right;}
|
||||
if (_driveKeys[LEFT ]) {_thrust -= THRUST_MAG * deltaTime * right;}
|
||||
if (_driveKeys[UP ]) {_thrust += THRUST_MAG * deltaTime * up;}
|
||||
if (_driveKeys[DOWN ]) {_thrust -= THRUST_MAG * deltaTime * up;}
|
||||
if (_driveKeys[ROT_RIGHT]) {_bodyYawDelta -= YAW_MAG * deltaTime;}
|
||||
if (_driveKeys[ROT_LEFT ]) {_bodyYawDelta += YAW_MAG * deltaTime;}
|
||||
|
||||
// Add thrusts from Transmitter
|
||||
if (transmitter) {
|
||||
transmitter->checkForLostTransmitter();
|
||||
glm::vec3 rotation = transmitter->getEstimatedRotation();
|
||||
const float TRANSMITTER_MIN_RATE = 1.f;
|
||||
const float TRANSMITTER_MIN_YAW_RATE = 4.f;
|
||||
const float TRANSMITTER_LATERAL_FORCE_SCALE = 25.f;
|
||||
const float TRANSMITTER_FWD_FORCE_SCALE = 100.f;
|
||||
const float TRANSMITTER_YAW_SCALE = 10.0f;
|
||||
const float TRANSMITTER_LIFT_SCALE = 3.f;
|
||||
const float TOUCH_POSITION_RANGE_HALF = 32767.f;
|
||||
if (fabs(rotation.z) > TRANSMITTER_MIN_RATE) {
|
||||
_thrust += rotation.z * TRANSMITTER_LATERAL_FORCE_SCALE * deltaTime * right;
|
||||
}
|
||||
if (fabs(rotation.x) > TRANSMITTER_MIN_RATE) {
|
||||
_thrust += -rotation.x * TRANSMITTER_FWD_FORCE_SCALE * deltaTime * front;
|
||||
}
|
||||
if (fabs(rotation.y) > TRANSMITTER_MIN_YAW_RATE) {
|
||||
_bodyYawDelta += rotation.y * TRANSMITTER_YAW_SCALE * deltaTime;
|
||||
}
|
||||
if (transmitter->getTouchState()->state == 'D') {
|
||||
_thrust += THRUST_MAG *
|
||||
(float)(transmitter->getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF *
|
||||
TRANSMITTER_LIFT_SCALE *
|
||||
deltaTime *
|
||||
up;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// add thrust to velocity
|
||||
_velocity += _thrust * deltaTime;
|
||||
|
||||
// update body yaw by body yaw delta
|
||||
orientation = orientation * glm::quat(glm::radians(
|
||||
glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime));
|
||||
|
@ -475,12 +522,22 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
_bodyYawDelta *= bodySpinMomentum;
|
||||
_bodyRollDelta *= bodySpinMomentum;
|
||||
|
||||
// add thrust to velocity
|
||||
_velocity += _thrust * deltaTime;
|
||||
|
||||
// calculate speed
|
||||
_speed = glm::length(_velocity);
|
||||
|
||||
// Decay velocity. If velocity is really low, increase decay to simulate static friction
|
||||
const float VELOCITY_DECAY_UNDER_THRUST = 0.2;
|
||||
const float VELOCITY_FAST_DECAY = 0.6;
|
||||
const float VELOCITY_SLOW_DECAY = 3.0;
|
||||
const float VELOCITY_FAST_THRESHOLD = 2.0f;
|
||||
float decayConstant, decay;
|
||||
if (glm::length(_thrust) > 0.f) {
|
||||
decayConstant = VELOCITY_DECAY_UNDER_THRUST;
|
||||
} else if (glm::length(_velocity) > VELOCITY_FAST_THRESHOLD) {
|
||||
decayConstant = VELOCITY_FAST_DECAY;
|
||||
} else {
|
||||
decayConstant = VELOCITY_SLOW_DECAY;
|
||||
}
|
||||
decay = glm::clamp(1.0f - decayConstant * deltaTime, 0.0f, 1.0f);
|
||||
_velocity *= decay;
|
||||
|
||||
//pitch and roll the body as a function of forward speed and turning delta
|
||||
const float BODY_PITCH_WHILE_WALKING = -20.0;
|
||||
const float BODY_ROLL_WHILE_TURNING = 0.2;
|
||||
|
@ -500,29 +557,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
//the following will be used to make the avatar upright no matter what gravity is
|
||||
setOrientation(computeRotationFromBodyToWorldUp(tiltDecay) * orientation);
|
||||
|
||||
// update position by velocity
|
||||
_position += _velocity * deltaTime;
|
||||
|
||||
// decay velocity
|
||||
const float VELOCITY_DECAY = 0.9;
|
||||
float decay = 1.0 - VELOCITY_DECAY * deltaTime;
|
||||
if ( decay < 0.0 ) {
|
||||
_velocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
} else {
|
||||
_velocity *= decay;
|
||||
}
|
||||
|
||||
// If another avatar is near, dampen velocity as a function of closeness
|
||||
if (_distanceToNearestAvatar < PERIPERSONAL_RADIUS) {
|
||||
float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS);
|
||||
float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime;
|
||||
if ( drag > 0.0f ) {
|
||||
_velocity *= drag;
|
||||
} else {
|
||||
_velocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
// Compute instantaneous acceleration
|
||||
float forwardAcceleration = glm::length(glm::dot(getBodyFrontDirection(), getVelocity() - oldVelocity)) / deltaTime;
|
||||
const float ACCELERATION_PITCH_DECAY = 0.4f;
|
||||
|
@ -602,6 +636,10 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
} else {
|
||||
_mode = AVATAR_MODE_INTERACTING;
|
||||
}
|
||||
|
||||
// Zero thrust out now that we've added it to velocity in this frame
|
||||
_thrust = glm::vec3(0, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
void Avatar::checkForMouseRayTouching() {
|
||||
|
@ -782,41 +820,52 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d
|
|||
}
|
||||
|
||||
void Avatar::updateCollisionWithEnvironment() {
|
||||
|
||||
glm::vec3 up = getBodyUpDirection();
|
||||
float radius = _height * 0.125f;
|
||||
const float ENVIRONMENT_SURFACE_ELASTICITY = 1.0f;
|
||||
const float ENVIRONMENT_SURFACE_DAMPING = 0.01;
|
||||
glm::vec3 penetration;
|
||||
if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
|
||||
_position - up * (_pelvisFloatingHeight - radius),
|
||||
_position + up * (_height - _pelvisFloatingHeight - radius), radius, penetration)) {
|
||||
applyCollisionWithScene(penetration);
|
||||
applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Avatar::updateCollisionWithVoxels() {
|
||||
float radius = _height * 0.125f;
|
||||
const float VOXEL_ELASTICITY = 1.4f;
|
||||
const float VOXEL_DAMPING = 0.0;
|
||||
glm::vec3 penetration;
|
||||
if (Application::getInstance()->getVoxels()->findCapsulePenetration(
|
||||
_position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f),
|
||||
_position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) {
|
||||
applyCollisionWithScene(penetration);
|
||||
applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::applyCollisionWithScene(const glm::vec3& penetration) {
|
||||
void Avatar::applyHardCollision(const glm::vec3& penetration, float elasticity, float damping) {
|
||||
//
|
||||
// Update the avatar in response to a hard collision. Position will be reset exactly
|
||||
// to outside the colliding surface. Velocity will be modified according to elasticity.
|
||||
//
|
||||
// if elasticity = 1.0, collision is inelastic.
|
||||
// if elasticity > 1.0, collision is elastic.
|
||||
//
|
||||
_position -= penetration;
|
||||
static float STATIC_FRICTION_VELOCITY = 0.15f;
|
||||
static float STATIC_FRICTION_DAMPING = 0.0f;
|
||||
static float KINETIC_FRICTION_DAMPING = 0.95f;
|
||||
|
||||
static float HALTING_VELOCITY = 0.2f;
|
||||
// cancel out the velocity component in the direction of penetration
|
||||
float penetrationLength = glm::length(penetration);
|
||||
if (penetrationLength > EPSILON) {
|
||||
_elapsedTimeSinceCollision = 0.0f;
|
||||
glm::vec3 direction = penetration / penetrationLength;
|
||||
_velocity -= glm::dot(_velocity, direction) * direction;
|
||||
_velocity *= KINETIC_FRICTION_DAMPING;
|
||||
// If velocity is quite low, apply static friction that takes away energy
|
||||
if (glm::length(_velocity) < STATIC_FRICTION_VELOCITY) {
|
||||
_velocity *= STATIC_FRICTION_DAMPING;
|
||||
_velocity -= glm::dot(_velocity, direction) * direction * elasticity;
|
||||
_velocity *= glm::clamp(1.f - damping, 0.0f, 1.0f);
|
||||
if ((glm::length(_velocity) < HALTING_VELOCITY) && (glm::length(_thrust) == 0.f)) {
|
||||
// If moving really slowly after a collision, and not applying forces, stop altogether
|
||||
_velocity *= 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -839,7 +888,6 @@ void Avatar::updateAvatarCollisions(float deltaTime) {
|
|||
// apply forces from collision
|
||||
applyCollisionWithOtherAvatar(otherAvatar, deltaTime);
|
||||
}
|
||||
|
||||
// test other avatar hand position for proximity
|
||||
glm::vec3 v(_skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position);
|
||||
v -= otherAvatar->getPosition();
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, Transmitter* transmitter);
|
||||
void updateThrust(float deltaTime, Transmitter * transmitter);
|
||||
void updateHeadFromGyros(float frametime, SerialInterface * serialInterface);
|
||||
void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight);
|
||||
void addBodyYaw(float y) {_bodyYaw += y;};
|
||||
|
@ -96,6 +97,7 @@ public:
|
|||
void setMovedHandOffset (glm::vec3 movedHandOffset ) { _movedHandOffset = movedHandOffset;}
|
||||
void setThrust (glm::vec3 newThrust ) { _thrust = newThrust; };
|
||||
void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors);}
|
||||
void setVelocity (const glm::vec3 velocity ) { _velocity = velocity; };
|
||||
void setLeanScale (float scale ) { _leanScale = scale;}
|
||||
void setGravity (glm::vec3 gravity);
|
||||
void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction);
|
||||
|
@ -117,6 +119,9 @@ public:
|
|||
float getHeight () const { return _height;}
|
||||
AvatarMode getMode () const { return _mode;}
|
||||
float getLeanScale () const { return _leanScale;}
|
||||
float getElapsedTimeStopped () const { return _elapsedTimeStopped;}
|
||||
float getElapsedTimeMoving () const { return _elapsedTimeMoving;}
|
||||
float getElapsedTimeSinceCollision() const { return _elapsedTimeSinceCollision;}
|
||||
float getAbsoluteHeadYaw () const;
|
||||
float getAbsoluteHeadPitch () const;
|
||||
Head& getHead () {return _head; }
|
||||
|
@ -130,6 +135,7 @@ public:
|
|||
// Set what driving keys are being pressed to control thrust levels
|
||||
void setDriveKeys(int key, bool val) { _driveKeys[key] = val; };
|
||||
bool getDriveKeys(int key) { return _driveKeys[key]; };
|
||||
void jump() { _shouldJump = true; };
|
||||
|
||||
// Set/Get update the thrust that will move the avatar around
|
||||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||
|
@ -182,6 +188,7 @@ private:
|
|||
glm::vec3 _handHoldingPosition;
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
bool _shouldJump;
|
||||
float _speed;
|
||||
float _maxArmLength;
|
||||
float _leanScale;
|
||||
|
@ -192,13 +199,16 @@ private:
|
|||
float _height;
|
||||
Balls* _balls;
|
||||
AvatarTouch _avatarTouch;
|
||||
float _distanceToNearestAvatar; // How close is the nearest avatar?
|
||||
float _distanceToNearestAvatar; // How close is the nearest avatar?
|
||||
glm::vec3 _gravity;
|
||||
glm::vec3 _worldUpDirection;
|
||||
glm::vec3 _mouseRayOrigin;
|
||||
glm::vec3 _mouseRayDirection;
|
||||
Avatar* _interactingOther;
|
||||
bool _isMouseTurningRight;
|
||||
float _elapsedTimeMoving; // Timers to drive camera transitions when moving
|
||||
float _elapsedTimeStopped;
|
||||
float _elapsedTimeSinceCollision;
|
||||
|
||||
AvatarVoxelSystem _voxels;
|
||||
|
||||
|
@ -218,7 +228,7 @@ private:
|
|||
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
|
||||
void updateCollisionWithEnvironment();
|
||||
void updateCollisionWithVoxels();
|
||||
void applyCollisionWithScene(const glm::vec3& penetration);
|
||||
void applyHardCollision(const glm::vec3& penetration, float elasticity, float damping);
|
||||
void applyCollisionWithOtherAvatar( Avatar * other, float deltaTime );
|
||||
void checkForMouseRayTouching();
|
||||
void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
||||
|
|
|
@ -70,9 +70,7 @@ void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) {
|
|||
|
||||
// Update estimated absolute position from rotation rates
|
||||
_estimatedRotation += _lastRotationRate * DELTA_TIME;
|
||||
|
||||
printf("The accel %f, %f, %f\n", _lastAcceleration.x, _lastAcceleration.y, _lastAcceleration.z);
|
||||
|
||||
|
||||
// Sensor Fusion! Slowly adjust estimated rotation to be relative to gravity (average acceleration)
|
||||
const float GRAVITY_FOLLOW_RATE = 1.f;
|
||||
float rollAngle = angleBetween(glm::vec3(_lastAcceleration.x, _lastAcceleration.y, 0.f), glm::vec3(0,-1,0)) *
|
||||
|
|
|
@ -166,15 +166,15 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
|
||||
void VoxelSystem::setupNewVoxelsForDrawing() {
|
||||
PerformanceWarning warn(_renderWarningsOn, "setupNewVoxelsForDrawing()"); // would like to include _voxelsInArrays, _voxelsUpdated
|
||||
double start = usecTimestampNow();
|
||||
double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000.0;
|
||||
long long start = usecTimestampNow();
|
||||
long long sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
|
||||
|
||||
bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
|
||||
if (!iAmDebugging && sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
|
||||
return; // bail early, it hasn't been long enough since the last time we ran
|
||||
}
|
||||
|
||||
double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;
|
||||
long long sinceLastViewCulling = (start - _lastViewCulling) / 1000;
|
||||
// If the view frustum is no longer changing, but has changed, since last time, then remove nodes that are out of view
|
||||
if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS))
|
||||
&& !isViewChanging() && hasViewChanged()) {
|
||||
|
@ -190,8 +190,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
// VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
|
||||
cleanupRemovedVoxels();
|
||||
|
||||
double endViewCulling = usecTimestampNow();
|
||||
_lastViewCullingElapsed = (endViewCulling - start) / 1000.0;
|
||||
long long endViewCulling = usecTimestampNow();
|
||||
_lastViewCullingElapsed = (endViewCulling - start) / 1000;
|
||||
}
|
||||
|
||||
bool didWriteFullVBO = _writeRenderFullVBO;
|
||||
|
@ -227,8 +227,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
|
||||
pthread_mutex_unlock(&_bufferWriteLock);
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start) / 1000.0;
|
||||
long long end = usecTimestampNow();
|
||||
long long elapsedmsec = (end - start) / 1000;
|
||||
_setupNewVoxelsForDrawingLastFinished = end;
|
||||
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination
|
|||
|
||||
injectorSocket->send(destinationSocket, dataPacket, sizeof(dataPacket));
|
||||
|
||||
double usecToSleep = usecTimestamp(&startTime) + (++nextFrame * INJECT_INTERVAL_USECS) - usecTimestampNow();
|
||||
long long usecToSleep = usecTimestamp(&startTime) + (++nextFrame * INJECT_INTERVAL_USECS) - usecTimestampNow();
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include "Agent.h"
|
||||
#include "AgentTypes.h"
|
||||
|
|
|
@ -37,11 +37,11 @@ public:
|
|||
uint16_t getAgentID() const { return _agentID; }
|
||||
void setAgentID(uint16_t agentID) { _agentID = agentID;}
|
||||
|
||||
double getWakeMicrostamp() const { return _wakeMicrostamp; }
|
||||
void setWakeMicrostamp(double wakeMicrostamp) { _wakeMicrostamp = wakeMicrostamp; }
|
||||
long long getWakeMicrostamp() const { return _wakeMicrostamp; }
|
||||
void setWakeMicrostamp(long long wakeMicrostamp) { _wakeMicrostamp = wakeMicrostamp; }
|
||||
|
||||
double getLastHeardMicrostamp() const { return _lastHeardMicrostamp; }
|
||||
void setLastHeardMicrostamp(double lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; }
|
||||
long long getLastHeardMicrostamp() const { return _lastHeardMicrostamp; }
|
||||
void setLastHeardMicrostamp(long long lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; }
|
||||
|
||||
sockaddr* getPublicSocket() const { return _publicSocket; }
|
||||
void setPublicSocket(sockaddr* publicSocket) { _publicSocket = publicSocket; }
|
||||
|
@ -71,8 +71,8 @@ private:
|
|||
|
||||
char _type;
|
||||
uint16_t _agentID;
|
||||
double _wakeMicrostamp;
|
||||
double _lastHeardMicrostamp;
|
||||
long long _wakeMicrostamp;
|
||||
long long _lastHeardMicrostamp;
|
||||
sockaddr* _publicSocket;
|
||||
sockaddr* _localSocket;
|
||||
sockaddr* _activeSocket;
|
||||
|
|
|
@ -205,6 +205,7 @@ void AgentList::sendDomainServerCheckIn() {
|
|||
|
||||
// construct the DS check in packet if we need to
|
||||
static unsigned char* checkInPacket = NULL;
|
||||
static int checkInPacketSize;
|
||||
|
||||
if (!checkInPacket) {
|
||||
int numBytesAgentsOfInterest = _agentTypesOfInterest ? strlen((char*) _agentTypesOfInterest) : 0;
|
||||
|
@ -236,10 +237,10 @@ void AgentList::sendDomainServerCheckIn() {
|
|||
packetPosition += numBytesAgentsOfInterest;
|
||||
}
|
||||
|
||||
*packetPosition = '\0';
|
||||
checkInPacketSize = packetPosition - checkInPacket;
|
||||
}
|
||||
|
||||
_agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, strlen((char*) checkInPacket));
|
||||
_agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, checkInPacketSize);
|
||||
}
|
||||
|
||||
int AgentList::processDomainServerList(unsigned char *packetData, size_t dataBytes) {
|
||||
|
@ -392,7 +393,7 @@ void *pingUnknownAgents(void *args) {
|
|||
}
|
||||
}
|
||||
|
||||
double usecToSleep = PING_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSend));
|
||||
long long usecToSleep = PING_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSend));
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
@ -413,7 +414,7 @@ void AgentList::stopPingUnknownAgentsThread() {
|
|||
|
||||
void *removeSilentAgents(void *args) {
|
||||
AgentList* agentList = (AgentList*) args;
|
||||
double checkTimeUSecs, sleepTime;
|
||||
long long checkTimeUSecs, sleepTime;
|
||||
|
||||
while (!silentAgentThreadStopFlag) {
|
||||
checkTimeUSecs = usecTimestampNow();
|
||||
|
@ -422,7 +423,7 @@ void *removeSilentAgents(void *args) {
|
|||
|
||||
if ((checkTimeUSecs - agent->getLastHeardMicrostamp()) > AGENT_SILENCE_THRESHOLD_USECS
|
||||
&& agent->getType() != AGENT_TYPE_VOXEL_SERVER) {
|
||||
|
||||
|
||||
printLog("Killed ");
|
||||
Agent::printLog(*agent);
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ int PerfStat::DumpStats(char** array) {
|
|||
|
||||
// Destructor handles recording all of our stats
|
||||
PerformanceWarning::~PerformanceWarning() {
|
||||
double end = usecTimestampNow();
|
||||
long long end = usecTimestampNow();
|
||||
double elapsedmsec = (end - _start) / 1000.0;
|
||||
if ((_alwaysDisplay || _renderWarningsOn) && elapsedmsec > 1) {
|
||||
if (elapsedmsec > 1000) {
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef std::map<std::string,PerfStatHistory,std::less<std::string> >::iterator
|
|||
|
||||
class PerformanceWarning {
|
||||
private:
|
||||
double _start;
|
||||
long long _start;
|
||||
const char* _message;
|
||||
bool _renderWarningsOn;
|
||||
bool _alwaysDisplay;
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
double usecTimestamp(timeval *time) {
|
||||
return (time->tv_sec * 1000000.0 + time->tv_usec);
|
||||
long long usecTimestamp(timeval *time) {
|
||||
return (time->tv_sec * 1000000 + time->tv_usec);
|
||||
}
|
||||
|
||||
double usecTimestampNow() {
|
||||
long long usecTimestampNow() {
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
return (now.tv_sec * 1000000.0 + now.tv_usec);
|
||||
return (now.tv_sec * 1000000 + now.tv_usec);
|
||||
}
|
||||
|
||||
float randFloat () {
|
||||
|
|
|
@ -36,8 +36,8 @@ static const float DECIMETER = 0.1f;
|
|||
static const float CENTIMETER = 0.01f;
|
||||
static const float MILLIIMETER = 0.001f;
|
||||
|
||||
double usecTimestamp(timeval *time);
|
||||
double usecTimestampNow();
|
||||
long long usecTimestamp(timeval *time);
|
||||
long long usecTimestampNow();
|
||||
|
||||
float randFloat();
|
||||
int randIntInRange (int min, int max);
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
float getAverageSampleValuePerSecond();
|
||||
private:
|
||||
int _numSamples;
|
||||
double _lastEventTimestamp;
|
||||
long long _lastEventTimestamp;
|
||||
float _average;
|
||||
float _eventDeltaAverage;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ private:
|
|||
#endif
|
||||
glBufferIndex _glBufferIndex;
|
||||
bool _isDirty;
|
||||
double _lastChanged;
|
||||
long long _lastChanged;
|
||||
bool _shouldRender;
|
||||
bool _isStagedForDeletion;
|
||||
AABox _box;
|
||||
|
@ -80,7 +80,7 @@ public:
|
|||
void printDebugDetails(const char* label) const;
|
||||
bool isDirty() const { return _isDirty; };
|
||||
void clearDirtyBit() { _isDirty = false; };
|
||||
bool hasChangedSince(double time) const { return (_lastChanged > time); };
|
||||
bool hasChangedSince(long long time) const { return (_lastChanged > time); };
|
||||
void markWithChangedTime() { _lastChanged = usecTimestampNow(); };
|
||||
void handleSubtreeChanged(VoxelTree* myTree);
|
||||
|
||||
|
@ -103,8 +103,8 @@ public:
|
|||
void setColor(const nodeColor& color);
|
||||
const nodeColor& getTrueColor() const { return _trueColor; };
|
||||
const nodeColor& getColor() const { return _currentColor; };
|
||||
void setDensity(const float density) { _density = density; };
|
||||
const float getDensity() const { return _density; };
|
||||
void setDensity(float density) { _density = density; };
|
||||
float getDensity() const { return _density; };
|
||||
#else
|
||||
void setFalseColor(colorPart red, colorPart green, colorPart blue) { /* no op */ };
|
||||
void setFalseColored(bool isFalseColored) { /* no op */ };
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
const char* LOCAL_VOXELS_PERSIST_FILE = "resources/voxels.svo";
|
||||
const char* VOXELS_PERSIST_FILE = "/etc/highfidelity/voxel-server/resources/voxels.svo";
|
||||
const double VOXEL_PERSIST_INTERVAL = 1000.0 * 30; // every 30 seconds
|
||||
const long long VOXEL_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds
|
||||
|
||||
const int VOXEL_LISTEN_PORT = 40106;
|
||||
|
||||
|
@ -118,7 +118,7 @@ void resInVoxelDistributor(AgentList* agentList,
|
|||
bool searchReset = false;
|
||||
int searchLoops = 0;
|
||||
int searchLevelWas = agentData->getMaxSearchLevel();
|
||||
double start = usecTimestampNow();
|
||||
long long start = usecTimestampNow();
|
||||
while (!searchReset && agentData->nodeBag.isEmpty()) {
|
||||
searchLoops++;
|
||||
|
||||
|
@ -137,19 +137,19 @@ void resInVoxelDistributor(AgentList* agentList,
|
|||
}
|
||||
}
|
||||
}
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
long long end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start)/1000;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - start)/1000000.0;
|
||||
printf("WARNING! searchForColoredNodes() took %lf seconds to identify %d nodes at level %d in %d loops\n",
|
||||
int elapsedsec = (end - start)/1000000;
|
||||
printf("WARNING! searchForColoredNodes() took %d seconds to identify %d nodes at level %d in %d loops\n",
|
||||
elapsedsec, agentData->nodeBag.count(), searchLevelWas, searchLoops);
|
||||
} else {
|
||||
printf("WARNING! searchForColoredNodes() took %lf milliseconds to identify %d nodes at level %d in %d loops\n",
|
||||
printf("WARNING! searchForColoredNodes() took %d milliseconds to identify %d nodes at level %d in %d loops\n",
|
||||
elapsedmsec, agentData->nodeBag.count(), searchLevelWas, searchLoops);
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("searchForColoredNodes() took %lf milliseconds to identify %d nodes at level %d in %d loops\n",
|
||||
printf("searchForColoredNodes() took %d milliseconds to identify %d nodes at level %d in %d loops\n",
|
||||
elapsedmsec, agentData->nodeBag.count(), searchLevelWas, searchLoops);
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ void resInVoxelDistributor(AgentList* agentList,
|
|||
int packetsSentThisInterval = 0;
|
||||
int truePacketsSent = 0;
|
||||
int trueBytesSent = 0;
|
||||
double start = usecTimestampNow();
|
||||
long long start = usecTimestampNow();
|
||||
|
||||
bool shouldSendEnvironments = shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
|
||||
|
@ -206,19 +206,19 @@ void resInVoxelDistributor(AgentList* agentList,
|
|||
trueBytesSent += envPacketLength;
|
||||
truePacketsSent++;
|
||||
}
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
long long end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start)/1000;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - start)/1000000.0;
|
||||
printf("WARNING! packetLoop() took %lf seconds to generate %d bytes in %d packets at level %d, %d nodes still to send\n",
|
||||
int elapsedsec = (end - start)/1000000;
|
||||
printf("WARNING! packetLoop() took %d seconds to generate %d bytes in %d packets at level %d, %d nodes still to send\n",
|
||||
elapsedsec, trueBytesSent, truePacketsSent, searchLevelWas, agentData->nodeBag.count());
|
||||
} else {
|
||||
printf("WARNING! packetLoop() took %lf milliseconds to generate %d bytes in %d packets at level %d, %d nodes still to send\n",
|
||||
printf("WARNING! packetLoop() took %d milliseconds to generate %d bytes in %d packets at level %d, %d nodes still to send\n",
|
||||
elapsedmsec, trueBytesSent, truePacketsSent, searchLevelWas, agentData->nodeBag.count());
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets at level %d, %d nodes still to send\n",
|
||||
printf("packetLoop() took %d milliseconds to generate %d bytes in %d packets at level %d, %d nodes still to send\n",
|
||||
elapsedmsec, trueBytesSent, truePacketsSent, searchLevelWas, agentData->nodeBag.count());
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
|||
pthread_mutex_lock(&::treeLock);
|
||||
|
||||
int maxLevelReached = 0;
|
||||
double start = usecTimestampNow();
|
||||
long long start = usecTimestampNow();
|
||||
|
||||
// FOR NOW... agent tells us if it wants to receive only view frustum deltas
|
||||
bool wantDelta = agentData->getWantDelta();
|
||||
|
@ -281,19 +281,19 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
|||
}
|
||||
|
||||
}
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
long long end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start)/1000;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - start)/1000000.0;
|
||||
printf("WARNING! searchForColoredNodes() took %lf seconds to identify %d nodes at level %d\n",
|
||||
int elapsedsec = (end - start)/1000000;
|
||||
printf("WARNING! searchForColoredNodes() took %d seconds to identify %d nodes at level %d\n",
|
||||
elapsedsec, agentData->nodeBag.count(), maxLevelReached);
|
||||
} else {
|
||||
printf("WARNING! searchForColoredNodes() took %lf milliseconds to identify %d nodes at level %d\n",
|
||||
printf("WARNING! searchForColoredNodes() took %d milliseconds to identify %d nodes at level %d\n",
|
||||
elapsedmsec, agentData->nodeBag.count(), maxLevelReached);
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("searchForColoredNodes() took %lf milliseconds to identify %d nodes at level %d\n",
|
||||
printf("searchForColoredNodes() took %d milliseconds to identify %d nodes at level %d\n",
|
||||
elapsedmsec, agentData->nodeBag.count(), maxLevelReached);
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,7 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
|||
int packetsSentThisInterval = 0;
|
||||
int truePacketsSent = 0;
|
||||
int trueBytesSent = 0;
|
||||
double start = usecTimestampNow();
|
||||
long long start = usecTimestampNow();
|
||||
|
||||
bool shouldSendEnvironments = shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
|
||||
|
@ -351,19 +351,19 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
|||
truePacketsSent++;
|
||||
}
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
long long end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start)/1000;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - start)/1000000.0;
|
||||
printf("WARNING! packetLoop() took %lf seconds to generate %d bytes in %d packets %d nodes still to send\n",
|
||||
int elapsedsec = (end - start)/1000000;
|
||||
printf("WARNING! packetLoop() took %d seconds to generate %d bytes in %d packets %d nodes still to send\n",
|
||||
elapsedsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
|
||||
} else {
|
||||
printf("WARNING! packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||
printf("WARNING! packetLoop() took %d milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||
elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||
printf("packetLoop() took %d milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||
elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
|
||||
}
|
||||
|
||||
|
@ -380,10 +380,10 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
|||
pthread_mutex_unlock(&::treeLock);
|
||||
}
|
||||
|
||||
double lastPersistVoxels = 0;
|
||||
long long lastPersistVoxels = 0;
|
||||
void persistVoxelsWhenDirty() {
|
||||
double now = usecTimestampNow();
|
||||
double sinceLastTime = (now - ::lastPersistVoxels) / 1000.0;
|
||||
long long now = usecTimestampNow();
|
||||
long long sinceLastTime = (now - ::lastPersistVoxels) / 1000;
|
||||
|
||||
// check the dirty bit and persist here...
|
||||
if (::wantVoxelPersist && ::serverTree.isDirty() && sinceLastTime > VOXEL_PERSIST_INTERVAL) {
|
||||
|
@ -428,7 +428,7 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
}
|
||||
|
||||
// dynamically sleep until we need to fire off the next set of voxels
|
||||
double usecToSleep = VOXEL_SEND_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSendTime));
|
||||
long long usecToSleep = VOXEL_SEND_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSendTime));
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
|
Loading…
Reference in a new issue