33 class VSG_TEMPLATE_DECLSPEC Array3D :
public Data
46 Array3D(
const Array3D& rhs,
const CopyOp copyop = {}) :
53 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height) *
static_cast<size_t>(_depth));
57 for (
const auto& v : rhs) *(dest_v++) = v;
62 Array3D(uint32_t width, uint32_t height, uint32_t depth,
Properties in_properties = {}) :
63 Data(in_properties,
sizeof(value_type)),
69 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height) *
static_cast<size_t>(_depth));
73 Array3D(uint32_t width, uint32_t height, uint32_t depth, value_type* data,
Properties in_properties = {},
MipmapLayout* mipmapLayout =
nullptr) :
74 Data(in_properties,
sizeof(value_type)),
84 Array3D(uint32_t width, uint32_t height, uint32_t depth,
const value_type& value,
Properties in_properties = {}) :
85 Data(in_properties,
sizeof(value_type)),
91 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height) *
static_cast<size_t>(_depth));
94 for (
auto& v : *
this) v = value;
99 Array3D(
ref_ptr<Data> data, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth,
Properties in_properties = {},
MipmapLayout* mipmapLayout =
nullptr) :
106 assign(data, offset, stride, width, height, depth, in_properties, mipmapLayout);
109 template<
typename... Args>
115 template<
typename... Args>
129 size_t sizeofObject() const noexcept
override {
return sizeof(Array3D); }
130 const char* className() const noexcept
override {
return type_name<Array3D>(); }
131 const std::type_info&
type_info() const noexcept
override {
return typeid(*this); }
132 bool is_compatible(
const std::type_info& type)
const noexcept override {
return typeid(
Array3D) == type || Data::is_compatible(type); }
135 void accept(Visitor& visitor)
override;
136 void accept(ConstVisitor& visitor)
const override;
138 void read(Input& input)
override
140 size_t original_size = size();
144 uint32_t w = input.readValue<uint32_t>(
"width");
145 uint32_t h = input.readValue<uint32_t>(
"height");
146 uint32_t d = input.readValue<uint32_t>(
"depth");
148 if (
auto data_storage = input.readObject<Data>(
"storage"))
150 uint32_t offset = input.readValue<uint32_t>(
"offset");
151 assign(data_storage, offset, properties.stride, w, h, d, properties);
155 if (input.matchPropertyName(
"data"))
157 properties.stride =
sizeof(value_type);
163 size_t new_size = computeValueCountIncludingMipmaps();
167 if (original_size != new_size)
170 _data = _allocate(new_size);
175 _data = _allocate(new_size);
178 if (_data) input.read(new_size, _data);
184 void write(Output& output)
const override
188 output.writeValue<uint32_t>(
"width", _width);
189 output.writeValue<uint32_t>(
"height", _height);
190 output.writeValue<uint32_t>(
"depth", _depth);
192 output.writeObject(
"storage", _storage);
195 auto offset = (
reinterpret_cast<uintptr_t
>(_data) -
reinterpret_cast<uintptr_t
>(_storage->dataPointer()));
196 output.writeValue<uint32_t>(
"offset", offset);
200 output.writePropertyName(
"data");
201 output.write(valueCount(), _data);
202 output.writeEndOfLine();
205 size_t size()
const {
return (properties.mipLevels <= 1) ? (
static_cast<size_t>(_width) * _height * _depth) : computeValueCountIncludingMipmaps(); }
207 bool available()
const {
return _data !=
nullptr; }
208 bool empty()
const {
return _data ==
nullptr; }
221 Array3D& operator=(
const Array3D& rhs)
223 if (&rhs ==
this)
return *
this;
230 _height = rhs._height;
233 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height) *
static_cast<size_t>(_depth));
237 for (
const auto& v : rhs) *(dest_v++) = v;
245 void assign(uint32_t width, uint32_t height, uint32_t depth, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout =
nullptr)
249 properties = in_properties;
250 properties.stride =
sizeof(value_type);
257 setMipmapLayout(mipmapLayout);
262 void assign(ref_ptr<Data> storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth, Properties in_properties = {}, MipmapLayout* mipmapLayout =
nullptr)
267 properties = in_properties;
268 properties.stride = stride;
269 if (_storage && _storage->dataPointer())
271 _data =
reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_storage->dataPointer()) + offset);
284 setMipmapLayout(mipmapLayout);
291 void* dataRelease()
override
308 size_t valueSize()
const override {
return sizeof(value_type); }
309 size_t valueCount()
const override {
return size(); }
311 bool dataAvailable()
const override {
return available(); }
312 size_t dataSize()
const override {
return size() * properties.stride; }
314 void* dataPointer()
override {
return _data; }
315 const void* dataPointer()
const override {
return _data; }
317 void* dataPointer(
size_t i)
override {
return data(i); }
318 const void* dataPointer(
size_t i)
const override {
return data(i); }
320 uint32_t dimensions()
const override {
return 3; }
322 uint32_t width()
const override {
return _width; }
323 uint32_t height()
const override {
return _height; }
324 uint32_t depth()
const override {
return _depth; }
326 value_type* data() {
return _data; }
327 const value_type* data()
const {
return _data; }
329 inline value_type* data(
size_t i) {
return reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_data) + i *
static_cast<size_t>(properties.stride)); }
330 inline const value_type* data(
size_t i)
const {
return reinterpret_cast<const value_type*
>(
reinterpret_cast<const uint8_t*
>(_data) + i *
static_cast<size_t>(properties.stride)); }
332 size_t index(uint32_t i, uint32_t j, uint32_t k)
const noexcept {
return static_cast<size_t>(
static_cast<size_t>(k) *
static_cast<size_t>(_width) *
static_cast<size_t>(_height) +
static_cast<size_t>(j) *
static_cast<size_t>(_width) +
static_cast<size_t>(i)); }
334 value_type& operator[](
size_t i) {
return *data(i); }
335 const value_type& operator[](
size_t i)
const {
return *data(i); }
337 value_type& at(
size_t i) {
return *data(i); }
338 const value_type& at(
size_t i)
const {
return *data(i); }
340 value_type& operator()(uint32_t i, uint32_t j, uint32_t k) {
return *data(index(i, j, k)); }
341 const value_type& operator()(uint32_t i, uint32_t j, uint32_t k)
const {
return *data(index(i, j, k)); }
343 value_type& at(uint32_t i, uint32_t j, uint32_t k) {
return *data(index(i, j, k)); }
344 const value_type& at(uint32_t i, uint32_t j, uint32_t k)
const {
return *data(index(i, j, k)); }
346 void set(
size_t i,
const value_type& v) { *data(i) = v; }
347 void set(uint32_t i, uint32_t j, uint32_t k,
const value_type& v) { *data(index(i, j, k)) = v; }
349 Data* storage() {
return _storage; }
350 const Data* storage()
const {
return _storage; }
352 iterator begin() {
return iterator{_data, properties.stride}; }
353 const_iterator begin()
const {
return const_iterator{_data, properties.stride}; }
355 iterator end() {
return iterator{data(_width * _height * _depth), properties.stride}; }
356 const_iterator end()
const {
return const_iterator{data(_width * _height * _depth), properties.stride}; }
364 value_type* _allocate(
size_t size)
const
368 else if (properties.allocatorType == ALLOCATOR_TYPE_NEW_DELETE)
369 return new value_type[size];
370 else if (properties.allocatorType == ALLOCATOR_TYPE_MALLOC_FREE)
371 return new (std::malloc(
sizeof(value_type) * size)) value_type[size];
373 return new (vsg::allocate(
sizeof(value_type) * size, ALLOCATOR_AFFINITY_DATA)) value_type[size];
378 if (!_storage && _data)
380 if (properties.allocatorType == ALLOCATOR_TYPE_NEW_DELETE)
382 else if (properties.allocatorType == ALLOCATOR_TYPE_MALLOC_FREE)
384 else if (properties.allocatorType != 0)
385 vsg::deallocate(_data);
396 ref_ptr<Data> _storage;