15 #include <vsg/core/Data.h>
17 #include <vsg/maths/mat4.h>
18 #include <vsg/maths/vec2.h>
19 #include <vsg/maths/vec3.h>
20 #include <vsg/maths/vec4.h>
22 #include <vsg/io/Input.h>
23 #include <vsg/io/Output.h>
25 #define VSG_array3D(N, T) \
26 using N = Array3D<T>; \
28 constexpr const char* type_name<N>() noexcept { return "vsg::" #N; }
53 if (_width != 0 && _height != 0 && _depth != 0)
55 _data = _allocate(_width * _height * _depth);
57 for (
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)),
64 _data(_allocate(width * height * depth)),
72 Array3D(uint32_t width, uint32_t height, uint32_t depth, value_type* data,
Properties in_properties = {}) :
73 Data(in_properties,
sizeof(value_type)),
77 _depth(depth) {
dirty(); }
79 Array3D(uint32_t width, uint32_t height, uint32_t depth,
const value_type& value,
Properties in_properties = {}) :
80 Data(in_properties,
sizeof(value_type)),
81 _data(_allocate(width * height * depth)),
86 for (
auto& v : *
this) v = value;
97 assign(data, offset, stride, width, height, depth, in_properties);
100 template<
typename... Args>
111 size_t sizeofObject()
const noexcept
override {
return sizeof(
Array3D); }
112 const char* className()
const noexcept
override {
return type_name<Array3D>(); }
113 const std::type_info&
type_info() const noexcept
override {
return typeid(*this); }
114 bool is_compatible(
const std::type_info& type)
const noexcept
override {
return typeid(
Array3D) == type || Data::is_compatible(type); }
117 void accept(Visitor& visitor)
override;
118 void accept(ConstVisitor& visitor)
const override;
120 void read(Input& input)
override
122 size_t original_size = size();
126 uint32_t w = input.readValue<uint32_t>(
"width");
127 uint32_t h = input.readValue<uint32_t>(
"height");
128 uint32_t d = input.readValue<uint32_t>(
"depth");
130 if (
auto data_storage = input.readObject<Data>(
"storage"))
132 uint32_t offset = input.readValue<uint32_t>(
"offset");
137 if (input.matchPropertyName(
"data"))
139 size_t new_size = computeValueCountIncludingMipmaps(w, h, d,
properties.maxNumMipmaps);
143 if (original_size != new_size)
146 _data = _allocate(new_size);
151 _data = _allocate(new_size);
160 if (_data) input.read(new_size, _data);
166 void write(Output& output)
const override
170 output.writeValue<uint32_t>(
"width", _width);
171 output.writeValue<uint32_t>(
"height", _height);
172 output.writeValue<uint32_t>(
"depth", _depth);
174 output.writeObject(
"storage", _storage);
177 auto offset = (
reinterpret_cast<uintptr_t
>(_data) -
reinterpret_cast<uintptr_t
>(_storage->dataPointer()));
178 output.writeValue<uint32_t>(
"offset", offset);
182 output.writePropertyName(
"data");
183 output.write(valueCount(), _data);
184 output.writeEndOfLine();
187 size_t size()
const {
return (
properties.maxNumMipmaps <= 1) ? (
static_cast<size_t>(_width) * _height * _depth) : computeValueCountIncludingMipmaps(_width, _height, _depth,
properties.maxNumMipmaps); }
189 bool available()
const {
return _data !=
nullptr; }
190 bool empty()
const {
return _data ==
nullptr; }
203 Array3D& operator=(
const Array3D& rhs)
205 if (&rhs ==
this)
return *
this;
211 _height = rhs._height;
214 if (_width != 0 && _height != 0 && _depth != 0)
216 _data = _allocate(_width * _height * _depth);
218 for (
auto& v : rhs) *(dest_v++) = v;
226 void assign(uint32_t width, uint32_t height, uint32_t depth, value_type* data, Properties in_properties = {})
241 void assign(ref_ptr<Data> storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth, Properties in_properties = {})
248 if (_storage && _storage->dataPointer())
250 _data =
reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_storage->dataPointer()) + offset);
268 void* dataRelease()
override
285 size_t valueSize()
const override {
return sizeof(value_type); }
286 size_t valueCount()
const override {
return size(); }
288 bool dataAvailable()
const override {
return available(); }
289 size_t dataSize()
const override {
return size() *
properties.stride; }
291 void* dataPointer()
override {
return _data; }
292 const void* dataPointer()
const override {
return _data; }
294 void* dataPointer(
size_t i)
override {
return data(i); }
295 const void* dataPointer(
size_t i)
const override {
return data(i); }
297 uint32_t dimensions()
const override {
return 3; }
299 uint32_t width()
const override {
return _width; }
300 uint32_t height()
const override {
return _height; }
301 uint32_t depth()
const override {
return _depth; }
303 value_type* data() {
return _data; }
304 const value_type* data()
const {
return _data; }
306 inline value_type* data(
size_t i) {
return reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_data) + i *
properties.stride); }
307 inline const value_type* data(
size_t i)
const {
return reinterpret_cast<const value_type*
>(
reinterpret_cast<const uint8_t*
>(_data) + i *
properties.stride); }
309 size_t index(uint32_t i, uint32_t j, uint32_t k)
const noexcept {
return static_cast<size_t>(k * _width * _height + j * _width + i); }
311 value_type& operator[](
size_t i) {
return *data(i); }
312 const value_type& operator[](
size_t i)
const {
return *data(i); }
314 value_type& at(
size_t i) {
return *data(i); }
315 const value_type& at(
size_t i)
const {
return *data(i); }
317 value_type& operator()(uint32_t i, uint32_t j, uint32_t k) {
return *data(index(i, j, k)); }
318 const value_type& operator()(uint32_t i, uint32_t j, uint32_t k)
const {
return *data(index(i, j, k)); }
320 value_type& at(uint32_t i, uint32_t j, uint32_t k) {
return *data(index(i, j, k)); }
321 const value_type& at(uint32_t i, uint32_t j, uint32_t k)
const {
return *data(index(i, j, k)); }
323 void set(
size_t i,
const value_type& v) { *data(i) = v; }
324 void set(uint32_t i, uint32_t j, uint32_t k,
const value_type& v) { *data(index(i, j, k)) = v; }
326 Data* storage() {
return _storage; }
327 const Data* storage()
const {
return _storage; }
329 iterator begin() {
return iterator{_data,
properties.stride}; }
330 const_iterator begin()
const {
return const_iterator{_data,
properties.stride}; }
332 iterator end() {
return iterator{data(_width * _height * _depth),
properties.stride}; }
333 const_iterator end()
const {
return const_iterator{data(_width * _height * _depth),
properties.stride}; }
341 value_type* _allocate(
size_t size)
const
346 return new value_type[size];
348 return new (std::malloc(
sizeof(value_type) * size)) value_type[size];
350 return new (vsg::allocate(
sizeof(value_type) * size, ALLOCATOR_AFFINITY_DATA)) value_type[size];
355 if (!_storage && _data)
362 vsg::deallocate(_data);
371 ref_ptr<Data> _storage;
374 VSG_array3D(byteArray3D, int8_t);
375 VSG_array3D(ubyteArray3D, uint8_t);
376 VSG_array3D(shortArray3D, int16_t);
377 VSG_array3D(ushortArray3D, uint16_t);
378 VSG_array3D(intArray3D, int32_t);
379 VSG_array3D(uintArray3D, uint32_t);
380 VSG_array3D(floatArray3D,
float);
381 VSG_array3D(doubleArray3D,
double);
383 VSG_array3D(vec2Array3D, vec2);
384 VSG_array3D(vec3Array3D, vec3);
385 VSG_array3D(vec4Array3D, vec4);
387 VSG_array3D(dvec2Array3D, dvec2);
388 VSG_array3D(dvec3Array3D, dvec3);
389 VSG_array3D(dvec4Array3D, dvec4);
391 VSG_array3D(ubvec2Array3D, ubvec2);
392 VSG_array3D(ubvec3Array3D, ubvec3);
393 VSG_array3D(ubvec4Array3D, ubvec4);
395 VSG_array3D(block64Array3D, block64);
396 VSG_array3D(block128Array3D, block128);
const std::type_info & type_info() const noexcept override
return the std::type_info of this Object
Definition: Array3D.h:113
Properties properties
properties of the data such as format, origin, stride, dataVariance etc.
Definition: Data.h:161
void dirty()
increment the ModifiedCount to signify the data has been modified
Definition: Data.h:196
AllocatorType allocatorType
hint as to how the data values may change during the lifetime of the vsg::Data.
Definition: Data.h:131