Improve BillboardOverlay::findRayIntersection.

This commit is contained in:
Zander Otavka 2015-07-17 14:29:53 -07:00
parent 377a1a54ae
commit c4cb6fba74
4 changed files with 60 additions and 53 deletions

View file

@ -38,9 +38,11 @@ BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) :
}
void BillboardOverlay::update(float deltatime) {
glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition());
if (newPos != glm::vec3()) {
setPosition(newPos);
if (getVisible()) {
glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition());
if (newPos != glm::vec3()) {
setPosition(newPos);
}
}
}
@ -59,46 +61,7 @@ void BillboardOverlay::render(RenderArgs* args) {
setPosition(newPos);
}
glm::quat rotation;
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
rotation = args->_viewFrustum->getOrientation();
rotation *= glm::angleAxis(glm::pi<float>(), IDENTITY_UP);
rotation *= getRotation();
} else {
rotation = getRotation();
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);
// }
}
}
glm::quat rotation = calculateRotation(args->_viewFrustum->getOrientation());
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
@ -143,8 +106,10 @@ void BillboardOverlay::render(RenderArgs* args) {
batch->setModelTransform(transform);
batch->setResourceTexture(0, _texture->getGPUTexture());
DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha));
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
}
@ -239,17 +204,40 @@ 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) {
if (_texture && _texture->isLoaded()) {
glm::quat rotation = getRotation();
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = Application::getInstance()->getCamera()->getRotation();
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
}
glm::quat rotation =
calculateRotation(Application::getInstance()->getCamera()->getRotation());
// 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();

View file

@ -41,6 +41,7 @@ public:
private:
void setBillboardURL(const QString& url);
glm::quat calculateRotation(glm::quat cameraOrientation) const;
QString _url;
NetworkTexturePointer _texture;

View file

@ -31,3 +31,20 @@ glm::vec3 PanelAttachable::getTranslatedPosition(glm::vec3 avatarPosition) const
}
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;
}

View file

@ -28,6 +28,7 @@ public:
void setAttachedPanel(FloatingUIPanel* panel) { _attachedPanel = panel; }
glm::vec3 getTranslatedPosition(glm::vec3 avatarPosition) const;
glm::quat getTranslatedRotation(glm::quat offsetRotation) const;
private:
FloatingUIPanel* _attachedPanel;