• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

excessive / cpml / 6132588926

09 Sep 2023 06:38PM UTC coverage: 14.013% (-44.7%) from 58.701%
6132588926

push

github

FatalError42O
fixed Busted support (hopefully)

975 of 6958 relevant lines covered (14.01%)

10.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.47
/modules/bound3.lua
1
--- A 3-component axis-aligned bounding box.
2
-- @module bound3
3

4
local vec3    = require(modules .. "vec3")
3✔
5

6
local bound3    = {}
×
7
local bound3_mt = {}
×
8

9
-- Private constructor.
10
local function new(min, max)
11
        return setmetatable({
×
12
                min=min, -- min: vec3, minimum value for each component
13
                max=max  -- max: vec3, maximum value for each component
×
14
        }, bound3_mt)
×
15
end
16

17
-- Do the check to see if JIT is enabled. If so use the optimized FFI structs.
18
local status, ffi
19
if type(jit) == "table" and jit.status() then
×
20
        status, ffi = pcall(require, "ffi")
×
21
        if status then
×
22
                ffi.cdef "typedef struct { cpml_vec3 min, max; } cpml_bound3;"
×
23
                new = ffi.typeof("cpml_bound3")
×
24
        end
25
end
26

27
bound3.zero = new(vec3.zero, vec3.zero)
×
28

29
--- The public constructor.
30
-- @param min Can be of two types: </br>
31
-- vec3 min, minimum value for each component
32
-- nil Create bound at single point 0,0,0
33
-- @tparam vec3 max, maximum value for each component
34
-- @treturn bound3 out
35
function bound3.new(min, max)
×
36
        if min and max then
×
37
                return new(min:clone(), max:clone())
×
38
        elseif min or max then
×
39
                error("Unexpected nil argument to bound3.new")
×
40
        else
41
                return new(vec3.zero, vec3.zero)
×
42
        end
43
end
44

45
--- Clone a bound.
46
-- @tparam bound3 a bound to be cloned
47
-- @treturn bound3 out
48
function bound3.clone(a)
×
49
        return new(a.min, a.max)
×
50
end
51

52
--- Construct a bound covering one or two points
53
-- @tparam vec3 a Any vector
54
-- @tparam vec3 b Any second vector (optional)
55
-- @treturn vec3 Minimum bound containing the given points
56
function bound3.at(a, b) -- "bounded by". b may be nil
×
57
        if b then
×
58
                return bound3.new(a,b):check()
×
59
        else
60
                return bound3.zero:with_center(a)
×
61
        end
62
end
63

64
--- Extend bound to include point
65
-- @tparam bound3 a bound
66
-- @tparam vec3 point to include
67
-- @treturn bound3 Bound covering current min, current max and new point
68
function bound3.extend(a, center)
×
69
        return bound3.new(a.min:component_min(center), a.max:component_max(center))
×
70
end
71

72
--- Extend bound to entirety of other bound
73
-- @tparam bound3 a bound
74
-- @tparam bound3 bound to cover
75
-- @treturn bound3 Bound covering current min and max of each bound in the pair
76
function bound3.extend_bound(a, b)
×
77
        return a:extend(b.min):extend(b.max)
×
78
end
79

80
--- Get size of bounding box as a vector
81
-- @tparam bound3 a bound
82
-- @treturn vec3 Vector spanning min to max points
83
function bound3.size(a)
×
84
        return a.max - a.min
×
85
end
86

87
--- Resize bounding box from minimum corner
88
-- @tparam bound3 a bound
89
-- @tparam vec3 new size
90
-- @treturn bound3 resized bound
91
function bound3.with_size(a, size)
×
92
        return bound3.new(a.min, a.min + size)
×
93
end
94

95
--- Get half-size of bounding box as a vector. A more correct term for this is probably "apothem"
96
-- @tparam bound3 a bound
97
-- @treturn vec3 Vector spanning center to max point
98
function bound3.radius(a)
×
99
        return a:size()/2
