1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef UI_GFX_GEOMETRY_BOX_F_H_ 6#define UI_GFX_GEOMETRY_BOX_F_H_ 7 8#include <iosfwd> 9#include <string> 10 11#include "ui/gfx/geometry/point3_f.h" 12#include "ui/gfx/geometry/vector3d_f.h" 13 14namespace gfx { 15 16// A 3d version of gfx::RectF, with the positive z-axis pointed towards 17// the camera. 18class GFX_EXPORT BoxF { 19 public: 20 BoxF() 21 : width_(0.f), 22 height_(0.f), 23 depth_(0.f) {} 24 25 BoxF(float width, float height, float depth) 26 : width_(width < 0 ? 0 : width), 27 height_(height < 0 ? 0 : height), 28 depth_(depth < 0 ? 0 : depth) {} 29 30 BoxF(float x, float y, float z, float width, float height, float depth) 31 : origin_(x, y, z), 32 width_(width < 0 ? 0 : width), 33 height_(height < 0 ? 0 : height), 34 depth_(depth < 0 ? 0 : depth) {} 35 36 BoxF(const Point3F& origin, float width, float height, float depth) 37 : origin_(origin), 38 width_(width < 0 ? 0 : width), 39 height_(height < 0 ? 0 : height), 40 depth_(depth < 0 ? 0 : depth) {} 41 42 ~BoxF() {} 43 44 // Scales all three axes by the given scale. 45 void Scale(float scale) { 46 Scale(scale, scale, scale); 47 } 48 49 // Scales each axis by the corresponding given scale. 50 void Scale(float x_scale, float y_scale, float z_scale) { 51 origin_.Scale(x_scale, y_scale, z_scale); 52 set_size(width_ * x_scale, height_ * y_scale, depth_ * z_scale); 53 } 54 55 // Moves the box by the specified distance in each dimension. 56 void operator+=(const Vector3dF& offset) { 57 origin_ += offset; 58 } 59 60 // Returns true if the box has no interior points. 61 bool IsEmpty() const; 62 63 // Computes the union of this box with the given box. The union is the 64 // smallest box that contains both boxes. 65 void Union(const BoxF& box); 66 67 std::string ToString() const; 68 69 float x() const { return origin_.x(); } 70 void set_x(float x) { origin_.set_x(x); } 71 72 float y() const { return origin_.y(); } 73 void set_y(float y) { origin_.set_y(y); } 74 75 float z() const { return origin_.z(); } 76 void set_z(float z) { origin_.set_z(z); } 77 78 float width() const { return width_; } 79 void set_width(float width) { width_ = width < 0 ? 0 : width; } 80 81 float height() const { return height_; } 82 void set_height(float height) { height_ = height < 0 ? 0 : height; } 83 84 float depth() const { return depth_; } 85 void set_depth(float depth) { depth_ = depth < 0 ? 0 : depth; } 86 87 float right() const { return x() + width(); } 88 float bottom() const { return y() + height(); } 89 float front() const { return z() + depth(); } 90 91 void set_size(float width, float height, float depth) { 92 width_ = width < 0 ? 0 : width; 93 height_ = height < 0 ? 0 : height; 94 depth_ = depth < 0 ? 0 : depth; 95 } 96 97 const Point3F& origin() const { return origin_; } 98 void set_origin(const Point3F& origin) { origin_ = origin; } 99 100 // Expands |this| to contain the given point, if necessary. Please note, even 101 // if |this| is empty, after the function |this| will continue to contain its 102 // |origin_|. 103 void ExpandTo(const Point3F& point); 104 105 // Expands |this| to contain the given box, if necessary. Please note, even 106 // if |this| is empty, after the function |this| will continue to contain its 107 // |origin_|. 108 void ExpandTo(const BoxF& box); 109 110 private: 111 // Expands the box to contain the two given points. It is required that each 112 // component of |min| is less than or equal to the corresponding component in 113 // |max|. Precisely, what this function does is ensure that after the function 114 // completes, |this| contains origin_, min, max, and origin_ + (width_, 115 // height_, depth_), even if the box is empty. Emptiness checks are handled in 116 // the public function Union. 117 void ExpandTo(const Point3F& min, const Point3F& max); 118 119 Point3F origin_; 120 float width_; 121 float height_; 122 float depth_; 123}; 124 125GFX_EXPORT BoxF UnionBoxes(const BoxF& a, const BoxF& b); 126 127inline BoxF ScaleBox(const BoxF& b, 128 float x_scale, 129 float y_scale, 130 float z_scale) { 131 return BoxF(b.x() * x_scale, 132 b.y() * y_scale, 133 b.z() * z_scale, 134 b.width() * x_scale, 135 b.height() * y_scale, 136 b.depth() * z_scale); 137} 138 139inline BoxF ScaleBox(const BoxF& b, float scale) { 140 return ScaleBox(b, scale, scale, scale); 141} 142 143inline bool operator==(const BoxF& a, const BoxF& b) { 144 return a.origin() == b.origin() && a.width() == b.width() && 145 a.height() == b.height() && a.depth() == b.depth(); 146} 147 148inline bool operator!=(const BoxF& a, const BoxF& b) { 149 return !(a == b); 150} 151 152inline BoxF operator+(const BoxF& b, const Vector3dF& v) { 153 return BoxF(b.x() + v.x(), 154 b.y() + v.y(), 155 b.z() + v.z(), 156 b.width(), 157 b.height(), 158 b.depth()); 159} 160 161// This is declared here for use in gtest-based unit tests but is defined in 162// the gfx_test_support target. Depend on that to use this in your unit test. 163// This should not be used in production code - call ToString() instead. 164void PrintTo(const BoxF& box, ::std::ostream* os); 165 166} // namespace gfx 167 168#endif // UI_GFX_GEOMETRY_BOX_F_H_ 169