mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:50:00 +02:00
properly scale avatar collision shape
This commit is contained in:
parent
29516619ee
commit
e9f52b1211
14 changed files with 108 additions and 82 deletions
|
@ -1260,15 +1260,14 @@ void Application::paintGL() {
|
||||||
hmdOffset.x = -hmdOffset.x;
|
hmdOffset.x = -hmdOffset.x;
|
||||||
|
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
+ glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0)
|
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
||||||
+ mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
+ mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
||||||
+ mirrorBodyOrientation * hmdOffset);
|
+ mirrorBodyOrientation * hmdOffset);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_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->getAvatarScale(), 0)
|
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,8 @@ 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);
|
setScale(glm::vec3(1.0f)); // avatar scale is uniform
|
||||||
|
|
||||||
// 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));
|
||||||
|
@ -143,15 +144,28 @@ 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(), getPosition()) / getAvatarScale();
|
glm::distance(qApp->getCamera()->getPosition(), getPosition()) / getUniformScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::animateScaleChanges(float deltaTime) {
|
||||||
|
float currentScale = getUniformScale();
|
||||||
|
if (currentScale != _targetScale) {
|
||||||
|
const float SCALE_ANIMATION_TIMESCALE = 1.0f;
|
||||||
|
float blendFactor = deltaTime / SCALE_ANIMATION_TIMESCALE;
|
||||||
|
float animatedScale = (1.0f - blendFactor) * currentScale + blendFactor * _targetScale;
|
||||||
|
const float CLOSE_ENOUGH = 0.05f;
|
||||||
|
if (fabsf(animatedScale - _targetScale) / _targetScale < CLOSE_ENOUGH) {
|
||||||
|
animatedScale = _targetScale;
|
||||||
|
}
|
||||||
|
setScale(glm::vec3(animatedScale)); // avatar scale is uniform
|
||||||
|
rebuildCollisionShape();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime) {
|
void Avatar::simulate(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("simulate");
|
PerformanceTimer perfTimer("simulate");
|
||||||
|
|
||||||
if (getAvatarScale() != _targetScale) {
|
animateScaleChanges(deltaTime);
|
||||||
setAvatarScale(_targetScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the billboard render flag
|
// update the billboard render flag
|
||||||
const float BILLBOARD_HYSTERESIS_PROPORTION = 0.1f;
|
const float BILLBOARD_HYSTERESIS_PROPORTION = 0.1f;
|
||||||
|
@ -164,7 +178,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
_shouldRenderBillboard = true;
|
_shouldRenderBillboard = true;
|
||||||
qCDebug(interfaceapp) << "Billboarding" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for LOD" << getLODDistance();
|
qCDebug(interfaceapp) << "Billboarding" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for LOD" << getLODDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isControllerLogging = DependencyManager::get<AvatarManager>()->getRenderDistanceControllerIsLogging();
|
const bool isControllerLogging = DependencyManager::get<AvatarManager>()->getRenderDistanceControllerIsLogging();
|
||||||
float renderDistance = DependencyManager::get<AvatarManager>()->getRenderDistance();
|
float renderDistance = DependencyManager::get<AvatarManager>()->getRenderDistance();
|
||||||
const float SKIP_HYSTERESIS_PROPORTION = isControllerLogging ? 0.0f : BILLBOARD_HYSTERESIS_PROPORTION;
|
const float SKIP_HYSTERESIS_PROPORTION = isControllerLogging ? 0.0f : BILLBOARD_HYSTERESIS_PROPORTION;
|
||||||
|
@ -210,7 +224,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
_skeletonModel.getHeadPosition(headPosition);
|
_skeletonModel.getHeadPosition(headPosition);
|
||||||
Head* head = getHead();
|
Head* head = getHead();
|
||||||
head->setPosition(headPosition);
|
head->setPosition(headPosition);
|
||||||
head->setScale(getAvatarScale());
|
head->setScale(getUniformScale());
|
||||||
head->simulate(deltaTime, false, _shouldRenderBillboard);
|
head->simulate(deltaTime, false, _shouldRenderBillboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,12 +252,12 @@ void Avatar::simulate(float deltaTime) {
|
||||||
measureMotionDerivatives(deltaTime);
|
measureMotionDerivatives(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) {
|
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
|
||||||
const float HEAD_SPHERE_RADIUS = 0.1f;
|
const float HEAD_SPHERE_RADIUS = 0.1f;
|
||||||
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 * getAvatarScale());
|
return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getUniformScale());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
||||||
|
@ -423,7 +437,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 * getAvatarScale();
|
float distance = BASE_LIGHT_DISTANCE * getUniformScale();
|
||||||
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()) {
|
||||||
|
@ -479,7 +493,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch,
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch,
|
||||||
Transform(transform).postScale(eyeDiameter * getAvatarScale() / 2.0f + RADIUS_INCREMENT),
|
Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT),
|
||||||
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
||||||
|
|
||||||
position = getHead()->getRightEyePosition();
|
position = getHead()->getRightEyePosition();
|
||||||
|
@ -489,7 +503,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 * getAvatarScale() / 2.0f + RADIUS_INCREMENT),
|
Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT),
|
||||||
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -590,9 +604,9 @@ void Avatar::simulateAttachments(float deltaTime) {
|
||||||
glm::quat jointRotation;
|
glm::quat jointRotation;
|
||||||
if (_skeletonModel.getJointPositionInWorldFrame(jointIndex, jointPosition) &&
|
if (_skeletonModel.getJointPositionInWorldFrame(jointIndex, jointPosition) &&
|
||||||
_skeletonModel.getJointRotationInWorldFrame(jointIndex, jointRotation)) {
|
_skeletonModel.getJointRotationInWorldFrame(jointIndex, jointRotation)) {
|
||||||
model->setTranslation(jointPosition + jointRotation * attachment.translation * getAvatarScale());
|
model->setTranslation(jointPosition + jointRotation * attachment.translation * getUniformScale());
|
||||||
model->setRotation(jointRotation * attachment.rotation);
|
model->setRotation(jointRotation * attachment.rotation);
|
||||||
model->setScaleToFit(true, getAvatarScale() * attachment.scale, true); // hack to force rescale
|
model->setScaleToFit(true, getUniformScale() * 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);
|
||||||
|
@ -647,7 +661,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Avatar::getBillboardSize() const {
|
float Avatar::getBillboardSize() const {
|
||||||
return getAvatarScale() * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
|
return getUniformScale() * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -796,7 +810,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 = getAvatarScale() * 0.5f;
|
const float MAX_OFFSET_LENGTH = getUniformScale() * 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;
|
||||||
|
@ -905,7 +919,7 @@ glm::vec3 Avatar::getJointPosition(const QString& name) const {
|
||||||
|
|
||||||
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 = getPosition() + getAvatarScale() * (positionToScale - getPosition());
|
positionToScale = getPosition() + getUniformScale() * (positionToScale - getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setFaceModelURL(const QUrl& faceModelURL) {
|
void Avatar::setFaceModelURL(const QUrl& faceModelURL) {
|
||||||
|
@ -945,7 +959,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, getAvatarScale() * _attachmentData.at(i).scale);
|
_attachmentModels[i]->setScaleToFit(true, getUniformScale() * _attachmentData.at(i).scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,15 +1047,6 @@ void Avatar::renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setAvatarScale(float scale) {
|
|
||||||
if (_targetScale * (1.0f - RESCALING_TOLERANCE) < scale &&
|
|
||||||
scale < _targetScale * (1.0f + RESCALING_TOLERANCE)) {
|
|
||||||
setScale(glm::vec3(_targetScale));
|
|
||||||
} else {
|
|
||||||
setScale(glm::vec3(scale));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float Avatar::getSkeletonHeight() const {
|
float Avatar::getSkeletonHeight() const {
|
||||||
Extents extents = _skeletonModel.getBindExtents();
|
Extents extents = _skeletonModel.getBindExtents();
|
||||||
return extents.maximum.y - extents.minimum.y;
|
return extents.maximum.y - extents.minimum.y;
|
||||||
|
@ -1053,7 +1058,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 * getAvatarScale() ) {
|
if (result >= 0.0f && result < 100.0f * getUniformScale() ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1096,13 +1101,20 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
shapeInfo.setCapsuleY(_skeletonModel.getBoundingCapsuleRadius(), 0.5f * _skeletonModel.getBoundingCapsuleHeight());
|
float uniformScale = getUniformScale();
|
||||||
shapeInfo.setOffset(_skeletonModel.getBoundingCapsuleOffset());
|
shapeInfo.setCapsuleY(uniformScale * _skeletonModel.getBoundingCapsuleRadius(),
|
||||||
|
0.5f * uniformScale * _skeletonModel.getBoundingCapsuleHeight());
|
||||||
|
shapeInfo.setOffset(uniformScale * _skeletonModel.getBoundingCapsuleOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void Avatar::rebuildSkeletonBody() {
|
void Avatar::rebuildCollisionShape() {
|
||||||
DependencyManager::get<AvatarManager>()->updateAvatarPhysicsShape(this);
|
if (_motionState) {
|
||||||
|
_motionState->addDirtyFlags(Simulation::DIRTY_SHAPE);
|
||||||
|
} else {
|
||||||
|
// adebug TODO: move most of updateAvatarPhysicsShape() to here
|
||||||
|
DependencyManager::get<AvatarManager>()->updateAvatarPhysicsShape(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Avatar::getLeftPalmPosition() {
|
glm::vec3 Avatar::getLeftPalmPosition() {
|
||||||
|
|
|
@ -36,7 +36,6 @@ namespace render {
|
||||||
|
|
||||||
static const float SCALING_RATIO = .05f;
|
static const float SCALING_RATIO = .05f;
|
||||||
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
|
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
|
||||||
static const float RESCALING_TOLERANCE = .02f;
|
|
||||||
|
|
||||||
static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees
|
static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees
|
||||||
static const float BILLBOARD_DISTANCE = 5.56f; // meters
|
static const float BILLBOARD_DISTANCE = 5.56f; // meters
|
||||||
|
@ -89,7 +88,7 @@ public:
|
||||||
SkeletonModel& getSkeletonModel() { return _skeletonModel; }
|
SkeletonModel& getSkeletonModel() { return _skeletonModel; }
|
||||||
const SkeletonModel& getSkeletonModel() const { return _skeletonModel; }
|
const SkeletonModel& getSkeletonModel() const { return _skeletonModel; }
|
||||||
glm::vec3 getChestPosition() const;
|
glm::vec3 getChestPosition() const;
|
||||||
float getAvatarScale() const { return getScale().y; }
|
float getUniformScale() 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); }
|
||||||
|
@ -154,7 +153,7 @@ public:
|
||||||
// (otherwise floating point error will cause problems at large positions).
|
// (otherwise floating point error will cause problems at large positions).
|
||||||
void applyPositionDelta(const glm::vec3& delta);
|
void applyPositionDelta(const glm::vec3& delta);
|
||||||
|
|
||||||
virtual void rebuildSkeletonBody();
|
virtual void rebuildCollisionShape();
|
||||||
|
|
||||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
||||||
|
|
||||||
|
@ -199,14 +198,15 @@ protected:
|
||||||
float _stringLength;
|
float _stringLength;
|
||||||
bool _moving; ///< set when position is changing
|
bool _moving; ///< set when position is changing
|
||||||
|
|
||||||
bool isLookingAtMe(AvatarSharedPointer avatar);
|
|
||||||
|
|
||||||
// protected methods...
|
// protected methods...
|
||||||
|
bool isLookingAtMe(AvatarSharedPointer avatar) const;
|
||||||
|
|
||||||
|
virtual void animateScaleChanges(float deltaTime);
|
||||||
|
|
||||||
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||||
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 setAvatarScale(float scale);
|
|
||||||
void measureMotionDerivatives(float deltaTime);
|
void measureMotionDerivatives(float deltaTime);
|
||||||
|
|
||||||
float getSkeletonHeight() const;
|
float getSkeletonHeight() const;
|
||||||
|
|
|
@ -203,7 +203,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->getAvatarScale() * SHRINK_RATE);
|
avatar->setTargetScale(avatar->getUniformScale() * SHRINK_RATE);
|
||||||
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);
|
||||||
|
@ -375,19 +375,17 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::updateAvatarPhysicsShape(Avatar* avatar) {
|
void AvatarManager::updateAvatarPhysicsShape(Avatar* avatar) {
|
||||||
AvatarMotionState* motionState = avatar->getMotionState();
|
// adebug TODO: move most of this logic to MyAvatar class
|
||||||
if (motionState) {
|
assert(!avatar->getMotionState());
|
||||||
motionState->addDirtyFlags(Simulation::DIRTY_SHAPE);
|
|
||||||
} else {
|
ShapeInfo shapeInfo;
|
||||||
ShapeInfo shapeInfo;
|
avatar->computeShapeInfo(shapeInfo);
|
||||||
avatar->computeShapeInfo(shapeInfo);
|
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||||
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
if (shape) {
|
||||||
if (shape) {
|
AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
|
||||||
AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
|
avatar->setMotionState(motionState);
|
||||||
avatar->setMotionState(motionState);
|
_motionStatesToAdd.insert(motionState);
|
||||||
_motionStatesToAdd.insert(motionState);
|
_avatarMotionStates.insert(motionState);
|
||||||
_avatarMotionStates.insert(motionState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
virtual float getObjectFriction() const;
|
virtual float getObjectFriction() const;
|
||||||
virtual float getObjectLinearDamping() const;
|
virtual float getObjectLinearDamping() const;
|
||||||
virtual float getObjectAngularDamping() const;
|
virtual float getObjectAngularDamping() const;
|
||||||
|
|
||||||
virtual glm::vec3 getObjectPosition() const;
|
virtual glm::vec3 getObjectPosition() const;
|
||||||
virtual glm::quat getObjectRotation() const;
|
virtual glm::quat getObjectRotation() const;
|
||||||
virtual glm::vec3 getObjectLinearVelocity() const;
|
virtual glm::vec3 getObjectLinearVelocity() const;
|
||||||
|
|
|
@ -37,7 +37,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->getAvatarScale();
|
avatarScale = _owningAvatar->getUniformScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
const float alpha = 1.0f;
|
const float alpha = 1.0f;
|
||||||
|
@ -62,7 +62,7 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
transform.setRotation(palm.getRotation());
|
transform.setRotation(palm.getRotation());
|
||||||
transform.postScale(SPHERE_RADIUS);
|
transform.postScale(SPHERE_RADIUS);
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, transform, grayColor);
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, transform, grayColor);
|
||||||
|
|
||||||
// draw a green sphere at the old "finger tip"
|
// draw a green sphere at the old "finger tip"
|
||||||
transform = Transform();
|
transform = Transform();
|
||||||
position = palm.getTipPosition();
|
position = palm.getTipPosition();
|
||||||
|
@ -72,7 +72,7 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, transform, greenColor);
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, transform, greenColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float AXIS_RADIUS = 0.1f * SPHERE_RADIUS;
|
const float AXIS_RADIUS = 0.1f * SPHERE_RADIUS;
|
||||||
const float AXIS_LENGTH = 10.0f * SPHERE_RADIUS;
|
const float AXIS_LENGTH = 10.0f * SPHERE_RADIUS;
|
||||||
|
|
||||||
|
|
|
@ -284,13 +284,26 @@ void MyAvatar::update(float deltaTime) {
|
||||||
extern QByteArray avatarStateToFrame(const AvatarData* _avatar);
|
extern QByteArray avatarStateToFrame(const AvatarData* _avatar);
|
||||||
extern void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);
|
extern void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);
|
||||||
|
|
||||||
|
void MyAvatar::animateScaleChanges(float deltaTime) {
|
||||||
|
// HACK: override Avatar::animateScaleChanges() until MyAvatar has a MotionState
|
||||||
|
float currentScale = getUniformScale();
|
||||||
|
if (currentScale != _targetScale) {
|
||||||
|
const float SCALE_ANIMATION_TIMESCALE = 1.0f;
|
||||||
|
float blendFactor = deltaTime / SCALE_ANIMATION_TIMESCALE;
|
||||||
|
float animatedScale = (1.0f - blendFactor) * currentScale + blendFactor * _targetScale;
|
||||||
|
const float CLOSE_ENOUGH = 0.05f;
|
||||||
|
if (fabsf(animatedScale - _targetScale) / _targetScale < CLOSE_ENOUGH) {
|
||||||
|
animatedScale = _targetScale;
|
||||||
|
}
|
||||||
|
setScale(glm::vec3(animatedScale));
|
||||||
|
rebuildCollisionShape();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::simulate(float deltaTime) {
|
void MyAvatar::simulate(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("simulate");
|
PerformanceTimer perfTimer("simulate");
|
||||||
|
|
||||||
if (getAvatarScale() != _targetScale) {
|
animateScaleChanges(deltaTime);
|
||||||
float scale = (1.0f - SMOOTHING_RATIO) * getAvatarScale() + SMOOTHING_RATIO * _targetScale;
|
|
||||||
setAvatarScale(scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("transform");
|
PerformanceTimer perfTimer("transform");
|
||||||
|
@ -337,7 +350,7 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
headPosition = getPosition();
|
headPosition = getPosition();
|
||||||
}
|
}
|
||||||
head->setPosition(headPosition);
|
head->setPosition(headPosition);
|
||||||
head->setScale(getAvatarScale());
|
head->setScale(getUniformScale());
|
||||||
head->simulate(deltaTime, true);
|
head->simulate(deltaTime, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +694,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);
|
||||||
setAvatarScale(getAvatarScale());
|
setScale(glm::vec3(getUniformScale()));
|
||||||
|
|
||||||
_animGraphUrl = settings.value("animGraphURL", "").toString();
|
_animGraphUrl = settings.value("animGraphURL", "").toString();
|
||||||
_fullAvatarURLFromPreferences = settings.value("fullAvatarURL", AvatarData::defaultFullAvatarModelUrl()).toUrl();
|
_fullAvatarURLFromPreferences = settings.value("fullAvatarURL", AvatarData::defaultFullAvatarModelUrl()).toUrl();
|
||||||
|
@ -809,7 +822,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
||||||
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() &&
|
if (!avatar->isMyAvatar() && avatar->isInitialized() &&
|
||||||
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getAvatarScale())) {
|
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getUniformScale())) {
|
||||||
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;
|
||||||
|
@ -1036,14 +1049,15 @@ glm::vec3 MyAvatar::getSkeletonPosition() const {
|
||||||
return Avatar::getPosition();
|
return Avatar::getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::rebuildSkeletonBody() {
|
void MyAvatar::rebuildCollisionShape() {
|
||||||
// compute localAABox
|
// compute localAABox
|
||||||
float radius = _skeletonModel.getBoundingCapsuleRadius();
|
float scale = getUniformScale();
|
||||||
float height = _skeletonModel.getBoundingCapsuleHeight() + 2.0f * radius;
|
float radius = scale * _skeletonModel.getBoundingCapsuleRadius();
|
||||||
|
float height = scale * _skeletonModel.getBoundingCapsuleHeight() + 2.0f * radius;
|
||||||
glm::vec3 corner(-radius, -0.5f * height, -radius);
|
glm::vec3 corner(-radius, -0.5f * height, -radius);
|
||||||
corner += _skeletonModel.getBoundingCapsuleOffset();
|
corner += scale * _skeletonModel.getBoundingCapsuleOffset();
|
||||||
glm::vec3 scale(2.0f * radius, height, 2.0f * radius);
|
glm::vec3 diagonal(2.0f * radius, height, 2.0f * radius);
|
||||||
_characterController.setLocalBoundingBox(corner, scale);
|
_characterController.setLocalBoundingBox(corner, diagonal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::prepareForPhysicsSimulation() {
|
void MyAvatar::prepareForPhysicsSimulation() {
|
||||||
|
@ -1331,7 +1345,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 * getAvatarScale());
|
return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getUniformScale());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||||
|
@ -1455,11 +1469,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 = getAvatarScale() * MAX_KEYBOARD_MOTOR_SPEED;
|
float finalMaxMotorSpeed = getUniformScale() * 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 = getAvatarScale() * MAX_BOOST_SPEED;
|
const float maxBoostSpeed = getUniformScale() * 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;
|
||||||
|
|
|
@ -249,7 +249,7 @@ public slots:
|
||||||
|
|
||||||
Q_INVOKABLE void updateMotionBehaviorFromMenu();
|
Q_INVOKABLE void updateMotionBehaviorFromMenu();
|
||||||
|
|
||||||
virtual void rebuildSkeletonBody() override;
|
virtual void rebuildCollisionShape() override;
|
||||||
|
|
||||||
Q_INVOKABLE QUrl getAnimGraphUrl() const { return _animGraphUrl; }
|
Q_INVOKABLE QUrl getAnimGraphUrl() const { return _animGraphUrl; }
|
||||||
|
|
||||||
|
@ -263,6 +263,9 @@ public slots:
|
||||||
glm::vec3 getPositionForAudio();
|
glm::vec3 getPositionForAudio();
|
||||||
glm::quat getOrientationForAudio();
|
glm::quat getOrientationForAudio();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void animateScaleChanges(float deltaTime);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void audioListenerModeChanged();
|
void audioListenerModeChanged();
|
||||||
void transformChanged();
|
void transformChanged();
|
||||||
|
|
|
@ -32,7 +32,7 @@ MyCharacterController::~MyCharacterController() {
|
||||||
|
|
||||||
void MyCharacterController::updateShapeIfNecessary() {
|
void MyCharacterController::updateShapeIfNecessary() {
|
||||||
if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) {
|
if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) {
|
||||||
_pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE;
|
_pendingFlags &= ~PENDING_FLAG_UPDATE_SHAPE;
|
||||||
|
|
||||||
// compute new dimensions from avatar's bounding box
|
// compute new dimensions from avatar's bounding box
|
||||||
float x = _boxScale.x;
|
float x = _boxScale.x;
|
||||||
|
|
|
@ -69,7 +69,7 @@ void SkeletonModel::initJointStates() {
|
||||||
_headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);
|
_headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);
|
||||||
_headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP);
|
_headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP);
|
||||||
|
|
||||||
_owningAvatar->rebuildSkeletonBody();
|
_owningAvatar->rebuildCollisionShape();
|
||||||
emit skeletonLoaded();
|
emit skeletonLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -386,7 +386,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->getAvatarScale(), &t)){
|
if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getUniformScale(), &t)){
|
||||||
result = position + direction * t;
|
result = position + direction * t;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ void PreferencesDialog::loadPreferences() {
|
||||||
|
|
||||||
ui.leanScaleSpin->setValue(myAvatar->getLeanScale());
|
ui.leanScaleSpin->setValue(myAvatar->getLeanScale());
|
||||||
|
|
||||||
ui.avatarScaleSpin->setValue(myAvatar->getAvatarScale());
|
ui.avatarScaleSpin->setValue(myAvatar->getUniformScale());
|
||||||
ui.avatarAnimationEdit->setText(myAvatar->getAnimGraphUrl().toString());
|
ui.avatarAnimationEdit->setText(myAvatar->getAnimGraphUrl().toString());
|
||||||
|
|
||||||
ui.maxOctreePPSSpin->setValue(qApp->getMaxOctreePacketsPerSecond());
|
ui.maxOctreePPSSpin->setValue(qApp->getMaxOctreePacketsPerSecond());
|
||||||
|
|
|
@ -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->getAvatarScale();
|
float myAvatarScale = avatar->getUniformScale();
|
||||||
Transform transform = Transform();
|
Transform transform = Transform();
|
||||||
transform.setTranslation(myAvatarPosition);
|
transform.setTranslation(myAvatarPosition);
|
||||||
transform.setRotation(glm::angleAxis(angle, axis));
|
transform.setRotation(glm::angleAxis(angle, axis));
|
||||||
|
|
|
@ -90,7 +90,7 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() {
|
||||||
// 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.
|
||||||
void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) {
|
void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) {
|
||||||
avatarLock.lock();
|
avatarLock.lock();
|
||||||
Transform trans;
|
Transform trans = getTransform();
|
||||||
trans.setTranslation(position);
|
trans.setTranslation(position);
|
||||||
trans.setRotation(orientation);
|
trans.setRotation(orientation);
|
||||||
SpatiallyNestable::setTransform(trans);
|
SpatiallyNestable::setTransform(trans);
|
||||||
|
|
Loading…
Reference in a new issue