Implemented tangible.find. Octrees are more or less done! Yay!

This commit is contained in:
2022-07-14 00:57:11 -04:00
parent 69efb12c26
commit 4735c1fd7d
6 changed files with 466 additions and 114 deletions

View File

@@ -272,7 +272,7 @@ LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self",
scan.set_bbox_given_center_radius(aqback.xyz(), LS.cknumber(lradius));
scan.set_shape(PlaneScan::SPHERE);
scan.set_sorted(true);
scan.set_special(tan->id(), LS.ckboolean(lomit_self));
scan.set_near(tan->id(), !LS.ckboolean(lomit_self));
scan.set_omit_nowhere(LS.ckboolean(lomit_nowhere));
util::IdVector idv = w->plane_map_.scan(scan);
@@ -301,6 +301,85 @@ LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere",
return LS.result();
}
LuaDefine(tangible_find, "config",
"|Find tangibles by their location."
"|"
"|There are multiple ways to specify the plane, the bounding"
"|box, and the shape of the search. The most basic is to"
"|include these parameters in the table:"
"|"
"| plane : the plane to search (a string)"
"| centerx : x-coordinate of the center of the search"
"| centery : y-coordinate of the center of the search"
"| centerz : z-coordinate of the center of the search"
"| radius : the radius of the search"
"| shape : 'box', 'sphere', or 'cylinder'"
"|"
"|Shape has a default: 'sphere'. The other parameters do"
"|not have default values."
"|"
"|Instead of specifying the radius as a single float,"
"|you may optionally specify separate radii for each dimension."
"|"
"| radiusx : the radius in the x-dimension."
"| radiusy : the radius in the y-dimension."
"| radiusz : the radius in the z-dimension."
"|"
"|If you specify different radii in each dimension, then the"
"|'sphere' shape will actually be a spheroid, and the 'cylinder'"
"|shape will actually be a cylindroid."
"|"
"|Instead of specifying the center and plane, you can specify"
"|a tangible to search near:"
"|"
"| near : a tangible in whose vicinity the search occurs"
"|"
"|If you specify 'near', then by default, the near tangible is"
"|filtered out of the search. If you want to include it in the"
"|results, set the 'include' flag to true. In this case, the"
"|near tangible will always be the first search result:"
"|"
"| include : include the 'near' object in the results"
"|"
"|If you want to search an entire plane, you can use the"
"|wholeplane option, which replaces all the other options:"
"|"
"| wholeplane: the name of the plane to scan in its entirety"
"|"
"|It is valid to use 0.0 as the radius. If you do so, then only"
"|objects at the exact center you specify will be found."
"|"
"|If you are making a 2D game, it works fine to set all object Z"
"|coordinates to zero, and then do searches with centerz=0.0"
"|and radiusz=0.0."
"|") {
LuaArg config;
LuaRet result;
LuaStack LS(L, config, result);
PlaneScan scan;
eng::string error = scan.configure(LS, config);
if (!error.empty()) {
luaL_error(L, "%s", error.c_str());
}
// When the configure routine sees the 'near' flag, it stores the tangible
// ID, but not the center and plane, because doing so would require it to
// know about world models. We have to handle center and plane for 'near'
// separately.
World *w = World::fetch_global_pointer(L);
int64_t near = scan.near();
if (near != 0) {
Tangible *t = w->tangible_get(near);
assert(t != nullptr); // Should never happen.
const AnimStep &aqback = t->anim_queue_.back();
scan.set_plane(aqback.plane());
scan.set_center(aqback.xyz());
}
// Do the scan.
util::IdVector idv = w->plane_map_.scan(scan);
tangible_getall(LS, result, idv);
return LS.result();
}
LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
"|Start a thread."
"|"
@@ -471,6 +550,9 @@ LuaDefine(math_random, "(args...)",
"| (high) - an int between 1 and high inclusive"
"| (low, high) - an int between low and high inclusive"
"|"
"|You may also pass in a randomstate table"
"|as an optional first argument."
"|"
"|math.random tries to cooperate with predictive"
"|reexecution to be as predictable as possible."
"|To achieve predictability, we used an ad-hoc"