From ab2ceee1e6033bf62473abcb8c779ab96db96ffd Mon Sep 17 00:00:00 2001 From: qmuntal Date: Wed, 20 Feb 2019 12:48:52 +0100 Subject: [PATCH] use float64 instead of float32 --- decoder_test.go | 37 ++++++----- encode_test.go | 20 +++--- struct.go | 66 +++++++++---------- struct_test.go | 48 +++++++------- .../BoxVertexColors/glTF/BoxVertexColors.gltf | 10 +-- validator/validator_test.go | 16 ++--- 6 files changed, 99 insertions(+), 98 deletions(-) diff --git a/decoder_test.go b/decoder_test.go index 4665572..c294943 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -16,6 +16,7 @@ func readFile(path string) []uint8 { } func TestOpen(t *testing.T) { + deep.FloatPrecision = 5 type args struct { name string embedded string @@ -28,11 +29,11 @@ func TestOpen(t *testing.T) { {args{"openError", ""}, nil, true}, {args{"testdata/Cube/glTF/Cube.gltf", ""}, &Document{ Accessors: []Accessor{ - {BufferView: 0, ByteOffset: 0, ComponentType: UnsignedShort, Count: 36, Max: []float32{35}, Min: []float32{0}, Type: Scalar}, - {BufferView: 1, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float32{1, 1, 1}, Min: []float32{-1, -1, -1}, Type: Vec3}, - {BufferView: 2, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float32{1, 1, 1}, Min: []float32{-1, -1, -1}, Type: Vec3}, - {BufferView: 3, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float32{1, 0, 0, 1}, Min: []float32{0, 0, -1, -1}, Type: Vec4}, - {BufferView: 4, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float32{1, 1}, Min: []float32{-1, -1}, Type: Vec2}}, + {BufferView: 0, ByteOffset: 0, ComponentType: UnsignedShort, Count: 36, Max: []float64{35}, Min: []float64{0}, Type: Scalar}, + {BufferView: 1, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float64{1, 1, 1}, Min: []float64{-1, -1, -1}, Type: Vec3}, + {BufferView: 2, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float64{1, 1, 1}, Min: []float64{-1, -1, -1}, Type: Vec3}, + {BufferView: 3, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float64{1, 0, 0, 1}, Min: []float64{0, 0, -1, -1}, Type: Vec4}, + {BufferView: 4, ByteOffset: 0, ComponentType: Float, Count: 36, Max: []float64{1, 1}, Min: []float64{-1, -1}, Type: Vec2}}, Asset: Asset{Generator: "VKTS glTF 2.0 exporter", Version: "2.0"}, BufferViews: []BufferView{ {Buffer: 0, ByteLength: 72, ByteOffset: 0, Target: ElementArrayBuffer}, @@ -43,9 +44,9 @@ func TestOpen(t *testing.T) { }, Buffers: []Buffer{{ByteLength: 1800, URI: "Cube.bin", Data: readFile("testdata/Cube/glTF/Cube.bin")}}, Images: []Image{{URI: "Cube_BaseColor.png"}, {URI: "Cube_MetallicRoughness.png"}}, - Materials: []Material{{Name: "Cube", AlphaMode: Opaque, AlphaCutoff: 0.5, PBRMetallicRoughness: &PBRMetallicRoughness{BaseColorFactor: [4]float32{1, 1, 1, 1}, MetallicFactor: 1, RoughnessFactor: 1, BaseColorTexture: &TextureInfo{Index: 0}, MetallicRoughnessTexture: &TextureInfo{Index: 1}}}}, + Materials: []Material{{Name: "Cube", AlphaMode: Opaque, AlphaCutoff: 0.5, PBRMetallicRoughness: &PBRMetallicRoughness{BaseColorFactor: [4]float64{1, 1, 1, 1}, MetallicFactor: 1, RoughnessFactor: 1, BaseColorTexture: &TextureInfo{Index: 0}, MetallicRoughnessTexture: &TextureInfo{Index: 1}}}}, Meshes: []Mesh{{Name: "Cube", Primitives: []Primitive{{Indices: 0, Material: 0, Mode: Triangles, Attributes: map[string]uint32{"NORMAL": 2, "POSITION": 1, "TANGENT": 3, "TEXCOORD_0": 4}}}}}, - Nodes: []Node{{Mesh: 0, Name: "Cube", Camera: -1, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}}}, + Nodes: []Node{{Mesh: 0, Name: "Cube", Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}}}, Samplers: []Sampler{{WrapS: Repeat, WrapT: Repeat}}, Scene: 0, Scenes: []Scene{{Nodes: []uint32{0}}}, @@ -55,8 +56,8 @@ func TestOpen(t *testing.T) { }, false}, {args{"testdata/Cameras/glTF/Cameras.gltf", "testdata/Cameras/glTF-Embedded/Cameras.gltf"}, &Document{ Accessors: []Accessor{ - {BufferView: 0, ByteOffset: 0, ComponentType: UnsignedShort, Count: 6, Max: []float32{3}, Min: []float32{0}, Type: Scalar}, - {BufferView: 1, ByteOffset: 0, ComponentType: Float, Count: 4, Max: []float32{1, 1, 0}, Min: []float32{0, 0, 0}, Type: Vec3}, + {BufferView: 0, ByteOffset: 0, ComponentType: UnsignedShort, Count: 6, Max: []float64{3}, Min: []float64{0}, Type: Scalar}, + {BufferView: 1, ByteOffset: 0, ComponentType: Float, Count: 4, Max: []float64{1, 1, 0}, Min: []float64{0, 0, 0}, Type: Vec3}, }, Asset: Asset{Version: "2.0"}, BufferViews: []BufferView{ @@ -70,9 +71,9 @@ func TestOpen(t *testing.T) { }, Meshes: []Mesh{{Primitives: []Primitive{{Indices: 0, Material: -1, Mode: Triangles, Attributes: map[string]uint32{"POSITION": 1}}}}}, Nodes: []Node{ - {Mesh: 0, Camera: -1, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{-0.3, 0, 0, 0.9}, Scale: [3]float32{1, 1, 1}}, - {Mesh: -1, Camera: 0, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}, Translation: [3]float32{0.5, 0.5, 3.0}}, - {Mesh: -1, Camera: 1, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}, Translation: [3]float32{0.5, 0.5, 3.0}}, + {Mesh: 0, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{-0.3, 0, 0, 0.9}, Scale: [3]float64{1, 1, 1}}, + {Mesh: -1, Camera: 0, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}, Translation: [3]float64{0.5, 0.5, 3.0}}, + {Mesh: -1, Camera: 1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}, Translation: [3]float64{0.5, 0.5, 3.0}}, }, Scene: -1, Scenes: []Scene{{Nodes: []uint32{0, 1, 2}}}, @@ -80,7 +81,7 @@ func TestOpen(t *testing.T) { {args{"testdata/BoxVertexColors/glTF-Binary/BoxVertexColors.glb", ""}, &Document{ Accessors: []Accessor{ {BufferView: 0, ByteOffset: 0, ComponentType: UnsignedShort, Count: 36, Type: Scalar}, - {BufferView: 1, ByteOffset: 0, ComponentType: Float, Count: 24, Max: []float32{0.5, 0.5, 0.5}, Min: []float32{-0.5, -0.5, -0.5}, Type: Vec3}, + {BufferView: 1, ByteOffset: 0, ComponentType: Float, Count: 24, Max: []float64{0.5, 0.5, 0.5}, Min: []float64{-0.5, -0.5, -0.5}, Type: Vec3}, {BufferView: 2, ByteOffset: 0, ComponentType: Float, Count: 24, Type: Vec3}, {BufferView: 3, ByteOffset: 0, ComponentType: Float, Count: 24, Type: Vec4}, {BufferView: 4, ByteOffset: 0, ComponentType: Float, Count: 24, Type: Vec2}, @@ -94,13 +95,13 @@ func TestOpen(t *testing.T) { {Buffer: 0, ByteLength: 192, ByteOffset: 1032, Target: ArrayBuffer}, }, Buffers: []Buffer{{ByteLength: 1224, Data: readFile("testdata/BoxVertexColors/glTF-Binary/BoxVertexColors.glb")[1628+20+8:]}}, - Materials: []Material{{Name: "Default", AlphaMode: Opaque, AlphaCutoff: 0.5, PBRMetallicRoughness: &PBRMetallicRoughness{BaseColorFactor: [4]float32{0.8, 0.8, 0.8, 1}, MetallicFactor: 0.1, RoughnessFactor: 0.99}}}, + Materials: []Material{{Name: "Default", AlphaMode: Opaque, AlphaCutoff: 0.5, PBRMetallicRoughness: &PBRMetallicRoughness{BaseColorFactor: [4]float64{0.8, 0.8, 0.8, 1}, MetallicFactor: 0.1, RoughnessFactor: 0.99}}}, Meshes: []Mesh{{Name: "Cube", Primitives: []Primitive{{Indices: 0, Material: 0, Mode: Triangles, Attributes: map[string]uint32{"POSITION": 1, "COLOR_0": 3, "NORMAL": 2, "TEXCOORD_0": 4}}}}}, Nodes: []Node{ - {Name: "RootNode", Mesh: -1, Camera: -1, Skin: -1, Children: []uint32{1, 2, 3}, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}}, - {Name: "Mesh", Mesh: -1, Camera: -1, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}}, - {Name: "Cube", Mesh: 0, Camera: -1, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}}, - {Name: "Texture Group", Mesh: -1, Camera: -1, Skin: -1, Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}}, + {Name: "RootNode", Mesh: -1, Camera: -1, Skin: -1, Children: []uint32{1, 2, 3}, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}}, + {Name: "Mesh", Mesh: -1, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}}, + {Name: "Cube", Mesh: 0, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}}, + {Name: "Texture Group", Mesh: -1, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}}, }, Samplers: []Sampler{{WrapS: Repeat, WrapT: Repeat}}, Scene: 0, diff --git a/encode_test.go b/encode_test.go index b105375..01b7ea1 100644 --- a/encode_test.go +++ b/encode_test.go @@ -49,7 +49,7 @@ func TestEncoder_Encode(t *testing.T) { {"withExtensions", args{&Document{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, ExtensionsUsed: []string{"c"}, ExtensionsRequired: []string{"d", "e"}}}, false}, {"withAsset", args{&Document{Asset: Asset{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Copyright: "@2019", Generator: "qmuntal/gltf", Version: "2.0", MinVersion: "1.0"}}}, false}, {"withAccessors", args{&Document{Accessors: []Accessor{ - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "acc_1", BufferView: 0, ByteOffset: 50, ComponentType: Byte, Normalized: true, Count: 5, Type: Vec3, Max: []float32{1, 2}, Min: []float32{2.4}}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "acc_1", BufferView: 0, ByteOffset: 50, ComponentType: Byte, Normalized: true, Count: 5, Type: Vec3, Max: []float64{1, 2}, Min: []float64{2.4}}, {BufferView: 0, Normalized: false, Count: 50, Type: Vec4, Sparse: &Sparse{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Count: 2, Values: SparseValues{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, BufferView: 1, ByteOffset: 2}, Indices: SparseIndices{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, BufferView: 1, ByteOffset: 2, ComponentType: Float}}, @@ -84,10 +84,10 @@ func TestEncoder_Encode(t *testing.T) { {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "external", URI: "https://web.com/a", MimeType: "data:image/png"}, }}}, false}, {"withMaterials", args{&Document{Materials: []Material{ - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "base", EmissiveFactor: [3]float32{1.0, 1.0, 1.0}, DoubleSided: true, AlphaCutoff: 0.5, AlphaMode: Opaque}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "base", EmissiveFactor: [3]float64{1.0, 1.0, 1.0}, DoubleSided: true, AlphaCutoff: 0.5, AlphaMode: Opaque}, {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "pbr", AlphaCutoff: 0.5, AlphaMode: Opaque, PBRMetallicRoughness: &PBRMetallicRoughness{ - Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, MetallicFactor: 1, RoughnessFactor: 2, BaseColorFactor: [4]float32{1, 2, 3, 4}, + Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, MetallicFactor: 1, RoughnessFactor: 2, BaseColorFactor: [4]float64{1, 2, 3, 4}, BaseColorTexture: &TextureInfo{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Index: 1, TexCoord: 3}, MetallicRoughnessTexture: &TextureInfo{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Index: 6, TexCoord: 5}, }, @@ -101,7 +101,7 @@ func TestEncoder_Encode(t *testing.T) { {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "emmisice", AlphaCutoff: 0.5, AlphaMode: Mask, EmissiveTexture: &TextureInfo{Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Index: 4, TexCoord: 50}}, }}}, false}, {"withMeshes", args{&Document{Meshes: []Mesh{ - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "mesh_1", Weights: []float32{1.2, 2}}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "mesh_1", Weights: []float64{1.2, 2}}, {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "mesh_2", Primitives: []Primitive{ {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Attributes: Attribute{"POSITION": 1}, Indices: 2, Material: 1, Mode: Lines}, {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Targets: []Attribute{{"POSITION": 1, "THEN": 4}, {"OTHER": 2}}, Indices: 2, Material: 1, Mode: Lines}, @@ -109,9 +109,9 @@ func TestEncoder_Encode(t *testing.T) { }}}, false}, {"withNodes", args{&Document{Nodes: []Node{ {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "n-1", Camera: 1, Children: []uint32{1, 2}, Skin: 3, - Matrix: [16]float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, Mesh: 15, Rotation: [4]float32{1.5, 1.3, 12, 0}, Scale: [3]float32{1, 3, 4}, Translation: [3]float32{0, 7.8, 9}, Weights: []float32{1, 3}}, + Matrix: [16]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, Mesh: 15, Rotation: [4]float64{1.5, 1.3, 12, 0}, Scale: [3]float64{1, 3, 4}, Translation: [3]float64{0, 7.8, 9}, Weights: []float64{1, 3}}, {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "n-2", Camera: 1, Children: []uint32{1, 2}, Skin: 3, - Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Mesh: 15, Rotation: [4]float32{0, 0, 0, 1}, Scale: [3]float32{1, 1, 1}}, + Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Mesh: 15, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}}, }}}, false}, {"withSampler", args{&Document{Samplers: []Sampler{ {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "s_1", MagFilter: MagLinear, MinFilter: MinLinearMipMapLinear, WrapS: ClampToEdge, WrapT: MirroredRepeat}, @@ -119,12 +119,12 @@ func TestEncoder_Encode(t *testing.T) { }}}, false}, {"withScene", args{&Document{Scene: 1}}, false}, {"withScenes", args{&Document{Scenes: []Scene{ - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "s_1", Nodes: []uint32{1,2}}, - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "s_2", Nodes: []uint32{2,3}}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "s_1", Nodes: []uint32{1, 2}}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "s_2", Nodes: []uint32{2, 3}}, }}}, false}, {"withSkins", args{&Document{Skins: []Skin{ - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "skin_1", InverseBindMatrices: 2, Skeleton: 4, Joints: []uint32{5,6}}, - {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "skin_2", InverseBindMatrices: 3, Skeleton: 4, Joints: []uint32{7,8}}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "skin_1", InverseBindMatrices: 2, Skeleton: 4, Joints: []uint32{5, 6}}, + {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "skin_2", InverseBindMatrices: 3, Skeleton: 4, Joints: []uint32{7, 8}}, }}}, false}, {"withTextures", args{&Document{Textures: []Texture{ {Extensions: 8.0, Extras: map[string]interface{}{"a": "b"}, Name: "t_1", Sampler: 2, Source: 3}, diff --git a/struct.go b/struct.go index c24f44d..0cc3612 100644 --- a/struct.go +++ b/struct.go @@ -133,8 +133,8 @@ type Accessor struct { Normalized bool `json:"normalized,omitempty"` // Specifies whether integer data values should be normalized. Count uint32 `json:"count" validate:"required"` // The number of attributes referenced by this accessor. Type AccessorType `json:"type" validate:"oneof=SCALAR VEC2 VEC3 VEC4 MAT2 MAT3 MAT4"` - Max []float32 `json:"max,omitempty" validate:"omitempty,lte=16"` // Maximum value of each component in this attribute. - Min []float32 `json:"min,omitempty" validate:"omitempty,lte=16"` // Minimum value of each component in this attribute. + Max []float64 `json:"max,omitempty" validate:"omitempty,lte=16"` // Maximum value of each component in this attribute. + Min []float64 `json:"min,omitempty" validate:"omitempty,lte=16"` // Minimum value of each component in this attribute. Sparse *Sparse `json:"sparse,omitempty"` // Sparse storage of attributes that deviate from their initialization value. } @@ -286,20 +286,20 @@ type Node struct { Camera int32 `json:"camera" validate:"gte=-1"` Children []uint32 `json:"children,omitempty" validate:"omitempty,unique"` Skin int32 `json:"skin" validate:"gte=-1"` - Matrix [16]float32 `json:"matrix"` // A 4x4 transformation matrix stored in column-major order. + Matrix [16]float64 `json:"matrix"` // A 4x4 transformation matrix stored in column-major order. Mesh int32 `json:"mesh" validate:"gte=-1"` - Rotation [4]float32 `json:"rotation" validate:"omitempty,dive,gte=-1,lte=1"` // The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar. - Scale [3]float32 `json:"scale"` - Translation [3]float32 `json:"translation"` - Weights []float32 `json:"weights,omitempty"` // The weights of the instantiated Morph Target. + Rotation [4]float64 `json:"rotation" validate:"omitempty,dive,gte=-1,lte=1"` // The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar. + Scale [3]float64 `json:"scale"` + Translation [3]float64 `json:"translation"` + Weights []float64 `json:"weights,omitempty"` // The weights of the instantiated Morph Target. } // NewNode returns a default Node. func NewNode() *Node { return &Node{ - Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, - Rotation: [4]float32{0, 0, 0, 1}, - Scale: [3]float32{1, 1, 1}, + Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, + Rotation: [4]float64{0, 0, 0, 1}, + Scale: [3]float64{1, 1, 1}, Camera: -1, Skin: -1, Mesh: -1, @@ -322,16 +322,16 @@ func (n *Node) MarshalJSON() ([]byte, error) { type alias Node out, err := json.Marshal(&struct{ *alias }{alias: (*alias)(n)}) if err == nil { - if n.Matrix == [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1} { + if n.Matrix == [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1} { out = removeProperty([]byte(`"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]`), out) } - if n.Rotation == [4]float32{0, 0, 0, 1} { + if n.Rotation == [4]float64{0, 0, 0, 1} { out = removeProperty([]byte(`"rotation":[0,0,0,1]`), out) } - if n.Scale == [3]float32{1, 1, 1} { + if n.Scale == [3]float64{1, 1, 1} { out = removeProperty([]byte(`"scale":[1,1,1]`), out) } - if n.Translation == [3]float32{0, 0, 0} { + if n.Translation == [3]float64{0, 0, 0} { out = removeProperty([]byte(`"translation":[0,0,0]`), out) } if n.Camera == -1 { @@ -413,20 +413,20 @@ type Camera struct { type Orthographic struct { Extensions interface{} `json:"extensions,omitempty"` Extras map[string]interface{} `json:"extras,omitempty"` - Xmag float32 `json:"xmag"` // The horizontal magnification of the view. - Ymag float32 `json:"ymag"` // The vertical magnification of the view. - Zfar float32 `json:"zfar" validate:"gt=0,gtfield=Znear"` // The distance to the far clipping plane. - Znear float32 `json:"znear" validate:"gte=0"` // The distance to the near clipping plane. + Xmag float64 `json:"xmag"` // The horizontal magnification of the view. + Ymag float64 `json:"ymag"` // The vertical magnification of the view. + Zfar float64 `json:"zfar" validate:"gt=0,gtfield=Znear"` // The distance to the far clipping plane. + Znear float64 `json:"znear" validate:"gte=0"` // The distance to the near clipping plane. } // Perspective camera containing properties to create a perspective projection matrix. type Perspective struct { Extensions interface{} `json:"extensions,omitempty"` Extras map[string]interface{} `json:"extras,omitempty"` - AspectRatio float32 `json:"aspectRatio,omitempty"` - Yfov float32 `json:"yfov"` // The vertical field of view in radians. - Zfar float32 `json:"zfar,omitempty"` // The distance to the far clipping plane. - Znear float32 `json:"znear"` // The distance to the near clipping plane. + AspectRatio float64 `json:"aspectRatio,omitempty"` + Yfov float64 `json:"yfov"` // The vertical field of view in radians. + Zfar float64 `json:"zfar,omitempty"` // The distance to the far clipping plane. + Znear float64 `json:"znear"` // The distance to the near clipping plane. } // Attribute is a map that each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data. @@ -451,7 +451,7 @@ type Mesh struct { Extras map[string]interface{} `json:"extras,omitempty"` Name string `json:"name,omitempty"` Primitives []Primitive `json:"primitives" validate:"required,gt=0,dive"` - Weights []float32 `json:"weights,omitempty"` + Weights []float64 `json:"weights,omitempty"` } // Primitive defines the geometry to be rendered with the given material. @@ -544,9 +544,9 @@ type Material struct { NormalTexture *NormalTexture `json:"normalTexture,omitempty"` OcclusionTexture *OcclusionTexture `json:"occlusionTexture,omitempty"` EmissiveTexture *TextureInfo `json:"emissiveTexture,omitempty"` - EmissiveFactor [3]float32 `json:"emissiveFactor,omitempty" validate:"dive,gte=0,lte=1"` + EmissiveFactor [3]float64 `json:"emissiveFactor,omitempty" validate:"dive,gte=0,lte=1"` AlphaMode AlphaMode `json:"alphaMode,omitempty" validate:"oneof=OPAQUE MASK BLEND"` - AlphaCutoff float32 `json:"alphaCutoff" validate:"gte=0"` + AlphaCutoff float64 `json:"alphaCutoff" validate:"gte=0"` DoubleSided bool `json:"doubleSided,omitempty"` } @@ -577,7 +577,7 @@ func (m *Material) MarshalJSON() ([]byte, error) { if m.AlphaMode == Opaque { out = removeProperty([]byte(`"alphaMode":"OPAQUE"`), out) } - if m.EmissiveFactor == [3]float32{0, 0, 0} { + if m.EmissiveFactor == [3]float64{0, 0, 0} { out = removeProperty([]byte(`"emissiveFactor":[0,0,0]`), out) } out = sanitizeJSON(out) @@ -591,7 +591,7 @@ type NormalTexture struct { Extras map[string]interface{} `json:"extras,omitempty"` Index int32 `json:"index" validate:"gte=-1"` TexCoord uint32 `json:"texCoord,omitempty"` // The index of texture's TEXCOORD attribute used for texture coordinate mapping. - Scale float32 `json:"scale"` + Scale float64 `json:"scale"` } // NewNormalTexture returns a default NormalTexture. @@ -637,7 +637,7 @@ type OcclusionTexture struct { Extras map[string]interface{} `json:"extras,omitempty"` Index int32 `json:"index" validate:"gte=-1"` TexCoord uint32 `json:"texCoord,omitempty"` // The index of texture's TEXCOORD attribute used for texture coordinate mapping. - Strength float32 `json:"strength" validate:"gte=0,lte=1"` + Strength float64 `json:"strength" validate:"gte=0,lte=1"` } // UnmarshalJSON unmarshal the texture info with the correct default values. @@ -671,16 +671,16 @@ func (o *OcclusionTexture) MarshalJSON() ([]byte, error) { type PBRMetallicRoughness struct { Extensions interface{} `json:"extensions,omitempty"` Extras map[string]interface{} `json:"extras,omitempty"` - BaseColorFactor [4]float32 `json:"baseColorFactor" validate:"dive,gte=0,lte=1"` + BaseColorFactor [4]float64 `json:"baseColorFactor" validate:"dive,gte=0,lte=1"` BaseColorTexture *TextureInfo `json:"baseColorTexture,omitempty"` - MetallicFactor float32 `json:"metallicFactor" validate:"gte=0,lte=1"` - RoughnessFactor float32 `json:"roughnessFactor" validate:"gte=0,lte=1"` + MetallicFactor float64 `json:"metallicFactor" validate:"gte=0,lte=1"` + RoughnessFactor float64 `json:"roughnessFactor" validate:"gte=0,lte=1"` MetallicRoughnessTexture *TextureInfo `json:"metallicRoughnessTexture,omitempty"` } // NewPBRMetallicRoughness returns a default PBRMetallicRoughness. func NewPBRMetallicRoughness() *PBRMetallicRoughness { - return &PBRMetallicRoughness{BaseColorFactor: [4]float32{1, 1, 1, 1}, MetallicFactor: 1, RoughnessFactor: 1} + return &PBRMetallicRoughness{BaseColorFactor: [4]float64{1, 1, 1, 1}, MetallicFactor: 1, RoughnessFactor: 1} } // UnmarshalJSON unmarshal the pbr with the correct default values. @@ -705,7 +705,7 @@ func (p *PBRMetallicRoughness) MarshalJSON() ([]byte, error) { if p.RoughnessFactor == -1 { out = removeProperty([]byte(`"roughnessFactor":-1`), out) } - if p.BaseColorFactor == [4]float32{1, 1, 1, 1} { + if p.BaseColorFactor == [4]float64{1, 1, 1, 1} { out = removeProperty([]byte(`"baseColorFactor":[1,1,1,1]`), out) } out = sanitizeJSON(out) diff --git a/struct_test.go b/struct_test.go index 8ea4b5e..f542a4d 100644 --- a/struct_test.go +++ b/struct_test.go @@ -100,25 +100,25 @@ func TestNode_UnmarshalJSON(t *testing.T) { wantErr bool }{ {"default", new(Node), args{[]byte("{}")}, &Node{ - Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, - Rotation: [4]float32{0, 0, 0, 1}, - Scale: [3]float32{1, 1, 1}, + Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, + Rotation: [4]float64{0, 0, 0, 1}, + Scale: [3]float64{1, 1, 1}, Camera: -1, Mesh: -1, Skin: -1, }, false}, {"nodefault", new(Node), args{[]byte(`{"matrix":[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],"rotation":[0,0,0,1],"scale":[1,1,1],"camera":0,"mesh":0,"skin":0}`)}, &Node{ - Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, - Rotation: [4]float32{0, 0, 0, 1}, - Scale: [3]float32{1, 1, 1}, + Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, + Rotation: [4]float64{0, 0, 0, 1}, + Scale: [3]float64{1, 1, 1}, Camera: 0, Mesh: 0, Skin: 0, }, false}, {"nodefault", new(Node), args{[]byte(`{"matrix":[1,2,2,0,0,1,3,4,0,0,1,0,5,0,0,5],"rotation":[1,2,3,4],"scale":[2,3,4],"camera":1,"mesh":2,"skin":3}`)}, &Node{ - Matrix: [16]float32{1, 2, 2, 0, 0, 1, 3, 4, 0, 0, 1, 0, 5, 0, 0, 5}, - Rotation: [4]float32{1, 2, 3, 4}, - Scale: [3]float32{2, 3, 4}, + Matrix: [16]float64{1, 2, 2, 0, 0, 1, 3, 4, 0, 0, 1, 0, 5, 0, 0, 5}, + Rotation: [4]float64{1, 2, 3, 4}, + Scale: [3]float64{2, 3, 4}, Camera: 1, Mesh: 2, Skin: 3, @@ -259,9 +259,9 @@ func TestPBRMetallicRoughness_UnmarshalJSON(t *testing.T) { want *PBRMetallicRoughness wantErr bool }{ - {"default", new(PBRMetallicRoughness), args{[]byte("{}")}, &PBRMetallicRoughness{BaseColorFactor: [4]float32{1, 1, 1, 1}, MetallicFactor: 1, RoughnessFactor: 1}, false}, + {"default", new(PBRMetallicRoughness), args{[]byte("{}")}, &PBRMetallicRoughness{BaseColorFactor: [4]float64{1, 1, 1, 1}, MetallicFactor: 1, RoughnessFactor: 1}, false}, {"nodefault", new(PBRMetallicRoughness), args{[]byte(`{"baseColorFactor": [0.1,0.2,0.6,0.7],"metallicFactor":0.5,"roughnessFactor":0.1}`)}, &PBRMetallicRoughness{ - BaseColorFactor: [4]float32{0.1, 0.2, 0.6, 0.7}, MetallicFactor: 0.5, RoughnessFactor: 0.1, + BaseColorFactor: [4]float64{0.1, 0.2, 0.6, 0.7}, MetallicFactor: 0.5, RoughnessFactor: 0.1, }, false}, } for _, tt := range tests { @@ -639,26 +639,26 @@ func TestNode_MarshalJSON(t *testing.T) { wantErr bool }{ {"default", &Node{ - Matrix: [16]float32{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, - Rotation: [4]float32{0, 0, 0, 1}, - Scale: [3]float32{1, 1, 1}, + Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, + Rotation: [4]float64{0, 0, 0, 1}, + Scale: [3]float64{1, 1, 1}, Camera: -1, Skin: -1, Mesh: -1, }, []byte("{}"), false}, {"empty", &Node{ - Matrix: [16]float32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - Rotation: [4]float32{0, 0, 0, 0}, - Scale: [3]float32{0, 0, 0}, + Matrix: [16]float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Rotation: [4]float64{0, 0, 0, 0}, + Scale: [3]float64{0, 0, 0}, Camera: 0, Skin: 0, Mesh: 0, }, []byte(`{"camera":0,"skin":0,"matrix":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"mesh":0,"rotation":[0,0,0,0],"scale":[0,0,0]}`), false}, {"nodefault", &Node{ - Matrix: [16]float32{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - Rotation: [4]float32{1, 0, 0, 0}, - Scale: [3]float32{1, 0, 0}, - Translation: [3]float32{1, 0, 0}, + Matrix: [16]float64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Rotation: [4]float64{1, 0, 0, 0}, + Scale: [3]float64{1, 0, 0}, + Translation: [3]float64{1, 0, 0}, Camera: 1, Skin: 1, Mesh: 1, @@ -810,9 +810,9 @@ func TestPBRMetallicRoughness_MarshalJSON(t *testing.T) { want []byte wantErr bool }{ - {"default", &PBRMetallicRoughness{MetallicFactor: -1, RoughnessFactor: -1, BaseColorFactor: [4]float32{1, 1, 1, 1}}, []byte(`{}`), false}, - {"empty", &PBRMetallicRoughness{MetallicFactor: 0, RoughnessFactor: 0, BaseColorFactor: [4]float32{0, 0, 0, 0}}, []byte(`{"baseColorFactor":[0,0,0,0],"metallicFactor":0,"roughnessFactor":0}`), false}, - {"nodefault", &PBRMetallicRoughness{MetallicFactor: 1, RoughnessFactor: 1, BaseColorFactor: [4]float32{1, 0.5, 1, 1}}, []byte(`{"baseColorFactor":[1,0.5,1,1],"metallicFactor":1,"roughnessFactor":1}`), false}, + {"default", &PBRMetallicRoughness{MetallicFactor: -1, RoughnessFactor: -1, BaseColorFactor: [4]float64{1, 1, 1, 1}}, []byte(`{}`), false}, + {"empty", &PBRMetallicRoughness{MetallicFactor: 0, RoughnessFactor: 0, BaseColorFactor: [4]float64{0, 0, 0, 0}}, []byte(`{"baseColorFactor":[0,0,0,0],"metallicFactor":0,"roughnessFactor":0}`), false}, + {"nodefault", &PBRMetallicRoughness{MetallicFactor: 1, RoughnessFactor: 1, BaseColorFactor: [4]float64{1, 0.5, 1, 1}}, []byte(`{"baseColorFactor":[1,0.5,1,1],"metallicFactor":1,"roughnessFactor":1}`), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/testdata/BoxVertexColors/glTF/BoxVertexColors.gltf b/testdata/BoxVertexColors/glTF/BoxVertexColors.gltf index 5ea966d..67ae222 100644 --- a/testdata/BoxVertexColors/glTF/BoxVertexColors.gltf +++ b/testdata/BoxVertexColors/glTF/BoxVertexColors.gltf @@ -93,13 +93,13 @@ "name": "Default", "pbrMetallicRoughness": { "baseColorFactor": [ - 0.800000011920929, - 0.800000011920929, - 0.800000011920929, + 0.8, + 0.8, + 0.8, 1.0 ], - "metallicFactor": 0.100000001490116, - "roughnessFactor": 0.990000005960464 + "metallicFactor": 0.1, + "roughnessFactor": 0.99 } } ], diff --git a/validator/validator_test.go b/validator/validator_test.go index 5ea8d8c..f55e410 100644 --- a/validator/validator_test.go +++ b/validator/validator_test.go @@ -24,9 +24,9 @@ func TestValidateDocument(t *testing.T) { {"Document.Accessors[0].Type", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Accessors: []gltf.Accessor{{ComponentType: gltf.Byte, Count: 1, Type: "OTHER"}}}}, true}, {"Document.Accessors[0].Max", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, - Accessors: []gltf.Accessor{{ComponentType: gltf.Byte, Count: 1, Type: "SCALAR", Max: make([]float32, 17)}}}}, true}, + Accessors: []gltf.Accessor{{ComponentType: gltf.Byte, Count: 1, Type: "SCALAR", Max: make([]float64, 17)}}}}, true}, {"Document.Accessors[0].Min", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, - Accessors: []gltf.Accessor{{ComponentType: gltf.Byte, Count: 1, Type: "SCALAR", Min: make([]float32, 17)}}}}, true}, + Accessors: []gltf.Accessor{{ComponentType: gltf.Byte, Count: 1, Type: "SCALAR", Min: make([]float64, 17)}}}}, true}, {"Document.Accessors[0].Sparse.Count", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Accessors: []gltf.Accessor{{ComponentType: gltf.Byte, Count: 1, Type: "SCALAR", Sparse: &gltf.Sparse{Count: 0}}}}}, true}, @@ -50,9 +50,9 @@ func TestValidateDocument(t *testing.T) { {"Document.Nodes[0].Children", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Nodes: []gltf.Node{{Children: []uint32{1, 1}}}}}, true}, {"Document.Nodes[0].Rotation[0]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, - Nodes: []gltf.Node{{Rotation: [4]float32{2, 1, 1, 1}}}}}, true}, + Nodes: []gltf.Node{{Rotation: [4]float64{2, 1, 1, 1}}}}}, true}, {"Document.Nodes[0].Rotation[1]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, - Nodes: []gltf.Node{{Rotation: [4]float32{1, -2, 1, 1}}}}}, true}, + Nodes: []gltf.Node{{Rotation: [4]float64{1, -2, 1, 1}}}}}, true}, {"Document.Skins[0].Joints", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Skins: []gltf.Skin{{Joints: []uint32{1, 1}}}}}, true}, {"Document.Cameras[0].Type", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, @@ -68,17 +68,17 @@ func TestValidateDocument(t *testing.T) { {"Document.Meshes[0].Primitives[0].Targets[0][OTHER]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Meshes: []gltf.Mesh{{Primitives: []gltf.Primitive{{Targets: []gltf.Attribute{{"OTHER": 1}}}}}}}}, true}, {"Document.Materials[0].EmissiveFactor[0]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, - Materials: []gltf.Material{{EmissiveFactor: [3]float32{-1, 1, 1}}}}}, true}, + Materials: []gltf.Material{{EmissiveFactor: [3]float64{-1, 1, 1}}}}}, true}, {"Document.Materials[0].EmissiveFactor[1]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, - Materials: []gltf.Material{{AlphaMode: gltf.Opaque, EmissiveFactor: [3]float32{1, 2, 1}}}}}, true}, + Materials: []gltf.Material{{AlphaMode: gltf.Opaque, EmissiveFactor: [3]float64{1, 2, 1}}}}}, true}, {"Document.Materials[0].AlphaMode", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Materials: []gltf.Material{{AlphaMode: "OTHER"}}}}, true}, {"Document.Materials[0].PBRMetallicRoughness.BaseColorFactor[0]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Materials: []gltf.Material{{AlphaMode: gltf.Opaque, - PBRMetallicRoughness: &gltf.PBRMetallicRoughness{BaseColorFactor: [4]float32{-1, 0, 0, 0}}}}}}, true}, + PBRMetallicRoughness: &gltf.PBRMetallicRoughness{BaseColorFactor: [4]float64{-1, 0, 0, 0}}}}}}, true}, {"Document.Materials[0].PBRMetallicRoughness.BaseColorFactor[1]", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Materials: []gltf.Material{{AlphaMode: gltf.Opaque, - PBRMetallicRoughness: &gltf.PBRMetallicRoughness{BaseColorFactor: [4]float32{1, 2, 0, 0}}}}}}, true}, + PBRMetallicRoughness: &gltf.PBRMetallicRoughness{BaseColorFactor: [4]float64{1, 2, 0, 0}}}}}}, true}, {"Document.Materials[0].PBRMetallicRoughness.MetallicFactor", args{&gltf.Document{Asset: gltf.Asset{Version: "1.0"}, Materials: []gltf.Material{{AlphaMode: gltf.Opaque, PBRMetallicRoughness: &gltf.PBRMetallicRoughness{MetallicFactor: 2}}}}}, true},