mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 02:13:28 +02:00
Improve and optimize panel transformations.
This commit is contained in:
parent
e5b8701215
commit
1d37df4775
4 changed files with 57 additions and 95 deletions
|
@ -39,13 +39,21 @@ BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) :
|
|||
{
|
||||
}
|
||||
|
||||
void BillboardOverlay::update(float deltatime) {
|
||||
if (getVisible()) {
|
||||
glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition());
|
||||
if (newPos != glm::vec3()) {
|
||||
setPosition(newPos);
|
||||
bool BillboardOverlay::setTransforms(Transform *transform) {
|
||||
PanelAttachable::setTransforms(transform);
|
||||
if (_isFacingAvatar) {
|
||||
glm::quat rotation = Application::getInstance()->getCamera()->getOrientation();
|
||||
rotation *= glm::angleAxis(glm::pi<float>(), IDENTITY_UP);
|
||||
setRotation(rotation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// }
|
||||
// return true;
|
||||
}
|
||||
|
||||
void BillboardOverlay::update(float deltatime) {
|
||||
setTransforms(&_transform);
|
||||
}
|
||||
|
||||
void BillboardOverlay::render(RenderArgs* args) {
|
||||
|
@ -58,12 +66,8 @@ void BillboardOverlay::render(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition());
|
||||
if (newPos != glm::vec3()) {
|
||||
setPosition(newPos);
|
||||
}
|
||||
|
||||
glm::quat rotation = calculateRotation(args->_viewFrustum->getOrientation());
|
||||
Q_ASSERT(args->_batch);
|
||||
auto batch = args->_batch;
|
||||
|
||||
float imageWidth = _texture->getWidth();
|
||||
float imageHeight = _texture->getHeight();
|
||||
|
@ -98,24 +102,20 @@ void BillboardOverlay::render(RenderArgs* args) {
|
|||
xColor color = getColor();
|
||||
float alpha = getAlpha();
|
||||
|
||||
auto batch = args->_batch;
|
||||
setTransforms(&_transform);
|
||||
Transform transform = _transform;
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
|
||||
if (batch) {
|
||||
Transform transform = _transform;
|
||||
transform.setRotation(rotation);
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
|
||||
batch->setModelTransform(transform);
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(*batch, true, true, true);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
|
||||
);
|
||||
batch->setModelTransform(transform);
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
||||
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me
|
||||
}
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(*batch, true, true, false);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
|
||||
);
|
||||
|
||||
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me
|
||||
}
|
||||
|
||||
void BillboardOverlay::setProperties(const QScriptValue &properties) {
|
||||
|
@ -207,40 +207,12 @@ void BillboardOverlay::setBillboardURL(const QString& url) {
|
|||
_isLoaded = false;
|
||||
}
|
||||
|
||||
glm::quat BillboardOverlay::calculateRotation(glm::quat cameraOrientation) const {
|
||||
if (_isFacingAvatar) {
|
||||
// LOL, quaternions are hard.
|
||||
// glm::vec3 dPos = getPosition() - args->_viewFrustum->getPosition();
|
||||
// dPos = glm::normalize(dPos);
|
||||
// rotation = glm::quat(0, dPos.x, dPos.y, dPos.z);
|
||||
// float horizontal = glm::sqrt(dPos.x * dPos.x + dPos.y + dPos.y);
|
||||
// glm::vec3 zAxis = glm::vec3(0, 0, 1);
|
||||
// rotation = rotationBetween(zAxis, dPos);
|
||||
// glm::vec3 euler = safeEulerAngles(rotationBetween(zAxis, dPos));
|
||||
// rotation = glm::quat(glm::vec3(euler.x, euler.y, 0));
|
||||
// float yaw = (dPos.x == 0.0f && dPos.z == 0.0f) ? 0.0f : glm::atan(dPos.x, dPos.z);
|
||||
// glm::quat yawQuat = glm::quat(glm::vec3(0, yaw, 0));
|
||||
// float pitch = (dPos.y == 0.0f && horizontal == 0.0f) ? 0.0f : glm::atan(dPos.y, horizontal);
|
||||
// glm::quat pitchQuat = glm::quat(glm::vec3(pitch, 0, 0));
|
||||
// glm::mat4x4 matrix = glm::lookAt(args->_viewFrustum->getPosition(), getPosition(),
|
||||
// glm::vec3(0, 1, 0));
|
||||
// rotation = glm::quat_cast(matrix);
|
||||
// rotation = yawQuat * pitchQuat;
|
||||
// glm::vec3 pitch = glm::vec3(dPos.x, dPos.y, 0);
|
||||
// rotation = glm::quat(glm::vec3(pitch, yaw, 0));
|
||||
// rotate about vertical to be perpendicular to the camera
|
||||
glm::quat rotation = cameraOrientation;
|
||||
rotation *= glm::angleAxis(glm::pi<float>(), IDENTITY_UP);
|
||||
return rotation * getRotation();
|
||||
}
|
||||
return getTranslatedRotation(getRotation());
|
||||
}
|
||||
|
||||
bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
float& distance, BoxFace& face) {
|
||||
float& distance, BoxFace& face) {
|
||||
if (_texture && _texture->isLoaded()) {
|
||||
glm::quat rotation =
|
||||
calculateRotation(Application::getInstance()->getCamera()->getRotation());
|
||||
// Make sure position and rotation is updated.
|
||||
setTransforms(&_transform);
|
||||
|
||||
// Produce the dimensions of the billboard based on the image's aspect ratio and the overlay's scale.
|
||||
bool isNull = _fromImage.isNull();
|
||||
float width = isNull ? _texture->getWidth() : _fromImage.width();
|
||||
|
@ -248,7 +220,7 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v
|
|||
float maxSize = glm::max(width, height);
|
||||
glm::vec2 dimensions = _dimensions * glm::vec2(width / maxSize, height / maxSize);
|
||||
|
||||
return findRayRectangleIntersection(origin, direction, rotation, getPosition(), dimensions, distance);
|
||||
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), dimensions, distance);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -39,10 +39,13 @@ public:
|
|||
|
||||
virtual BillboardOverlay* createClone() const;
|
||||
|
||||
protected:
|
||||
bool setTransforms(Transform* transform);
|
||||
|
||||
private:
|
||||
void setBillboardURL(const QString& url);
|
||||
glm::quat calculateRotation(glm::quat cameraOrientation) const;
|
||||
|
||||
// glm::quat calculateRotation(glm::quat cameraOrientation) const;
|
||||
|
||||
QString _url;
|
||||
NetworkTexturePointer _texture;
|
||||
|
||||
|
|
|
@ -20,31 +20,14 @@ PanelAttachable::PanelAttachable(const PanelAttachable* panelAttachable) :
|
|||
{
|
||||
}
|
||||
|
||||
glm::vec3 PanelAttachable::getTranslatedPosition(glm::vec3 avatarPosition) const {
|
||||
bool PanelAttachable::setTransforms(Transform* transform) {
|
||||
Q_ASSERT(transform != nullptr);
|
||||
if (getAttachedPanel()) {
|
||||
glm::vec3 totalOffsetPosition =
|
||||
getAttachedPanel()->getFacingRotation() * getOffsetPosition() +
|
||||
getAttachedPanel()->getOffsetPosition();
|
||||
|
||||
return getAttachedPanel()->getOffsetRotation() * totalOffsetPosition +
|
||||
avatarPosition;
|
||||
transform->setTranslation(getAttachedPanel()->getAnchorPosition());
|
||||
transform->setRotation(getAttachedPanel()->getOffsetRotation());
|
||||
transform->postTranslate(getOffsetPosition() + getAttachedPanel()->getOffsetPosition());
|
||||
transform->postRotate(getFacingRotation() * getAttachedPanel()->getFacingRotation());
|
||||
return true;
|
||||
}
|
||||
return glm::vec3();
|
||||
}
|
||||
|
||||
glm::quat PanelAttachable::getTranslatedRotation(glm::quat offsetRotation) const {
|
||||
glm::quat rotation = offsetRotation;
|
||||
if (getAttachedPanel()) {
|
||||
rotation *= getAttachedPanel()->getOffsetRotation() *
|
||||
getAttachedPanel()->getFacingRotation();
|
||||
// if (getAttachedPanel()->getFacingRotation() != glm::quat(0, 0, 0, 0)) {
|
||||
// rotation *= getAttachedPanel()->getFacingRotation();
|
||||
// } else if (getAttachedPanel()->getOffsetRotation() != glm::quat(0, 0, 0, 0)) {
|
||||
// rotation *= getAttachedPanel()->getOffsetRotation();
|
||||
// } else {
|
||||
// rotation *= Application::getInstance()->getCamera()->getOrientation() *
|
||||
// glm::quat(0, 0, 1, 0);
|
||||
// }
|
||||
}
|
||||
return rotation;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,24 +15,28 @@
|
|||
#include "FloatingUIPanel.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <Transform.h>
|
||||
|
||||
class PanelAttachable {
|
||||
public:
|
||||
PanelAttachable();
|
||||
PanelAttachable(const PanelAttachable* panelAttachable);
|
||||
|
||||
glm::vec3 getOffsetPosition() const { return _offsetPosition; }
|
||||
void setOffsetPosition(glm::vec3 position) { _offsetPosition = position; }
|
||||
|
||||
FloatingUIPanel* getAttachedPanel() const { return _attachedPanel; }
|
||||
void setAttachedPanel(FloatingUIPanel* panel) { _attachedPanel = panel; }
|
||||
glm::vec3 getOffsetPosition() const { return _offsetPosition; }
|
||||
glm::quat getFacingRotation() const { return _facingRotation; }
|
||||
|
||||
glm::vec3 getTranslatedPosition(glm::vec3 avatarPosition) const;
|
||||
glm::quat getTranslatedRotation(glm::quat offsetRotation) const;
|
||||
void setAttachedPanel(FloatingUIPanel* panel) { _attachedPanel = panel; }
|
||||
void setOffsetPosition(glm::vec3 position) { _offsetPosition = position; }
|
||||
void setFacingRotation(glm::quat rotation) { _facingRotation = rotation; }
|
||||
|
||||
protected:
|
||||
bool setTransforms(Transform* transform);
|
||||
|
||||
private:
|
||||
FloatingUIPanel* _attachedPanel;
|
||||
glm::vec3 _offsetPosition = glm::vec3(0, 0, 0);
|
||||
glm::vec3 _offsetPosition;
|
||||
glm::quat _facingRotation;
|
||||
};
|
||||
|
||||
#endif // hifi_PanelAttachable_h
|
||||
|
|
Loading…
Reference in a new issue