<% shape_name = ENV["shape_name"] real_numeric_types = { "float" => "float", "double" => "double", "fixed16_16" => "fixed16_16", "int" => "int", "uint" => "unsigned int" } numeric_type = real_numeric_types[ENV["numeric_type"]] const_zero = { "float" => "0.0f", "double" => "0.0", "fixed16_16" => "0x00000", "int" => "0", "unsigned int" => "0" } const_one = { "float" => "1.0f", "double" => "1.0", "fixed16_16" => "0x10000", "int" => "1", "unsigned int" => "1" } numeric_type_suffixes = { "float" => "f", "double" => "d", "fixed16_16" => "x", "int" => "i", "unsigned int" => "u" } class_name = "#{shape_name}#{numeric_type_suffixes[numeric_type]}" class_name_upper = "#{shape_name.upcase}#{numeric_type_suffixes[numeric_type]}" class_argument_name = "#{shape_name.downcase.chop}" if (shape_name == "Rect4") vector_type = "Vector2#{numeric_type_suffixes[numeric_type]}" else vector_type = "Vector3#{numeric_type_suffixes[numeric_type]}" end c0 = const_zero[numeric_type] c1 = const_one[numeric_type] if numeric_type == "fixed16_16" def multiply(lhs, rhs) return "xmul(#{lhs}, #{rhs})" end def divide(lhs, rhs) return "xdiv(#{lhs}, #{rhs})" end def round(number) return "xround(#{number})" end else def multiply(lhs, rhs) return "#{lhs} * #{rhs}" end def divide(lhs, rhs) return "#{lhs} / #{rhs}" end if numeric_type == "float" def round(number) return "roundpositivef(#{number})" end elsif numeric_type == "double" def round(number) return "roundpositive(#{number})" end end end -%> /* Copyright (c) 2016 Alex Diener This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Alex Diener alex@ludobloom.com */ #include "gamemath/<%= class_name %>.h" <% if numeric_type == "float" || numeric_type == "double" -%> #include "gamemath/Scalar.h" <% end -%> <%= class_name %> <%= class_name %>_fromPositionAndSize(<%= vector_type %> position, <%= vector_type %> size) { <%= class_name %> result; result.xMin = position.x; result.yMin = position.y; <% if shape_name == "Box6" -%> result.zMin = position.z; <% end -%> result.xMax = result.xMin + size.x; result.yMax = result.yMin + size.y; <% if shape_name == "Box6" -%> result.zMax = result.zMin + size.z; <% end -%> return result; } <%= class_name %> <%= class_name %>_fromPositionSizeOrigin(<%= vector_type %> position, <%= vector_type %> size, <%= vector_type %> origin) { <%= class_name %> result; result.xMin = position.x - <%= multiply("size.x", "origin.x") %>; result.yMin = position.y - <%= multiply("size.y", "origin.y") %>; <% if shape_name == "Box6" -%> result.zMin = position.z - <%= multiply("size.z", "origin.z") %>; <% end -%> result.xMax = result.xMin + size.x; result.yMax = result.yMin + size.y; <% if shape_name == "Box6" -%> result.zMax = result.zMin + size.z; <% end -%> return result; } <%= class_name %> <%= class_name %>_enclosingPoints(<%= vector_type %> point1, <%= vector_type %> point2) { <%= class_name %> result; result.xMin = point1.x < point2.x ? point1.x : point2.x; result.xMax = point1.x > point2.x ? point1.x : point2.x; result.yMin = point1.y < point2.y ? point1.y : point2.y; result.yMax = point1.y > point2.y ? point1.y : point2.y; <% if shape_name == "Box6" -%> result.zMin = point1.z < point2.z ? point1.z : point2.z; result.zMax = point1.z > point2.z ? point1.z : point2.z; <% end -%> return result; } <%= numeric_type %> <%= class_name %>_getWidth(<%= class_name %> <%= class_argument_name %>) { return <%= class_argument_name %>.xMax - <%= class_argument_name %>.xMin; } <%= numeric_type %> <%= class_name %>_getHeight(<%= class_name %> <%= class_argument_name %>) { return <%= class_argument_name %>.yMax - <%= class_argument_name %>.yMin; } <%= vector_type %> <%= class_name %>_getSize(<%= class_name %> <%= class_argument_name %>) { return (<%= vector_type %>) {<%= class_argument_name %>.xMax - <%= class_argument_name %>.xMin, <%= class_argument_name %>.yMax - <%= class_argument_name %>.yMin<% if shape_name == "Box6" %>, <%= class_argument_name %>.zMax - <%= class_argument_name %>.zMin<% end %>}; } <% if shape_name == "Box6" -%> <%= numeric_type %> <%= class_name %>_getDepth(<%= class_name %> <%= class_argument_name %>) { return <%= class_argument_name %>.zMax - <%= class_argument_name %>.zMin; } <% end -%> <%= vector_type %> <%= class_name %>_getCenter(<%= class_name %> <%= class_argument_name %>) { return (<%= vector_type %>) {<%= class_argument_name %>.xMin + (<%= class_argument_name %>.xMax - <%= class_argument_name %>.xMin) / 2, <%= class_argument_name %>.yMin + (<%= class_argument_name %>.yMax - <%= class_argument_name %>.yMin) / 2<% if shape_name == "Box6" %>, <%= class_argument_name %>.zMin + (<%= class_argument_name %>.zMax - <%= class_argument_name %>.zMin) / 2<% end %>}; } <%= class_name %> <%= class_name %>_intersection(<%= class_name %> lhs, <%= class_name %> rhs) { if (!<%= class_name %>_intersects<%= class_name %>(lhs, rhs)) { return <%= class_name_upper %>_EMPTY; } return <%= class_name %>_intersectionNonempty(lhs, rhs); } <%= class_name %> <%= class_name %>_intersectionNonempty(<%= class_name %> lhs, <%= class_name %> rhs) { <%= class_name %> result; result.xMin = lhs.xMin < rhs.xMin ? rhs.xMin : lhs.xMin; result.xMax = lhs.xMax > rhs.xMax ? rhs.xMax : lhs.xMax; result.yMin = lhs.yMin < rhs.yMin ? rhs.yMin : lhs.yMin; result.yMax = lhs.yMax > rhs.yMax ? rhs.yMax : lhs.yMax; <% if shape_name == "Box6" -%> result.zMin = lhs.zMin < rhs.zMin ? rhs.zMin : lhs.zMin; result.zMax = lhs.zMax > rhs.zMax ? rhs.zMax : lhs.zMax; <% end -%> return result; } <%= class_name %> <%= class_name %>_union(<%= class_name %> lhs, <%= class_name %> rhs) { if (<%= class_name %>_isEmpty(lhs)) { if (<%= class_name %>_isEmpty(rhs)) { return <%= class_name_upper %>_EMPTY; } return rhs; } if (<%= class_name %>_isEmpty(rhs)) { return lhs; } return <%= class_name %>_unionNonempty(lhs, rhs); } <%= class_name %> <%= class_name %>_unionNonempty(<%= class_name %> lhs, <%= class_name %> rhs) { <%= class_name %> result; result.xMin = lhs.xMin < rhs.xMin ? lhs.xMin : rhs.xMin; result.xMax = lhs.xMax > rhs.xMax ? lhs.xMax : rhs.xMax; result.yMin = lhs.yMin < rhs.yMin ? lhs.yMin : rhs.yMin; result.yMax = lhs.yMax > rhs.yMax ? lhs.yMax : rhs.yMax; <% if shape_name == "Box6" -%> result.zMin = lhs.zMin < rhs.zMin ? lhs.zMin : rhs.zMin; result.zMax = lhs.zMax > rhs.zMax ? lhs.zMax : rhs.zMax; <% end -%> return result; } <%= class_name %> <%= class_name %>_offset(<%= class_name %> <%= class_argument_name %>, <%= vector_type %> offset) { <%= class_argument_name %>.xMin += offset.x; <%= class_argument_name %>.xMax += offset.x; <%= class_argument_name %>.yMin += offset.y; <%= class_argument_name %>.yMax += offset.y; <% if shape_name == "Box6" -%> <%= class_argument_name %>.zMin += offset.z; <%= class_argument_name %>.zMax += offset.z; <% end -%> return <%= class_argument_name %>; } <%= class_name %> <%= class_name %>_constrainWithin(<%= class_name %> <%= class_argument_name %>, <%= class_name %> constraint) { if (<%= class_argument_name %>.xMin < constraint.xMin) { <%= class_argument_name %>.xMax = constraint.xMin + (<%= class_argument_name %>.xMax - <%= class_argument_name %>.xMin); <%= class_argument_name %>.xMin = constraint.xMin; } else if (<%= class_argument_name %>.xMax > constraint.xMax) { <%= class_argument_name %>.xMin = constraint.xMax - (<%= class_argument_name %>.xMax - <%= class_argument_name %>.xMin); <%= class_argument_name %>.xMax = constraint.xMax; } if (<%= class_argument_name %>.yMin < constraint.yMin) { <%= class_argument_name %>.yMax = constraint.yMin + (<%= class_argument_name %>.yMax - <%= class_argument_name %>.yMin); <%= class_argument_name %>.yMin = constraint.yMin; } else if (<%= class_argument_name %>.yMax > constraint.yMax) { <%= class_argument_name %>.yMin = constraint.yMax - (<%= class_argument_name %>.yMax - <%= class_argument_name %>.yMin); <%= class_argument_name %>.yMax = constraint.yMax; } <% if shape_name == "Box6" -%> if (<%= class_argument_name %>.zMin < constraint.zMin) { <%= class_argument_name %>.zMax = constraint.zMin + (<%= class_argument_name %>.zMax - <%= class_argument_name %>.zMin); <%= class_argument_name %>.zMin = constraint.zMin; } else if (<%= class_argument_name %>.zMax > constraint.zMax) { <%= class_argument_name %>.zMin = constraint.zMax - (<%= class_argument_name %>.zMax - <%= class_argument_name %>.zMin); <%= class_argument_name %>.zMax = constraint.zMax; } <% end -%> return <%= class_argument_name %>; } <%= class_name %> <%= class_name %>_inset(<%= class_name %> <%= class_argument_name %>, <%= vector_type %> inset) { <%= class_argument_name %>.xMin += inset.x; <%= class_argument_name %>.xMax -= inset.x; <%= class_argument_name %>.yMin += inset.y; <%= class_argument_name %>.yMax -= inset.y; <% if shape_name == "Box6" -%> <%= class_argument_name %>.zMin += inset.z; <%= class_argument_name %>.zMax -= inset.z; <% end -%> return <%= class_argument_name %>; } <%= class_name %> <%= class_name %>_insetMargins(<%= class_name %> <%= class_argument_name %>, <%= class_name %> margins) { <%= class_argument_name %>.xMin += margins.xMin; <%= class_argument_name %>.xMax -= margins.xMax; <%= class_argument_name %>.yMin += margins.yMin; <%= class_argument_name %>.yMax -= margins.yMax; <% if shape_name == "Box6" -%> <%= class_argument_name %>.zMin += margins.zMin; <%= class_argument_name %>.zMax -= margins.zMax; <% end -%> return <%= class_argument_name %>; } <%= class_name %> <%= class_name %>_outsetMargins(<%= class_name %> <%= class_argument_name %>, <%= class_name %> margins) { <%= class_argument_name %>.xMin -= margins.xMin; <%= class_argument_name %>.xMax += margins.xMax; <%= class_argument_name %>.yMin -= margins.yMin; <%= class_argument_name %>.yMax += margins.yMax; <% if shape_name == "Box6" -%> <%= class_argument_name %>.zMin -= margins.zMin; <%= class_argument_name %>.zMax += margins.zMax; <% end -%> return <%= class_argument_name %>; } <% if numeric_type != "int" && numeric_type != "unsigned int" -%> <%= class_name %> <%= class_name %>_interpolate(<%= class_name %> lhs, <%= class_name %> rhs, <%= numeric_type %> value) { <%= class_name %> result; result.xMin = <%= multiply("lhs.xMin", "(#{c1} - value)") %> + <%= multiply("rhs.xMin", "value") %>; result.xMax = <%= multiply("lhs.xMax", "(#{c1} - value)") %> + <%= multiply("rhs.xMax", "value") %>; result.yMin = <%= multiply("lhs.yMin", "(#{c1} - value)") %> + <%= multiply("rhs.yMin", "value") %>; result.yMax = <%= multiply("lhs.yMax", "(#{c1} - value)") %> + <%= multiply("rhs.yMax", "value") %>; <% if shape_name == "Box6" -%> result.zMin = <%= multiply("lhs.zMin", "(#{c1} - value)") %> + <%= multiply("rhs.zMin", "value") %>; result.zMax = <%= multiply("lhs.zMax", "(#{c1} - value)") %> + <%= multiply("rhs.zMax", "value") %>; <% end -%> return result; } <%= class_name %> <%= class_name %>_round(<%= class_name %> <%= class_argument_name %>) { <%= class_name %> result; result.xMin = <%= round("#{class_argument_name}.xMin") %>; result.xMax = <%= round("#{class_argument_name}.xMax") %>; result.yMin = <%= round("#{class_argument_name}.yMin") %>; result.yMax = <%= round("#{class_argument_name}.yMax") %>; <% if shape_name == "Box6" -%> result.zMin = <%= round("#{class_argument_name}.zMin") %>; result.zMax = <%= round("#{class_argument_name}.zMax") %>; <% end -%> return result; } <% end -%> bool <%= class_name %>_isEmpty(<%= class_name %> <%= class_argument_name %>) { if (<%= class_argument_name %>.xMin >= <%= class_argument_name %>.xMax || <%= class_argument_name %>.yMin >= <%= class_argument_name %>.yMax<% if shape_name == "Box6" %> || <%= class_argument_name %>.zMin >= <%= class_argument_name %>.zMax<% end %>) { return true; } return false; } bool <%= class_name %>_isZero(<%= class_name %> <%= class_argument_name %>) { if (<%= class_argument_name %>.xMin != <%= c0 %> || <%= class_argument_name %>.xMax != <%= c0 %> || <%= class_argument_name %>.yMin != <%= c0 %> || <%= class_argument_name %>.yMax != <%= c0 %><% if shape_name == "Box6" %> || <%= class_argument_name %>.zMin != <%= c0 %> || <%= class_argument_name %>.zMax != <%= c0 %><% end %>) { return false; } return true; } bool <%= class_name %>_isEqual(<%= class_name %> lhs, <%= class_name %> rhs) { if (lhs.xMin != rhs.xMin || lhs.xMax != rhs.xMax || lhs.yMin != rhs.yMin || lhs.yMax != rhs.yMax<% if shape_name == "Box6" %> || lhs.zMin != rhs.zMin || lhs.zMax != rhs.zMax<% end %>) { return false; } return true; } bool <%= class_name %>_intersects<%= class_name %>(<%= class_name %> lhs, <%= class_name %> rhs) { if (<%= class_name %>_isEmpty(lhs) || <%= class_name %>_isEmpty(rhs)) { return false; } if (lhs.xMax > rhs.xMin && lhs.xMin < rhs.xMax && lhs.yMax > rhs.yMin && lhs.yMin < rhs.yMax<% if shape_name == "Box6" %> && lhs.zMax > rhs.zMin && lhs.zMin < rhs.zMax<% end %>) { return true; } return false; } bool <%= class_name %>_contains<%= class_name %>(<%= class_name %> lhs, <%= class_name %> rhs) { if (<%= class_name %>_isEmpty(lhs) || <%= class_name %>_isEmpty(rhs)) { return false; } if (lhs.xMax >= rhs.xMax && lhs.xMin <= rhs.xMin && lhs.yMax >= rhs.yMax && lhs.yMin <= rhs.yMin<% if shape_name == "Box6" %> && lhs.zMax >= rhs.zMax && lhs.zMin <= rhs.zMin<% end %>) { return true; } return false; } bool <%= class_name %>_contains<%= vector_type %>(<%= class_name %> <%= class_argument_name %>, <%= vector_type %> vector) { if (vector.x <= <%= class_argument_name %>.xMax && vector.x >= <%= class_argument_name %>.xMin && vector.y <= <%= class_argument_name %>.yMax && vector.y >= <%= class_argument_name %>.yMin<% if shape_name == "Box6" %> && vector.z <= <%= class_argument_name %>.zMax && vector.z >= <%= class_argument_name %>.zMin<% end %>) { return true; } return false; } <%= vector_type %> <%= class_name %>_clamp<%= vector_type %>(<%= class_name %> <%= class_argument_name %>, <%= vector_type %> vector) { if (vector.x < <%= class_argument_name %>.xMin) { vector.x = <%= class_argument_name %>.xMin; } else if (vector.x > <%= class_argument_name %>.xMax) { vector.x = <%= class_argument_name %>.xMax; } if (vector.y < <%= class_argument_name %>.yMin) { vector.y = <%= class_argument_name %>.yMin; } else if (vector.y > <%= class_argument_name %>.yMax) { vector.y = <%= class_argument_name %>.yMax; } <%- if shape_name == "Box6" %> if (vector.z < <%= class_argument_name %>.zMin) { vector.z = <%= class_argument_name %>.zMin; } else if (vector.z > <%= class_argument_name %>.zMax) { vector.z = <%= class_argument_name %>.zMax; } <%- end %> return vector; }