Skip to content

Instantly share code, notes, and snippets.

@eugeneko
Created May 15, 2018 20:34
Show Gist options
  • Save eugeneko/2ecb140556ee2e94eff4a983ebf16426 to your computer and use it in GitHub Desktop.
Save eugeneko/2ecb140556ee2e94eff4a983ebf16426 to your computer and use it in GitHub Desktop.
Tried to make DOD octree. Dropped this idea.
struct FlatOctant
{
static const unsigned NUM_OCTANTS = 8;
IntVector3 index_;
BoundingBox boundingBox_;
SceneProcessorDrawableSoA data_;
Vector<FlatOctant> children_;
unsigned numActiveChildren_ = 0;
bool HasChildren() const { return data_.size_ == 0; }
bool IsSubdivided() const { return !children_.Empty(); }
void Subdivide()
{
const Vector3 center = boundingBox_.Center();
children_.Resize(NUM_OCTANTS);
for (unsigned i = 0; i < NUM_OCTANTS; ++i)
{
FlatOctant& child = children_[i];
child.index_ = IntVector3(i & 1u, i & 2u, i & 4u);
child.boundingBox_.min_ = boundingBox_.min_;
child.boundingBox_.max_ = boundingBox_.max_;
if (child.index_.x_)
child.boundingBox_.min_.x_ = center.x_;
else
child.boundingBox_.max_.x_ = center.x_;
if (child.index_.y_)
child.boundingBox_.min_.y_ = center.y_;
else
child.boundingBox_.max_.y_ = center.y_;
if (child.index_.z_)
child.boundingBox_.min_.z_ = center.z_;
else
child.boundingBox_.max_.z_ = center.z_;
}
}
void Rebalance(unsigned threshold, Vector<bool>& tempObjectsMask)
{
const unsigned effectiveThreshold = (threshold * (NUM_OCTANTS - numActiveChildren_) - 1) / NUM_OCTANTS + 1;
Rebalance(effectiveThreshold, threshold / NUM_OCTANTS, threshold / NUM_OCTANTS / 2, tempObjectsMask);
}
void Rebalance(unsigned subdivisionThreshold, unsigned childCreationThreshold, unsigned childCollapseThreshold,
Vector<bool>& tempObjectsMask)
{
if (data_.size_ < subdivisionThreshold || numActiveChildren_ == NUM_OCTANTS)
return;
// Subdivide if needed
if (!IsSubdivided())
Subdivide();
// For each chunk, check whether to collapse
tempObjectsMask.Resize(data_.size_);
for (unsigned i = 0; i < NUM_OCTANTS; ++i)
{
// Skip already initialized children
FlatOctant& child = children_[i];
if (child.HasChildren())
continue;
for ()
{
}
}
}
bool IsInside(const BoundingBox& boundingBox) const
{
return boundingBox_.IsInsideFast(boundingBox) == INSIDE;
}
};
class FlatOctree
{
public:
void Reset(float rootOctantSize, const BoundingBox& volume)
{
rootOctantSize_ = rootOctantSize;
const IntVector3 beginOctant = VectorCeilToInt(volume.min_ / rootOctantSize_);
const IntVector3 endOctant = VectorCeilToInt(volume.max_ / rootOctantSize_);
const IntVector3 numOctants3 = endOctant - beginOctant + IntVector3::ONE;
const unsigned numOctants = static_cast<unsigned>(numOctants3.x_ * numOctants3.y_ * numOctants3.z_);
// Initialize octants
rootOctants_.Resize(numOctants);
unsigned index = 0;
for (int x = beginOctant.x_; x <= endOctant.x_; ++x)
{
for (int y = beginOctant.y_; y <= endOctant.y_; ++y)
{
for (int z = beginOctant.z_; z <= endOctant.z_; ++z)
{
FlatOctant& octant = rootOctants_[index];
octant.index_ = IntVector3(x, y, z);
octant.boundingBox_.min_ = Vector3(x, y, z) * rootOctantSize_;
octant.boundingBox_.max_ = octant.boundingBox_.min_ + Vector3::ONE * rootOctantSize_;
++index;
}
}
}
}
/// Update or add drawable.
void UpdateDrawable(Drawable* drawable)
{
const BoundingBox& boundingBox = drawable->GetWorldBoundingBox();
}
private:
float rootOctantSize_;
FlatOctant defaultOctant_;
Vector<FlatOctant> rootOctants_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment