Skip to content

Commit

Permalink
Readd tex deduplication by value
Browse files Browse the repository at this point in the history
  • Loading branch information
alexykot committed Dec 17, 2024
1 parent 0f69f45 commit 6f807f5
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 64 deletions.
16 changes: 8 additions & 8 deletions formats/gltf/extensions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ func TestMaterialExtension_ToExtensionData(t *testing.T) {
extension: gltf.PolyformPbrSpecularGlossiness{
DiffuseFactor: color.Black,
SpecularFactor: color.White,
DiffuseTexture: &gltf.PolyformTexture{},
DiffuseTexture: &gltf.PolyformTexture{URI: "DiffuseTexture.png"},
GlossinessFactor: pointer(.5),
SpecularGlossinessTexture: &gltf.PolyformTexture{},
SpecularGlossinessTexture: &gltf.PolyformTexture{URI: "SpecularGlossinessTexture.png"},
},
want: map[string]any{
"diffuseFactor": [4]float64{0., 0., 0., 1.},
Expand Down Expand Up @@ -238,11 +238,11 @@ func TestMaterialExtension_ToExtensionData(t *testing.T) {
"Iridescence/everything": {
extension: gltf.PolyformIridescence{
IridescenceFactor: 1,
IridescenceTexture: &gltf.PolyformTexture{},
IridescenceTexture: &gltf.PolyformTexture{URI: "IridescenceTexture.png"},
IridescenceIor: pointer(1.),
IridescenceThicknessMinimum: pointer(1.),
IridescenceThicknessMaximum: pointer(1.),
IridescenceThicknessTexture: &gltf.PolyformTexture{},
IridescenceThicknessTexture: &gltf.PolyformTexture{URI: "IridescenceThicknessTexture.png"},
},
want: map[string]any{
"iridescenceFactor": 1.,
Expand Down Expand Up @@ -289,8 +289,8 @@ func TestMaterialExtension_ToExtensionData(t *testing.T) {
"Sheen/everything": {
extension: gltf.PolyformSheen{
SheenRoughnessFactor: 1,
SheenRoughnessTexture: &gltf.PolyformTexture{},
SheenColorTexture: &gltf.PolyformTexture{},
SheenRoughnessTexture: &gltf.PolyformTexture{URI: "SheenRoughnessTexture.png"},
SheenColorTexture: &gltf.PolyformTexture{URI: "SheenColorTexture.png"},
SheenColorFactor: color.White,
},
want: map[string]any{
Expand Down Expand Up @@ -447,9 +447,9 @@ func TestMaterialExtension_ToExtensionData(t *testing.T) {
"Specular/everything": {
extension: gltf.PolyformSpecular{
Factor: pointer(1.),
Texture: &gltf.PolyformTexture{},
Texture: &gltf.PolyformTexture{URI: "Texture.png"},
ColorFactor: color.White,
ColorTexture: &gltf.PolyformTexture{},
ColorTexture: &gltf.PolyformTexture{URI: "ColorTexture.png"},
},
want: map[string]any{
"specularFactor": 1.0,
Expand Down
29 changes: 29 additions & 0 deletions formats/gltf/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,35 @@ type PolyformTexture struct {
Extensions []TextureExtension
}

func (pm *PolyformTexture) prepareExtensions(w *Writer) (map[string]any, map[string]any) {
var texInfoExt map[string]any
var texExt map[string]any

for _, ext := range pm.Extensions {
id := ext.ExtensionID()
if ext.IsInfo() {
if texInfoExt == nil {
texInfoExt = make(map[string]any)
}

texInfoExt[id] = ext.ToTextureExtensionData(w)
} else {
if texExt == nil {
texExt = make(map[string]any)
}

texExt[id] = ext.ToTextureExtensionData(w)
}

w.extensionsUsed[id] = true
if ext.IsRequired() {
w.extensionsRequired[id] = true
}
}

return texExt, texInfoExt
}

func (pm *PolyformMaterial) equal(other *PolyformMaterial) bool {
if pm == other {
return true
Expand Down
3 changes: 0 additions & 3 deletions formats/gltf/model_trackers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,5 @@ type meshEntry struct {
// materialIndices handle deduplication of GLTF materials
type meshIndices map[meshEntry]int

// samplerIndices handle deduplication of texture samplers
type samplerIndices map[*Sampler]int

// textureIndices handle deduplication of textures
type textureIndices map[*PolyformTexture]int
47 changes: 47 additions & 0 deletions formats/gltf/sampler.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,50 @@ type Sampler struct {
WrapS SamplerWrap `json:"wrapS,omitempty"` // S (U) wrapping mode. All valid values correspond to WebGL enums.
WrapT SamplerWrap `json:"wrapT,omitempty"` // T (V) wrapping mode.
}

func (s *Sampler) equal(other *Sampler) bool {
if s == other { // Either both nil or point to the same object
return true
}

if s == nil || other == nil { // only one can be nil at this point
return false
}

if s.MagFilter != other.MagFilter || s.MinFilter != other.MinFilter ||
s.WrapS != other.WrapS || s.WrapT != other.WrapT {
return false
}

if !s.ChildOfRootProperty.equal(other.ChildOfRootProperty) {
return false
}

return true
}

func (s ChildOfRootProperty) equal(other ChildOfRootProperty) bool {
if s.Name != other.Name {
return false
}
if len(s.Extensions) != len(other.Extensions) {
return false
}
if len(s.Extras) != len(other.Extras) {
return false
}

for key, val := range s.Extensions {
if other.Extensions[key] != val {
return false
}
}

for key, val := range s.Extras {
if other.Extras[key] != val {
return false
}
}

return true
}
21 changes: 21 additions & 0 deletions formats/gltf/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,24 @@ type Gltf struct {
Skins []Skin `json:"skins,omitempty"` // An array of skins. A skin is defined by joints and matrices.
Textures []Texture `json:"textures,omitempty"` // An array of textures
}

func (t Texture) equal(other Texture) bool {
if !ptrIEqual(t.Source, other.Source) || !ptrIEqual(t.Sampler, other.Sampler) {
return false
}
if len(t.Extensions) != len(other.Extensions) {
return false
}

for key, val := range t.Extensions {
if other.Extensions[key] != val {
return false
}
}

if !t.ChildOfRootProperty.equal(other.ChildOfRootProperty) {
return false
}

return true
}
4 changes: 4 additions & 0 deletions formats/gltf/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func ptrI(i int) *int {
return &i
}

func ptrIEqual(i, j *int) bool {
return (i == nil && j == nil) || (i != nil && j != nil && *i == *j)
}

func flattenSkeletonToNodes(offset int, skeleton animation.Skeleton, out *bytes.Buffer) []Node {
nodes := make([]Node, 0)

Expand Down
68 changes: 48 additions & 20 deletions formats/gltf/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ import (
"github.com/stretchr/testify/assert"
)

type mockTextureExtension struct{}

func (m mockTextureExtension) ExtensionID() string {
return "mocXtension"
}
func (m mockTextureExtension) ToTextureExtensionData(w *gltf.Writer) map[string]any {
return nil
}
func (m mockTextureExtension) IsRequired() bool {
return false
}
func (m mockTextureExtension) IsInfo() bool {
return false
}

func TestWriteBasicTri(t *testing.T) {
// ARRANGE ================================================================
tri := modeling.NewTriangleMesh([]int{0, 1, 2}).
Expand Down Expand Up @@ -555,8 +570,9 @@ func TestWrite_TexturedTriWithMaterialWithColor_ImageSampleDedupe(t *testing.T)
BaseColorFactor: color.RGBA{255, 100, 80, 255},
RoughnessFactor: &roughness,
BaseColorTexture: &gltf.PolyformTexture{
URI: "this_is_a_test.png",
Sampler: sampler,
URI: "this_is_a_test.png",
Sampler: sampler,
Extensions: []gltf.TextureExtension{&mockTextureExtension{}},
},
},
},
Expand All @@ -567,6 +583,9 @@ func TestWrite_TexturedTriWithMaterialWithColor_ImageSampleDedupe(t *testing.T)
// ASSERT =================================================================
assert.NoError(t, err)
assert.Equal(t, `{
"extensionsUsed": [
"mocXtension"
],
"accessors": [
{
"bufferView": 0,
Expand Down Expand Up @@ -832,13 +851,16 @@ func TestWrite_TexturedTriWithMaterialWithColor_ImageSampleDedupe(t *testing.T)
},
{
"sampler": 0,
"source": 0
"source": 0,
"extensions": {
"mocXtension": null
}
}
]
}`, buf.String())
}

func TestWrite_TexturedTriWithMaterialWithColor_TextureDedupe(t *testing.T) {
func TestWrite_TexturedTriWithMaterialWithColor_TextureValueDedupe(t *testing.T) {
// ARRANGE ================================================================
tri1 := modeling.NewTriangleMesh([]int{0, 1, 2}).
SetFloat3Attribute(
Expand Down Expand Up @@ -895,16 +917,6 @@ func TestWrite_TexturedTriWithMaterialWithColor_TextureDedupe(t *testing.T) {

// ACT ====================================================================
roughness := 0.
texture := &gltf.PolyformTexture{
URI: "this_is_a_test.png",
Sampler: &gltf.Sampler{
WrapS: gltf.SamplerWrap_REPEAT,
WrapT: gltf.SamplerWrap_REPEAT,
MinFilter: gltf.SamplerMinFilter_LINEAR_MIPMAP_LINEAR,
MagFilter: gltf.SamplerMagFilter_LINEAR,
},
}

err := gltf.WriteText(gltf.PolyformScene{
Models: []gltf.PolyformModel{
{
Expand All @@ -913,9 +925,17 @@ func TestWrite_TexturedTriWithMaterialWithColor_TextureDedupe(t *testing.T) {
Material: &gltf.PolyformMaterial{
Name: "My Material1",
PbrMetallicRoughness: &gltf.PolyformPbrMetallicRoughness{
BaseColorFactor: color.RGBA{255, 100, 80, 255},
RoughnessFactor: &roughness,
BaseColorTexture: texture,
BaseColorFactor: color.RGBA{255, 100, 80, 255},
RoughnessFactor: &roughness,
BaseColorTexture: &gltf.PolyformTexture{
URI: "this_is_a_test.png",
Sampler: &gltf.Sampler{
WrapS: gltf.SamplerWrap_REPEAT,
WrapT: gltf.SamplerWrap_REPEAT,
MinFilter: gltf.SamplerMinFilter_LINEAR_MIPMAP_LINEAR,
MagFilter: gltf.SamplerMagFilter_LINEAR,
},
},
},
},
},
Expand All @@ -925,9 +945,17 @@ func TestWrite_TexturedTriWithMaterialWithColor_TextureDedupe(t *testing.T) {
Material: &gltf.PolyformMaterial{
Name: "My Material2",
PbrMetallicRoughness: &gltf.PolyformPbrMetallicRoughness{
BaseColorFactor: color.RGBA{255, 100, 80, 255},
RoughnessFactor: &roughness,
BaseColorTexture: texture,
BaseColorFactor: color.RGBA{255, 100, 80, 255},
RoughnessFactor: &roughness,
BaseColorTexture: &gltf.PolyformTexture{
URI: "this_is_a_test.png",
Sampler: &gltf.Sampler{
WrapS: gltf.SamplerWrap_REPEAT,
WrapT: gltf.SamplerWrap_REPEAT,
MinFilter: gltf.SamplerMinFilter_LINEAR_MIPMAP_LINEAR,
MagFilter: gltf.SamplerMagFilter_LINEAR,
},
},
},
},
},
Expand Down
Loading

0 comments on commit 6f807f5

Please sign in to comment.