-
-
Notifications
You must be signed in to change notification settings - Fork 72
/
ContentSharingTests.cs
145 lines (108 loc) · 5.72 KB
/
ContentSharingTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using NUnit.Framework;
using SharpGLTF.Geometry.Parametric;
using SharpGLTF.Geometry.VertexTypes;
using SharpGLTF.Scenes;
using SharpGLTF.Schema2;
namespace SharpGLTF.Materials
{
[Category("Toolkit.Materials")]
public class ContentSharingTests
{
private static string AssetsPath = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, "Assets");
[Test]
public void TestMaterialBuilderEquality()
{
var tex1Bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(AssetsPath, "shannon.png"));
// create a material using our shared texture
var material1 = new MaterialBuilder()
.WithUnlitShader()
.WithBaseColor(tex1Bytes);
var material2 = material1.Clone();
Assert.IsTrue(MaterialBuilder.AreEqualByContent(material1, material2));
material2
.GetChannel(KnownChannel.BaseColor)
.Texture
.PrimaryImage
.Extras = IO.JsonContent.Serialize(new KeyValuePair<int, string>(1, "hello"));
var material3 = material2.Clone();
Assert.IsFalse(MaterialBuilder.AreEqualByContent(material1, material2));
Assert.IsTrue(MaterialBuilder.AreEqualByContent(material2, material3));
var kvp = material3.GetChannel(KnownChannel.BaseColor)
.Texture
.PrimaryImage
.Extras.Deserialize<KeyValuePair<int, string>>();
Assert.AreEqual(kvp.Key, 1);
Assert.AreEqual(kvp.Value, "hello");
}
[Test]
public void WriteTwoModelsWithSharedTexture()
{
TestContext.CurrentContext.AttachShowDirLink();
TestContext.CurrentContext.AttachGltfValidatorLinks();
var tex1Bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(AssetsPath, "shannon.png"));
var tex2Bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(AssetsPath, "Texture1.jpg"));
var tex1 = tex1Bytes.AttachToCurrentTest("shared-shannon.png");
var tex2 = tex2Bytes.AttachToCurrentTest("subdir\\shared-in-dir-Texture1.jpg");
// create a material using our shared texture
var material1 = new MaterialBuilder()
.WithUnlitShader()
.WithBaseColor(tex1);
// create a material using our shared texture
var material2 = new MaterialBuilder()
.WithUnlitShader()
.WithBaseColor(tex2);
// create a simple cube mesh
var mesh1 = new Cube<MaterialBuilder>(material1).ToMesh(Matrix4x4.Identity);
var mesh2 = new Cube<MaterialBuilder>(material2).ToMesh(Matrix4x4.Identity);
var scene = new SceneBuilder();
scene.AddRigidMesh(mesh1, Matrix4x4.CreateTranslation(-2, 0, 0));
scene.AddRigidMesh(mesh2, Matrix4x4.CreateTranslation(2, 0, 0));
var gltf = scene.ToGltf2();
// define the texture sharing hook; this is a pretty naive approach, but it's good
// enough to demonstrate how it works.
string imageSharingHook(WriteContext ctx, string uri, Memory.MemoryImage image)
{
Assert.IsTrue(new string[] { tex1, tex2 }.Contains(image.SourcePath) );
if (File.Exists(image.SourcePath))
{
// image.SourcePath is an absolute path, we must make it relative to ctx.CurrentDirectory
var currDir = ctx.CurrentDirectory.FullName + "\\";
// if the shared texture can be reached by the model in its directory, reuse the texture.
if (image.SourcePath.StartsWith(currDir, StringComparison.OrdinalIgnoreCase))
{
// we've found the shared texture!, return the uri relative to the model:
return image.SourcePath.Substring(currDir.Length);
}
// TODO: Here we could also try to find a texture equivalent to MemoryImage in the
// CurrentDirectory even if it has a different name, to minimize texture duplication.
}
// we were unable to reuse the shared texture,
// default to write our own texture.
image.SaveToFile(Path.Combine(ctx.CurrentDirectory.FullName, uri));
return uri;
}
var settings = new WriteSettings();
settings.ImageWriting = ResourceWriteMode.SatelliteFile;
settings.ImageWriteCallback = imageSharingHook;
// save the model several times:
var path1 = gltf.AttachToCurrentTest("model1.glb", settings);
var path2 = gltf.AttachToCurrentTest("model2.glb", settings);
var path3 = gltf.AttachToCurrentTest("model3.gltf", settings);
var satellites1 = ModelRoot.GetSatellitePaths(path1);
var satellites2 = ModelRoot.GetSatellitePaths(path2);
var satellites3 = ModelRoot.GetSatellitePaths(path3);
Assert.IsTrue(satellites1.Contains("shared-shannon.png"));
Assert.IsTrue(satellites1.Contains("subdir/shared-in-dir-Texture1.jpg"));
Assert.IsTrue(satellites2.Contains("shared-shannon.png"));
Assert.IsTrue(satellites2.Contains("subdir/shared-in-dir-Texture1.jpg"));
Assert.IsTrue(satellites3.Contains("shared-shannon.png"));
Assert.IsTrue(satellites3.Contains("subdir/shared-in-dir-Texture1.jpg"));
}
}
}