mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-28 02:39:54 +02:00
Better scale support in SpatiallyNestable class.
Previously avatar used SpatiallyNestable scale to keep track of model rendering scale. It now uses a new member variable _modelScale instead. This is important because the notion of "Avatar" space does NOT include scale, so this is now reflected correctly in the SpatiallyNestable class. Similarly, EntityItems no longer stuff dimensions into the SpatiallyNestable scale field. a new _dimensions member variable is used instead. The SpatiallyNestable scale field for entities should always be one. Parent joints can now have scale if getAbsoluteJointScaleInObjectFrame() returns a non-zero scale. This is used in the case of the faux SENSOR_TO_WORLD_MATRIX_INDEX joint. Overlays now ignore the SpatiallyNestable scale, and render using only orientation, position and dimensions. Added qDebug stream support for Transform class.
This commit is contained in:
parent
9cd8b6991e
commit
c9cdaadeb5
18 changed files with 146 additions and 153 deletions
|
@ -2463,7 +2463,7 @@ void Application::paintGL() {
|
|||
PerformanceTimer perfTimer("CameraUpdates");
|
||||
|
||||
auto myAvatar = getMyAvatar();
|
||||
boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
|
||||
boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
|
||||
|
||||
// The render mode is default or mirror if the camera is in mirror mode, assigned further below
|
||||
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||
|
@ -2516,14 +2516,14 @@ void Application::paintGL() {
|
|||
hmdOffset.x = -hmdOffset.x;
|
||||
|
||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
||||
+ glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0)
|
||||
+ mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
||||
+ mirrorBodyOrientation * hmdOffset);
|
||||
} else {
|
||||
_myCamera.setOrientation(myAvatar->getOrientation()
|
||||
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
||||
+ glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0)
|
||||
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
}
|
||||
|
|
|
@ -558,7 +558,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
headPosition = getPosition();
|
||||
}
|
||||
head->setPosition(headPosition);
|
||||
head->setScale(getUniformScale());
|
||||
head->setScale(getModelScale());
|
||||
head->simulate(deltaTime);
|
||||
}
|
||||
|
||||
|
@ -1223,7 +1223,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
|||
float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition);
|
||||
avatar->setIsLookAtTarget(false);
|
||||
if (!avatar->isMyAvatar() && avatar->isInitialized() &&
|
||||
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getUniformScale())) {
|
||||
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getModelScale())) {
|
||||
float radius = glm::length(avatar->getHead()->getEyePosition() - avatar->getHead()->getRightEyePosition());
|
||||
float angleTo = coneSphereAngle(getHead()->getEyePosition(), lookForward, avatar->getHead()->getEyePosition(), radius);
|
||||
if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) {
|
||||
|
@ -1465,7 +1465,7 @@ glm::vec3 MyAvatar::getSkeletonPosition() const {
|
|||
|
||||
void MyAvatar::rebuildCollisionShape() {
|
||||
// compute localAABox
|
||||
float scale = getUniformScale();
|
||||
float scale = getModelScale();
|
||||
float radius = scale * _skeletonModel->getBoundingCapsuleRadius();
|
||||
float height = scale * _skeletonModel->getBoundingCapsuleHeight() + 2.0f * radius;
|
||||
glm::vec3 corner(-radius, -0.5f * height, -radius);
|
||||
|
@ -1896,7 +1896,7 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
|
|||
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f;
|
||||
|
||||
bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const {
|
||||
return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getUniformScale());
|
||||
return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getModelScale());
|
||||
}
|
||||
|
||||
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||
|
@ -2251,7 +2251,7 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings
|
|||
_targetScale = clampedScale;
|
||||
}
|
||||
|
||||
setScale(glm::vec3(_targetScale));
|
||||
setModelScale(_targetScale);
|
||||
rebuildCollisionShape();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
@ -2940,6 +2940,30 @@ glm::mat4 MyAvatar::computeCameraRelativeHandControllerMatrix(const glm::mat4& c
|
|||
return glm::inverse(avatarMatrix) * controllerWorldMatrix;
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getAbsoluteJointScaleInObjectFrame(int index) const {
|
||||
if (index < 0) {
|
||||
index += numeric_limits<unsigned short>::max() + 1; // 65536
|
||||
}
|
||||
|
||||
// only sensor to world matrix has non identity scale.
|
||||
switch (index) {
|
||||
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX: {
|
||||
auto pose = getControllerPoseInSensorFrame(controller::Action::LEFT_HAND);
|
||||
glm::mat4 controllerSensorMatrix = createMatFromQuatAndPos(pose.rotation, pose.translation);
|
||||
glm::mat4 result = computeCameraRelativeHandControllerMatrix(controllerSensorMatrix);
|
||||
return extractScale(result);
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX: {
|
||||
auto pose = getControllerPoseInSensorFrame(controller::Action::RIGHT_HAND);
|
||||
glm::mat4 controllerSensorMatrix = createMatFromQuatAndPos(pose.rotation, pose.translation);
|
||||
glm::mat4 result = computeCameraRelativeHandControllerMatrix(controllerSensorMatrix);
|
||||
return extractScale(result);
|
||||
}
|
||||
default:
|
||||
return Avatar::getAbsoluteJointScaleInObjectFrame(index);
|
||||
}
|
||||
}
|
||||
|
||||
glm::quat MyAvatar::getAbsoluteJointRotationInObjectFrame(int index) const {
|
||||
if (index < 0) {
|
||||
index += numeric_limits<unsigned short>::max() + 1; // 65536
|
||||
|
|
|
@ -513,6 +513,7 @@ public:
|
|||
Q_INVOKABLE void setCharacterControllerEnabled(bool enabled); // deprecated
|
||||
Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated
|
||||
|
||||
virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const override;
|
||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
|
||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
|
||||
|
||||
|
|
|
@ -193,8 +193,8 @@ void setupPreferences() {
|
|||
preferences->addPreference(new PrimaryHandPreference(AVATAR_TUNING, "Dominant Hand", getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getUniformScale(); };
|
||||
auto setter = [=](float value) { myAvatar->setTargetScale(value); };
|
||||
auto getter = [=]()->float { return myAvatar->getModelScale(); };
|
||||
auto setter = [=](float value) { myAvatar->setModelScale(value); };
|
||||
auto preference = new SpinnerSliderPreference(AVATAR_TUNING, "Avatar Scale", getter, setter);
|
||||
preference->setStep(0.05f);
|
||||
preference->setDecimals(2);
|
||||
|
|
|
@ -46,13 +46,15 @@ void ModelOverlay::update(float deltatime) {
|
|||
if (_updateModel) {
|
||||
_updateModel = false;
|
||||
_model->setSnapModelToCenter(true);
|
||||
Transform transform = getTransform();
|
||||
transform.setScale(1.0f); // disable inherited scale
|
||||
if (_scaleToFit) {
|
||||
_model->setScaleToFit(true, getScale() * getDimensions());
|
||||
_model->setScaleToFit(true, transform.getScale() * getDimensions());
|
||||
} else {
|
||||
_model->setScale(getScale());
|
||||
_model->setScale(transform.getScale());
|
||||
}
|
||||
_model->setRotation(getRotation());
|
||||
_model->setTranslation(getPosition());
|
||||
_model->setRotation(transform.getRotation());
|
||||
_model->setTranslation(transform.getTranslation());
|
||||
_model->setURL(_url);
|
||||
_model->simulate(deltatime, true);
|
||||
} else {
|
||||
|
@ -93,13 +95,13 @@ void ModelOverlay::setProperties(const QVariantMap& properties) {
|
|||
auto origPosition = getPosition();
|
||||
auto origRotation = getRotation();
|
||||
auto origDimensions = getDimensions();
|
||||
auto origScale = getScale();
|
||||
auto origScale = getSNScale();
|
||||
|
||||
Base3DOverlay::setProperties(properties);
|
||||
|
||||
auto scale = properties["scale"];
|
||||
if (scale.isValid()) {
|
||||
setScale(vec3FromVariant(scale));
|
||||
setSNScale(vec3FromVariant(scale));
|
||||
}
|
||||
|
||||
auto dimensions = properties["dimensions"];
|
||||
|
@ -112,7 +114,7 @@ void ModelOverlay::setProperties(const QVariantMap& properties) {
|
|||
_scaleToFit = false;
|
||||
}
|
||||
|
||||
if (origPosition != getPosition() || origRotation != getRotation() || origDimensions != getDimensions() || origScale != getScale()) {
|
||||
if (origPosition != getPosition() || origRotation != getRotation() || origDimensions != getDimensions() || origScale != getSNScale()) {
|
||||
_updateModel = true;
|
||||
}
|
||||
|
||||
|
@ -194,7 +196,7 @@ QVariant ModelOverlay::getProperty(const QString& property) {
|
|||
return vec3toVariant(getDimensions());
|
||||
}
|
||||
if (property == "scale") {
|
||||
return vec3toVariant(getScale());
|
||||
return vec3toVariant(getSNScale());
|
||||
}
|
||||
if (property == "textures") {
|
||||
if (_modelTextures.size() > 0) {
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace render {
|
|||
glm::vec3 myAvatarPosition = avatar->getPosition();
|
||||
float angle = glm::degrees(glm::angle(myAvatarRotation));
|
||||
glm::vec3 axis = glm::axis(myAvatarRotation);
|
||||
float myAvatarScale = avatar->getUniformScale();
|
||||
float myAvatarScale = avatar->getModelScale();
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(myAvatarPosition);
|
||||
transform.setRotation(glm::angleAxis(angle, axis));
|
||||
|
|
|
@ -199,7 +199,6 @@ QString Web3DOverlay::pickURL() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Web3DOverlay::loadSourceURL() {
|
||||
if (!_webSurface) {
|
||||
return;
|
||||
|
@ -302,19 +301,11 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
emit resizeWebSurface();
|
||||
}
|
||||
|
||||
|
||||
vec2 halfSize = getSize() / 2.0f;
|
||||
vec4 color(toGlm(getColor()), getAlpha());
|
||||
|
||||
Transform transform = getTransform();
|
||||
|
||||
// FIXME: applyTransformTo causes tablet overlay to detach from tablet entity.
|
||||
// Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true?
|
||||
/*
|
||||
applyTransformTo(transform, true);
|
||||
setTransform(transform);
|
||||
*/
|
||||
|
||||
transform.setScale(1.0f); // ignore inherited scale factor from parents
|
||||
if (glm::length2(getDimensions()) != 1.0f) {
|
||||
transform.postScale(vec3(getDimensions(), 1.0f));
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ Avatar::Avatar(QThread* thread) :
|
|||
// we may have been created in the network thread, but we live in the main thread
|
||||
moveToThread(thread);
|
||||
|
||||
setScale(glm::vec3(1.0f)); // avatar scale is uniform
|
||||
setModelScale(1.0f); // avatar scale is uniform
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
_nameRectGeometryID = geometryCache->allocateID();
|
||||
|
@ -156,14 +156,14 @@ glm::vec3 Avatar::getNeckPosition() const {
|
|||
AABox Avatar::getBounds() const {
|
||||
if (!_skeletonModel->isRenderable() || _skeletonModel->needsFixupInScene()) {
|
||||
// approximately 2m tall, scaled to user request.
|
||||
return AABox(getPosition() - glm::vec3(getUniformScale()), getUniformScale() * 2.0f);
|
||||
return AABox(getPosition() - glm::vec3(getModelScale()), getModelScale() * 2.0f);
|
||||
}
|
||||
return _skeletonModel->getRenderableMeshBound();
|
||||
}
|
||||
|
||||
void Avatar::animateScaleChanges(float deltaTime) {
|
||||
if (_isAnimatingScale) {
|
||||
float currentScale = getUniformScale();
|
||||
float currentScale = getModelScale();
|
||||
float desiredScale = getDomainLimitedScale();
|
||||
|
||||
// use exponential decay toward the domain limit clamped scale
|
||||
|
@ -178,7 +178,7 @@ void Avatar::animateScaleChanges(float deltaTime) {
|
|||
animatedScale = desiredScale;
|
||||
_isAnimatingScale = false;
|
||||
}
|
||||
setScale(glm::vec3(animatedScale)); // avatar scale is uniform
|
||||
setModelScale(animatedScale); // avatar scale is uniform
|
||||
|
||||
// flag the joints as having changed for force update to RenderItem
|
||||
_hasNewJointData = true;
|
||||
|
@ -365,7 +365,7 @@ void Avatar::simulate(float deltaTime, bool inView) {
|
|||
}
|
||||
head->setPosition(headPosition);
|
||||
}
|
||||
head->setScale(getUniformScale());
|
||||
head->setScale(getModelScale());
|
||||
head->simulate(deltaTime);
|
||||
} else {
|
||||
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
|
||||
|
@ -423,7 +423,7 @@ bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
|
|||
glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition();
|
||||
glm::vec3 myEyePosition = getHead()->getEyePosition();
|
||||
|
||||
return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getUniformScale());
|
||||
return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getModelScale());
|
||||
}
|
||||
|
||||
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
||||
|
@ -654,7 +654,7 @@ void Avatar::render(RenderArgs* renderArgs) {
|
|||
if (showCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) {
|
||||
PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes");
|
||||
const float BOUNDING_SHAPE_ALPHA = 0.7f;
|
||||
_skeletonModel->renderBoundingCollisionShapes(renderArgs, *renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA);
|
||||
_skeletonModel->renderBoundingCollisionShapes(renderArgs, *renderArgs->_batch, getModelScale(), BOUNDING_SHAPE_ALPHA);
|
||||
}
|
||||
|
||||
if (showReceiveStats || showNamesAboveHeads) {
|
||||
|
@ -727,9 +727,9 @@ void Avatar::simulateAttachments(float deltaTime) {
|
|||
} else {
|
||||
if (_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPosition) &&
|
||||
_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRotation)) {
|
||||
model->setTranslation(jointPosition + jointRotation * attachment.translation * getUniformScale());
|
||||
model->setTranslation(jointPosition + jointRotation * attachment.translation * getModelScale());
|
||||
model->setRotation(jointRotation * attachment.rotation);
|
||||
float scale = getUniformScale() * attachment.scale;
|
||||
float scale = getModelScale() * attachment.scale;
|
||||
model->setScaleToFit(true, model->getNaturalDimensions() * scale, true); // hack to force rescale
|
||||
model->setSnapModelToCenter(false); // hack to force resnap
|
||||
model->setSnapModelToCenter(true);
|
||||
|
@ -889,7 +889,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const
|
|||
}
|
||||
|
||||
void Avatar::setSkeletonOffset(const glm::vec3& offset) {
|
||||
const float MAX_OFFSET_LENGTH = getUniformScale() * 0.5f;
|
||||
const float MAX_OFFSET_LENGTH = getModelScale() * 0.5f;
|
||||
float offsetLength = glm::length(offset);
|
||||
if (offsetLength > MAX_OFFSET_LENGTH) {
|
||||
_skeletonOffset = (MAX_OFFSET_LENGTH / offsetLength) * offset;
|
||||
|
@ -990,11 +990,8 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
|
|||
switch (index) {
|
||||
case SENSOR_TO_WORLD_MATRIX_INDEX: {
|
||||
glm::mat4 sensorToWorldMatrix = getSensorToWorldMatrix();
|
||||
bool success;
|
||||
Transform avatarTransform;
|
||||
Transform::mult(avatarTransform, getParentTransform(success), getLocalTransform());
|
||||
glm::mat4 invAvatarMat = avatarTransform.getInverseMatrix();
|
||||
glm::mat4 finalMat = invAvatarMat * sensorToWorldMatrix;
|
||||
glm::mat4 avatarMatrix = getLocalTransform().getMatrix();
|
||||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||
return glmExtractRotation(finalMat);
|
||||
}
|
||||
case CONTROLLER_LEFTHAND_INDEX: {
|
||||
|
@ -1031,11 +1028,8 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
|||
switch (index) {
|
||||
case SENSOR_TO_WORLD_MATRIX_INDEX: {
|
||||
glm::mat4 sensorToWorldMatrix = getSensorToWorldMatrix();
|
||||
bool success;
|
||||
Transform avatarTransform;
|
||||
Transform::mult(avatarTransform, getParentTransform(success), getLocalTransform());
|
||||
glm::mat4 invAvatarMat = avatarTransform.getInverseMatrix();
|
||||
glm::mat4 finalMat = invAvatarMat * sensorToWorldMatrix;
|
||||
glm::mat4 avatarMatrix = getLocalTransform().getMatrix();
|
||||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||
return extractTranslation(finalMat);
|
||||
}
|
||||
case CONTROLLER_LEFTHAND_INDEX: {
|
||||
|
@ -1064,7 +1058,6 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
glm::vec3 Avatar::getAbsoluteJointScaleInObjectFrame(int index) const {
|
||||
if (index < 0) {
|
||||
index += numeric_limits<unsigned short>::max() + 1; // 65536
|
||||
|
@ -1080,7 +1073,6 @@ glm::vec3 Avatar::getAbsoluteJointScaleInObjectFrame(int index) const {
|
|||
return AvatarData::getAbsoluteJointScaleInObjectFrame(index);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Avatar::invalidateJointIndicesCache() const {
|
||||
QWriteLocker writeLock(&_modelJointIndicesCacheLock);
|
||||
|
@ -1170,7 +1162,7 @@ glm::vec3 Avatar::getJointPosition(const QString& name) const {
|
|||
|
||||
void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const {
|
||||
//Scale a world space vector as if it was relative to the position
|
||||
positionToScale = getPosition() + getUniformScale() * (positionToScale - getPosition());
|
||||
positionToScale = getPosition() + getModelScale() * (positionToScale - getPosition());
|
||||
}
|
||||
|
||||
void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||
|
@ -1372,7 +1364,7 @@ void Avatar::updateDisplayNameAlpha(bool showDisplayName) {
|
|||
|
||||
// virtual
|
||||
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||
float uniformScale = getUniformScale();
|
||||
float uniformScale = getModelScale();
|
||||
shapeInfo.setCapsuleY(uniformScale * _skeletonModel->getBoundingCapsuleRadius(),
|
||||
0.5f * uniformScale * _skeletonModel->getBoundingCapsuleHeight());
|
||||
shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset());
|
||||
|
@ -1581,7 +1573,7 @@ float Avatar::getEyeHeight() const {
|
|||
// TODO: if performance becomes a concern we can cache this value rather then computing it everytime.
|
||||
// Makes assumption that the y = 0 plane in geometry is the ground plane.
|
||||
// We also make that assumption in Rig::computeAvatarBoundingCapsule()
|
||||
float avatarScale = getUniformScale();
|
||||
float avatarScale = getModelScale();
|
||||
if (_skeletonModel) {
|
||||
auto& rig = _skeletonModel->getRig();
|
||||
int headTopJoint = rig.indexOfJoint("HeadTop_End");
|
||||
|
|
|
@ -108,7 +108,6 @@ public:
|
|||
SkeletonModelPointer getSkeletonModel() { return _skeletonModel; }
|
||||
const SkeletonModelPointer getSkeletonModel() const { return _skeletonModel; }
|
||||
glm::vec3 getChestPosition() const;
|
||||
float getUniformScale() const { return getScale().y; }
|
||||
const Head* getHead() const { return static_cast<const Head*>(_headData); }
|
||||
Head* getHead() { return static_cast<Head*>(_headData); }
|
||||
|
||||
|
@ -151,9 +150,7 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE virtual glm::vec3 getAbsoluteDefaultJointTranslationInObjectFrame(int index) const;
|
||||
|
||||
#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const override;
|
||||
#endif
|
||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
|
||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
|
||||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; }
|
||||
|
@ -263,6 +260,9 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE float getEyeHeight() const;
|
||||
|
||||
float getModelScale() const { return _modelScale; }
|
||||
void setModelScale(float scale) { _modelScale = scale; }
|
||||
|
||||
public slots:
|
||||
|
||||
// FIXME - these should be migrated to use Pose data instead
|
||||
|
@ -365,6 +365,7 @@ private:
|
|||
bool _isAnimatingScale { false };
|
||||
bool _mustFadeIn { false };
|
||||
bool _isFading { false };
|
||||
float _modelScale { 1.0f };
|
||||
|
||||
static int _jointConesID;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
void SkeletonModel::updateAttitude(const glm::quat& orientation) {
|
||||
setTranslation(_owningAvatar->getSkeletonPosition());
|
||||
setRotation(orientation * Quaternions::Y_180);
|
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale());
|
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getModelScale());
|
||||
}
|
||||
|
||||
// Called by Avatar::simulate after it has set the joint states (fullUpdate true if changed),
|
||||
|
@ -294,7 +294,7 @@ bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& seco
|
|||
}
|
||||
|
||||
glm::vec3 SkeletonModel::getDefaultEyeModelPosition() const {
|
||||
return _owningAvatar->getScale() * _defaultEyeModelPosition;
|
||||
return _owningAvatar->getModelScale() * _defaultEyeModelPosition;
|
||||
}
|
||||
|
||||
float DENSITY_OF_WATER = 1000.0f; // kg/m^3
|
||||
|
@ -316,7 +316,7 @@ void SkeletonModel::computeBoundingShape() {
|
|||
float radius, height;
|
||||
glm::vec3 offset;
|
||||
_rig.computeAvatarBoundingCapsule(geometry, radius, height, offset);
|
||||
float invScale = 1.0f / _owningAvatar->getUniformScale();
|
||||
float invScale = 1.0f / _owningAvatar->getModelScale();
|
||||
_boundingCapsuleRadius = invScale * radius;
|
||||
_boundingCapsuleHeight = invScale * height;
|
||||
_boundingCapsuleLocalOffset = invScale * offset;
|
||||
|
|
|
@ -42,7 +42,8 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
|||
setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY);
|
||||
setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
|
||||
// explicitly set transform parts to set dirty flags used by batch rendering
|
||||
setScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||
locationChanged();
|
||||
dimensionsChanged();
|
||||
quint64 now = usecTimestampNow();
|
||||
_lastSimulated = now;
|
||||
_lastUpdated = now;
|
||||
|
@ -1382,7 +1383,11 @@ void EntityItem::setDimensions(const glm::vec3& value) {
|
|||
if (value.x <= 0.0f || value.y <= 0.0f || value.z <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
setScale(value);
|
||||
if (_dimensions != value) {
|
||||
_dimensions = value;
|
||||
locationChanged();
|
||||
dimensionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// The maximum bounding cube for the entity, independent of it's rotation.
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
void setDescription(const QString& value);
|
||||
|
||||
/// Dimensions in meters (0.0 - TREE_SCALE)
|
||||
inline const glm::vec3 getDimensions() const { return getScale(); }
|
||||
inline const glm::vec3 getDimensions() const { return _dimensions; }
|
||||
virtual void setDimensions(const glm::vec3& value);
|
||||
|
||||
float getLocalRenderAlpha() const;
|
||||
|
@ -470,6 +470,7 @@ protected:
|
|||
|
||||
virtual void dimensionsChanged() override;
|
||||
|
||||
glm::vec3 _dimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS };
|
||||
EntityTypes::EntityType _type { EntityTypes::Unknown };
|
||||
quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity,
|
||||
// and physics changes
|
||||
|
|
|
@ -176,7 +176,7 @@ void PolyLineEntityItem::calculateScaleAndRegistrationPoint() {
|
|||
}
|
||||
|
||||
// if Polyline has only one or fewer points, use default dimension settings
|
||||
SpatiallyNestable::setScale(newScale);
|
||||
setDimensions(newScale);
|
||||
EntityItem::setRegistrationPoint(newRegistrationPoint);
|
||||
}
|
||||
|
||||
|
|
|
@ -91,8 +91,6 @@ class PolyLineEntityItem : public EntityItem {
|
|||
|
||||
// disable these external interfaces as PolyLineEntities caculate their own dimensions based on the points they contain
|
||||
virtual void setRegistrationPoint(const glm::vec3& value) override {};
|
||||
virtual void setScale(const glm::vec3& scale) override {};
|
||||
virtual void setScale(float value) override {};
|
||||
|
||||
virtual void debugDump() const override;
|
||||
static const float DEFAULT_LINE_WIDTH;
|
||||
|
|
|
@ -84,12 +84,7 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const
|
|||
return result;
|
||||
}
|
||||
if (parent) {
|
||||
#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
result = parent->getTransform(_parentJointIndex, success, depth + 1);
|
||||
#else
|
||||
Transform parentTransform = parent->getTransform(_parentJointIndex, success, depth + 1);
|
||||
result = parentTransform.setScale(1.0f); // TODO: scaling
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -161,7 +156,6 @@ void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) {
|
|||
glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
||||
const QUuid& parentID, int parentJointIndex,
|
||||
bool& success) {
|
||||
Transform result;
|
||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||
if (!parentFinder) {
|
||||
success = false;
|
||||
|
@ -185,25 +179,17 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
|||
if (!success) {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
parentTransform.setScale(1.0f); // TODO: scale
|
||||
#endif
|
||||
}
|
||||
success = true;
|
||||
|
||||
Transform positionTransform;
|
||||
positionTransform.setTranslation(position);
|
||||
Transform myWorldTransform;
|
||||
Transform::mult(myWorldTransform, parentTransform, positionTransform);
|
||||
myWorldTransform.setTranslation(position);
|
||||
Transform::inverseMult(result, parentTransform, myWorldTransform);
|
||||
return result.getTranslation();
|
||||
Transform invParentTransform;
|
||||
parentTransform.evalInverse(invParentTransform);
|
||||
return invParentTransform.transform(position);
|
||||
}
|
||||
|
||||
glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
||||
const QUuid& parentID, int parentJointIndex,
|
||||
bool& success) {
|
||||
Transform result;
|
||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||
if (!parentFinder) {
|
||||
success = false;
|
||||
|
@ -227,19 +213,11 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
|||
if (!success) {
|
||||
return glm::quat();
|
||||
}
|
||||
#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
parentTransform.setScale(1.0f); // TODO: scale
|
||||
#endif
|
||||
}
|
||||
success = true;
|
||||
|
||||
Transform orientationTransform;
|
||||
orientationTransform.setRotation(orientation);
|
||||
Transform myWorldTransform;
|
||||
Transform::mult(myWorldTransform, parentTransform, orientationTransform);
|
||||
myWorldTransform.setRotation(orientation);
|
||||
Transform::inverseMult(result, parentTransform, myWorldTransform);
|
||||
return result.getRotation();
|
||||
glm::quat invParentOrientation = glm::inverse(parentTransform.getRotation());
|
||||
return invParentOrientation * orientation;
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
||||
|
@ -301,9 +279,6 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
|
|||
if (!success) {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
parentTransform.setScale(1.0f); // TODO: scale
|
||||
#endif
|
||||
}
|
||||
success = true;
|
||||
|
||||
|
@ -645,9 +620,6 @@ const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, i
|
|||
}
|
||||
|
||||
Transform worldTransform = getTransform(success, depth);
|
||||
#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
worldTransform.setScale(1.0f); // TODO: scale
|
||||
#endif
|
||||
if (!success) {
|
||||
return jointInWorldFrame;
|
||||
}
|
||||
|
@ -686,61 +658,51 @@ bool SpatiallyNestable::setTransform(const Transform& transform) {
|
|||
return success;
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getScale() const {
|
||||
// TODO: scale
|
||||
glm::vec3 result;
|
||||
_transformLock.withReadLock([&] {
|
||||
result = _transform.getScale();
|
||||
});
|
||||
glm::vec3 SpatiallyNestable::getSNScale() const {
|
||||
bool success;
|
||||
auto result = getSNScale(success);
|
||||
#ifdef WANT_DEBUG
|
||||
if (!success) {
|
||||
qCDebug(shared) << "Warning -- getScale failed" << getID();
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getScale(int jointIndex) const {
|
||||
// TODO: scale
|
||||
return getScale();
|
||||
glm::vec3 SpatiallyNestable::getSNScale(bool& success) const {
|
||||
return getTransform(success).getScale();
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setScale(const glm::vec3& scale) {
|
||||
glm::vec3 SpatiallyNestable::getSNScale(int jointIndex, bool& success) const {
|
||||
return getTransform(jointIndex, success).getScale();
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setSNScale(const glm::vec3& scale) {
|
||||
bool success;
|
||||
setSNScale(scale, success);
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setSNScale(const glm::vec3& scale, bool& success) {
|
||||
// guard against introducing NaN into the transform
|
||||
if (isNaN(scale)) {
|
||||
qCDebug(shared) << "SpatiallyNestable::setScale -- scale contains NaN";
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
// TODO: scale
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
Transform myWorldTransform;
|
||||
_transformLock.withWriteLock([&] {
|
||||
if (_transform.getScale() != scale) {
|
||||
_transform.setScale(scale);
|
||||
Transform::mult(myWorldTransform, parentTransform, _transform);
|
||||
if (myWorldTransform.getScale() != scale) {
|
||||
changed = true;
|
||||
myWorldTransform.setScale(scale);
|
||||
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
||||
_scaleChanged = usecTimestampNow();
|
||||
}
|
||||
});
|
||||
if (changed) {
|
||||
dimensionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setScale(float value) {
|
||||
// guard against introducing NaN into the transform
|
||||
if (value <= 0.0f) {
|
||||
qCDebug(shared) << "SpatiallyNestable::setScale -- scale is zero or negative value";
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
// TODO: scale
|
||||
_transformLock.withWriteLock([&] {
|
||||
glm::vec3 beforeScale = _transform.getScale();
|
||||
_transform.setScale(value);
|
||||
if (_transform.getScale() != beforeScale) {
|
||||
changed = true;
|
||||
_scaleChanged = usecTimestampNow();
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
dimensionsChanged();
|
||||
if (success && changed) {
|
||||
locationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,8 +819,7 @@ void SpatiallyNestable::setLocalAngularVelocity(const glm::vec3& angularVelocity
|
|||
});
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getLocalScale() const {
|
||||
// TODO: scale
|
||||
glm::vec3 SpatiallyNestable::getLocalSNScale() const {
|
||||
glm::vec3 result;
|
||||
_transformLock.withReadLock([&] {
|
||||
result = _transform.getScale();
|
||||
|
@ -866,7 +827,7 @@ glm::vec3 SpatiallyNestable::getLocalScale() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
|
||||
void SpatiallyNestable::setLocalSNScale(const glm::vec3& scale) {
|
||||
// guard against introducing NaN into the transform
|
||||
if (isNaN(scale)) {
|
||||
qCDebug(shared) << "SpatiallyNestable::setLocalScale -- scale contains NaN";
|
||||
|
@ -874,7 +835,6 @@ void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
|
|||
}
|
||||
|
||||
bool changed = false;
|
||||
// TODO: scale
|
||||
_transformLock.withWriteLock([&] {
|
||||
if (_transform.getScale() != scale) {
|
||||
_transform.setScale(scale);
|
||||
|
@ -918,10 +878,8 @@ const Transform SpatiallyNestable::getAbsoluteJointTransformInObjectFrame(int jo
|
|||
Transform jointTransformInObjectFrame;
|
||||
glm::vec3 position = getAbsoluteJointTranslationInObjectFrame(jointIndex);
|
||||
glm::quat orientation = getAbsoluteJointRotationInObjectFrame(jointIndex);
|
||||
#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
glm::vec3 scale = getAbsoluteJointScaleInObjectFrame(jointIndex);
|
||||
jointTransformInObjectFrame.setScale(scale);
|
||||
#endif
|
||||
jointTransformInObjectFrame.setRotation(orientation);
|
||||
jointTransformInObjectFrame.setTranslation(position);
|
||||
return jointTransformInObjectFrame;
|
||||
|
@ -1214,3 +1172,13 @@ QString SpatiallyNestable::nestableTypeToString(NestableType nestableType) {
|
|||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void SpatiallyNestable::dump(const QString& prefix) const {
|
||||
qDebug().noquote() << prefix << "id = " << getID();
|
||||
qDebug().noquote() << prefix << "transform = " << _transform;
|
||||
bool success;
|
||||
SpatiallyNestablePointer parent = getParentPointer(success);
|
||||
if (success && parent) {
|
||||
parent->dump(prefix + " ");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,14 +111,15 @@ public:
|
|||
virtual AACube getQueryAACube(bool& success) const;
|
||||
virtual AACube getQueryAACube() const;
|
||||
|
||||
virtual glm::vec3 getScale() const;
|
||||
virtual void setScale(const glm::vec3& scale);
|
||||
virtual void setScale(float value);
|
||||
virtual glm::vec3 getSNScale() const;
|
||||
virtual glm::vec3 getSNScale(bool& success) const;
|
||||
virtual void setSNScale(const glm::vec3& scale);
|
||||
virtual void setSNScale(const glm::vec3& scale, bool& success);
|
||||
|
||||
// get world-frame values for a specific joint
|
||||
virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const;
|
||||
virtual glm::vec3 getPosition(int jointIndex, bool& success) const;
|
||||
virtual glm::vec3 getScale(int jointIndex) const;
|
||||
virtual glm::vec3 getSNScale(int jointIndex, bool& success) const;
|
||||
|
||||
// object's parent's frame
|
||||
virtual const Transform getLocalTransform() const;
|
||||
|
@ -136,8 +137,8 @@ public:
|
|||
virtual glm::vec3 getLocalAngularVelocity() const;
|
||||
virtual void setLocalAngularVelocity(const glm::vec3& angularVelocity);
|
||||
|
||||
virtual glm::vec3 getLocalScale() const;
|
||||
virtual void setLocalScale(const glm::vec3& scale);
|
||||
virtual glm::vec3 getLocalSNScale() const;
|
||||
virtual void setLocalSNScale(const glm::vec3& scale);
|
||||
|
||||
QList<SpatiallyNestablePointer> getChildren() const;
|
||||
bool hasChildren() const;
|
||||
|
@ -146,9 +147,7 @@ public:
|
|||
|
||||
// this object's frame
|
||||
virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
|
||||
#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT
|
||||
virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const { return glm::vec3(1.0f); }
|
||||
#endif
|
||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { return glm::quat(); }
|
||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { return glm::vec3(); }
|
||||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { return false; }
|
||||
|
@ -193,6 +192,8 @@ public:
|
|||
bool tranlationChangedSince(quint64 time) const { return _translationChanged > time; }
|
||||
bool rotationChangedSince(quint64 time) const { return _rotationChanged > time; }
|
||||
|
||||
void dump(const QString& prefix = "") const;
|
||||
|
||||
protected:
|
||||
const NestableType _nestableType; // EntityItem or an AvatarData
|
||||
QUuid _id;
|
||||
|
|
|
@ -150,3 +150,10 @@ QJsonObject Transform::toJson(const Transform& transform) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QDebug& operator<<(QDebug& debug, const Transform& transform) {
|
||||
debug << "Transform, trans = (" << transform._translation.x << transform._translation.y << transform._translation.z << "), rot = ("
|
||||
<< transform._rotation.x << transform._rotation.y << transform._rotation.z << transform._rotation.w << "), scale = ("
|
||||
<< transform._scale.x << transform._scale.y << transform._scale.z << ")";
|
||||
return debug;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ inline bool isValidScale(float scale) {
|
|||
|
||||
class Transform {
|
||||
public:
|
||||
friend QDebug& operator<<(QDebug& debug, const Transform& transform);
|
||||
using Pointer = std::shared_ptr<Transform>;
|
||||
typedef glm::mat4 Mat4;
|
||||
typedef glm::mat3 Mat3;
|
||||
|
@ -170,7 +171,6 @@ protected:
|
|||
};
|
||||
typedef std::bitset<NUM_FLAGS> Flags;
|
||||
|
||||
|
||||
// TRS
|
||||
Quat _rotation;
|
||||
Vec3 _scale;
|
||||
|
@ -202,6 +202,8 @@ protected:
|
|||
Mat4& getCachedMatrix(Mat4& result) const;
|
||||
};
|
||||
|
||||
QDebug& operator<<(QDebug& debug, const Transform& transform);
|
||||
|
||||
inline Transform& Transform::setIdentity() {
|
||||
_translation = Vec3(0.0f);
|
||||
_rotation = Quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
|
Loading…
Reference in a new issue