chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <eigen3/Eigen/Dense>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace splat {
|
||||
class SH {
|
||||
public:
|
||||
SH() noexcept;
|
||||
SH(size_t size);
|
||||
SH(const SH& other);
|
||||
SH(SH&& other) noexcept;
|
||||
|
||||
SH& operator=(const SH& other);
|
||||
SH& operator=(SH&& other) noexcept;
|
||||
|
||||
void swap(SH& other) noexcept;
|
||||
|
||||
SH& set_zero() noexcept;
|
||||
SH& add_multiplied(const SH& other, float scalar) noexcept;
|
||||
|
||||
const float& operator[](size_t index) const;
|
||||
float& operator[](size_t index);
|
||||
|
||||
float* data() noexcept;
|
||||
size_t size() const noexcept;
|
||||
|
||||
~SH() noexcept;
|
||||
|
||||
private:
|
||||
void reset() noexcept;
|
||||
|
||||
size_t size_;
|
||||
std::unique_ptr<float[]> ptr;
|
||||
};
|
||||
|
||||
struct Gaussian {
|
||||
Eigen::Vector3f mean;
|
||||
Eigen::Vector3f scale;
|
||||
Eigen::Vector4f rotation;
|
||||
Eigen::Matrix3f covariance;
|
||||
SH sh;
|
||||
float opacity;
|
||||
Eigen::AlignedBox3f bounding_box;
|
||||
|
||||
void compute_covariance();
|
||||
void decompose_covariance();
|
||||
void compute_bounding_box(float k = 3.0f);
|
||||
float area() const;
|
||||
};
|
||||
|
||||
struct Splat {
|
||||
std::vector<Gaussian> gaussians;
|
||||
Eigen::AlignedBox3f bounding_box;
|
||||
|
||||
void compute_bounding_box();
|
||||
void compute_compact_bounding_box();
|
||||
};
|
||||
} // namespace splat
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <splat/splat.h>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace splat::block {
|
||||
namespace detail {
|
||||
std::vector<Splat> split(const Splat& splat, size_t max_block_size);
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
requires std::is_same_v<std::remove_reference_t<T>, Splat>
|
||||
std::vector<Splat> split(T&& input, double precision) {
|
||||
auto max_block_size = static_cast<size_t>(static_cast<double>(input.gaussians.size()) * precision);
|
||||
return detail::split(input, max_block_size);
|
||||
}
|
||||
} // namespace splat::block
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <container_helpers.h>
|
||||
#include <cstdint>
|
||||
#include <splat/splat.h>
|
||||
#include <vector>
|
||||
|
||||
namespace splat::lod {
|
||||
namespace detail {
|
||||
Splat reduce_gaussians(size_t id, const Splat& splat, size_t target_count, float scale_boost, size_t max_step);
|
||||
}
|
||||
|
||||
struct SplatLod {
|
||||
std::vector<Splat> splats;
|
||||
std::vector<uint32_t> levels;
|
||||
};
|
||||
|
||||
struct SplatLevelParameters {
|
||||
float precision;
|
||||
float scale_boost;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
requires requires(T) {
|
||||
requires helpers::container::range_of<T, SplatLevelParameters>;
|
||||
}
|
||||
inline void generate_lod(size_t id, SplatLod& lod, T&& parameters, size_t min_size, size_t max_step) {
|
||||
auto base_count = lod.splats.back().gaussians.size();
|
||||
for (auto& parameter : parameters) {
|
||||
auto target_count = std::max<size_t>(static_cast<size_t>(std::floor(static_cast<double>(base_count) * parameter.precision)), 1);
|
||||
auto& current = lod.splats.back();
|
||||
if (current.gaussians.size() > min_size && target_count < current.gaussians.size()) {
|
||||
auto generated = detail::reduce_gaussians(
|
||||
id,
|
||||
current,
|
||||
target_count,
|
||||
parameter.scale_boost,
|
||||
max_step);
|
||||
lod.splats.push_back(std::move(generated));
|
||||
}
|
||||
lod.levels.push_back(lod.splats.size() - 1);
|
||||
}
|
||||
}
|
||||
} // namespace splat::lod
|
||||
Reference in New Issue
Block a user