have avatar make use of SpatiallyNestable

This commit is contained in:
Seth Alves 2015-10-18 09:48:46 -07:00
parent 37923e81bb
commit a78f2a9577
11 changed files with 112 additions and 109 deletions

View file

@ -1136,7 +1136,7 @@ void Application::paintGL() {
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation);
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
_myCamera.setPosition(myAvatar->getDefaultEyePosition() _myCamera.setPosition(myAvatar->getDefaultEyePosition()
+ glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0) + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0)
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset);
@ -1144,7 +1144,7 @@ void Application::paintGL() {
_myCamera.setRotation(myAvatar->getWorldAlignedOrientation() _myCamera.setRotation(myAvatar->getWorldAlignedOrientation()
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
_myCamera.setPosition(myAvatar->getDefaultEyePosition() _myCamera.setPosition(myAvatar->getDefaultEyePosition()
+ glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0) + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0)
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
} }

View file

@ -90,7 +90,6 @@ Avatar::Avatar(RigPointer rig) :
_angularAcceleration(0.0f), _angularAcceleration(0.0f),
_lastOrientation(), _lastOrientation(),
_leanScale(0.5f), _leanScale(0.5f),
_scale(1.0f),
_worldUpDirection(DEFAULT_UP_DIRECTION), _worldUpDirection(DEFAULT_UP_DIRECTION),
_moving(false), _moving(false),
_initialized(false), _initialized(false),
@ -100,6 +99,7 @@ Avatar::Avatar(RigPointer rig) :
// we may have been created in the network thread, but we live in the main thread // we may have been created in the network thread, but we live in the main thread
moveToThread(qApp->thread()); moveToThread(qApp->thread());
setAvatarScale(1.0f);
// give the pointer to our head to inherited _headData variable from AvatarData // give the pointer to our head to inherited _headData variable from AvatarData
_headData = static_cast<HeadData*>(new Head(this)); _headData = static_cast<HeadData*>(new Head(this));
_handData = static_cast<HandData*>(new Hand(this)); _handData = static_cast<HandData*>(new Hand(this));
@ -124,12 +124,12 @@ void Avatar::init() {
glm::vec3 Avatar::getChestPosition() const { glm::vec3 Avatar::getChestPosition() const {
// for now, let's just assume that the "chest" is halfway between the root and the neck // for now, let's just assume that the "chest" is halfway between the root and the neck
glm::vec3 neckPosition; glm::vec3 neckPosition;
return _skeletonModel.getNeckPosition(neckPosition) ? (_position + neckPosition) * 0.5f : _position; return _skeletonModel.getNeckPosition(neckPosition) ? (getPosition() + neckPosition) * 0.5f : getPosition();
} }
glm::vec3 Avatar::getNeckPosition() const { glm::vec3 Avatar::getNeckPosition() const {
glm::vec3 neckPosition; glm::vec3 neckPosition;
return _skeletonModel.getNeckPosition(neckPosition) ? neckPosition : _position; return _skeletonModel.getNeckPosition(neckPosition) ? neckPosition : getPosition();
} }
@ -143,14 +143,14 @@ AABox Avatar::getBounds() const {
float Avatar::getLODDistance() const { float Avatar::getLODDistance() const {
return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() * return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() *
glm::distance(qApp->getCamera()->getPosition(), _position) / _scale; glm::distance(qApp->getCamera()->getPosition(), getPosition()) / getAvatarScale();
} }
void Avatar::simulate(float deltaTime) { void Avatar::simulate(float deltaTime) {
PerformanceTimer perfTimer("simulate"); PerformanceTimer perfTimer("simulate");
if (_scale != _targetScale) { if (getAvatarScale() != _targetScale) {
setScale(_targetScale); setAvatarScale(_targetScale);
} }
// update the billboard render flag // update the billboard render flag
@ -165,7 +165,7 @@ void Avatar::simulate(float deltaTime) {
// simple frustum check // simple frustum check
float boundingRadius = getBillboardSize(); float boundingRadius = getBillboardSize();
bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(_position, boundingRadius) != bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(getPosition(), boundingRadius) !=
ViewFrustum::OUTSIDE; ViewFrustum::OUTSIDE;
{ {
@ -189,11 +189,11 @@ void Avatar::simulate(float deltaTime) {
} }
{ {
PerformanceTimer perfTimer("head"); PerformanceTimer perfTimer("head");
glm::vec3 headPosition = _position; glm::vec3 headPosition = getPosition();
_skeletonModel.getHeadPosition(headPosition); _skeletonModel.getHeadPosition(headPosition);
Head* head = getHead(); Head* head = getHead();
head->setPosition(headPosition); head->setPosition(headPosition);
head->setScale(_scale); head->setScale(getAvatarScale());
head->simulate(deltaTime, false, _shouldRenderBillboard); head->simulate(deltaTime, false, _shouldRenderBillboard);
} }
} }
@ -226,7 +226,7 @@ bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) {
glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition(); glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition();
glm::vec3 myEyePosition = getHead()->getEyePosition(); glm::vec3 myEyePosition = getHead()->getEyePosition();
return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getScale()); return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getAvatarScale());
} }
void Avatar::slamPosition(const glm::vec3& newPosition) { void Avatar::slamPosition(const glm::vec3& newPosition) {
@ -237,7 +237,7 @@ void Avatar::slamPosition(const glm::vec3& newPosition) {
} }
void Avatar::applyPositionDelta(const glm::vec3& delta) { void Avatar::applyPositionDelta(const glm::vec3& delta) {
_position += delta; setPosition(getPosition() + delta);
_positionDeltaAccumulator += delta; _positionDeltaAccumulator += delta;
} }
@ -307,7 +307,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
auto& batch = *renderArgs->_batch; auto& batch = *renderArgs->_batch;
if (glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) { if (glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), getPosition()) < 10.0f) {
auto geometryCache = DependencyManager::get<GeometryCache>(); auto geometryCache = DependencyManager::get<GeometryCache>();
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>(); auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
@ -405,7 +405,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
const float BASE_LIGHT_DISTANCE = 2.0f; const float BASE_LIGHT_DISTANCE = 2.0f;
const float LIGHT_EXPONENT = 1.0f; const float LIGHT_EXPONENT = 1.0f;
const float LIGHT_CUTOFF = glm::radians(80.0f); const float LIGHT_CUTOFF = glm::radians(80.0f);
float distance = BASE_LIGHT_DISTANCE * _scale; float distance = BASE_LIGHT_DISTANCE * getAvatarScale();
glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f);
glm::quat orientation = getOrientation(); glm::quat orientation = getOrientation();
foreach (const AvatarManager::LocalLight& light, DependencyManager::get<AvatarManager>()->getLocalLights()) { foreach (const AvatarManager::LocalLight& light, DependencyManager::get<AvatarManager>()->getLocalLights()) {
@ -435,7 +435,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
static const float INDICATOR_OFFSET = 0.22f; static const float INDICATOR_OFFSET = 0.22f;
static const float INDICATOR_RADIUS = 0.03f; static const float INDICATOR_RADIUS = 0.03f;
static const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; static const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f };
glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + INDICATOR_OFFSET, _position.z); glm::vec3 position = glm::vec3(getPosition().x, getDisplayNamePosition().y + INDICATOR_OFFSET, getPosition().z);
Transform transform; Transform transform;
transform.setTranslation(position); transform.setTranslation(position);
transform.postScale(INDICATOR_RADIUS); transform.postScale(INDICATOR_RADIUS);
@ -467,7 +467,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
} }
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch,
Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), Transform(transform).postScale(eyeDiameter * getAvatarScale() / 2.0f + RADIUS_INCREMENT),
glm::vec4(LOOKING_AT_ME_COLOR, alpha)); glm::vec4(LOOKING_AT_ME_COLOR, alpha));
position = getHead()->getRightEyePosition(); position = getHead()->getRightEyePosition();
@ -477,7 +477,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
eyeDiameter = DEFAULT_EYE_DIAMETER; eyeDiameter = DEFAULT_EYE_DIAMETER;
} }
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch,
Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), Transform(transform).postScale(eyeDiameter * getAvatarScale() / 2.0f + RADIUS_INCREMENT),
glm::vec4(LOOKING_AT_ME_COLOR, alpha)); glm::vec4(LOOKING_AT_ME_COLOR, alpha));
} }
@ -507,7 +507,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
Transform transform; Transform transform;
transform.setTranslation(_position); transform.setTranslation(getPosition());
transform.setScale(height); transform.setScale(height);
transform.postScale(sphereRadius); transform.postScale(sphereRadius);
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch,
@ -610,9 +610,9 @@ void Avatar::simulateAttachments(float deltaTime) {
glm::quat jointRotation; glm::quat jointRotation;
if (_skeletonModel.getJointPositionInWorldFrame(jointIndex, jointPosition) && if (_skeletonModel.getJointPositionInWorldFrame(jointIndex, jointPosition) &&
_skeletonModel.getJointCombinedRotation(jointIndex, jointRotation)) { _skeletonModel.getJointCombinedRotation(jointIndex, jointRotation)) {
model->setTranslation(jointPosition + jointRotation * attachment.translation * _scale); model->setTranslation(jointPosition + jointRotation * attachment.translation * getAvatarScale());
model->setRotation(jointRotation * attachment.rotation); model->setRotation(jointRotation * attachment.rotation);
model->setScaleToFit(true, _scale * attachment.scale, true); // hack to force rescale model->setScaleToFit(true, getAvatarScale() * attachment.scale, true); // hack to force rescale
model->setSnapModelToCenter(false); // hack to force resnap model->setSnapModelToCenter(false); // hack to force resnap
model->setSnapModelToCenter(true); model->setSnapModelToCenter(true);
model->simulate(deltaTime); model->simulate(deltaTime);
@ -639,14 +639,14 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
} }
// rotate about vertical to face the camera // rotate about vertical to face the camera
glm::quat rotation = getOrientation(); glm::quat rotation = getOrientation();
glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - _position); glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - getPosition());
rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f)); rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f));
// compute the size from the billboard camera parameters and scale // compute the size from the billboard camera parameters and scale
float size = getBillboardSize(); float size = getBillboardSize();
Transform transform; Transform transform;
transform.setTranslation(_position); transform.setTranslation(getPosition());
transform.setRotation(rotation); transform.setRotation(rotation);
transform.setScale(size); transform.setScale(size);
@ -663,7 +663,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
} }
float Avatar::getBillboardSize() const { float Avatar::getBillboardSize() const {
return _scale * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); return getAvatarScale() * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
} }
#ifdef DEBUG #ifdef DEBUG
@ -700,7 +700,7 @@ glm::vec3 Avatar::getDisplayNamePosition() const {
DEBUG_VALUE("_position =", _position); DEBUG_VALUE("_position =", _position);
DEBUG_VALUE("billboardSize =", billboardSize); DEBUG_VALUE("billboardSize =", billboardSize);
namePosition = _position + bodyUpDirection * (billboardSize * HEAD_PROPORTION); namePosition = getPosition() + bodyUpDirection * (billboardSize * HEAD_PROPORTION);
} }
if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) { if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) {
@ -803,7 +803,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co
} }
void Avatar::setSkeletonOffset(const glm::vec3& offset) { void Avatar::setSkeletonOffset(const glm::vec3& offset) {
const float MAX_OFFSET_LENGTH = _scale * 0.5f; const float MAX_OFFSET_LENGTH = getAvatarScale() * 0.5f;
float offsetLength = glm::length(offset); float offsetLength = glm::length(offset);
if (offsetLength > MAX_OFFSET_LENGTH) { if (offsetLength > MAX_OFFSET_LENGTH) {
_skeletonOffset = (MAX_OFFSET_LENGTH / offsetLength) * offset; _skeletonOffset = (MAX_OFFSET_LENGTH / offsetLength) * offset;
@ -816,7 +816,7 @@ glm::vec3 Avatar::getSkeletonPosition() const {
// The avatar is rotated PI about the yAxis, so we have to correct for it // The avatar is rotated PI about the yAxis, so we have to correct for it
// to get the skeleton offset contribution in the world-frame. // to get the skeleton offset contribution in the world-frame.
const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
return _position + getOrientation() * FLIP * _skeletonOffset; return getPosition() + getOrientation() * FLIP * _skeletonOffset;
} }
QVector<glm::quat> Avatar::getJointRotations() const { QVector<glm::quat> Avatar::getJointRotations() const {
@ -941,7 +941,7 @@ void Avatar::setJointModelPositionAndOrientation(const QString& name, glm::vec3
void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const {
//Scale a world space vector as if it was relative to the position //Scale a world space vector as if it was relative to the position
positionToScale = _position + _scale * (positionToScale - _position); positionToScale = getPosition() + getAvatarScale() * (positionToScale - getPosition());
} }
void Avatar::setFaceModelURL(const QUrl& faceModelURL) { void Avatar::setFaceModelURL(const QUrl& faceModelURL) {
@ -981,7 +981,7 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
for (int i = 0; i < attachmentData.size(); i++) { for (int i = 0; i < attachmentData.size(); i++) {
_attachmentModels[i]->setURL(attachmentData.at(i).modelURL); _attachmentModels[i]->setURL(attachmentData.at(i).modelURL);
_attachmentModels[i]->setSnapModelToCenter(true); _attachmentModels[i]->setSnapModelToCenter(true);
_attachmentModels[i]->setScaleToFit(true, _scale * _attachmentData.at(i).scale); _attachmentModels[i]->setScaleToFit(true, getAvatarScale() * _attachmentData.at(i).scale);
} }
} }
@ -1000,12 +1000,12 @@ int Avatar::parseDataFromBuffer(const QByteArray& buffer) {
} }
// change in position implies movement // change in position implies movement
glm::vec3 oldPosition = _position; glm::vec3 oldPosition = getPosition();
int bytesRead = AvatarData::parseDataFromBuffer(buffer); int bytesRead = AvatarData::parseDataFromBuffer(buffer);
const float MOVE_DISTANCE_THRESHOLD = 0.001f; const float MOVE_DISTANCE_THRESHOLD = 0.001f;
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD; _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD;
if (_moving && _motionState) { if (_moving && _motionState) {
_motionState->addDirtyFlags(Simulation::DIRTY_POSITION); _motionState->addDirtyFlags(Simulation::DIRTY_POSITION);
} }
@ -1068,12 +1068,12 @@ void Avatar::renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, g
} }
} }
void Avatar::setScale(float scale) { void Avatar::setAvatarScale(float scale) {
_scale = scale; if (_targetScale * (1.0f - RESCALING_TOLERANCE) < scale &&
scale < _targetScale * (1.0f + RESCALING_TOLERANCE)) {
if (_targetScale * (1.0f - RESCALING_TOLERANCE) < _scale && setScale(glm::vec3(_targetScale));
_scale < _targetScale * (1.0f + RESCALING_TOLERANCE)) { } else {
_scale = _targetScale; setScale(glm::vec3(scale));
} }
} }
@ -1088,7 +1088,7 @@ float Avatar::getHeadHeight() const {
// HACK: We have a really odd case when fading out for some models where this value explodes // HACK: We have a really odd case when fading out for some models where this value explodes
float result = extents.maximum.y - extents.minimum.y; float result = extents.maximum.y - extents.minimum.y;
if (result >= 0.0f && result < 100.0f * _scale ) { if (result >= 0.0f && result < 100.0f * getAvatarScale() ) {
return result; return result;
} }
} }
@ -1096,7 +1096,7 @@ float Avatar::getHeadHeight() const {
extents = _skeletonModel.getMeshExtents(); extents = _skeletonModel.getMeshExtents();
glm::vec3 neckPosition; glm::vec3 neckPosition;
if (!extents.isEmpty() && extents.isValid() && _skeletonModel.getNeckPosition(neckPosition)) { if (!extents.isEmpty() && extents.isValid() && _skeletonModel.getNeckPosition(neckPosition)) {
return extents.maximum.y / 2.0f - neckPosition.y + _position.y; return extents.maximum.y / 2.0f - neckPosition.y + getPosition().y;
} }
const float DEFAULT_HEAD_HEIGHT = 0.25f; const float DEFAULT_HEAD_HEIGHT = 0.25f;

View file

@ -103,7 +103,7 @@ public:
const SkeletonModel& getSkeletonModel() const { return _skeletonModel; } const SkeletonModel& getSkeletonModel() const { return _skeletonModel; }
const QVector<Model*>& getAttachmentModels() const { return _attachmentModels; } const QVector<Model*>& getAttachmentModels() const { return _attachmentModels; }
glm::vec3 getChestPosition() const; glm::vec3 getChestPosition() const;
float getScale() const { return _scale; } float getAvatarScale() const { return getScale().y; }
const Head* getHead() const { return static_cast<const Head*>(_headData); } const Head* getHead() const { return static_cast<const Head*>(_headData); }
Head* getHead() { return static_cast<Head*>(_headData); } Head* getHead() { return static_cast<Head*>(_headData); }
Hand* getHand() { return static_cast<Hand*>(_handData); } Hand* getHand() { return static_cast<Hand*>(_handData); }
@ -207,7 +207,6 @@ protected:
glm::quat _lastOrientation; glm::quat _lastOrientation;
float _leanScale; float _leanScale;
float _scale;
glm::vec3 _worldUpDirection; glm::vec3 _worldUpDirection;
float _stringLength; float _stringLength;
bool _moving; ///< set when position is changing bool _moving; ///< set when position is changing
@ -219,7 +218,7 @@ protected:
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
glm::vec3 getBodyFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } glm::vec3 getBodyFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const;
void setScale(float scale); void setAvatarScale(float scale);
void measureMotionDerivatives(float deltaTime); void measureMotionDerivatives(float deltaTime);
float getSkeletonHeight() const; float getSkeletonHeight() const;

View file

@ -151,7 +151,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
while (fadingIterator != _avatarFades.end()) { while (fadingIterator != _avatarFades.end()) {
auto avatar = std::static_pointer_cast<Avatar>(*fadingIterator); auto avatar = std::static_pointer_cast<Avatar>(*fadingIterator);
avatar->startUpdate(); avatar->startUpdate();
avatar->setTargetScale(avatar->getScale() * SHRINK_RATE, true); avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE, true);
if (avatar->getTargetScale() < MIN_FADE_SCALE) { if (avatar->getTargetScale() < MIN_FADE_SCALE) {
avatar->removeFromScene(*fadingIterator, scene, pendingChanges); avatar->removeFromScene(*fadingIterator, scene, pendingChanges);
fadingIterator = _avatarFades.erase(fadingIterator); fadingIterator = _avatarFades.erase(fadingIterator);

View file

@ -43,7 +43,7 @@ void Hand::simulate(float deltaTime, bool isMine) {
void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
float avatarScale = 1.0f; float avatarScale = 1.0f;
if (_owningAvatar) { if (_owningAvatar) {
avatarScale = _owningAvatar->getScale(); avatarScale = _owningAvatar->getAvatarScale();
} }
const float alpha = 1.0f; const float alpha = 1.0f;

View file

@ -129,11 +129,11 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
CameraMode mode = qApp->getCamera()->getMode(); CameraMode mode = qApp->getCamera()->getMode();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
// fake the avatar position that is sent up to the AvatarMixer // fake the avatar position that is sent up to the AvatarMixer
glm::vec3 oldPosition = _position; glm::vec3 oldPosition = getPosition();
_position = getSkeletonPosition(); setPosition(getSkeletonPosition());
QByteArray array = AvatarData::toByteArray(cullSmallChanges, sendAll); QByteArray array = AvatarData::toByteArray(cullSmallChanges, sendAll);
// copy the correct position back // copy the correct position back
_position = oldPosition; setPosition(oldPosition);
return array; return array;
} }
return AvatarData::toByteArray(cullSmallChanges, sendAll); return AvatarData::toByteArray(cullSmallChanges, sendAll);
@ -228,9 +228,9 @@ void MyAvatar::simulate(float deltaTime) {
_player->play(); _player->play();
} }
if (_scale != _targetScale) { if (getAvatarScale() != _targetScale) {
float scale = (1.0f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale; float scale = (1.0f - SMOOTHING_RATIO) * getAvatarScale() + SMOOTHING_RATIO * _targetScale;
setScale(scale); setAvatarScale(scale);
} }
{ {
@ -277,10 +277,10 @@ void MyAvatar::simulate(float deltaTime) {
Head* head = getHead(); Head* head = getHead();
glm::vec3 headPosition; glm::vec3 headPosition;
if (!_skeletonModel.getHeadPosition(headPosition)) { if (!_skeletonModel.getHeadPosition(headPosition)) {
headPosition = _position; headPosition = getPosition();
} }
head->setPosition(headPosition); head->setPosition(headPosition);
head->setScale(_scale); head->setScale(getAvatarScale());
head->simulate(deltaTime, true); head->simulate(deltaTime, true);
} }
@ -846,7 +846,7 @@ void MyAvatar::loadData() {
_leanScale = loadSetting(settings, "leanScale", 0.05f); _leanScale = loadSetting(settings, "leanScale", 0.05f);
_targetScale = loadSetting(settings, "scale", 1.0f); _targetScale = loadSetting(settings, "scale", 1.0f);
setScale(_scale); setAvatarScale(getAvatarScale());
_animGraphUrl = settings.value("animGraphURL", "").toString(); _animGraphUrl = settings.value("animGraphURL", "").toString();
_fullAvatarURLFromPreferences = settings.value("fullAvatarURL", AvatarData::defaultFullAvatarModelUrl()).toUrl(); _fullAvatarURLFromPreferences = settings.value("fullAvatarURL", AvatarData::defaultFullAvatarModelUrl()).toUrl();
@ -992,7 +992,8 @@ void MyAvatar::updateLookAtTargetAvatar() {
bool isCurrentTarget = avatar->getIsLookAtTarget(); bool isCurrentTarget = avatar->getIsLookAtTarget();
float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition);
avatar->setIsLookAtTarget(false); avatar->setIsLookAtTarget(false);
if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { if (!avatar->isMyAvatar() && avatar->isInitialized() &&
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getAvatarScale())) {
float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition));
if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) {
_lookAtTargetAvatar = avatarPointer; _lookAtTargetAvatar = avatarPointer;
@ -1228,7 +1229,7 @@ glm::vec3 MyAvatar::getSkeletonPosition() const {
// The avatar is rotated PI about the yAxis, so we have to correct for it // The avatar is rotated PI about the yAxis, so we have to correct for it
// to get the skeleton offset contribution in the world-frame. // to get the skeleton offset contribution in the world-frame.
const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
return _position + getOrientation() * FLIP * _skeletonOffset; return getPosition() + getOrientation() * FLIP * _skeletonOffset;
} }
return Avatar::getPosition(); return Avatar::getPosition();
} }
@ -1464,7 +1465,7 @@ const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f;
bool MyAvatar::cameraInsideHead() const { bool MyAvatar::cameraInsideHead() const {
const Head* head = getHead(); const Head* head = getHead();
const glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); const glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * _scale); return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getAvatarScale());
} }
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
@ -1618,11 +1619,11 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe
if (isHovering) { if (isHovering) {
// we're flying --> complex acceleration curve with high max speed // we're flying --> complex acceleration curve with high max speed
float motorSpeed = glm::length(_keyboardMotorVelocity); float motorSpeed = glm::length(_keyboardMotorVelocity);
float finalMaxMotorSpeed = _scale * MAX_KEYBOARD_MOTOR_SPEED; float finalMaxMotorSpeed = getAvatarScale() * MAX_KEYBOARD_MOTOR_SPEED;
float speedGrowthTimescale = 2.0f; float speedGrowthTimescale = 2.0f;
float speedIncreaseFactor = 1.8f; float speedIncreaseFactor = 1.8f;
motorSpeed *= 1.0f + glm::clamp(deltaTime / speedGrowthTimescale , 0.0f, 1.0f) * speedIncreaseFactor; motorSpeed *= 1.0f + glm::clamp(deltaTime / speedGrowthTimescale , 0.0f, 1.0f) * speedIncreaseFactor;
const float maxBoostSpeed = _scale * MAX_BOOST_SPEED; const float maxBoostSpeed = getAvatarScale() * MAX_BOOST_SPEED;
if (motorSpeed < maxBoostSpeed) { if (motorSpeed < maxBoostSpeed) {
// an active keyboard motor should never be slower than this // an active keyboard motor should never be slower than this
float boostCoefficient = (maxBoostSpeed - motorSpeed) / maxBoostSpeed; float boostCoefficient = (maxBoostSpeed - motorSpeed) / maxBoostSpeed;

View file

@ -416,7 +416,7 @@ bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& positi
glm::vec3 relativeDirection = glm::normalize(inverseOrientation * direction); glm::vec3 relativeDirection = glm::normalize(inverseOrientation * direction);
float t; float t;
if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getScale(), &t)){ if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getAvatarScale(), &t)){
result = position + direction * t; result = position + direction * t;
return true; return true;
} }