×
100
end
101

102
--- Get center of bounding box
103
-- @tparam bound3 a bound
104
-- @treturn bound3 Point in center of bound
105
function bound3.center(a)
×
106
        return (a.min + a.max)/2
×
107
end
108

109
--- Move bounding box to new center
110
-- @tparam bound3 a bound
111
-- @tparam vec3 new center
112
-- @treturn bound3 Bound with same size as input but different center
113
function bound3.with_center(a, center)
×
114
        return bound3.offset(a, center - a:center())
×
115
end
116

117
--- Resize bounding box from center
118
-- @tparam bound3 a bound
119
-- @tparam vec3 new size
120
-- @treturn bound3 resized bound
121
function bound3.with_size_centered(a, size)
×
122
        local center = a:center()
×
123
        local rad = size/2
×
124
        return bound3.new(center - rad, center + rad)
×
125
end
126

127
--- Convert possibly-invalid bounding box to valid one
128
-- @tparam bound3 a bound
129
-- @treturn bound3 bound with all components corrected for min-max property
130
function bound3.check(a)
×
131
        if a.min.x > a.max.x or a.min.y > a.max.y or a.min.z > a.max.z then
×
132
                return bound3.new(vec3.component_min(a.min, a.max), vec3.component_max(a.min, a.max))
×
133
        end
134
        return a
×
135
end
136

137
--- Shrink bounding box with fixed margin
138
-- @tparam bound3 a bound
139
-- @tparam vec3 a margin
140
-- @treturn bound3 bound with margin subtracted from all edges. May not be valid, consider calling check()
141
function bound3.inset(a, v)
×
142
        return bound3.new(a.min + v, a.max - v)
×
143
end
144

145
--- Expand bounding box with fixed margin
146
-- @tparam bound3 a bound
147
-- @tparam vec3 a margin
148
-- @treturn bound3 bound with margin added to all edges. May not be valid, consider calling check()
149
function bound3.outset(a, v)
×
150
        return bound3.new(a.min - v, a.max + v)
×
151
end
152

153
--- Offset bounding box
154
-- @tparam bound3 a bound
155
-- @tparam vec3 offset
156
-- @treturn bound3 bound with same size, but position moved by offset
157
function bound3.offset(a, v)
×
158
        return bound3.new(a.min + v, a.max + v)
×
159
end
160

161
--- Test if point in bound
162
-- @tparam bound3 a bound
163
-- @tparam vec3 point to test
164
-- @treturn boolean true if point in bounding box
165
function bound3.contains(a, v)
×
166
        return a.min.x <= v.x and a.min.y <= v.y and a.min.z <= v.z
×
167
           and a.max.x >= v.x and a.max.y >= v.y and a.max.z >= v.z
×
168
end
169

170
-- Round all components of all vectors to nearest int (or other precision).
171
-- @tparam vec3 a bound to round.
172
-- @tparam precision Digits after the decimal (round number if unspecified)
173
-- @treturn vec3 Rounded bound
174
function bound3.round(a, precision)
×
175
        return bound3.new(a.min:round(precision), a.max:round(precision))
×
176
end
177

178
--- Return a formatted string.
179
-- @tparam bound3 a bound to be turned into a string
180
-- @treturn string formatted
181
function bound3.to_string(a)
×
182
        return string.format("(%s-%s)", a.min, a.max)
×
183
end
184

185
bound3_mt.__index    = bound3
×
186
bound3_mt.__tostring = bound3.to_string
×
187

188
function bound3_mt.__call(_, a, b)
×
189
        return bound3.new(a, b)
×
190
end
191

192
if status then
×
193
        xpcall(function() -- Allow this to silently fail; assume failure means someone messed with package.loaded
×
194
                ffi.metatype(new, bound3_mt)
×
195
        end, function() end)
×
196
end
197

198
return setmetatable({}, bound3_mt)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc