mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 04:03:59 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into recursive_voxel_delete
This commit is contained in:
commit
d94b5074c2
18 changed files with 89 additions and 179 deletions
|
@ -18,10 +18,4 @@ include_glm(${TARGET_NAME} ${ROOT_DIR})
|
|||
# link the shared hifi library
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link the stk library
|
||||
set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
|
||||
find_package(STK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
|
@ -11,18 +11,10 @@
|
|||
#include "AvatarAudioRingBuffer.h"
|
||||
|
||||
AvatarAudioRingBuffer::AvatarAudioRingBuffer() :
|
||||
_freeVerbs(),
|
||||
_shouldLoopbackForAgent(false) {
|
||||
|
||||
}
|
||||
|
||||
AvatarAudioRingBuffer::~AvatarAudioRingBuffer() {
|
||||
// enumerate the freeVerbs map and delete the FreeVerb objects
|
||||
for (FreeVerbAgentMap::iterator verbIterator = _freeVerbs.begin(); verbIterator != _freeVerbs.end(); verbIterator++) {
|
||||
delete verbIterator->second;
|
||||
}
|
||||
}
|
||||
|
||||
int AvatarAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
_shouldLoopbackForAgent = (sourceBuffer[0] == PACKET_HEADER_MICROPHONE_AUDIO_WITH_ECHO);
|
||||
return PositionalAudioRingBuffer::parseData(sourceBuffer, numBytes);
|
||||
|
|
|
@ -9,28 +9,20 @@
|
|||
#ifndef __hifi__AvatarAudioRingBuffer__
|
||||
#define __hifi__AvatarAudioRingBuffer__
|
||||
|
||||
#include <Stk.h>
|
||||
#include <FreeVerb.h>
|
||||
|
||||
#include "PositionalAudioRingBuffer.h"
|
||||
|
||||
typedef std::map<uint16_t, stk::FreeVerb*> FreeVerbAgentMap;
|
||||
|
||||
class AvatarAudioRingBuffer : public PositionalAudioRingBuffer {
|
||||
public:
|
||||
AvatarAudioRingBuffer();
|
||||
~AvatarAudioRingBuffer();
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
FreeVerbAgentMap& getFreeVerbs() { return _freeVerbs; }
|
||||
bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; }
|
||||
private:
|
||||
// disallow copying of AvatarAudioRingBuffer objects
|
||||
AvatarAudioRingBuffer(const AvatarAudioRingBuffer&);
|
||||
AvatarAudioRingBuffer& operator= (const AvatarAudioRingBuffer&);
|
||||
|
||||
FreeVerbAgentMap _freeVerbs;
|
||||
bool _shouldLoopbackForAgent;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,4 +40,4 @@ int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes
|
|||
currentBuffer += parseAudioSamples(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,4 +65,4 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) {
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include <AgentTypes.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <StdDev.h>
|
||||
#include <Stk.h>
|
||||
#include <FreeVerb.h>
|
||||
|
||||
#include "InjectedAudioRingBuffer.h"
|
||||
#include "AvatarAudioRingBuffer.h"
|
||||
|
@ -104,11 +102,6 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
int16_t clientSamples[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {};
|
||||
|
||||
// setup STK for the reverb effect
|
||||
const float DISTANCE_REVERB_DAMPING = 0.6f;
|
||||
const float DISTANCE_REVERB_ROOM_SIZE = 0.75f;
|
||||
const float DISTANCE_REVERB_WIDTH = 0.5f;
|
||||
|
||||
gettimeofday(&startTime, NULL);
|
||||
|
||||
while (true) {
|
||||
|
@ -129,8 +122,6 @@ int main(int argc, const char* argv[]) {
|
|||
// zero out the client mix for this agent
|
||||
memset(clientSamples, 0, sizeof(clientSamples));
|
||||
|
||||
const int PHASE_DELAY_AT_90 = 20;
|
||||
|
||||
for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) {
|
||||
if (((PositionalAudioRingBuffer*) otherAgent->getLinkedData())->willBeAddedToMix()
|
||||
&& (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent()))) {
|
||||
|
@ -142,8 +133,6 @@ int main(int argc, const char* argv[]) {
|
|||
int numSamplesDelay = 0;
|
||||
float weakChannelAmplitudeRatio = 1.0f;
|
||||
|
||||
stk::FreeVerb* otherAgentFreeVerb = NULL;
|
||||
|
||||
if (otherAgent != agent) {
|
||||
|
||||
glm::vec3 listenerPosition = agentRingBuffer->getPosition();
|
||||
|
@ -212,6 +201,7 @@ int main(int argc, const char* argv[]) {
|
|||
glm::normalize(rotatedSourcePosition),
|
||||
glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
const int PHASE_DELAY_AT_90 = 20;
|
||||
const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5;
|
||||
|
||||
// figure out the number of samples of delay and the ratio of the amplitude
|
||||
|
@ -220,40 +210,6 @@ int main(int argc, const char* argv[]) {
|
|||
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
||||
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
|
||||
}
|
||||
|
||||
FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs();
|
||||
FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID());
|
||||
|
||||
if (freeVerbIterator == agentFreeVerbs.end()) {
|
||||
// setup the freeVerb effect for this source for this client
|
||||
otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb;
|
||||
|
||||
otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING);
|
||||
otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE);
|
||||
otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH);
|
||||
} else {
|
||||
otherAgentFreeVerb = freeVerbIterator->second;
|
||||
}
|
||||
|
||||
const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f;
|
||||
const float MAX_REVERB_DISTANCE = 160.0f;
|
||||
|
||||
// higher value increases wetness more quickly with distance
|
||||
const float WETNESS_CALC_EXPONENT_BASE = 2.0f;
|
||||
|
||||
const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR);
|
||||
const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT);
|
||||
const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT);
|
||||
const float DISTANCE_REVERB_MAX_WETNESS = 1.0f;
|
||||
const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR,
|
||||
MAX_EXPONENT_INT);
|
||||
|
||||
float effectMix = powf(WETNESS_CALC_EXPONENT_BASE,
|
||||
(0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE))
|
||||
- DISTANCE_REVERB_LOG_REMAINDER);
|
||||
effectMix *= EFFECT_MIX_RHS;
|
||||
|
||||
otherAgentFreeVerb->setEffectMix(effectMix);
|
||||
}
|
||||
|
||||
int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f)
|
||||
|
@ -278,20 +234,7 @@ int main(int argc, const char* argv[]) {
|
|||
plateauAdditionOfSamples(delayedChannel[s], earlierSample);
|
||||
}
|
||||
|
||||
int16_t currentSample = otherAgentBuffer->getNextOutput()[s];
|
||||
|
||||
// apply the STK FreeVerb effect
|
||||
if (otherAgentFreeVerb) {
|
||||
currentSample = otherAgentFreeVerb->tick(currentSample);
|
||||
|
||||
if (s >= BUFFER_LENGTH_SAMPLES_PER_CHANNEL - PHASE_DELAY_AT_90) {
|
||||
// there is the possiblity this will be re-used as a delayed sample
|
||||
// so store the reverbed sample so that is what will be pulled
|
||||
otherAgentBuffer->getNextOutput()[s] = currentSample;
|
||||
}
|
||||
}
|
||||
|
||||
currentSample *= attenuationCoefficient;
|
||||
int16_t currentSample = otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient;
|
||||
|
||||
plateauAdditionOfSamples(goodChannel[s], currentSample);
|
||||
|
||||
|
|
|
@ -19,10 +19,4 @@ include_glm(${TARGET_NAME} ${ROOT_DIR})
|
|||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link the stk library
|
||||
set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
|
||||
find_package(STK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
||||
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
|
@ -146,12 +146,6 @@ else (WIN32)
|
|||
include_directories(${PORTAUDIO_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${PORTAUDIO_LIBRARIES})
|
||||
|
||||
# link the stk library
|
||||
set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
|
||||
find_package(STK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
||||
|
||||
# link required libraries on UNIX
|
||||
if (UNIX AND NOT APPLE)
|
||||
find_package(Threads REQUIRED)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QColorDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QFormLayout>
|
||||
#include <QGLWidget>
|
||||
#include <QKeyEvent>
|
||||
|
@ -311,11 +312,11 @@ void Application::paintGL() {
|
|||
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||
_myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay
|
||||
_myCamera.setTargetPosition(_myAvatar.getBallPosition(AVATAR_JOINT_HEAD_BASE));
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale));
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
_myCamera.setTargetPosition(_myAvatar.getHeadJointPosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale));
|
||||
}
|
||||
|
||||
// Update camera position
|
||||
|
@ -1026,6 +1027,10 @@ void Application::editPreferences() {
|
|||
avatarURL->setMinimumWidth(400);
|
||||
form->addRow("Avatar URL:", avatarURL);
|
||||
|
||||
QDoubleSpinBox* headCameraPitchYawScale = new QDoubleSpinBox();
|
||||
headCameraPitchYawScale->setValue(_headCameraPitchYawScale);
|
||||
form->addRow("Head Camera Pitch/Yaw Scale:", headCameraPitchYawScale);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
|
||||
dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject()));
|
||||
|
@ -1038,6 +1043,8 @@ void Application::editPreferences() {
|
|||
_settings->setValue("avatarURL", url);
|
||||
_myAvatar.getVoxels()->setVoxelURL(url);
|
||||
sendAvatarVoxelURLMessage(url);
|
||||
|
||||
_headCameraPitchYawScale = headCameraPitchYawScale->value();
|
||||
}
|
||||
|
||||
void Application::pair() {
|
||||
|
@ -1454,7 +1461,9 @@ void Application::initMenu() {
|
|||
voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C);
|
||||
voxelMenu->addAction("Paste Voxels", this, SLOT(pasteVoxels()), Qt::CTRL | Qt::Key_V);
|
||||
|
||||
QMenu* frustumMenu = menuBar->addMenu("Frustum");
|
||||
QMenu* debugMenu = menuBar->addMenu("Debug");
|
||||
|
||||
QMenu* frustumMenu = debugMenu->addMenu("View Frustum...");
|
||||
(_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true);
|
||||
_frustumOn->setShortcut(Qt::SHIFT | Qt::Key_F);
|
||||
(_viewFrustumFromOffset = frustumMenu->addAction(
|
||||
|
@ -1466,7 +1475,6 @@ void Application::initMenu() {
|
|||
"Render Mode", this, SLOT(cycleFrustumRenderMode()), Qt::SHIFT | Qt::Key_R);
|
||||
updateFrustumRenderModeAction();
|
||||
|
||||
QMenu* debugMenu = menuBar->addMenu("Debug");
|
||||
debugMenu->addAction("Show Render Pipeline Warnings", this, SLOT(setRenderWarnings(bool)))->setCheckable(true);
|
||||
debugMenu->addAction("Kill Local Voxels", this, SLOT(doKillLocalVoxels()));
|
||||
debugMenu->addAction("Randomize Voxel TRUE Colors", this, SLOT(doRandomizeVoxelColors()), Qt::CTRL | Qt::Key_R);
|
||||
|
@ -2536,15 +2544,19 @@ void Application::setAutosave(bool wantsAutosave) {
|
|||
void Application::loadSettings(QSettings* set) {
|
||||
if (!set) set = getSettings();
|
||||
|
||||
_headCameraPitchYawScale = set->value("headCameraPitchYawScale", 0.0f).toFloat();
|
||||
scanMenuBar(&Application::loadAction, set);
|
||||
getAvatar()->loadData(set);
|
||||
getAvatar()->loadData(set);
|
||||
}
|
||||
|
||||
void Application::saveSettings(QSettings* set) {
|
||||
if (!set) set = getSettings();
|
||||
|
||||
set->setValue("headCameraPitchYawScale", _headCameraPitchYawScale);
|
||||
scanMenuBar(&Application::saveAction, set);
|
||||
getAvatar()->saveData(set);
|
||||
|
||||
set->sync();
|
||||
}
|
||||
|
||||
void Application::importSettings() {
|
||||
|
|
|
@ -248,6 +248,7 @@ private:
|
|||
|
||||
int _headMouseX, _headMouseY;
|
||||
bool _manualFirstPerson;
|
||||
float _headCameraPitchYawScale;
|
||||
|
||||
HandControl _handControl;
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ int audioCallback (const void* inputBuffer,
|
|||
glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition();
|
||||
glm::quat headOrientation = interfaceAvatar->getHead().getOrientation();
|
||||
|
||||
int leadingBytes = 1 + sizeof(headPosition) + sizeof(headOrientation);
|
||||
int leadingBytes = sizeof(PACKET_HEADER_MICROPHONE_AUDIO_NO_ECHO) + sizeof(headPosition) + sizeof(headOrientation);
|
||||
|
||||
// we need the amount of bytes in the buffer + 1 for type
|
||||
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
||||
|
|
|
@ -62,37 +62,35 @@ float chatMessageScale = 0.0015;
|
|||
float chatMessageHeight = 0.20;
|
||||
|
||||
Avatar::Avatar(Agent* owningAgent) :
|
||||
AvatarData(owningAgent),
|
||||
_initialized(false),
|
||||
_head(this),
|
||||
_ballSpringsInitialized(false),
|
||||
_TEST_bigSphereRadius(0.5f),
|
||||
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||
_mousePressed(false),
|
||||
_bodyPitchDelta(0.0f),
|
||||
_bodyYawDelta(0.0f),
|
||||
_bodyRollDelta(0.0f),
|
||||
_movedHandOffset(0.0f, 0.0f, 0.0f),
|
||||
_mode(AVATAR_MODE_STANDING),
|
||||
_cameraPosition(0.0f, 0.0f, 0.0f),
|
||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||
_velocity(0.0f, 0.0f, 0.0f),
|
||||
_thrust(0.0f, 0.0f, 0.0f),
|
||||
_speed(0.0f),
|
||||
_maxArmLength(0.0f),
|
||||
_pelvisStandingHeight(0.0f),
|
||||
_pelvisFloatingHeight(0.0f),
|
||||
_distanceToNearestAvatar(std::numeric_limits<float>::max()),
|
||||
_gravity(0.0f, -1.0f, 0.0f),
|
||||
_worldUpDirection(DEFAULT_UP_DIRECTION),
|
||||
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
|
||||
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||
_interactingOther(NULL),
|
||||
_isMouseTurningRight(false),
|
||||
_voxels(this)
|
||||
|
||||
AvatarData(owningAgent),
|
||||
_initialized(false),
|
||||
_head(this),
|
||||
_ballSpringsInitialized(false),
|
||||
_TEST_bigSphereRadius(0.5f),
|
||||
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||
_mousePressed(false),
|
||||
_bodyPitchDelta(0.0f),
|
||||
_bodyYawDelta(0.0f),
|
||||
_bodyRollDelta(0.0f),
|
||||
_movedHandOffset(0.0f, 0.0f, 0.0f),
|
||||
_mode(AVATAR_MODE_STANDING),
|
||||
_cameraPosition(0.0f, 0.0f, 0.0f),
|
||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||
_velocity(0.0f, 0.0f, 0.0f),
|
||||
_thrust(0.0f, 0.0f, 0.0f),
|
||||
_speed(0.0f),
|
||||
_maxArmLength(0.0f),
|
||||
_pelvisStandingHeight(0.0f),
|
||||
_pelvisFloatingHeight(0.0f),
|
||||
_distanceToNearestAvatar(std::numeric_limits<float>::max()),
|
||||
_gravity(0.0f, -1.0f, 0.0f),
|
||||
_worldUpDirection(DEFAULT_UP_DIRECTION),
|
||||
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
|
||||
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||
_interactingOther(NULL),
|
||||
_isMouseTurningRight(false),
|
||||
_voxels(this)
|
||||
{
|
||||
|
||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||
_headData = &_head;
|
||||
|
||||
|
@ -659,7 +657,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
|||
//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) {
|
||||
if (agent->getLinkedData() && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
// test whether shoulders are close enough to allow for reaching to touch hands
|
||||
|
@ -806,13 +804,12 @@ void Avatar::applyCollisionWithScene(const glm::vec3& penetration) {
|
|||
static float STATIC_FRICTION_VELOCITY = 0.15f;
|
||||
static float STATIC_FRICTION_DAMPING = 0.0f;
|
||||
static float KINETIC_FRICTION_DAMPING = 0.95f;
|
||||
const float BOUNCE = 0.3f;
|
||||
|
||||
// reflect the velocity component in the direction of penetration
|
||||
// cancel out the velocity component in the direction of penetration
|
||||
float penetrationLength = glm::length(penetration);
|
||||
if (penetrationLength > EPSILON) {
|
||||
glm::vec3 direction = penetration / penetrationLength;
|
||||
_velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE;
|
||||
_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) {
|
||||
|
@ -829,7 +826,7 @@ void Avatar::updateAvatarCollisions(float deltaTime) {
|
|||
// 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) {
|
||||
if (agent->getLinkedData() && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
// check if the bounding spheres of the two avatars are colliding
|
||||
|
@ -1008,7 +1005,6 @@ void Avatar::updateBodyBalls(float deltaTime) {
|
|||
resetBodyBalls();
|
||||
}
|
||||
glm::quat orientation = getOrientation();
|
||||
glm::vec3 jointDirection = orientation * JOINT_DIRECTION;
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
|
||||
glm::vec3 springVector;
|
||||
|
@ -1068,11 +1064,18 @@ void Avatar::updateBodyBalls(float deltaTime) {
|
|||
if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL || length < SMALL_SPRING_LENGTH) {
|
||||
_bodyBall[b].rotation = orientation * _skeleton.joint[_bodyBall[b].parentJoint].absoluteBindPoseRotation;
|
||||
} else {
|
||||
glm::vec3 parentDirection = _bodyBall[ _skeleton.joint[b].parent ].rotation * JOINT_DIRECTION;
|
||||
glm::vec3 parentDirection = _bodyBall[ _bodyBall[b].parentBall ].rotation * JOINT_DIRECTION;
|
||||
_bodyBall[b].rotation = rotationBetween(parentDirection, springVector) *
|
||||
_bodyBall[ _skeleton.joint[b].parent ].rotation;
|
||||
_bodyBall[ _bodyBall[b].parentBall ].rotation;
|
||||
}
|
||||
}
|
||||
|
||||
// copy the head's rotation
|
||||
_bodyBall[BODY_BALL_HEAD_BASE].rotation = _bodyBall[BODY_BALL_HEAD_TOP].rotation = _head.getOrientation();
|
||||
_bodyBall[BODY_BALL_HEAD_BASE].position = _bodyBall[BODY_BALL_NECK_BASE].position +
|
||||
_bodyBall[BODY_BALL_HEAD_BASE].rotation * _skeleton.joint[BODY_BALL_HEAD_BASE].bindPosePosition;
|
||||
_bodyBall[BODY_BALL_HEAD_TOP].position = _bodyBall[BODY_BALL_HEAD_BASE].position +
|
||||
_bodyBall[BODY_BALL_HEAD_TOP].rotation * _skeleton.joint[BODY_BALL_HEAD_TOP].bindPosePosition;
|
||||
}
|
||||
|
||||
void Avatar::updateArmIKAndConstraints(float deltaTime) {
|
||||
|
@ -1133,7 +1136,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
const float RENDER_TRANSLUCENT_BEYOND = 0.5f;
|
||||
|
||||
// Render the body as balls and cones
|
||||
if (renderAvatarBalls) {
|
||||
if (renderAvatarBalls || !_voxels.getVoxelURL().isValid()) {
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
float distanceToCamera = glm::length(_cameraPosition - _bodyBall[b].position);
|
||||
|
||||
|
|
|
@ -314,10 +314,10 @@ glm::quat Head::getOrientation() const {
|
|||
glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll)));
|
||||
}
|
||||
|
||||
glm::quat Head::getWorldAlignedOrientation () const {
|
||||
glm::quat Head::getCameraOrientation (float pitchYawScale) const {
|
||||
Avatar* owningAvatar = static_cast<Avatar*>(_owningAvatar);
|
||||
return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(_lookingInMirror ?
|
||||
glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll)));
|
||||
return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(
|
||||
_pitch * pitchYawScale, _yaw * pitchYawScale, 0.0f)));
|
||||
}
|
||||
|
||||
void Head::renderHeadSphere() {
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; }
|
||||
|
||||
glm::quat getOrientation() const;
|
||||
glm::quat getWorldAlignedOrientation () const;
|
||||
glm::quat getCameraOrientation (float pitchYawScale) const;
|
||||
|
||||
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||
glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
#include "SerialInterface.h"
|
||||
#include "Util.h"
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
#include <math.h>
|
||||
|
||||
|
@ -17,7 +18,7 @@
|
|||
|
||||
const short NO_READ_MAXIMUM_MSECS = 3000;
|
||||
const int GRAVITY_SAMPLES = 60; // Use the first few samples to baseline values
|
||||
const int SENSOR_FUSION_SAMPLES = 200;
|
||||
const int SENSOR_FUSION_SAMPLES = 20;
|
||||
const int LONG_TERM_RATE_SAMPLES = 1000;
|
||||
|
||||
const bool USING_INVENSENSE_MPU9150 = 1;
|
||||
|
@ -214,7 +215,7 @@ void SerialInterface::readData(float deltaTime) {
|
|||
// From MPU-9150 register map, with setting on
|
||||
// highest resolution = +/- 2G
|
||||
|
||||
_lastAcceleration = glm::vec3(accelXRate, accelYRate, -accelZRate) * LSB_TO_METERS_PER_SECOND2;
|
||||
_lastAcceleration = glm::vec3(-accelXRate, -accelYRate, -accelZRate) * LSB_TO_METERS_PER_SECOND2;
|
||||
|
||||
int rollRate, yawRate, pitchRate;
|
||||
|
||||
|
@ -229,8 +230,8 @@ void SerialInterface::readData(float deltaTime) {
|
|||
_lastRotationRates[2] = ((float) -rollRate) * LSB_TO_DEGREES_PER_SECOND;
|
||||
|
||||
// Update raw rotation estimates
|
||||
_estimatedRotation += deltaTime * (_lastRotationRates - _averageRotationRates);
|
||||
|
||||
glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) *
|
||||
glm::quat(glm::radians(deltaTime * (_lastRotationRates - _averageRotationRates)));
|
||||
|
||||
// Update estimated position and velocity
|
||||
float const DECAY_VELOCITY = 0.95f;
|
||||
|
@ -258,29 +259,19 @@ void SerialInterface::readData(float deltaTime) {
|
|||
1.f/(float)GRAVITY_SAMPLES * _lastAcceleration;
|
||||
} else {
|
||||
// Use gravity reading to do sensor fusion on the pitch and roll estimation
|
||||
float truePitchAngle = glm::angle(glm::normalize(glm::vec3(0, _gravity.y, _gravity.z)),
|
||||
glm::normalize(glm::vec3(0, _lastAcceleration.y, _lastAcceleration.z)))
|
||||
* ((_lastAcceleration.z > _gravity.z) ? -1.0 : 1.0);
|
||||
|
||||
float trueRollAngle = glm::angle(glm::normalize(glm::vec3(_gravity.x, _gravity.y, 0)),
|
||||
glm::normalize(glm::vec3(_lastAcceleration.x, _lastAcceleration.y, 0)))
|
||||
* ((_lastAcceleration.x > _gravity.x) ? -1.0 : 1.0);
|
||||
|
||||
// PER: BUG: This is bizarre, because glm::angle() SOMETIMES returns NaN for what seem to
|
||||
// be perfectly valid inputs. So I added these NaN tests, gotta fix.
|
||||
if (!glm::isnan(truePitchAngle) && !glm::isnan(trueRollAngle)) {
|
||||
_estimatedRotation.x = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.x
|
||||
+ 1.f/(float)SENSOR_FUSION_SAMPLES * truePitchAngle;
|
||||
_estimatedRotation.z = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.z
|
||||
+ 1.f/(float)SENSOR_FUSION_SAMPLES * trueRollAngle;
|
||||
// Without a compass heading, always decay estimated Yaw slightly
|
||||
const float YAW_DECAY = 0.995;
|
||||
_estimatedRotation.y *= YAW_DECAY;
|
||||
}
|
||||
estimatedRotation = safeMix(estimatedRotation,
|
||||
rotationBetween(estimatedRotation * _lastAcceleration, _gravity) * estimatedRotation,
|
||||
1.0f / SENSOR_FUSION_SAMPLES);
|
||||
|
||||
// Without a compass heading, always decay estimated Yaw slightly
|
||||
const float YAW_DECAY = 0.999f;
|
||||
glm::vec3 forward = estimatedRotation * glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
estimatedRotation = safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)),
|
||||
glm::vec3(0.0f, 1.0f, 0.0f)) * estimatedRotation, estimatedRotation, YAW_DECAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_estimatedRotation = safeEulerAngles(estimatedRotation);
|
||||
|
||||
totalSamples++;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ void Skeleton::initialize() {
|
|||
joint[ AVATAR_JOINT_CHEST ].bindPosePosition = glm::vec3( 0.0, 0.09, -0.01 );
|
||||
joint[ AVATAR_JOINT_NECK_BASE ].bindPosePosition = glm::vec3( 0.0, 0.14, 0.01 );
|
||||
joint[ AVATAR_JOINT_HEAD_BASE ].bindPosePosition = glm::vec3( 0.0, 0.04, 0.00 );
|
||||
joint[ AVATAR_JOINT_HEAD_TOP ].bindPosePosition = glm::vec3( 0.0, 0.04, 0.00 );
|
||||
|
||||
joint[ AVATAR_JOINT_LEFT_COLLAR ].bindPosePosition = glm::vec3( -0.06, 0.04, 0.01 );
|
||||
joint[ AVATAR_JOINT_LEFT_SHOULDER ].bindPosePosition = glm::vec3( -0.05, 0.0, 0.01 );
|
||||
|
@ -85,6 +86,7 @@ void Skeleton::initialize() {
|
|||
joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, -0.01 );
|
||||
joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, 0.01 );
|
||||
joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 );
|
||||
joint[ AVATAR_JOINT_HEAD_TOP ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 );
|
||||
|
||||
joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, 0.01 );
|
||||
joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.01 );
|
||||
|
|
|
@ -256,7 +256,6 @@ void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() {
|
|||
|
||||
void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() {
|
||||
glBufferIndex segmentStart = 0;
|
||||
glBufferIndex segmentEnd = 0;
|
||||
bool inSegment = false;
|
||||
for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
|
||||
bool thisVoxelDirty = _writeVoxelDirtyArray[i];
|
||||
|
@ -560,7 +559,6 @@ void VoxelSystem::updateFullVBOs() {
|
|||
|
||||
void VoxelSystem::updatePartialVBOs() {
|
||||
glBufferIndex segmentStart = 0;
|
||||
glBufferIndex segmentEnd = 0;
|
||||
bool inSegment = false;
|
||||
for (glBufferIndex i = 0; i < _voxelsInReadArrays; i++) {
|
||||
bool thisVoxelDirty = _readVoxelDirtyArray[i];
|
||||
|
|
|
@ -19,10 +19,4 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|||
|
||||
# link the threads library
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
# link the stk library
|
||||
set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
|
||||
find_package(STK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
Loading…
Reference in a new issue