1/*
2 * Copyright (c) 2014, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30#ifndef FloatBox_h
31#define FloatBox_h
32
33#include "platform/geometry/FloatPoint3D.h"
34#include <cmath>
35
36namespace blink {
37
38class FloatBox {
39public:
40    FloatBox()
41        : m_x(0)
42        , m_y(0)
43        , m_z(0)
44        , m_width(0)
45        , m_height(0)
46        , m_depth(0)
47    {
48    }
49
50    FloatBox(float x, float y, float z, float width, float height, float depth)
51        : m_x(x)
52        , m_y(y)
53        , m_z(z)
54        , m_width(width)
55        , m_height(height)
56        , m_depth(depth)
57    {
58    }
59
60    FloatBox(const FloatBox& box)
61        : m_x(box.x())
62        , m_y(box.y())
63        , m_z(box.z())
64        , m_width(box.width())
65        , m_height(box.height())
66        , m_depth(box.depth())
67    {
68    }
69
70    void setOrigin(const FloatPoint3D& origin)
71    {
72        m_x = origin.x();
73        m_y = origin.y();
74        m_z = origin.z();
75    }
76
77    void setSize(const FloatPoint3D& origin)
78    {
79        ASSERT(origin.x() >= 0);
80        ASSERT(origin.y() >= 0);
81        ASSERT(origin.z() >= 0);
82
83        m_width = origin.x();
84        m_height = origin.y();
85        m_depth = origin.z();
86    }
87
88    void move(const FloatPoint3D& location)
89    {
90        m_x += location.x();
91        m_y += location.y();
92        m_z += location.z();
93    }
94
95    void flatten()
96    {
97        m_z = 0;
98        m_depth = 0;
99    }
100
101    void expandTo(const FloatPoint3D& low, const FloatPoint3D& high)
102    {
103        ASSERT(low.x() <= high.x());
104        ASSERT(low.y() <= high.y());
105        ASSERT(low.z() <= high.z());
106
107        float minX = std::min(m_x, low.x());
108        float minY = std::min(m_y, low.y());
109        float minZ = std::min(m_z, low.z());
110
111        float maxX = std::max(right(), high.x());
112        float maxY = std::max(bottom(), high.y());
113        float maxZ = std::max(front(), high.z());
114
115        m_x = minX;
116        m_y = minY;
117        m_z = minZ;
118
119        m_width = maxX - minX;
120        m_height = maxY - minY;
121        m_depth = maxZ - minZ;
122    }
123
124    void expandTo(const FloatPoint3D& point)
125    {
126        expandTo(point, point);
127    }
128
129    void expandTo(const FloatBox& box)
130    {
131        expandTo(FloatPoint3D(box.x(), box.y(), box.z()), FloatPoint3D(box.right(), box.bottom(), box.front()));
132    }
133
134    void unionBounds(const FloatBox& box)
135    {
136        if (box.isEmpty())
137            return;
138
139        if (isEmpty()) {
140            *this = box;
141            return;
142        }
143
144        expandTo(box);
145    }
146
147    bool isEmpty() const { return (m_width <= 0 && m_height <= 0) || (m_width <= 0 && m_depth <= 0) || (m_height <= 0 && m_depth <= 0); }
148
149    float right() const { return m_x + m_width; }
150    float bottom() const { return m_y + m_height; }
151    float front() const { return m_z + m_depth; }
152    float x() const { return m_x; }
153    float y() const { return m_y; }
154    float z() const { return m_z; }
155    float width() const { return m_width; }
156    float height() const { return m_height; }
157    float depth() const { return m_depth; }
158private:
159    float m_x;
160    float m_y;
161    float m_z;
162    float m_width;
163    float m_height;
164    float m_depth;
165};
166
167inline bool operator==(const FloatBox& a, const FloatBox& b)
168{
169    return a.x() == b.x() && a.y() == b.y() && a.z() == b.z() && a.width() == b.width()
170        && a.height() == b.height() && a.depth() == b.depth();
171}
172
173inline bool operator!=(const FloatBox& a, const FloatBox& b)
174{
175    return !(a == b);
176}
177
178} // namespace blink
179
180#endif
181