mirror of https://github.com/minetest/minetest.git
Merge ffc8c46908
into b23042839b
This commit is contained in:
commit
515191519f
|
@ -1327,16 +1327,20 @@ The function of `param2` is determined by `paramtype2` in node definition.
|
|||
* 4dir modulo 4 = rotation
|
||||
* Otherwise, behavior is identical to facedir
|
||||
* `paramtype2 = "leveled"`
|
||||
* Only valid for "nodebox" with 'type = "leveled"', and "plantlike_rooted".
|
||||
* Leveled nodebox:
|
||||
* Only valid for the drawtypes `nodebox`, `plantlike` and `plantlike_rooted`
|
||||
* Nodebox:
|
||||
* Nodebox `type` must be set to `"leveled"`
|
||||
* The level of the top face of the nodebox is stored in `param2`.
|
||||
* The other faces are defined by 'fixed = {}' like 'type = "fixed"'
|
||||
nodeboxes.
|
||||
* The nodebox height is (`param2` / 64) nodes.
|
||||
* The maximum accepted value of `param2` is 127.
|
||||
* Rooted plantlike:
|
||||
* Boxes in '`leveled_fixed = {}`' will never change.
|
||||
* Plantlike:
|
||||
* The height of the 'plantlike' section is stored in `param2`.
|
||||
* The height is (`param2` / 16) nodes.
|
||||
* Rooted plantlike:
|
||||
* Same as plantlike
|
||||
* `paramtype2 = "degrotate"`
|
||||
* Valid for `plantlike` and `mesh` drawtypes. The rotation of the node is
|
||||
stored in `param2`.
|
||||
|
@ -1535,8 +1539,29 @@ A nodebox is defined as any of:
|
|||
-- by the node parameter 'leveled = ', or if 'paramtype2 == "leveled"'
|
||||
-- by param2.
|
||||
-- Other faces are defined by 'fixed = {}' as with 'type = "fixed"'.
|
||||
-- Optionally add 'leveled_fixed = {}' for static boxes.
|
||||
type = "leveled",
|
||||
fixed = box OR {box1, box2, ...}
|
||||
fixed = box OR {box1, box2, ...} -- top face is variable
|
||||
leveled_fixed = box OR {box1, box2, ...} -- never changes
|
||||
}
|
||||
{
|
||||
-- Same as leveled, but the box height is in sync with the 'plant'
|
||||
-- of 'plantlike' nodes (steps of 1/16).
|
||||
-- Recommended use for this is as selection box.
|
||||
-- Be careful when using this as a collision box -- do not exceed the
|
||||
-- max. permissible heights of collision boxes (see collision box
|
||||
-- definition).
|
||||
type = "leveled_plantlike",
|
||||
fixed, leveled_fixed = -- see above
|
||||
}
|
||||
{
|
||||
-- Same as leveled, but the box height is in sync with the graphical
|
||||
-- representation of of 'plantlike_rooted' nodes (steps of 1/16).
|
||||
-- The upper box bound begins at the top side of the base cube (0.5).
|
||||
-- Recommended use for this is as selection box.
|
||||
-- Be careful when using this as a collision box (see above).
|
||||
type = "leveled_plantlike_rooted",
|
||||
fixed, leveled_fixed = -- see above
|
||||
}
|
||||
{
|
||||
-- A box like the selection box for torches
|
||||
|
@ -9477,6 +9502,9 @@ Used by `minetest.register_node`.
|
|||
-- Custom collision box definition. Multiple boxes can be defined.
|
||||
-- If "nodebox" drawtype is used and collision_box is nil, then node_box
|
||||
-- definition is used for the collision box.
|
||||
-- Collision boxes that are larger than the node itself are allowed, but
|
||||
-- only up to an absolute value of -0.5 + 127/64 on each axis. If you
|
||||
-- exceed this limit, there's no guarantee that collisions still work.
|
||||
|
||||
-- Support maps made in and before January 2012
|
||||
legacy_facedir_simple = false,
|
||||
|
|
|
@ -363,6 +363,11 @@ minetest.register_node("testnodes:plantlike_leveled", {
|
|||
tiles = {
|
||||
{ name = "testnodes_plantlike_leveled.png", tileable_vertical = true },
|
||||
},
|
||||
-- also test the 'leveled_plantlike' nodebox
|
||||
selection_box = {
|
||||
type = "leveled_plantlike",
|
||||
fixed = { -0.4, -0.5, -0.4, 0.4, 0.4, 0.4 },
|
||||
},
|
||||
|
||||
|
||||
-- We set a default param2 here only for convenience, to make the "plant" visible after placement
|
||||
|
@ -442,6 +447,14 @@ minetest.register_node("testnodes:plantlike_rooted_leveled", {
|
|||
special_tiles = {
|
||||
{ name = "testnodes_plantlike_rooted_leveled.png", tileable_vertical = true },
|
||||
},
|
||||
-- also test the 'leveled_plantlike_rooted' nodebox
|
||||
selection_box = {
|
||||
type = "leveled_plantlike_rooted",
|
||||
-- variable box for plant
|
||||
fixed = { -0.4, 0.5, -0.4, 0.4, 0.5, 0.4 },
|
||||
-- fixed box for the base cube
|
||||
leveled_fixed = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
|
||||
|
||||
-- We set a default param2 here only for convenience, to make the "plant" visible after placement
|
||||
|
|
|
@ -61,6 +61,30 @@ minetest.register_node("testnodes:nodebox_leveled", {
|
|||
|
||||
groups = {dig_immediate=3},
|
||||
})
|
||||
-- Leveled nodebox that also contains a static nodebox
|
||||
minetest.register_node("testnodes:nodebox_leveled_fixed", {
|
||||
description = S("Combined Leveled Nodebox Test Node").."\n"..
|
||||
S("param2 = height of center box (0..127)").."\n"..
|
||||
S("Other boxes are unaffected by param2"),
|
||||
tiles = {"testnodes_nodebox.png"},
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "leveled",
|
||||
node_box = {
|
||||
type = "leveled",
|
||||
fixed = {-0.25, 0.0, -0.25, 0.25, -0.499, 0.25},
|
||||
leveled_fixed = {
|
||||
{-0.5, -0.5, -0.5, -0.25, 0.0, -0.25},
|
||||
{0.25, -0.5, 0.25, 0.5, 0.0, 0.5},
|
||||
{-0.5, -0.5, 0.25, -0.25, 0.0, 0.5},
|
||||
{0.25, -0.5, -0.5, 0.5, 0.0, -0.25},
|
||||
},
|
||||
},
|
||||
|
||||
groups = {dig_immediate=3},
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
local nodebox_wall = {
|
||||
|
|
|
@ -75,6 +75,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
// Use floatToInt(p, BS) and intToFloat(p, BS).
|
||||
#define BS 10.0f
|
||||
|
||||
// This number defines the safe max absolute X/Y/Z coordinate in which
|
||||
// selection boxes still work safely. Beyond that limit, selection boxes
|
||||
// might break.
|
||||
#define SAFE_SELECTION_BOX_LIMIT (16.5f)
|
||||
|
||||
// Dimension of a MapBlock
|
||||
#define MAP_BLOCKSIZE 16
|
||||
// This makes mesh updates too slow, as many meshes are updated during
|
||||
|
|
290
src/mapnode.cpp
290
src/mapnode.cpp
|
@ -185,142 +185,174 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
|
|||
}
|
||||
}
|
||||
|
||||
void buildFixedNodeBox(const MapNode &n, const NodeBox &nodebox, const NodeDefManager *nodemgr,
|
||||
std::vector<aabb3f> &boxes, std::vector<aabb3f> input_boxes,
|
||||
enum NodeBoxType nbt) {
|
||||
u8 facedir = n.getFaceDir(nodemgr, true);
|
||||
u8 axisdir = facedir>>2;
|
||||
facedir &= 0x03;
|
||||
for (aabb3f box : input_boxes) {
|
||||
switch (nbt) {
|
||||
case NODEBOX_LEVELED: {
|
||||
box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS;
|
||||
break;
|
||||
}
|
||||
case NODEBOX_LEVELED_PLANTLIKE:
|
||||
case NODEBOX_LEVELED_PLANTLIKE_ROOTED: {
|
||||
u8 height = n.getParam2();
|
||||
if (nbt == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
box.MaxEdge.Y = (0.5f + height / 16.0f) * BS;
|
||||
} else {
|
||||
box.MaxEdge.Y = (-0.5f + height / 16.0f) * BS;
|
||||
}
|
||||
if (box.MaxEdge.Y > SAFE_SELECTION_BOX_LIMIT * BS) {
|
||||
box.MaxEdge.Y = SAFE_SELECTION_BOX_LIMIT * BS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (axisdir) {
|
||||
case 0:
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(-90);
|
||||
box.MaxEdge.rotateXZBy(-90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(180);
|
||||
box.MaxEdge.rotateXZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(90);
|
||||
box.MaxEdge.rotateXZBy(90);
|
||||
}
|
||||
break;
|
||||
case 1: // z+
|
||||
box.MinEdge.rotateYZBy(90);
|
||||
box.MaxEdge.rotateYZBy(90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(90);
|
||||
box.MaxEdge.rotateXYBy(90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(180);
|
||||
box.MaxEdge.rotateXYBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(-90);
|
||||
box.MaxEdge.rotateXYBy(-90);
|
||||
}
|
||||
break;
|
||||
case 2: //z-
|
||||
box.MinEdge.rotateYZBy(-90);
|
||||
box.MaxEdge.rotateYZBy(-90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(-90);
|
||||
box.MaxEdge.rotateXYBy(-90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(180);
|
||||
box.MaxEdge.rotateXYBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(90);
|
||||
box.MaxEdge.rotateXYBy(90);
|
||||
}
|
||||
break;
|
||||
case 3: //x+
|
||||
box.MinEdge.rotateXYBy(-90);
|
||||
box.MaxEdge.rotateXYBy(-90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(90);
|
||||
box.MaxEdge.rotateYZBy(90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(180);
|
||||
box.MaxEdge.rotateYZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(-90);
|
||||
box.MaxEdge.rotateYZBy(-90);
|
||||
}
|
||||
break;
|
||||
case 4: //x-
|
||||
box.MinEdge.rotateXYBy(90);
|
||||
box.MaxEdge.rotateXYBy(90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(-90);
|
||||
box.MaxEdge.rotateYZBy(-90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(180);
|
||||
box.MaxEdge.rotateYZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(90);
|
||||
box.MaxEdge.rotateYZBy(90);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
box.MinEdge.rotateXYBy(-180);
|
||||
box.MaxEdge.rotateXYBy(-180);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(90);
|
||||
box.MaxEdge.rotateXZBy(90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(180);
|
||||
box.MaxEdge.rotateXZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(-90);
|
||||
box.MaxEdge.rotateXZBy(-90);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
box.repair();
|
||||
boxes.push_back(box);
|
||||
}
|
||||
}
|
||||
|
||||
void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
|
||||
const NodeDefManager *nodemgr, std::vector<aabb3f> *p_boxes,
|
||||
u8 neighbors = 0)
|
||||
{
|
||||
std::vector<aabb3f> &boxes = *p_boxes;
|
||||
|
||||
if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) {
|
||||
const auto &fixed = nodebox.fixed;
|
||||
int facedir = n.getFaceDir(nodemgr, true);
|
||||
u8 axisdir = facedir>>2;
|
||||
facedir&=0x03;
|
||||
|
||||
boxes.reserve(boxes.size() + fixed.size());
|
||||
for (aabb3f box : fixed) {
|
||||
if (nodebox.type == NODEBOX_LEVELED)
|
||||
box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS;
|
||||
|
||||
switch (axisdir) {
|
||||
case 0:
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(-90);
|
||||
box.MaxEdge.rotateXZBy(-90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(180);
|
||||
box.MaxEdge.rotateXZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(90);
|
||||
box.MaxEdge.rotateXZBy(90);
|
||||
}
|
||||
break;
|
||||
case 1: // z+
|
||||
box.MinEdge.rotateYZBy(90);
|
||||
box.MaxEdge.rotateYZBy(90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(90);
|
||||
box.MaxEdge.rotateXYBy(90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(180);
|
||||
box.MaxEdge.rotateXYBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(-90);
|
||||
box.MaxEdge.rotateXYBy(-90);
|
||||
}
|
||||
break;
|
||||
case 2: //z-
|
||||
box.MinEdge.rotateYZBy(-90);
|
||||
box.MaxEdge.rotateYZBy(-90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(-90);
|
||||
box.MaxEdge.rotateXYBy(-90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(180);
|
||||
box.MaxEdge.rotateXYBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXYBy(90);
|
||||
box.MaxEdge.rotateXYBy(90);
|
||||
}
|
||||
break;
|
||||
case 3: //x+
|
||||
box.MinEdge.rotateXYBy(-90);
|
||||
box.MaxEdge.rotateXYBy(-90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(90);
|
||||
box.MaxEdge.rotateYZBy(90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(180);
|
||||
box.MaxEdge.rotateYZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(-90);
|
||||
box.MaxEdge.rotateYZBy(-90);
|
||||
}
|
||||
break;
|
||||
case 4: //x-
|
||||
box.MinEdge.rotateXYBy(90);
|
||||
box.MaxEdge.rotateXYBy(90);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(-90);
|
||||
box.MaxEdge.rotateYZBy(-90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(180);
|
||||
box.MaxEdge.rotateYZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateYZBy(90);
|
||||
box.MaxEdge.rotateYZBy(90);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
box.MinEdge.rotateXYBy(-180);
|
||||
box.MaxEdge.rotateXYBy(-180);
|
||||
if(facedir == 1)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(90);
|
||||
box.MaxEdge.rotateXZBy(90);
|
||||
}
|
||||
else if(facedir == 2)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(180);
|
||||
box.MaxEdge.rotateXZBy(180);
|
||||
}
|
||||
else if(facedir == 3)
|
||||
{
|
||||
box.MinEdge.rotateXZBy(-90);
|
||||
box.MaxEdge.rotateXZBy(-90);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
box.repair();
|
||||
boxes.push_back(box);
|
||||
if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED ||
|
||||
nodebox.type == NODEBOX_LEVELED_PLANTLIKE ||
|
||||
nodebox.type == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
const std::vector<aabb3f> &fixed = nodebox.fixed;
|
||||
const std::vector<aabb3f> &leveled_fixed = nodebox.leveled_fixed;
|
||||
enum NodeBoxType nbt = nodebox.type;
|
||||
if (nbt == NODEBOX_LEVELED || nbt == NODEBOX_LEVELED_PLANTLIKE ||
|
||||
nbt == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
buildFixedNodeBox(n, nodebox, nodemgr, boxes, leveled_fixed, NODEBOX_FIXED);
|
||||
}
|
||||
buildFixedNodeBox(n, nodebox, nodemgr, boxes, fixed, nbt);
|
||||
}
|
||||
else if(nodebox.type == NODEBOX_WALLMOUNTED)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@ void NodeBox::reset()
|
|||
type = NODEBOX_REGULAR;
|
||||
// default is empty
|
||||
fixed.clear();
|
||||
leveled_fixed.clear();
|
||||
// default is sign/ladder-like
|
||||
wall_top = aabb3f(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2);
|
||||
wall_bottom = aabb3f(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2);
|
||||
|
@ -65,6 +66,8 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
|
|||
|
||||
switch (type) {
|
||||
case NODEBOX_LEVELED:
|
||||
case NODEBOX_LEVELED_PLANTLIKE:
|
||||
case NODEBOX_LEVELED_PLANTLIKE_ROOTED:
|
||||
case NODEBOX_FIXED:
|
||||
writeU8(os, type);
|
||||
|
||||
|
@ -73,6 +76,14 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
|
|||
writeV3F32(os, nodebox.MinEdge);
|
||||
writeV3F32(os, nodebox.MaxEdge);
|
||||
}
|
||||
if (type == NODEBOX_LEVELED || type == NODEBOX_LEVELED_PLANTLIKE ||
|
||||
type == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
writeU16(os, leveled_fixed.size());
|
||||
for (const aabb3f &nodebox : leveled_fixed) {
|
||||
writeV3F32(os, nodebox.MinEdge);
|
||||
writeV3F32(os, nodebox.MaxEdge);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODEBOX_WALLMOUNTED:
|
||||
writeU8(os, type);
|
||||
|
@ -111,6 +122,7 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
|
|||
WRITEBOX(c.disconnected_right);
|
||||
WRITEBOX(c.disconnected);
|
||||
WRITEBOX(c.disconnected_sides);
|
||||
WRITEBOX(leveled_fixed);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -131,7 +143,10 @@ void NodeBox::deSerialize(std::istream &is)
|
|||
case NODEBOX_REGULAR:
|
||||
break;
|
||||
case NODEBOX_FIXED:
|
||||
case NODEBOX_LEVELED: {
|
||||
case NODEBOX_LEVELED:
|
||||
case NODEBOX_LEVELED_PLANTLIKE:
|
||||
case NODEBOX_LEVELED_PLANTLIKE_ROOTED:
|
||||
{
|
||||
u16 fixed_count = readU16(is);
|
||||
while(fixed_count--) {
|
||||
aabb3f box;
|
||||
|
@ -139,6 +154,18 @@ void NodeBox::deSerialize(std::istream &is)
|
|||
box.MaxEdge = readV3F32(is);
|
||||
fixed.push_back(box);
|
||||
}
|
||||
if(type == NODEBOX_LEVELED ||
|
||||
type == NODEBOX_LEVELED_PLANTLIKE ||
|
||||
type == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
u16 leveled_fixed_count = readU16(is);
|
||||
while(leveled_fixed_count--)
|
||||
{
|
||||
aabb3f box;
|
||||
box.MinEdge = readV3F32(is);
|
||||
box.MaxEdge = readV3F32(is);
|
||||
leveled_fixed.push_back(box);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NODEBOX_WALLMOUNTED:
|
||||
|
@ -177,6 +204,7 @@ void NodeBox::deSerialize(std::istream &is)
|
|||
READBOXES(c.disconnected_right);
|
||||
READBOXES(c.disconnected);
|
||||
READBOXES(c.disconnected_sides);
|
||||
READBOXES(leveled_fixed);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1204,6 +1232,54 @@ void boxVectorUnion(const std::vector<aabb3f> &boxes, aabb3f *box_union)
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Helper function for fixed/leveled nodeboxes in getBoxUnionReturns.
|
||||
* Returns the smallest box that contains all boxes
|
||||
* in the vector. Box_union is expanded.
|
||||
* @param[in] features used to decide whether the nodebox
|
||||
* can be rotated
|
||||
* @param[in, out] box_union the union of the arguments
|
||||
* @param to_add nodebox to add to union
|
||||
* @param nbt node box type
|
||||
*/
|
||||
void rawUnionFixed(const ContentFeatures &features,
|
||||
aabb3f *box_union,
|
||||
const std::vector<aabb3f> &to_add, enum NodeBoxType nbt)
|
||||
{
|
||||
// Raw union (fixed)
|
||||
aabb3f half_processed(0, 0, 0, 0, 0, 0);
|
||||
boxVectorUnion(to_add, &half_processed);
|
||||
// Set leveled boxes to maximal
|
||||
if (nbt == NODEBOX_LEVELED) {
|
||||
// -0.5 + 127/64
|
||||
half_processed.MaxEdge.Y = 1.484375f * BS;
|
||||
} else if (nbt == NODEBOX_LEVELED_PLANTLIKE ||
|
||||
nbt == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
half_processed.MaxEdge.Y = SAFE_SELECTION_BOX_LIMIT * BS;
|
||||
}
|
||||
if (features.param_type_2 == CPT2_FACEDIR ||
|
||||
features.param_type_2 == CPT2_COLORED_FACEDIR) {
|
||||
// Get maximal coordinate
|
||||
f32 coords[] = {
|
||||
fabsf(half_processed.MinEdge.X),
|
||||
fabsf(half_processed.MinEdge.Y),
|
||||
fabsf(half_processed.MinEdge.Z),
|
||||
fabsf(half_processed.MaxEdge.X),
|
||||
fabsf(half_processed.MaxEdge.Y),
|
||||
fabsf(half_processed.MaxEdge.Z) };
|
||||
f32 max = 0;
|
||||
for (float coord : coords) {
|
||||
if (max < coord) {
|
||||
max = coord;
|
||||
}
|
||||
}
|
||||
// Add the union of all possible rotated boxes
|
||||
box_union->addInternalPoint(-max, -max, -max);
|
||||
box_union->addInternalPoint(+max, +max, +max);
|
||||
} else {
|
||||
box_union->addInternalBox(half_processed);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns a box that contains the nodebox in every case.
|
||||
|
@ -1250,6 +1326,16 @@ void getNodeBoxUnion(const NodeBox &nodebox, const ContentFeatures &features,
|
|||
} else {
|
||||
box_union->addInternalBox(half_processed);
|
||||
}
|
||||
}
|
||||
case NODEBOX_LEVELED_PLANTLIKE:
|
||||
case NODEBOX_LEVELED_PLANTLIKE_ROOTED: {
|
||||
NodeBoxType nbt = nodebox.type;
|
||||
if (nbt == NODEBOX_LEVELED ||
|
||||
nbt == NODEBOX_LEVELED_PLANTLIKE ||
|
||||
nbt == NODEBOX_LEVELED_PLANTLIKE_ROOTED) {
|
||||
rawUnionFixed(features, box_union, nodebox.leveled_fixed, NODEBOX_FIXED);
|
||||
}
|
||||
rawUnionFixed(features, box_union, nodebox.fixed, nbt);
|
||||
break;
|
||||
}
|
||||
case NODEBOX_WALLMOUNTED: {
|
||||
|
|
|
@ -103,6 +103,8 @@ enum NodeBoxType : u8
|
|||
NODEBOX_WALLMOUNTED, // Box for wall mounted nodes; (top, bottom, side)
|
||||
NODEBOX_LEVELED, // Same as fixed, but with dynamic height from param2. for snow, ...
|
||||
NODEBOX_CONNECTED, // optionally draws nodeboxes if a neighbor node attaches
|
||||
NODEBOX_LEVELED_PLANTLIKE, // Same as leveled, but in sync with plantlike height
|
||||
NODEBOX_LEVELED_PLANTLIKE_ROOTED, // Same as leveled, but in sync with plantlike_rooted height
|
||||
};
|
||||
|
||||
struct NodeBoxConnected
|
||||
|
@ -136,6 +138,8 @@ struct NodeBox
|
|||
// NODEBOX_CONNECTED
|
||||
// (kept externally to not bloat the structure)
|
||||
std::shared_ptr<NodeBoxConnected> connected;
|
||||
// NODEBOX_LEVELED
|
||||
std::vector<aabb3f> leveled_fixed;
|
||||
|
||||
NodeBox()
|
||||
{ reset(); }
|
||||
|
|
|
@ -1111,13 +1111,27 @@ void push_nodebox(lua_State *L, const NodeBox &box)
|
|||
lua_pushstring(L, "regular");
|
||||
lua_setfield(L, -2, "type");
|
||||
break;
|
||||
case NODEBOX_LEVELED:
|
||||
case NODEBOX_FIXED:
|
||||
lua_pushstring(L, "fixed");
|
||||
lua_setfield(L, -2, "type");
|
||||
push_aabb3f_vector(L, box.fixed);
|
||||
lua_setfield(L, -2, "fixed");
|
||||
break;
|
||||
case NODEBOX_LEVELED:
|
||||
case NODEBOX_LEVELED_PLANTLIKE:
|
||||
case NODEBOX_LEVELED_PLANTLIKE_ROOTED:
|
||||
if (box.type == NODEBOX_LEVELED)
|
||||
lua_pushstring(L, "leveled");
|
||||
else if (box.type == NODEBOX_LEVELED_PLANTLIKE)
|
||||
lua_pushstring(L, "leveled_plantlike");
|
||||
else if (box.type == NODEBOX_LEVELED_PLANTLIKE_ROOTED)
|
||||
lua_pushstring(L, "leveled_plantlike_rooted");
|
||||
lua_setfield(L, -2, "type");
|
||||
push_aabb3f_vector(L, box.fixed);
|
||||
lua_setfield(L, -2, "fixed");
|
||||
push_aabb3f_vector(L, box.leveled_fixed);
|
||||
lua_setfield(L, -2, "leveled_fixed");
|
||||
break;
|
||||
case NODEBOX_WALLMOUNTED:
|
||||
lua_pushstring(L, "wallmounted");
|
||||
lua_setfield(L, -2, "type");
|
||||
|
@ -1286,6 +1300,7 @@ NodeBox read_nodebox(lua_State *L, int index)
|
|||
NODEBOXREADVEC(c.disconnected, "disconnected");
|
||||
NODEBOXREADVEC(c.disconnected_sides, "disconnected_sides");
|
||||
}
|
||||
NODEBOXREADVEC(nodebox.leveled_fixed, "leveled_fixed");
|
||||
|
||||
return nodebox;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,8 @@ struct EnumString ScriptApiNode::es_NodeBoxType[] =
|
|||
{NODEBOX_WALLMOUNTED, "wallmounted"},
|
||||
{NODEBOX_LEVELED, "leveled"},
|
||||
{NODEBOX_CONNECTED, "connected"},
|
||||
{NODEBOX_LEVELED_PLANTLIKE, "leveled_plantlike"},
|
||||
{NODEBOX_LEVELED_PLANTLIKE_ROOTED, "leveled_plantlike_rooted"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue