|
@@ -551,52 +551,96 @@ inline void BufferView::Read(Value &obj, Asset &r) {
|
|
|
}
|
|
|
|
|
|
//
|
|
|
-// struct Accessor
|
|
|
+// struct BufferViewClient
|
|
|
//
|
|
|
|
|
|
-inline void Accessor::Read(Value &obj, Asset &r) {
|
|
|
+inline uint8_t *BufferViewClient::GetPointer() {
|
|
|
+ if (!bufferView || !bufferView->buffer) return 0;
|
|
|
+ uint8_t *basePtr = bufferView->buffer->GetPointer();
|
|
|
+ if (!basePtr) return 0;
|
|
|
+
|
|
|
+ size_t offset = byteOffset + bufferView->byteOffset;
|
|
|
+
|
|
|
+ // Check if region is encoded.
|
|
|
+ if (bufferView->buffer->EncodedRegion_Current != nullptr) {
|
|
|
+ const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
|
|
|
+ const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;
|
|
|
+
|
|
|
+ if ((offset >= begin) && (offset < end))
|
|
|
+ return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
|
|
|
+ }
|
|
|
+
|
|
|
+ return basePtr + offset;
|
|
|
+}
|
|
|
+
|
|
|
+inline void BufferViewClient::Read(Value &obj, Asset &r) {
|
|
|
|
|
|
if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
|
|
|
bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
|
|
|
}
|
|
|
|
|
|
byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
|
|
|
- componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
|
|
|
- count = MemberOrDefault(obj, "count", size_t(0));
|
|
|
-
|
|
|
- const char *typestr;
|
|
|
- type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
|
|
|
}
|
|
|
|
|
|
-inline unsigned int Accessor::GetNumComponents() {
|
|
|
- return AttribType::GetNumComponents(type);
|
|
|
-}
|
|
|
+//
|
|
|
+// struct ComponentTypedBufferViewClient
|
|
|
+//
|
|
|
|
|
|
-inline unsigned int Accessor::GetBytesPerComponent() {
|
|
|
+inline unsigned int ComponentTypedBufferViewClient::GetBytesPerComponent() {
|
|
|
return int(ComponentTypeSize(componentType));
|
|
|
}
|
|
|
|
|
|
-inline unsigned int Accessor::GetElementSize() {
|
|
|
- return GetNumComponents() * GetBytesPerComponent();
|
|
|
+inline void ComponentTypedBufferViewClient::Read(Value &obj, Asset &r) {
|
|
|
+
|
|
|
+ BufferViewClient::Read(obj, r);
|
|
|
+
|
|
|
+ componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
|
|
|
}
|
|
|
|
|
|
+//
|
|
|
+// struct Accessor
|
|
|
+//
|
|
|
+
|
|
|
inline uint8_t *Accessor::GetPointer() {
|
|
|
- if (!bufferView || !bufferView->buffer) return 0;
|
|
|
- uint8_t *basePtr = bufferView->buffer->GetPointer();
|
|
|
- if (!basePtr) return 0;
|
|
|
+ if (!sparse) return BufferViewClient::GetPointer();
|
|
|
|
|
|
- size_t offset = byteOffset + bufferView->byteOffset;
|
|
|
+ return sparse->data.data();
|
|
|
+}
|
|
|
|
|
|
- // Check if region is encoded.
|
|
|
- if (bufferView->buffer->EncodedRegion_Current != nullptr) {
|
|
|
- const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
|
|
|
- const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;
|
|
|
+inline void Accessor::Read(Value &obj, Asset &r) {
|
|
|
|
|
|
- if ((offset >= begin) && (offset < end))
|
|
|
- return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
|
|
|
+ ComponentTypedBufferViewClient::Read(obj, r);
|
|
|
+
|
|
|
+ count = MemberOrDefault(obj, "count", size_t(0));
|
|
|
+
|
|
|
+ const char *typestr;
|
|
|
+ type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
|
|
|
+
|
|
|
+ if (Value *sparseValue = FindObject(obj, "sparse")) {
|
|
|
+ sparse.reset(new Sparse);
|
|
|
+ ReadMember(*sparseValue, "count", sparse->count);
|
|
|
+
|
|
|
+ if (Value *indicesValue = FindObject(*sparseValue, "indices")) {
|
|
|
+ sparse->indices.Read(*indicesValue, r);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Value *valuesValue = FindObject(*sparseValue, "values")) {
|
|
|
+ sparse->values.Read(*valuesValue, r);
|
|
|
+ }
|
|
|
+
|
|
|
+ const unsigned int elementSize = GetElementSize();
|
|
|
+ const size_t dataSize = count * elementSize;
|
|
|
+ sparse->PopulateData(dataSize, BufferViewClient::GetPointer());
|
|
|
+ sparse->PatchData(elementSize);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- return basePtr + offset;
|
|
|
+inline unsigned int Accessor::GetNumComponents() {
|
|
|
+ return AttribType::GetNumComponents(type);
|
|
|
+}
|
|
|
+
|
|
|
+inline unsigned int Accessor::GetElementSize() {
|
|
|
+ return GetNumComponents() * GetBytesPerComponent();
|
|
|
}
|
|
|
|
|
|
namespace {
|
|
@@ -635,7 +679,7 @@ void Accessor::ExtractData(T *&outData)
|
|
|
const size_t targetElemSize = sizeof(T);
|
|
|
ai_assert(elemSize <= targetElemSize);
|
|
|
|
|
|
- ai_assert(count * stride <= bufferView->byteLength);
|
|
|
+ ai_assert(count * stride <= (bufferView ? bufferView->byteLength : sparse->data.size()));
|
|
|
|
|
|
outData = new T[count];
|
|
|
if (stride == elemSize && targetElemSize == elemSize) {
|