1
0

Bindings: Fixed cBoundingBox API.

This commit is contained in:
Mattes D 2016-06-05 18:23:16 +02:00
parent fbe9866524
commit c2759186c0
6 changed files with 167 additions and 15 deletions

View File

@ -29,9 +29,22 @@ return
{ Params = "{{Vector3d|Pos}}, Radius, Height", Return = "cBoundingBox", Notes = "Creates a new bounding box from the position given and radius (X/Z) and height. Radius is added from X/Z to calculate the maximum coords and subtracted from X/Z to get the minimum; minimum Y is set to Pos.y and maxumim Y to Pos.y plus Height. This corresponds with how {{cEntity|entities}} are represented in Minecraft." },
{ Params = "OtherBoundingBox", Return = "cBoundingBox", Notes = "Creates a new copy of the given bounding box. Same result can be achieved by using a simple assignment." },
},
CalcLineIntersection = { Params = "{{Vector3d|LineStart}}, {{Vector3d|LinePt2}}", Return = "DoesIntersect, LineCoeff, Face", Notes = "Calculates the intersection of a ray (half-line), given by two of its points, with the bounding box. Returns false if the line doesn't intersect the bounding box, or true, together with coefficient of the intersection (how much of the difference between the two ray points is needed to reach the intersection), and the face of the box which is intersected.<br /><b>TODO</b>: Lua binding for this function is wrong atm." },
CalcLineIntersection =
{
{ Params = "{{Vector3d|LineStart}}, {{Vector3d|LinePt2}}", Return = "DoesIntersect, [LineCoeff, Face]", Notes = "Calculates the intersection of a ray (half-line), given by two of its points, with the bounding box. Returns false if the line doesn't intersect the bounding box, or true, together with coefficient of the intersection (how much of the difference between the two ray points is needed to reach the intersection), and the face of the box which is intersected." },
{ Params = "{{Vector3d|BoxMin}}, {{Vector3d|BoxMax}}, {{Vector3d|LineStart}}, {{Vector3d|LinePt2}}", Return = "DoesIntersect, [LineCoeff, Face]", Notes = "(STATIC) Calculates the intersection of a ray (half-line), given by two of its points, with the bounding box specified as its minimum and maximum coords. Returns false if the line doesn't intersect the bounding box, or true, together with coefficient of the intersection (how much of the difference between the two ray points is needed to reach the intersection), and the face of the box which is intersected." },
},
DoesIntersect = { Params = "OtherBoundingBox", Return = "bool", Notes = "Returns true if the two bounding boxes have an intersection of nonzero volume." },
Expand = { Params = "ExpandX, ExpandY, ExpandZ", Return = "", Notes = "Expands this bounding box by the specified amount in each direction (so the box becomes larger by 2 * Expand in each axis)." },
GetMax = { Params = "", Return = "{{Vector3d|Point}}", Notes = "Returns the boundary point with the maximum coords" },
GetMaxX = { Params = "", Return = "number", Notes = "Returns the maximum X coord of the bounding box" },
GetMaxY = { Params = "", Return = "number", Notes = "Returns the maximum Y coord of the bounding box" },
GetMaxZ = { Params = "", Return = "number", Notes = "Returns the maximum Z coord of the bounding box" },
GetMin = { Params = "", Return = "{{Vector3d|Point}}", Notes = "Returns the boundary point with the minimum coords" },
GetMinX = { Params = "", Return = "number", Notes = "Returns the minimum X coord of the bounding box" },
GetMinY = { Params = "", Return = "number", Notes = "Returns the minimum Y coord of the bounding box" },
GetMinZ = { Params = "", Return = "number", Notes = "Returns the minimum Z coord of the bounding box" },
Intersect = { Params = "{{cBoundingBox|OtherBbox}}", Return = "bool, [{{cBoundingBox|bbox}}]", Notes = "Checks if the intersection between this bounding box and another one is non-empty. Returns false if the intersection is empty, true and a new cBoundingBox representing the intersection of the two boxes." },
IsInside =
{
{ Params = "{{Vector3d|Point}}", Return = "bool", Notes = "Returns true if the specified point is inside (including on the edge) of the box." },

View File

@ -1921,6 +1921,52 @@ end
function HandleConsoleTestBbox(a_Split, a_EntireCmd)
-- Test bbox intersection:
local bbox1 = cBoundingBox(0, 5, 0, 5, 0, 5)
local bbox2 = cBoundingBox(bbox1) -- Make a copy
bbox2:Move(20, 20, 20)
local bbox3 = cBoundingBox(bbox1) -- Make a copy
bbox3:Move(2, 2, 2)
local doesIntersect, intersection = bbox1:Intersect(bbox2)
LOG("Bbox 2 intersection: " .. tostring(doesIntersect))
LOG(" Intersection type: " .. type(intersection) .. " / " .. tolua.type(intersection))
if (intersection) then
LOG(" {" .. intersection:GetMinX() .. ", " .. intersection:GetMinY() .. ", " .. intersection:GetMinZ() .. "}")
LOG(" {" .. intersection:GetMaxX() .. ", " .. intersection:GetMaxY() .. ", " .. intersection:GetMaxZ() .. "}")
end
doesIntersect, intersection = bbox1:Intersect(bbox3)
LOG("Bbox 3 intersection: " .. tostring(doesIntersect))
LOG(" Intersection type: " .. type(intersection) .. " / " .. tolua.type(intersection))
if (intersection) then
LOG(" {" .. intersection:GetMinX() .. ", " .. intersection:GetMinY() .. ", " .. intersection:GetMinZ() .. "}")
LOG(" {" .. intersection:GetMaxX() .. ", " .. intersection:GetMaxY() .. ", " .. intersection:GetMaxZ() .. "}")
end
-- Test line intersection:
local lines =
{
{ Vector3d(5, 0, 5), Vector3d(5, 1, 5) },
{ Vector3d(0, 0, 0), Vector3d(0, 1, 0) },
}
for idx, line in ipairs(lines) do
local doesIntersect, coeff, face = bbox2:CalcLineIntersection(line[1], line[2])
LOG("Line " .. idx .. " intersection: " .. tostring(doesIntersect))
LOG(" Coeff: " .. tostring(coeff))
LOG(" Face: " .. tostring(face))
local doesIntersect2, coeff2, face2 = cBoundingBox:CalcLineIntersection(bbox2:GetMin(), bbox2:GetMax(), line[1], line[2])
assert(doesIntersect == doesIntersect2)
assert(coeff == coeff2)
assert(face == face2)
end
return true
end
function HandleConsoleTestCall(a_Split, a_EntireCmd)
LOG("Testing inter-plugin calls")
LOG("Note: These will fail if the Core plugin is not enabled")

View File

@ -254,6 +254,12 @@ g_PluginInfo =
HelpString = "Tests the world scheduling",
},
["testbbox"] =
{
Handler = HandleConsoleTestBbox,
HelpString = "Tests cBoundingBox API"
},
["testcall"] =
{
Handler = HandleConsoleTestCall,

View File

@ -37,6 +37,7 @@
#include "../CommandOutput.h"
#include "../BuildInfo.h"
#include "../HTTP/UrlParser.h"
#include "../BoundingBox.h"
@ -3143,6 +3144,80 @@ static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S)
static int tolua_cBoundingBox_CalcLineIntersection(lua_State * a_LuaState)
{
/* Function signatures:
bbox:CalcLineIntersection(pt1, pt2) -> bool, [number, blockface]
cBoundingBox:CalcLineIntersection(min, max, pt1, pt2) -> bool, [number, blockface]
*/
cLuaState L(a_LuaState);
const Vector3d * min;
const Vector3d * max;
const Vector3d * pt1;
const Vector3d * pt2;
double lineCoeff;
eBlockFace blockFace;
bool res;
if (L.GetStackValues(2, min, max, pt1, pt2)) // Try the static signature first
{
res = cBoundingBox::CalcLineIntersection(min, max, pt1, pt2, lineCoeff, blockFace);
}
else
{
const cBoundingBox * bbox;
if (!L.GetStackValues(1, bbox, pt1, pt2)) // Try the regular signature
{
L.LogStack();
tolua_error(a_LuaState, "Invalid function params. Expected either bbox:CalcLineIntersection(pt1, pt2) or cBoundingBox:CalcLineIntersection(min, max, pt1, pt2).", nullptr);
return 0;
}
res = bbox->CalcLineIntersection(pt1, pt2, lineCoeff, blockFace);
}
L.Push(res);
if (res)
{
L.Push(lineCoeff);
L.Push(blockFace);
return 3;
}
return 1;
}
static int tolua_cBoundingBox_Intersect(lua_State * a_LuaState)
{
/* Function signature:
bbox:Intersect(a_OtherBbox) -> bool, cBoundingBox
*/
cLuaState L(a_LuaState);
const cBoundingBox * self;
const cBoundingBox * other;
if (!L.GetStackValues(1, self, other))
{
L.LogStack();
tolua_error(a_LuaState, "Invalid function params. Expected bbox:Intersect(otherBbox).", nullptr);
return 0;
}
auto intersection = new cBoundingBox(*self);
auto res = self->Intersect(*other, *intersection);
L.Push(res);
if (!res)
{
delete intersection;
return 1;
}
L.Push(intersection);
tolua_register_gc(L, lua_gettop(L)); // Make Lua own the "intersection" object
return 2;
}
static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S)
{
// function cCompositeChat:AddRunCommandPart(Message, Command, [Style])
@ -3431,6 +3506,11 @@ void cManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "SaveToSchematicString", tolua_cBlockArea_SaveToSchematicString);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cBoundingBox");
tolua_function(tolua_S, "CalcLineIntersection", tolua_cBoundingBox_CalcLineIntersection);
tolua_function(tolua_S, "Intersect", tolua_cBoundingBox_Intersect);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cClientHandle");
tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE);
tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE);

