5 changed files with 462 additions and 140 deletions
@ -0,0 +1,84 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <core.h> |
||||
|
|
||||
|
#include <vector> |
||||
|
#include <cassert> |
||||
|
|
||||
|
|
||||
|
template<typename TScalar, typename TIndex> |
||||
|
class GenericMesh { |
||||
|
public: |
||||
|
using Scalar = TScalar; |
||||
|
using Index = TIndex; |
||||
|
using Vector = Eigen::Matrix<Scalar, 3, 1>; |
||||
|
|
||||
|
public: |
||||
|
GenericMesh() = default; |
||||
|
GenericMesh(const GenericMesh&) = delete; |
||||
|
GenericMesh(GenericMesh&&) = default; |
||||
|
~GenericMesh() = default; |
||||
|
|
||||
|
GenericMesh& operator=(const GenericMesh&) = delete; |
||||
|
GenericMesh& operator=(GenericMesh&&) = default; |
||||
|
|
||||
|
inline size_t vertexCount() const { |
||||
|
return m_positions.size(); |
||||
|
} |
||||
|
inline size_t indexCount() const { |
||||
|
return m_indices.size(); |
||||
|
} |
||||
|
|
||||
|
inline void resizeVertex(Index vertexCount) { |
||||
|
m_positions.resize(vertexCount); |
||||
|
} |
||||
|
inline void resizeIndices(Index indexCount) { |
||||
|
m_indices.resize(indexCount); |
||||
|
} |
||||
|
|
||||
|
inline const Vector& position(Index vertexIndex) const { |
||||
|
assert(vertexIndex < m_positions.size()); |
||||
|
return m_positions[vertexIndex]; |
||||
|
} |
||||
|
inline Vector& position(Index vertexIndex) { |
||||
|
assert(vertexIndex < m_positions.size()); |
||||
|
return m_positions[vertexIndex]; |
||||
|
} |
||||
|
|
||||
|
inline Index index(Index indexIndex) const { |
||||
|
assert(indexIndex < m_indices.size()); |
||||
|
return m_indices[indexIndex]; |
||||
|
} |
||||
|
inline Index& index(Index indexIndex) { |
||||
|
assert(indexIndex < m_indices.size()); |
||||
|
return m_indices[indexIndex]; |
||||
|
} |
||||
|
|
||||
|
inline const Vector* positionData() const { |
||||
|
return m_positions.data(); |
||||
|
} |
||||
|
inline Vector* positionData() { |
||||
|
return m_positions.data(); |
||||
|
} |
||||
|
|
||||
|
inline const Index* indexData() const { |
||||
|
return m_indices.data(); |
||||
|
} |
||||
|
inline Index* indexData() { |
||||
|
return m_indices.data(); |
||||
|
} |
||||
|
|
||||
|
inline const std::vector<Vector>& positions() const { |
||||
|
return m_positions; |
||||
|
} |
||||
|
|
||||
|
inline const std::vector<Index>& indices() const { |
||||
|
return m_indices; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
std::vector<Vector> m_positions; |
||||
|
std::vector<Index> m_indices; |
||||
|
}; |
||||
|
|
||||
|
using Mesh = GenericMesh<Real, uint32_t>; |
||||
@ -0,0 +1,105 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
|
||||
|
#include <Eigen/Dense> |
||||
|
|
||||
|
#include <type_traits> |
||||
|
|
||||
|
|
||||
|
using Byte = unsigned char; |
||||
|
using Index = uint32_t; |
||||
|
using Real = float; |
||||
|
using Vector3 = Eigen::Matrix<Real, 3, 1>; |
||||
|
|
||||
|
|
||||
|
template<typename Scalar, typename Derived0, typename Derived1> |
||||
|
auto lerp( |
||||
|
Scalar factor, |
||||
|
const Eigen::MatrixBase<Derived0>& m0, |
||||
|
const Eigen::MatrixBase<Derived1>& m1 |
||||
|
) -> std::enable_if_t< |
||||
|
Derived0::RowsAtCompileTime == Derived1::RowsAtCompileTime && |
||||
|
Derived0::ColsAtCompileTime == Derived1::ColsAtCompileTime, |
||||
|
Eigen::Matrix< |
||||
|
std::common_type_t< |
||||
|
Scalar, |
||||
|
typename Derived0::Scalar, |
||||
|
typename Derived1::Scalar |
||||
|
>, |
||||
|
Derived0::RowsAtCompileTime, |
||||
|
Derived0::ColsAtCompileTime |
||||
|
> |
||||
|
> { |
||||
|
return (Scalar(1) - factor) * m0 + factor * m1; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template<typename T> |
||||
|
class ArrayView { |
||||
|
public: |
||||
|
ArrayView() = default; |
||||
|
ArrayView(const ArrayView&) = default; |
||||
|
ArrayView(ArrayView&&) = default; |
||||
|
~ArrayView() = default; |
||||
|
|
||||
|
template<typename U> |
||||
|
ArrayView(Index size, U* data, Index stride=sizeof(T)) |
||||
|
: m_data(reinterpret_cast<Byte*>(data)) |
||||
|
, m_size(size) |
||||
|
, m_stride(stride) |
||||
|
{ |
||||
|
assert(m_data != nullptr || m_size == 0); |
||||
|
} |
||||
|
|
||||
|
explicit ArrayView(std::vector<T>& vector) |
||||
|
: m_data(vector.data()) |
||||
|
, m_data(vector.size()) |
||||
|
{} |
||||
|
|
||||
|
ArrayView& operator=(const ArrayView&) = default; |
||||
|
ArrayView& operator=(ArrayView&&) = default; |
||||
|
|
||||
|
explicit operator bool() const { |
||||
|
return m_size != 0; |
||||
|
} |
||||
|
|
||||
|
Index size() const { |
||||
|
return m_size; |
||||
|
} |
||||
|
|
||||
|
Index stride() const { |
||||
|
return m_stride; |
||||
|
} |
||||
|
|
||||
|
const T* data() const { |
||||
|
return m_data; |
||||
|
} |
||||
|
|
||||
|
T* data() { |
||||
|
return m_data; |
||||
|
} |
||||
|
|
||||
|
const T& operator[](Index index) const { |
||||
|
assert(index < m_size); |
||||
|
return *reinterpret_cast<T*>(m_data + index * m_stride); |
||||
|
} |
||||
|
|
||||
|
T& operator[](Index index) { |
||||
|
return const_cast<T&>(const_cast<ArrayView&>(*this)[index]); |
||||
|
} |
||||
|
|
||||
|
ArrayView slice(Index start, Index count, Index step=1) { |
||||
|
assert(step > 0); |
||||
|
assert(start + count * step < m_size); |
||||
|
return ArrayView( |
||||
|
count, |
||||
|
m_data + start * m_stride, |
||||
|
m_stride * step |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
Byte* m_data = nullptr; |
||||
|
Index m_size = 0; |
||||
|
Index m_stride = sizeof(T); |
||||
|
}; |
||||
Loading…
Reference in new issue