Skip to content

Commit

Permalink
Avoid duplicate math when computing VR scene hierarchy.
Browse files Browse the repository at this point in the history
When computing the transformations of UI elements in the scene, re-use
the calculations done by parents when computing child element
transforms.

BUG=680253

Review-Url: https://codereview.chromium.org/2777633003
Cr-Commit-Position: refs/heads/master@{#459807}
  • Loading branch information
cjgrant authored and Commit bot committed Mar 27, 2017
1 parent 6ff8b95 commit 5513e50
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 39 deletions.
4 changes: 0 additions & 4 deletions chrome/browser/android/vr_shell/ui_elements.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ const gvr::Mat4f& WorldRectangle::TransformMatrix() const {
return transform_.to_world;
}

void WorldRectangle::SetTransform(const Transform& transform) {
transform_ = transform;
}

gvr::Vec3f WorldRectangle::GetCenter() const {
const gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f};
return MatrixVectorMul(transform_.to_world, kOrigin);
Expand Down
8 changes: 7 additions & 1 deletion chrome/browser/android/vr_shell/ui_elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct Transform {
class WorldRectangle {
public:
const gvr::Mat4f& TransformMatrix() const;
void SetTransform(const Transform& transform);
Transform* mutable_transform() { return &transform_; }

gvr::Vec3f GetCenter() const;
gvr::Vec3f GetNormal() const;
Expand Down Expand Up @@ -154,6 +154,12 @@ struct ContentRectangle : public WorldRectangle {

int draw_phase = 1;

// This transform can be used by children to derive position of its parent.
Transform inheritable_transform;

// A flag usable during transformation calculates to avoid duplicate work.
bool dirty;

private:
DISALLOW_COPY_AND_ASSIGN(ContentRectangle);
};
Expand Down
67 changes: 39 additions & 28 deletions chrome/browser/android/vr_shell/ui_scene.cc
Original file line number Diff line number Diff line change
Expand Up @@ -328,20 +328,13 @@ void UiScene::HandleCommands(std::unique_ptr<base::ListValue> commands,
}

void UiScene::UpdateTransforms(int64_t time_in_micro) {
// Process all animations before calculating object transforms.
for (auto& element : ui_elements_) {
// Process all animations before calculating object transforms.
element->Animate(time_in_micro);
element->dirty = true;
}
for (auto& element : ui_elements_) {
Transform transform;
transform.MakeIdentity();
transform.Scale(element->size.x, element->size.y, element->size.z);
element->computed_opacity = 1.0f;
element->computed_lock_to_fov = false;
ApplyRecursiveTransforms(*element.get(), &transform,
&element->computed_opacity,
&element->computed_lock_to_fov);
element->SetTransform(transform);
ApplyRecursiveTransforms(element.get());
}
}

Expand Down Expand Up @@ -399,26 +392,44 @@ UiScene::UiScene() = default;

UiScene::~UiScene() = default;

void UiScene::ApplyRecursiveTransforms(const ContentRectangle& element,
Transform* transform,
float* opacity,
bool* lock_to_fov) {
transform->Scale(element.scale.x, element.scale.y, element.scale.z);
transform->Rotate(element.rotation.x, element.rotation.y, element.rotation.z,
element.rotation.angle);
transform->Translate(element.translation.x, element.translation.y,
element.translation.z);
*opacity *= element.opacity;
// Head-locked state inherited from a parent element.
*lock_to_fov = element.lock_to_fov;

if (element.parent_id >= 0) {
const ContentRectangle* parent = GetUiElementById(element.parent_id);
void UiScene::ApplyRecursiveTransforms(ContentRectangle* element) {
if (!element->dirty)
return;

ContentRectangle* parent = nullptr;
if (element->parent_id >= 0) {
parent = GetUiElementById(element->parent_id);
CHECK(parent != nullptr);
ApplyAnchoring(*parent, element.x_anchoring, element.y_anchoring,
transform);
ApplyRecursiveTransforms(*parent, transform, opacity, lock_to_fov);
}

Transform* transform = element->mutable_transform();
transform->MakeIdentity();
transform->Scale(element->size.x, element->size.y, element->size.z);
element->computed_opacity = element->opacity;
element->computed_lock_to_fov = element->lock_to_fov;

// Compute an inheritable transformation that can be applied to this element,
// and it's children, if applicable.
Transform* inheritable = &element->inheritable_transform;
inheritable->MakeIdentity();
inheritable->Scale(element->scale.x, element->scale.y, element->scale.z);
inheritable->Rotate(element->rotation.x, element->rotation.y,
element->rotation.z, element->rotation.angle);
inheritable->Translate(element->translation.x, element->translation.y,
element->translation.z);
if (parent) {
ApplyAnchoring(*parent, element->x_anchoring, element->y_anchoring,
inheritable);
ApplyRecursiveTransforms(parent);
inheritable->to_world = MatrixMul(parent->inheritable_transform.to_world,
inheritable->to_world);

element->computed_opacity *= parent->opacity;
element->computed_lock_to_fov = parent->lock_to_fov;
}

transform->to_world = MatrixMul(inheritable->to_world, transform->to_world);
element->dirty = false;
}

void UiScene::ApplyDictToElement(const base::DictionaryValue& dict,
Expand Down
6 changes: 1 addition & 5 deletions chrome/browser/android/vr_shell/ui_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ namespace vr_shell {

class Animation;
struct ContentRectangle;
struct Transform;

class UiScene {
public:
Expand Down Expand Up @@ -78,10 +77,7 @@ class UiScene {
bool GetWebVrRenderingEnabled() const;

private:
void ApplyRecursiveTransforms(const ContentRectangle& element,
Transform* transform,
float* opacity,
bool* lock_to_fov);
void ApplyRecursiveTransforms(ContentRectangle* element);
void ApplyDictToElement(const base::DictionaryValue& dict,
ContentRectangle* element);

Expand Down
1 change: 0 additions & 1 deletion chrome/browser/android/vr_shell/ui_scene_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ TEST(UiScene, ParentTransformAppliesToChild) {
const gvr::Vec3f origin({0, 0, 0});
const gvr::Vec3f point({1, 0, 0});

// Check resulting transform with no screen tilt.
scene.UpdateTransforms(0);
auto new_origin = MatrixVectorMul(child->TransformMatrix(), origin);
auto new_point = MatrixVectorMul(child->TransformMatrix(), point);
Expand Down

0 comments on commit 5513e50

Please sign in to comment.