Skip to content

Commit aed1fc5

Browse files
authored
Merge pull request #92 from qmuntal/invmatrix
Implement inverse bind matrices reader and writer
2 parents 19bcd97 + 6347d9a commit aed1fc5

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

modeler/read.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,27 @@ func ReadColor64(doc *gltf.Document, acr *gltf.Accessor, buffer [][4]uint16) ([]
453453
return buffer, nil
454454
}
455455

456+
// ReadInverseBindMatrices returns the data referenced by acr.
457+
//
458+
// See ReadAccessor for more info.
459+
func ReadInverseBindMatrices(doc *gltf.Document, acr *gltf.Accessor, buffer [][4][4]float32) ([][4][4]float32, error) {
460+
if acr.ComponentType != gltf.ComponentFloat {
461+
return nil, errComponentType(acr.ComponentType)
462+
}
463+
if acr.Type != gltf.AccessorMat4 {
464+
return nil, errAccessorType(acr.Type)
465+
}
466+
bufPtr := bufPool.Get().(*[]byte)
467+
defer bufPool.Put(bufPtr)
468+
data, err := ReadAccessor(doc, acr, *bufPtr)
469+
if err != nil {
470+
return nil, err
471+
}
472+
buffer = makeBufferOf(acr.Count, buffer)
473+
copy(buffer, data.([][4][4]float32))
474+
return buffer, nil
475+
}
476+
456477
func errAccessorType(tp gltf.AccessorType) error {
457478
return fmt.Errorf("gltf: accessor type %v not allowed", tp)
458479
}

modeler/read_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,3 +694,53 @@ func TestReadColor64(t *testing.T) {
694694
})
695695
}
696696
}
697+
698+
func TestReadInverseBindMatrices(t *testing.T) {
699+
type args struct {
700+
data []byte
701+
acr *gltf.Accessor
702+
buffer [][4][4]float32
703+
}
704+
tests := []struct {
705+
name string
706+
args args
707+
want [][4][4]float32
708+
wantErr bool
709+
}{
710+
{"base", args{[]byte{
711+
0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
712+
0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
713+
0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
714+
0, 0, 128, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
715+
}, &gltf.Accessor{BufferView: gltf.Index(0), Count: 1, Type: gltf.AccessorMat4, ComponentType: gltf.ComponentFloat}, nil},
716+
[][4][4]float32{{{1, 2, 3, 4}}}, false,
717+
},
718+
{"incorrect-type", args{[]byte{}, &gltf.Accessor{
719+
BufferView: gltf.Index(0), Type: gltf.AccessorMat2, ComponentType: gltf.ComponentFloat,
720+
}, nil}, nil, true},
721+
{"incorrect-componenttype", args{[]byte{}, &gltf.Accessor{
722+
BufferView: gltf.Index(0), Type: gltf.AccessorMat4, ComponentType: gltf.ComponentByte,
723+
}, nil}, nil, true},
724+
}
725+
for _, tt := range tests {
726+
t.Run(tt.name, func(t *testing.T) {
727+
doc := &gltf.Document{
728+
BufferViews: []*gltf.BufferView{
729+
{Buffer: 0, ByteLength: len(tt.args.data)},
730+
},
731+
Buffers: []*gltf.Buffer{
732+
{Data: tt.args.data, ByteLength: len(tt.args.data)},
733+
},
734+
}
735+
got, err := modeler.ReadInverseBindMatrices(doc, tt.args.acr, tt.args.buffer)
736+
if (err != nil) != tt.wantErr {
737+
t.Errorf("ReadInverseBindMatrices() error = %v, wantErr %v", err, tt.wantErr)
738+
return
739+
}
740+
if !reflect.DeepEqual(got, tt.want) {
741+
t.Errorf("ReadInverseBindMatrices() = %v, want %v", got, tt.want)
742+
}
743+
})
744+
}
745+
746+
}

modeler/write.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ func WriteJoints(doc *gltf.Document, data any) int {
102102
return WriteAccessor(doc, gltf.TargetArrayBuffer, data)
103103
}
104104

105+
// WriteInverseBindMatrices adds a new inverse bind matrices accessor to doc
106+
// and fills the last buffer with data.
107+
// If success it returns the index of the new accessor.
108+
func WriteInverseBindMatrices(doc *gltf.Document, data [][4][4]float32) int {
109+
return WriteAccessor(doc, gltf.TargetArrayBuffer, data)
110+
}
111+
105112
func checkJoints(data any) error {
106113
switch data.(type) {
107114
case [][4]uint8, [][4]uint16:

modeler/write_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,49 @@ func TestWriteImage(t *testing.T) {
733733
}
734734
}
735735

736+
func TestWriteInverseBindMatrices(t *testing.T) {
737+
tests := []struct {
738+
name string
739+
m *gltf.Document
740+
args [][4][4]float32
741+
want int
742+
wantDoc *gltf.Document
743+
}{
744+
{"base", &gltf.Document{
745+
Accessors: []*gltf.Accessor{{}},
746+
}, [][4][4]float32{{{1, 2, 3, 4}}}, 1, &gltf.Document{
747+
Accessors: []*gltf.Accessor{
748+
{},
749+
{BufferView: gltf.Index(0), Count: 1, Type: gltf.AccessorMat4, ComponentType: gltf.ComponentFloat},
750+
},
751+
BufferViews: []*gltf.BufferView{
752+
{ByteLength: 64, Target: gltf.TargetArrayBuffer},
753+
},
754+
Buffers: []*gltf.Buffer{
755+
{ByteLength: 64, Data: []byte{
756+
0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
757+
0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
758+
0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
759+
0, 0, 128, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
760+
}},
761+
},
762+
}},
763+
}
764+
for _, tt := range tests {
765+
t.Run(tt.name, func(t *testing.T) {
766+
got := modeler.WriteInverseBindMatrices(tt.m, tt.args)
767+
if tt.want != got {
768+
t.Errorf("WriteInverseBindMatrices() = %v, want %v", got, tt.want)
769+
return
770+
}
771+
if diff := deep.Equal(tt.m, tt.wantDoc); diff != nil {
772+
t.Errorf("WriteInverseBindMatrices() = %v", diff)
773+
return
774+
}
775+
})
776+
}
777+
}
778+
736779
type errReader struct{}
737780

738781
func (r *errReader) Read(p []byte) (int, error) {

0 commit comments

Comments
 (0)