15 changed files with 1051 additions and 974 deletions
@ -0,0 +1,33 @@ |
|||
#pragma once |
|||
|
|||
#include "primitive_descriptor.h" |
|||
|
|||
#include "utils/eigen_alias.hpp" |
|||
|
|||
struct aabb_t { |
|||
Eigen::Vector3d min{std::numeric_limits<double>::max(), |
|||
std::numeric_limits<double>::max(), |
|||
std::numeric_limits<double>::max()}; |
|||
Eigen::Vector3d max{std::numeric_limits<double>::min(), |
|||
std::numeric_limits<double>::min(), |
|||
std::numeric_limits<double>::min()}; |
|||
|
|||
void extend(const Eigen::Vector3d& point) |
|||
{ |
|||
min = min.cwiseMin(point); |
|||
max = max.cwiseMax(point); |
|||
} |
|||
|
|||
void extend(const aabb_t& aabb) |
|||
{ |
|||
min = min.cwiseMin(aabb.min); |
|||
max = max.cwiseMax(aabb.max); |
|||
} |
|||
|
|||
void offset(const Eigen::Vector3d& offset) |
|||
{ |
|||
min = min + offset; |
|||
max = max + offset; |
|||
} |
|||
|
|||
}; |
@ -0,0 +1,21 @@ |
|||
#pragma once |
|||
|
|||
#include <vector> |
|||
#include <stack> |
|||
|
|||
#include <tbb/tbb.h> |
|||
|
|||
#include "blobtree.h" |
|||
|
|||
#include "aabb.hpp" |
|||
#include "node_operation.hpp" |
|||
|
|||
struct blobtree_t { |
|||
std::vector<node_t, tbb::tbb_allocator<node_t>> nodes{}; |
|||
std::vector<uint32_t, tbb::tbb_allocator<uint32_t>> leaf_index{}; |
|||
}; |
|||
|
|||
extern std::vector<blobtree_t, tbb::tbb_allocator<blobtree_t>> structures; |
|||
extern std::vector<aabb_t, tbb::tbb_allocator<aabb_t>> aabbs; |
|||
extern std::vector<primitive_node_t, tbb::tbb_allocator<primitive_node_t>> primitives; |
|||
extern std::stack<uint32_t, std::deque<uint32_t, tbb::tbb_allocator<uint32_t>>> free_structure_list; |
@ -0,0 +1,236 @@ |
|||
#pragma once |
|||
|
|||
#include <type_traits> |
|||
|
|||
struct node_t { |
|||
uint64_t data[2]; |
|||
|
|||
constexpr node_t() : data{0, 0} {} |
|||
|
|||
constexpr node_t(const uint64_t n1, const uint64_t n2) : data{n1, n2} {} |
|||
|
|||
template <typename T, typename = std::enable_if_t<sizeof(T) <= sizeof(uint64_t)>> |
|||
constexpr node_t(T value) |
|||
{ |
|||
data[0] = 0; |
|||
data[1] = static_cast<uint64_t>(value); |
|||
} |
|||
|
|||
template <typename T, typename = std::enable_if_t<sizeof(T) <= sizeof(uint64_t)>> |
|||
constexpr operator T() const |
|||
{ |
|||
return static_cast<T>(data[1]); |
|||
} |
|||
|
|||
node_t operator>>(const uint32_t shift) const |
|||
{ |
|||
if (shift == 0) { return *this; } |
|||
|
|||
node_t result = *this; |
|||
|
|||
if (shift >= 128) { |
|||
result.data[0] = 0; |
|||
result.data[1] = 0; |
|||
} else if (shift >= 64) { |
|||
result.data[1] = this->data[0] >> (shift - 64); |
|||
result.data[0] = 0; |
|||
} else { |
|||
result.data[1] = (this->data[1] >> shift) | (this->data[0] << (64 - shift)); |
|||
result.data[0] = this->data[0] >> shift; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
node_t operator<<(const uint32_t shift) const |
|||
{ |
|||
if (shift == 0) { return *this; } |
|||
|
|||
node_t result = *this; |
|||
|
|||
if (shift >= 128) { |
|||
result.data[0] = 0; |
|||
result.data[1] = 0; |
|||
} else if (shift >= 64) { |
|||
result.data[0] = this->data[1] << (shift - 64); |
|||
result.data[1] = 0; |
|||
} else { |
|||
result.data[0] = (this->data[0] << shift) | (this->data[1] >> (64 - shift)); |
|||
result.data[1] = this->data[1] << shift; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
const node_t operator&(const node_t& other) const |
|||
{ |
|||
node_t result = *this; |
|||
result.data[0] &= other.data[0]; |
|||
result.data[1] &= other.data[1]; |
|||
return result; |
|||
} |
|||
|
|||
friend const node_t operator&(node_t, const uint32_t&); |
|||
|
|||
const node_t operator|(const node_t& other) const |
|||
{ |
|||
node_t result = *this; |
|||
result.data[0] |= other.data[0]; |
|||
result.data[1] |= other.data[1]; |
|||
return result; |
|||
} |
|||
|
|||
friend const node_t operator|(node_t, const uint32_t&); |
|||
|
|||
const node_t operator~() const |
|||
{ |
|||
node_t result = *this; |
|||
result.data[0] = ~result.data[0]; |
|||
result.data[1] = ~result.data[1]; |
|||
return result; |
|||
} |
|||
}; |
|||
|
|||
inline const node_t operator&(node_t lhs, const uint32_t& rhs) |
|||
{ |
|||
lhs.data[1] &= rhs; |
|||
return lhs; |
|||
} |
|||
|
|||
inline const node_t operator|(node_t lhs, const uint32_t& rhs) |
|||
{ |
|||
lhs.data[1] |= rhs; |
|||
return lhs; |
|||
} |
|||
|
|||
enum class eNodeLocation : uint32_t { in = 0, out = 1, edge = 2, unset = 3 }; |
|||
enum class eNodeOperation : uint32_t { unionOp = 0, intersectionOp = 1, differenceOp = 2, unsetOp = 3 }; |
|||
|
|||
/* getter/setter for node_t */ |
|||
template <typename _Tp> |
|||
struct node_proxy { |
|||
constexpr node_proxy() = default; |
|||
|
|||
constexpr node_proxy(node_t& _data, uint32_t _offset, node_t _mask) : data(&_data), offset(_offset), mask(_mask) {} |
|||
|
|||
void reinit(node_t& _data, uint32_t _offset, node_t _mask) |
|||
{ |
|||
data = &_data; |
|||
offset = _offset; |
|||
mask = _mask; |
|||
} |
|||
|
|||
void reinit(node_proxy&& other) |
|||
{ |
|||
data = std::move(other.data); |
|||
offset = std::move(other.offset); |
|||
mask = std::move(other.mask); |
|||
} |
|||
|
|||
node_proxy(const node_proxy&) = delete; |
|||
node_proxy(node_proxy&&) = delete; |
|||
|
|||
constexpr node_proxy& operator=(const node_proxy& other) |
|||
{ |
|||
const auto _mask = mask << offset; |
|||
*data = (*data & ~_mask) | (other.data & _mask); |
|||
return *this; |
|||
} |
|||
|
|||
constexpr node_proxy& operator=(node_proxy&& other) |
|||
{ |
|||
const auto _mask = mask << offset; |
|||
*data = (*data & ~_mask) | (std::forward(other.data) & _mask); |
|||
return *this; |
|||
} |
|||
|
|||
template <typename _Fp, typename = std::enable_if_t<!std::is_same_v<_Fp, node_proxy>>> |
|||
constexpr node_proxy& operator=(_Fp&& other) |
|||
{ |
|||
const auto _mask = mask << offset; |
|||
if constexpr (std::is_enum_v<_Fp>) { |
|||
const auto offset_value = static_cast<std::underlying_type_t<_Fp>>(std::forward<_Fp>(other)) << offset; |
|||
*data = (*data & ~_mask) | (_mask & offset_value); |
|||
} else if constexpr (std::is_same_v<_Fp, bool>) { |
|||
const auto offset_value = static_cast<uint32_t>(std::forward<_Fp>(other)) << offset; |
|||
*data = (*data & ~_mask) | (_mask & offset_value); |
|||
} else { |
|||
const auto offset_value = std::forward<_Fp>(other) << offset; |
|||
*data = (*data & ~_mask) | (_mask & offset_value); |
|||
} |
|||
return *this; |
|||
} |
|||
|
|||
template <typename _Fp, |
|||
typename = std::enable_if_t<!std::is_same_v<_Fp, node_proxy> && //
|
|||
!std::is_enum_v<_Fp> && //
|
|||
!std::is_same_v<_Fp, bool>>> |
|||
constexpr node_proxy& operator+=(_Fp&& other) |
|||
{ |
|||
const auto _mask = mask << offset; |
|||
const _Fp low_data = (*data) >> offset; |
|||
const auto low_result = std::forward<_Fp>(other) + low_data; |
|||
*data = (*data & ~_mask) | (_mask & (low_result << offset)); |
|||
return *this; |
|||
} |
|||
|
|||
constexpr operator _Tp() const { return static_cast<_Tp>(((*data) >> offset) & mask); } |
|||
|
|||
protected: |
|||
node_t* data; |
|||
uint32_t offset{}; |
|||
node_t mask{}; |
|||
}; |
|||
|
|||
template <typename _Tp> |
|||
struct const_node_proxy { |
|||
constexpr const_node_proxy(const node_t& _data, uint32_t _offset, node_t _mask) : data(&_data), offset(_offset), mask(_mask) |
|||
{ |
|||
} |
|||
|
|||
const_node_proxy(const const_node_proxy&) = delete; |
|||
const_node_proxy(const_node_proxy&&) = delete; |
|||
|
|||
constexpr operator _Tp() const { return static_cast<_Tp>(((*data) >> offset) & mask); } |
|||
|
|||
protected: |
|||
const node_t* data; |
|||
uint32_t offset{}; |
|||
node_t mask{}; |
|||
}; |
|||
|
|||
// 0 for internal node, 1 for primitive node
|
|||
static constexpr inline auto node_fetch_is_primitive(node_t& node) { return node_proxy<bool>(node, 127u, 0x01u); } |
|||
|
|||
// 0 for union, 1 for intersection, 2 for difference, 3 for unset
|
|||
static constexpr inline auto node_fetch_operation(node_t& node) { return node_proxy<eNodeOperation>(node, 125u, 0x03u); } |
|||
|
|||
// 0 for in, 1 for out, 2 for on edge, 3 for unset
|
|||
static constexpr inline auto node_fetch_in_out(node_t& node) { return node_proxy<eNodeLocation>(node, 123u, 0x03u); } |
|||
|
|||
// If primitive node, the index to the primitive information
|
|||
static constexpr inline auto node_fetch_primitive_index(node_t& node) { return node_proxy<uint32_t>(node, 96u, 0xFFFFFFu); } |
|||
|
|||
static constexpr inline auto node_is_parent_null(const node_t& node) |
|||
{ |
|||
return const_node_proxy<uint32_t>(node, 96u, 0xFFFFFFu) == 0xFFFFFFFFu; |
|||
} |
|||
|
|||
// Parent node index
|
|||
static constexpr inline auto node_fetch_parent_index(node_t& node) { return node_proxy<uint32_t>(node, 64u, 0xFFFFFFFFu); } |
|||
|
|||
// Left child node index
|
|||
static constexpr inline auto node_fetch_left_child_index(node_t& node) { return node_proxy<uint32_t>(node, 32u, 0xFFFFFFFFu); } |
|||
|
|||
static constexpr inline auto node_is_left_child_null(const node_t& node) |
|||
{ |
|||
return const_node_proxy<uint32_t>(node, 32u, 0xFFFFFFFFu) == 0xFFFFFFFFu; |
|||
} |
|||
|
|||
// Right child node index
|
|||
static constexpr inline auto node_fetch_right_child_index(node_t& node) { return node_proxy<uint32_t>(node, 0u, 0xFFFFFFFFu); } |
|||
|
|||
static constexpr inline auto node_is_right_child_null(const node_t& node) |
|||
{ |
|||
return const_node_proxy<uint32_t>(node, 0u, 0xFFFFFFFFu) == 0xFFFFFFFFu; |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,169 @@ |
|||
#include <iostream> |
|||
|
|||
#include "primitive_descriptor.h" |
|||
|
|||
#include "globals.hpp" |
|||
|
|||
#ifdef _DEBUG |
|||
|
|||
void output_primitive_node(const primitive_node_t& node) |
|||
{ |
|||
auto output_point = [](const raw_vector3d_t& point) { |
|||
std::cout << "( " << point.x << ", " << point.y << ", " << point.z << " )" << std::endl; |
|||
}; |
|||
|
|||
auto type = node.type; |
|||
switch (type) { |
|||
case PRIMITIVE_TYPE_CONSTANT: { |
|||
auto desc = static_cast<constant_descriptor_t*>(node.desc); |
|||
std::cout << "constant:" << std::endl; |
|||
std::cout << "\tvalue: " << desc->value << std::endl << std::endl; |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_PLANE: { |
|||
auto desc = static_cast<plane_descriptor_t*>(node.desc); |
|||
std::cout << "plane:" << std::endl; |
|||
std::cout << "\tbase point: "; |
|||
output_point(desc->point); |
|||
std::cout << "\tnormal: "; |
|||
output_point(desc->normal); |
|||
std::cout << std::endl; |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_SPHERE: { |
|||
auto desc = static_cast<sphere_descriptor_t*>(node.desc); |
|||
std::cout << "sphere:" << std::endl; |
|||
std::cout << "\tcenter: "; |
|||
output_point(desc->center); |
|||
std::cout << "\tradius: " << desc->radius << std::endl << std::endl; |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_CYLINDER: { |
|||
auto desc = static_cast<cylinder_descriptor_t*>(node.desc); |
|||
std::cout << "cylinder:" << std::endl; |
|||
std::cout << "\tbottom point: "; |
|||
output_point(desc->bottom_origion); |
|||
std::cout << "\tradius: " << desc->radius << std::endl << std::endl; |
|||
std::cout << "\toffset: "; |
|||
output_point(desc->offset); |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_CONE: { |
|||
auto desc = static_cast<cone_descriptor_t*>(node.desc); |
|||
std::cout << "cone:" << std::endl; |
|||
std::cout << "\tbottom point: "; |
|||
output_point(desc->bottom_point); |
|||
std::cout << "\ttop point: "; |
|||
output_point(desc->top_point); |
|||
std::cout << "\tradius1: " << desc->radius1 << std::endl; |
|||
std::cout << "\tradius2: " << desc->radius2 << std::endl << std::endl; |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_BOX: { |
|||
auto desc = static_cast<box_descriptor_t*>(node.desc); |
|||
std::cout << "box:" << std::endl; |
|||
std::cout << "\tcenter: "; |
|||
output_point(desc->center); |
|||
std::cout << "\thalf_size "; |
|||
output_point(desc->half_size); |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_MESH: { |
|||
auto desc = static_cast<mesh_descriptor_t*>(node.desc); |
|||
std::cout << "mesh:" << std::endl; |
|||
std::cout << "\tpoint number: " << desc->point_number << std::endl; |
|||
for (int i = 0; i < desc->point_number; i++) { |
|||
std::cout << "\t\t( " << desc->points[i].x << ", " << desc->points[i].y << ", " << desc->points[i].z << " )" |
|||
<< std::endl; |
|||
} |
|||
|
|||
std::cout << "\tfaces number: " << desc->face_number << std::endl; |
|||
for (int i = 0; i < desc->face_number; i++) { |
|||
auto begin = desc->faces[i][0]; |
|||
auto length = desc->faces[i][1]; |
|||
std::cout << "\t\t<" << begin << ", " << length << "> : "; |
|||
for (int j = begin; j < begin + length; j++) { std::cout << desc->indexs[j] << " "; } |
|||
std::cout << std::endl; |
|||
} |
|||
break; |
|||
} |
|||
case PRIMITIVE_TYPE_EXTRUDE: { |
|||
auto desc = static_cast<extrude_descriptor_t*>(node.desc); |
|||
std::cout << "extrude:" << std::endl; |
|||
std::cout << "\tedges number: " << desc->edges_number << std::endl; |
|||
std::cout << "\textusion: "; |
|||
output_point(desc->extusion); |
|||
|
|||
std::cout << "\tpoints: " << std::endl; |
|||
for (int i = 0; i < desc->edges_number; i++) { |
|||
std::cout << "\t\t( " << desc->points[i].x << ", " << desc->points[i].y << ", " << desc->points[i].z << " )" |
|||
<< std::endl; |
|||
} |
|||
|
|||
std::cout << "\tbulges: " << std::endl; |
|||
for (int i = 0; i < desc->edges_number; i++) { std::cout << "\t\t" << desc->bulges[i] << std::endl; } |
|||
break; |
|||
} |
|||
default: { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void output_blobtree(virtual_node_t node) |
|||
{ |
|||
std::map<int, std::string> index; |
|||
index[0] = "constant"; |
|||
index[1] = "plane"; |
|||
index[2] = "sphere"; |
|||
index[3] = "cylinder"; |
|||
index[4] = "cone"; |
|||
index[5] = "box"; |
|||
index[6] = "mesh"; |
|||
index[7] = "extrude"; |
|||
|
|||
auto root = structures[node.main_index].nodes[node.inner_index]; |
|||
std::queue<node_t> now, next; |
|||
now.push(root); |
|||
|
|||
std::vector<primitive_node_t> temp; |
|||
|
|||
while (!now.empty()) { |
|||
auto begin = now.front(); |
|||
now.pop(); |
|||
|
|||
if (is_primitive_node(begin)) { |
|||
std::cout << index[primitives[node_fetch_primitive_index(begin)].type] << "\t\t"; |
|||
temp.push_back(primitives[node_fetch_primitive_index(begin)]); |
|||
} else { |
|||
auto op = (uint32_t)node_fetch_operation(begin); |
|||
if (op == 0) { |
|||
std::cout << "or" |
|||
<< "\t\t"; |
|||
} else if (op == 1) { |
|||
std::cout << "and" |
|||
<< "\t\t"; |
|||
} else if (op == 2) { |
|||
std::cout << "sub" |
|||
<< "\t\t"; |
|||
} |
|||
} |
|||
|
|||
if (!node_is_left_child_null(begin)) { |
|||
next.push(structures[node.main_index].nodes[node_fetch_left_child_index(begin)]); |
|||
} |
|||
if (!node_is_right_child_null(begin)) { |
|||
next.push(structures[node.main_index].nodes[node_fetch_right_child_index(begin)]); |
|||
} |
|||
|
|||
if (now.empty()) { |
|||
now = next; |
|||
while (!next.empty()) { next.pop(); } |
|||
std::cout << std::endl; |
|||
} |
|||
} |
|||
std::cout << std::endl; |
|||
|
|||
for (int i = 0; i < temp.size(); i++) { output_primitive_node(temp[i]); } |
|||
} |
|||
#endif // _DEBUG
|
@ -0,0 +1,130 @@ |
|||
#include "internal_api.hpp" |
|||
|
|||
#include "globals.hpp" |
|||
#include "aabb.hpp" |
|||
#include "node_operation.hpp" |
|||
|
|||
/* Geometry Generation */ |
|||
|
|||
static constexpr node_t standard_new_node = {(uint64_t)0xFFFFFFFFFFFFFFFFu, (uint64_t)0xFFFFFFFFFFFFFFFFu}; |
|||
|
|||
virtual_node_t push_primitive_node(primitive_node_t&& primitive_node, const aabb_t&& aabb) |
|||
{ |
|||
aabbs.emplace_back(aabb); |
|||
primitives.emplace_back(primitive_node); |
|||
|
|||
node_t node = standard_new_node; |
|||
node_fetch_primitive_index(node) = static_cast<uint32_t>(primitives.size() - 1); |
|||
|
|||
blobtree_t tree; |
|||
tree.nodes.emplace_back(node); |
|||
tree.leaf_index.push_back(0); |
|||
|
|||
structures.push_back(tree); |
|||
|
|||
return virtual_node_t{static_cast<uint32_t>(structures.size() - 1), 0}; |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const constant_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_CONSTANT, malloc(sizeof(constant_descriptor_t))}; |
|||
*((constant_descriptor_t*)node.desc) = std::move(desc); |
|||
|
|||
aabb_t aabb{}; |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const plane_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_PLANE, malloc(sizeof(plane_descriptor_t))}; |
|||
*((plane_descriptor_t*)node.desc) = std::move(desc); |
|||
|
|||
aabb_t aabb{}; |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const sphere_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_SPHERE, malloc(sizeof(sphere_descriptor_t))}; |
|||
|
|||
Eigen::Map<const Eigen::Vector3d> center(&desc.center.x); |
|||
|
|||
aabb_t aabb{center.array() - desc.radius, center.array() + desc.radius}; |
|||
|
|||
*((sphere_descriptor_t*)node.desc) = std::move(desc); |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const cylinder_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_CYLINDER, malloc(sizeof(cylinder_descriptor_t))}; |
|||
|
|||
// NOTE: A rough AABB bounding box
|
|||
aabb_t aabb{}; |
|||
Eigen::Map<const Eigen::Vector3d> bottom_center(&desc.bottom_origion.x), offset(&desc.offset.x); |
|||
aabb.extend(bottom_center.array() + desc.radius); |
|||
aabb.extend(bottom_center.array() - desc.radius); |
|||
aabb.extend(bottom_center.array() + offset.array() + desc.radius); |
|||
aabb.extend(bottom_center.array() + offset.array() - desc.radius); |
|||
|
|||
*((cylinder_descriptor_t*)node.desc) = std::move(desc); |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const cone_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_CONE, malloc(sizeof(cone_descriptor_t))}; |
|||
|
|||
// NOTE: A rough AABB bounding box
|
|||
aabb_t aabb{}; |
|||
Eigen::Map<const Eigen::Vector3d> top_point(&desc.top_point.x), bottom_point(&desc.bottom_point.x); |
|||
aabb.extend(top_point.array() + desc.radius1); |
|||
aabb.extend(top_point.array() - desc.radius1); |
|||
aabb.extend(bottom_point.array() + desc.radius2); |
|||
aabb.extend(bottom_point.array() - desc.radius2); |
|||
|
|||
*((cone_descriptor_t*)node.desc) = std::move(desc); |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const box_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_BOX, malloc(sizeof(box_descriptor_t))}; |
|||
|
|||
Eigen::Map<const Eigen::Vector3d> center(&desc.center.x), half_size(&desc.half_size.x); |
|||
|
|||
aabb_t aabb{center - half_size, center + half_size}; |
|||
|
|||
*((box_descriptor_t*)node.desc) = std::move(desc); |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const mesh_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_MESH, malloc(sizeof(mesh_descriptor_t))}; |
|||
|
|||
aabb_t aabb{}; |
|||
for (int i = 0; i < desc.point_number; i++) { aabb.extend(Eigen::Map<const Eigen::Vector3d>(&desc.points[i].x)); } |
|||
|
|||
*((mesh_descriptor_t*)node.desc) = std::move(desc); |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API virtual_node_t blobtree_new_virtual_node(const extrude_descriptor_t& desc) |
|||
{ |
|||
primitive_node_t node{PRIMITIVE_TYPE_EXTRUDE, malloc(sizeof(extrude_descriptor_t))}; |
|||
|
|||
aabb_t aabb{}; |
|||
Eigen::Map<const Eigen::Vector3d> e(&desc.extusion.x); |
|||
// NOTE: Currently only straight edges are considered
|
|||
for (int i = 0; i < desc.edges_number; i++) { |
|||
Eigen::Map<const Eigen::Vector3d> p(&desc.points[i].x); |
|||
aabb.extend(p); |
|||
aabb.extend(p + e); |
|||
} |
|||
|
|||
*((extrude_descriptor_t*)node.desc) = std::move(desc); |
|||
return push_primitive_node(std::move(node), std::move(aabb)); |
|||
} |
|||
|
|||
BPE_API void blobtree_free_virtual_node(virtual_node_t* node) { free_sub_blobtree(node->main_index); } |
@ -0,0 +1,159 @@ |
|||
#include "internal_api.hpp" |
|||
|
|||
#include "globals.hpp" |
|||
#include "aabb.hpp" |
|||
#include "node_operation.hpp" |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const constant_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
*((constant_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_CONSTANT; |
|||
aabbs[primitive_index] = aabb_t{}; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const plane_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
*((plane_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_PLANE; |
|||
aabbs[primitive_index] = aabb_t{}; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const sphere_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
|
|||
Eigen::Map<const Eigen::Vector3d> center(&desc.center.x); |
|||
|
|||
aabb_t aabb{center.array() - desc.radius, center.array() + desc.radius}; |
|||
|
|||
*((sphere_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_SPHERE; |
|||
aabbs[primitive_index] = std::move(aabb); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cylinder_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
|
|||
// NOTE: A rough AABB bounding box
|
|||
aabb_t aabb{}; |
|||
Eigen::Map<const Eigen::Vector3d> bottom_center(&desc.bottom_origion.x), offset(&desc.offset.x); |
|||
aabb.extend(bottom_center.array() + desc.radius); |
|||
aabb.extend(bottom_center.array() - desc.radius); |
|||
aabb.extend(bottom_center.array() + offset.array() + desc.radius); |
|||
aabb.extend(bottom_center.array() + offset.array() - desc.radius); |
|||
|
|||
*((cylinder_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_CYLINDER; |
|||
aabbs[primitive_index] = std::move(aabb); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cone_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
|
|||
// NOTE: A rough AABB bounding box
|
|||
aabb_t aabb{}; |
|||
Eigen::Map<const Eigen::Vector3d> top_point(&desc.top_point.x), bottom_point(&desc.bottom_point.x); |
|||
aabb.extend(top_point.array() + desc.radius1); |
|||
aabb.extend(top_point.array() - desc.radius1); |
|||
aabb.extend(bottom_point.array() + desc.radius2); |
|||
aabb.extend(bottom_point.array() - desc.radius2); |
|||
|
|||
*((cone_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_CONE; |
|||
aabbs[primitive_index] = std::move(aabb); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const box_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
|
|||
Eigen::Map<const Eigen::Vector3d> center(&desc.center.x), half_size(&desc.half_size.x); |
|||
|
|||
aabb_t aabb{center - half_size, center + half_size}; |
|||
|
|||
*((box_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_BOX; |
|||
aabbs[primitive_index] = std::move(aabb); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const mesh_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
|
|||
aabb_t aabb{}; |
|||
for (int i = 0; i < desc.point_number; i++) { aabb.extend(Eigen::Map<const Eigen::Vector3d>(&desc.points[i].x)); } |
|||
|
|||
*((mesh_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_MESH; |
|||
aabbs[primitive_index] = std::move(aabb); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const extrude_descriptor_t& desc) |
|||
{ |
|||
auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; |
|||
|
|||
if (!node_fetch_is_primitive(node_in_tree)) { return false; } |
|||
|
|||
const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); |
|||
|
|||
aabb_t aabb{}; |
|||
Eigen::Map<const Eigen::Vector3d> e(&desc.extusion.x); |
|||
// NOTE: Currently only straight edges are considered
|
|||
for (int i = 0; i < desc.edges_number; i++) { |
|||
Eigen::Map<const Eigen::Vector3d> p(&desc.points[i].x); |
|||
aabb.extend(p); |
|||
aabb.extend(p + e); |
|||
} |
|||
|
|||
*((extrude_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); |
|||
primitives[primitive_index].type = PRIMITIVE_TYPE_EXTRUDE; |
|||
aabbs[primitive_index] = std::move(aabb); |
|||
|
|||
return true; |
|||
} |
Loading…
Reference in new issue