View File

@ -261,7 +261,7 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, doub
bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, eBlockFace & a_Face)
bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, eBlockFace & a_Face) const
{
return CalcLineIntersection(m_Min, m_Max, a_Line1, a_Line2, a_LineCoeff, a_Face);
}
@ -336,7 +336,7 @@ bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d &
bool cBoundingBox::Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection)
bool cBoundingBox::Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection) const
{
a_Intersection.m_Min.x = std::max(m_Min.x, a_Other.m_Min.x);
a_Intersection.m_Max.x = std::min(m_Max.x, a_Other.m_Max.x);

View File

@ -63,20 +63,25 @@ public:
/** Returns true if the specified point is inside the bounding box specified by its min / max corners */
static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z);
/** Returns true if this bounding box is intersected by the line specified by its two points
Also calculates the distance along the line in which the intersection occurs (0 .. 1)
Only forward collisions (a_LineCoeff >= 0) are returned. */
bool CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, eBlockFace & a_Face);
/** Returns true if the specified bounding box is intersected by the line specified by its two points
Also calculates the distance along the line in which the intersection occurs (0 .. 1) and the face hit (BLOCK_FACE_ constants)
Only forward collisions (a_LineCoeff >= 0) are returned. */
static bool CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, eBlockFace & a_Face);
// tolua_end
/** Calculates the intersection of the two bounding boxes; returns true if nonempty */
bool Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection);
/** Returns true if this bounding box is intersected by the line specified by its two points
Also calculates the distance along the line in which the intersection occurs, and the face hit (BLOCK_FACE_ constants)
Only forward collisions (a_LineCoeff >= 0) are returned.
Exported to Lua manually, because ToLua++ would generate needless input params (a_LineCoeff, a_Face). */
bool CalcLineIntersection(const Vector3d & a_LinePoint1, const Vector3d & a_LinePoint2, double & a_LineCoeff, eBlockFace & a_Face) const;
/** Returns true if the specified bounding box is intersected by the line specified by its two points
Also calculates the distance along the line in which the intersection occurs, and the face hit (BLOCK_FACE_ constants)
Only forward collisions (a_LineCoeff >= 0) are returned.
Exported to Lua manually, because ToLua++ would generate needless input params (a_LineCoeff, a_Face). */
static bool CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_LinePoint1, const Vector3d & a_LinePoint2, double & a_LineCoeff, eBlockFace & a_Face);
/** Calculates the intersection of the two bounding boxes; returns true if nonempty.
Exported manually, because ToLua++ would generate needless input params (a_Intersection). */
bool Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection) const;
// tolua_begin
double GetMinX(void) const { return m_Min.x; }
double GetMinY(void) const { return m_Min.y; }
@ -89,6 +94,8 @@ public:
const Vector3d & GetMin(void) const { return m_Min; }
const Vector3d & GetMax(void) const { return m_Max; }
// tolua_end
protected:
Vector3d m_Min;
Vector3d m_Max;