View file

@ -189,7 +189,7 @@ void PreferencesDialog::loadPreferences() {
ui.leanScaleSpin->setValue(myAvatar->getLeanScale()); ui.leanScaleSpin->setValue(myAvatar->getLeanScale());
ui.avatarScaleSpin->setValue(myAvatar->getScale()); ui.avatarScaleSpin->setValue(myAvatar->getAvatarScale());
ui.avatarAnimationEdit->setText(myAvatar->getAnimGraphUrl()); ui.avatarAnimationEdit->setText(myAvatar->getAnimGraphUrl());
ui.maxOctreePPSSpin->setValue(qApp->getMaxOctreePacketsPerSecond()); ui.maxOctreePPSSpin->setValue(qApp->getMaxOctreePacketsPerSecond());

View file

@ -68,7 +68,7 @@ namespace render {
glm::vec3 myAvatarPosition = avatar->getPosition(); glm::vec3 myAvatarPosition = avatar->getPosition();
float angle = glm::degrees(glm::angle(myAvatarRotation)); float angle = glm::degrees(glm::angle(myAvatarRotation));
glm::vec3 axis = glm::axis(myAvatarRotation); glm::vec3 axis = glm::axis(myAvatarRotation);
float myAvatarScale = avatar->getScale(); float myAvatarScale = avatar->getAvatarScale();
Transform transform = Transform(); Transform transform = Transform();
transform.setTranslation(myAvatarPosition); transform.setTranslation(myAvatarPosition);
transform.setRotation(glm::angleAxis(angle, axis)); transform.setRotation(glm::angleAxis(angle, axis));

View file

@ -38,11 +38,7 @@ const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f);
AvatarData::AvatarData() : AvatarData::AvatarData() :
_sessionUUID(), _sessionUUID(),
_position(0.0f),
_handPosition(0.0f), _handPosition(0.0f),
_bodyYaw(-90.0f),
_bodyPitch(0.0f),
_bodyRoll(0.0f),
_targetScale(1.0f), _targetScale(1.0f),
_handState(0), _handState(0),
_keyState(NO_KEY_DOWN), _keyState(NO_KEY_DOWN),
@ -61,7 +57,9 @@ AvatarData::AvatarData() :
_targetVelocity(0.0f), _targetVelocity(0.0f),
_localAABox(DEFAULT_LOCAL_AABOX_CORNER, DEFAULT_LOCAL_AABOX_SCALE) _localAABox(DEFAULT_LOCAL_AABOX_CORNER, DEFAULT_LOCAL_AABOX_SCALE)
{ {
setBodyPitch(0.0f);
setBodyYaw(-90.0f);
setBodyRoll(0.0f);
} }
AvatarData::~AvatarData() { AvatarData::~AvatarData() {
@ -79,23 +77,37 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() {
return _defaultFullAvatarModelUrl; return _defaultFullAvatarModelUrl;
} }
const glm::vec3& AvatarData::getPosition() const { float AvatarData::getBodyYaw() const {
return _position; glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation()));
return eulerAngles.y;
} }
void AvatarData::setPosition(const glm::vec3 position) { void AvatarData::setBodyYaw(float bodyYaw) {
_position = position; glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation()));
eulerAngles.y = bodyYaw;
setOrientation(glm::quat(glm::radians(eulerAngles)));
} }
glm::quat AvatarData::getOrientation() const { float AvatarData::getBodyPitch() const {
return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation()));
return eulerAngles.x;
} }
void AvatarData::setOrientation(const glm::quat& orientation) { void AvatarData::setBodyPitch(float bodyPitch) {
glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation)); glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation()));
_bodyPitch = eulerAngles.x; eulerAngles.x = bodyPitch;
_bodyYaw = eulerAngles.y; setOrientation(glm::quat(glm::radians(eulerAngles)));
_bodyRoll = eulerAngles.z; }
float AvatarData::getBodyRoll() const {
glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation()));
return eulerAngles.z;
}
void AvatarData::setBodyRoll(float bodyRoll) {
glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation()));
eulerAngles.z = bodyRoll;
setOrientation(glm::quat(glm::radians(eulerAngles)));
} }
// There are a number of possible strategies for this set of tools through endRender, below. // There are a number of possible strategies for this set of tools through endRender, below.
@ -162,12 +174,12 @@ void AvatarData::setClampedTargetScale(float targetScale, bool overideReferentia
} }
glm::vec3 AvatarData::getHandPosition() const { glm::vec3 AvatarData::getHandPosition() const {
return getOrientation() * _handPosition + _position; return getOrientation() * _handPosition + getPosition();
} }
void AvatarData::setHandPosition(const glm::vec3& handPosition) { void AvatarData::setHandPosition(const glm::vec3& handPosition) {
// store relative to position/orientation // store relative to position/orientation
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position); _handPosition = glm::inverse(getOrientation()) * (handPosition - getPosition());
} }
QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
@ -188,13 +200,14 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
unsigned char* destinationBuffer = reinterpret_cast<unsigned char*>(avatarDataByteArray.data()); unsigned char* destinationBuffer = reinterpret_cast<unsigned char*>(avatarDataByteArray.data());
unsigned char* startPosition = destinationBuffer; unsigned char* startPosition = destinationBuffer;
memcpy(destinationBuffer, &_position, sizeof(_position)); const glm::vec3& position = getPosition();
destinationBuffer += sizeof(_position); memcpy(destinationBuffer, &position, sizeof(position));
destinationBuffer += sizeof(position);
// Body rotation (NOTE: This needs to become a quaternion to save two bytes) // Body rotation
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyYaw());
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyPitch());
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyRoll());
// Body scale // Body scale
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale);
@ -487,11 +500,12 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
} }
return maxAvailableSize; return maxAvailableSize;
} }
if (_bodyYaw != yaw || _bodyPitch != pitch || _bodyRoll != roll) {
// TODO is this safe? will the floats not exactly match?
if (getBodyYaw() != yaw || getBodyPitch() != pitch || getBodyRoll() != roll) {
_hasNewJointRotations = true; _hasNewJointRotations = true;
_bodyYaw = yaw; glm::vec3 eulerAngles(pitch, yaw, roll);
_bodyPitch = pitch; setOrientation(glm::quat(glm::radians(eulerAngles)));
_bodyRoll = roll;
} }
// scale // scale

View file

@ -50,6 +50,7 @@ typedef unsigned long long quint64;
#include <Node.h> #include <Node.h>
#include <RegisteredMetaTypes.h> #include <RegisteredMetaTypes.h>
#include <SimpleMovingAverage.h> #include <SimpleMovingAverage.h>
#include <SpatiallyNestable.h>
#include "AABox.h" #include "AABox.h"
#include "HandData.h" #include "HandData.h"
@ -134,7 +135,7 @@ class QDataStream;
class AttachmentData; class AttachmentData;
class JointData; class JointData;
class AvatarData : public QObject { class AvatarData : public QObject, public SpatiallyNestable {
Q_OBJECT Q_OBJECT
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
@ -172,9 +173,6 @@ public:
const QUuid& getSessionUUID() const { return _sessionUUID; } const QUuid& getSessionUUID() const { return _sessionUUID; }
const glm::vec3& getPosition() const;
virtual void setPosition(const glm::vec3 position);
glm::vec3 getHandPosition() const; glm::vec3 getHandPosition() const;
void setHandPosition(const glm::vec3& handPosition); void setHandPosition(const glm::vec3& handPosition);
@ -189,16 +187,13 @@ public:
/// \return number of bytes parsed /// \return number of bytes parsed
virtual int parseDataFromBuffer(const QByteArray& buffer); virtual int parseDataFromBuffer(const QByteArray& buffer);
// Body Rotation (degrees) // Body Rotation (degrees)
float getBodyYaw() const { return _bodyYaw; } float getBodyYaw() const;
void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; } void setBodyYaw(float bodyYaw);
float getBodyPitch() const { return _bodyPitch; } float getBodyPitch() const;
void setBodyPitch(float bodyPitch) { _bodyPitch = bodyPitch; } void setBodyPitch(float bodyPitch);
float getBodyRoll() const { return _bodyRoll; } float getBodyRoll() const;
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } void setBodyRoll(float bodyRoll);
glm::quat getOrientation() const;
virtual void setOrientation(const glm::quat& orientation);
void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time.
void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc.
@ -363,13 +358,7 @@ public slots:
protected: protected:
QUuid _sessionUUID; QUuid _sessionUUID;
glm::vec3 _position = START_LOCATION;
glm::vec3 _handPosition; glm::vec3 _handPosition;
// Body rotation
float _bodyYaw; // degrees
float _bodyPitch; // degrees
float _bodyRoll; // degrees
glm::vec3 _nextPosition {}; glm::vec3 _nextPosition {};
glm::quat _nextOrientation {}; glm::quat _nextOrientation {};