Skip to content

Commit

Permalink
Merge pull request #89 from qmuntal/simsparse
Browse files Browse the repository at this point in the history
Implement accessor sparse reading using Read helpers
  • Loading branch information
qmuntal authored Aug 29, 2024
2 parents a9e4b38 + 8926044 commit f1adfc5
Showing 1 changed file with 26 additions and 40 deletions.
66 changes: 26 additions & 40 deletions modeler/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import (
"github.com/qmuntal/gltf/binary"
)

var uint32Pool = sync.Pool{
New: func() any {
buf := make([]uint32, 100)
return &buf
},
}

// ReadAccessor returns the data references by acr as an slice
// whose element types are the ones associated with acr.ComponentType and acr.Type.
//
Expand Down Expand Up @@ -42,57 +49,36 @@ func ReadAccessor(doc *gltf.Document, acr *gltf.Accessor, buffer []byte) (any, e
}

if acr.Sparse != nil {
indicesBuffer, err := readBufferView(doc, acr.Sparse.Indices.BufferView)
bufPtr := uint32Pool.Get().(*[]uint32)
defer uint32Pool.Put(bufPtr)
indices, err := ReadIndices(doc, &gltf.Accessor{
ComponentType: acr.Sparse.Indices.ComponentType,
Count: acr.Sparse.Count,
Type: gltf.AccessorScalar,
BufferView: &acr.Sparse.Indices.BufferView,
ByteOffset: acr.Sparse.Indices.ByteOffset,
}, *bufPtr)
if err != nil {
return nil, err
}

byteStride := doc.BufferViews[acr.Sparse.Indices.BufferView].ByteStride
indices, err := binary.MakeSlice(acr.Sparse.Indices.ComponentType, gltf.AccessorScalar, acr.Sparse.Count)
if err != nil {
return nil, err
}
err = binary.Read(indicesBuffer[acr.Sparse.Indices.ByteOffset:], byteStride, indices)
if err != nil {
return nil, err
}

valuesBuffer, err := readBufferView(doc, acr.Sparse.Values.BufferView)
if err != nil {
return nil, err
}
byteStride = doc.BufferViews[acr.Sparse.Values.ByteOffset].ByteStride
values, err := binary.MakeSlice(acr.ComponentType, acr.Type, acr.Sparse.Count)
if err != nil {
return nil, err
}
err = binary.Read(valuesBuffer[acr.Sparse.Values.ByteOffset:], byteStride, values)
valuesBufPtr := bufPool.Get().(*[]byte)
defer bufPool.Put(valuesBufPtr)
values, err := ReadAccessor(doc, &gltf.Accessor{
ComponentType: acr.ComponentType,
Count: acr.Sparse.Count,
Type: acr.Type,
BufferView: &acr.Sparse.Values.BufferView,
ByteOffset: acr.Sparse.Values.ByteOffset,
}, *valuesBufPtr)
if err != nil {
return nil, err
}

s := reflect.ValueOf(data)
ind := reflect.ValueOf(indices)
vals := reflect.ValueOf(values)
for i := 0; i < int(acr.Sparse.Count); i++ {
var id int
idx := ind.Index(i)
if idx.CanInt() {
v := idx.Int()
if v < 0 || v >= int64(acr.Count) {
return nil, fmt.Errorf("gltf: sparse accessor index '%d' out of range: %d", i, v)
}
id = int(v)
} else if idx.CanUint() {
v := idx.Uint()
if v >= uint64(acr.Count) {
return nil, fmt.Errorf("gltf: sparse accessor index '%d' out of range: %d", i, v)
}
id = int(v)
} else {
return nil, fmt.Errorf("gltf: sparse accessor index '%d' is not an integer", i)
}
s.Index(id).Set(vals.Index(i))
s.Index(int(indices[i])).Set(vals.Index(i))
}
}
return data, nil
Expand Down

0 comments on commit f1adfc5

Please sign in to comment.