// Use LookupOrCreate() instead private GlTF_Sampler(GlTF_Globals globals, string name, MagFilter magFilter, MinFilter minFilter, Wrap wrap) : base(globals) { this.name = name; this.magFilter = magFilter; this.minFilter = minFilter; this.wrap = wrap; }
public static GlTF_Image LookupOrCreate(GlTF_Globals G, GlTF_FileReference fileRef, string proposedName = null) { if (!G.imagesByFileRefUri.ContainsKey(fileRef.m_uri)) { string name = "image_" + (proposedName ?? $"{G.imagesByFileRefUri.Count}"); G.imagesByFileRefUri.Add(fileRef.m_uri, new GlTF_Image(G, name, fileRef)); } return(G.imagesByFileRefUri[fileRef.m_uri]); }
public void TestGltfDispose() { string tempDir = Path.Combine(Application.dataPath, "..", "Temp", "TiltBrushUnitTests"); using (var globals = new GlTF_Globals(tempDir, gltfVersion: 1)) { globals.binary = true; globals.OpenFiles(Path.Combine(tempDir, "foo.glb1")); globals.CloseFiles(); } }
// temporaryDirectory may be null. // If non-null, ownership of the directory is transferred. public GlTF_ScriptableExporter(string temporaryDirectory, int gltfVersion) { m_globals = new GlTF_Globals(temporaryDirectory, gltfVersion); if (TiltBrush.App.PlatformConfig.EnableExportMemoryOptimization) { m_globals.EnableFileStream(); } m_previousCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; }
private GlTF_Node(GlTF_Globals globals, string name, Matrix4x4 mat, GlTF_Node parent) : base(globals) { this.Parent = parent; if (parent != null) { parent.m_children.Add(this); } this.matrix = new GlTF_Matrix(globals, mat); this.name = name; }
public static GlTF_Texture LookupOrCreate( GlTF_Globals G, GlTF_Image img, GlTF_Sampler sampler, string proposedName = null) { string name = "texture_" + (proposedName ?? $"{img.name}_{sampler.name}"); if (!G.textures.ContainsKey(name)) { G.textures.Add(name, new GlTF_Texture(G, name, img, sampler)); } return(G.textures[name]); }
/// Always creates a node, but the name may not be your desired name. public static GlTF_Node Create( GlTF_Globals globals, string desiredName, Matrix4x4 mat, GlTF_Node parent) { string name = desiredName; for (int i = 0; globals.nodes.ContainsKey(name); ++i) { name = $"{desiredName} {i}"; } return(GetOrCreate(globals, name, mat, parent, out _)); }
/// Returns an accessor that uses a differenttype. /// This is useful if you want to create (for example) a VEC2 view of a buffer that holds VEC4s. /// If the type is smaller, you get a new accessor that uses the same bufferview /// If the type is the same, you get the same accessor back. /// If the type is bigger, you get an exception public static GlTF_Accessor CloneWithDifferentType( GlTF_Globals G, GlTF_Accessor fromAccessor, Type newType) { if (newType == fromAccessor.type) { return(fromAccessor); } var ret = new GlTF_Accessor(G, fromAccessor, newType); G.accessors.Add(ret); return(ret); }
// Creates new technique based on name of material. public static GlTF_Technique CreateTechnique( GlTF_Globals G, TiltBrush.IExportableMaterial exportableMaterial) { var name = GlTF_Technique.GetNameFromObject(exportableMaterial); Debug.Assert(!G.techniques.ContainsKey(name)); var ret = new GlTF_Technique(G); ret.name = name; G.techniques.Add(name, ret); return(ret); }
/// Use this instead of the constructor, in order to share samplers. public static GlTF_Sampler LookupOrCreate( GlTF_Globals G, MagFilter magFilter, MinFilter minFilter, Wrap wrap = Wrap.REPEAT) { // Samplers are only distinguished by their filter settings, so no need for // unique naming beyond that. string name = "sampler_" + magFilter + "_" + minFilter + "_" + wrap; if (!G.samplers.ContainsKey(name)) { G.samplers[name] = new GlTF_Sampler(G, name, magFilter, minFilter, wrap); } return(G.samplers[name]); }
public IEnumerable <GlTF_ReferencedObject> IterReferences(GlTF_Globals G) { if (attributes != null) { foreach (var objRef in attributes.IterReferences(G)) { yield return(G.Lookup(objRef)); } } yield return(G.Lookup(indices)); yield return(G.Lookup <GlTF_Material>(materialName)); }
public void WriteAsUnnamedJObject(GlTF_Globals G) { G.jsonWriter.Write("{\n"); G.IndentIn(); if (attributes != null) { G.CommaNL(); G.Indent(); attributes.WriteAsNamedJObject(G, "attributes"); } G.CNI.WriteNamedReference("indices", indices); G.CNI.WriteNamedReference <GlTF_Material>("material", materialName); G.CNI.WriteNamedInt("mode", kPrimitiveMode_Triangles); G.NewlineAndIndentOut("}"); }
public GlTF_Buffer(GlTF_Globals globals, [CanBeNull] string uri) : base(globals) { if (uri == null) { // The built-in buffer for a .glb in gltf1 needs to be called "binary_glTF" this.name = "binary_glTF"; } else { this.name = "buffer_" + Path.GetFileNameWithoutExtension(uri); } m_uri = uri; }
public GlTF_Channel(GlTF_Globals globals, string ch, GlTF_AnimSampler s) : base(globals) { sampler = s; switch (ch) { case "translation": break; case "rotation": break; case "scale": break; } }
public GlTF_Matrix(GlTF_Globals globals, Matrix4x4 m) : base(globals) { unityMatrix = m; name = "matrix"; minItems = 16; maxItems = 16; // unity: m[row][col] // gltf: column major items = new float[] { m.m00, m.m10, m.m20, m.m30, m.m01, m.m11, m.m21, m.m31, m.m02, m.m12, m.m22, m.m32, m.m03, m.m13, m.m23, m.m33 }; }
// Pass: // normalized - // true if integral values are intended to be values in [0, 1] // For convenience, this parameter is ignored if the ComponentType is non-integral. public GlTF_Accessor( GlTF_Globals globals, string n, Type t, ComponentType c, GlTF_BufferView bufferView, bool isNonVertexAttributeAccessor, bool normalized) : base(globals) { name = n; type = t; componentType = c; bool isIntegral = (c != ComponentType.FLOAT); m_normalized = isIntegral && normalized; this.bufferView = bufferView; // I think (but am not sure) that we can infer whether this is a vertex attribute or some // other kind of accessor by what the "target" of the bufferview is. // All bufferviews except for ushortBufferView use kTarget.ARRAY_BUFFER. // The old code used to look at Type (SCALAR implies non-vertex-attribute), but I // think vertexId is a counterexample of a scalar vertex attribute. Debug.Assert(isNonVertexAttributeAccessor == (bufferView.target == GlTF_BufferView.kTarget_ELEMENT_ARRAY_BUFFER)); int packedSize = GetSize(componentType) * GetNumComponents(type); if (isNonVertexAttributeAccessor) { // Gltf2 rule is that bufferView.byteStride may only be set if the accessor is for // a vertex attributes. I think gltf1 is the same way. byteStride = 0; } else if (type == Type.SCALAR && !G.Gltf2) { // Old gltf1 code used to use "packed" for anything of Type.SCALAR. // I'm going to replicate that odd behavior for ease of diffing old vs new .glb1. // As long as stride == packedSize then it's mostly safe to omit the stride, at least in gltf1 Debug.Assert(byteStride == 0 || byteStride == packedSize); byteStride = 0; } else { byteStride = packedSize; } SanityCheckBufferViewStride(); }
/// Convert a Tilt Brush VertexLayout to a GlTF VertexLayout. public GlTF_VertexLayout(GlTF_Globals G, GeometryPool.VertexLayout tbLayout) { bool suppressVertexId = G.Gltf2 || G.GltfCompatibilityMode; m_tbLayout = tbLayout; this.PositionInfo = new AttributeInfo( GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT); this.NormalInfo = tbLayout.bUseNormals ? new AttributeInfo(GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT) : default(AttributeInfo?); // Keep using float colors for gltf1 because it breaks Poly (uint8 values are not normalized) // and Poly Toolkit. It's possible gltf1 just doesn't support uint8 color. var colorType = (G.Gltf2 ? ComponentType.UNSIGNED_BYTE : ComponentType.FLOAT); this.ColorInfo = tbLayout.bUseColors ? new AttributeInfo(GlTF_Accessor.Type.VEC4, colorType) : default(AttributeInfo?); this.TangentInfo = tbLayout.bUseTangents ? new AttributeInfo(GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT) : default(AttributeInfo?); Debug.Assert(GeometryPool.kNumTexcoords == 3); this.m_texcoord0Size = (tbLayout.texcoord0.size); this.m_texcoord1Size = (tbLayout.texcoord1.size); this.m_texcoord2Size = (tbLayout.texcoord2.size); this.m_texcoord3Size = 0; // Poly can't currently load custom attributes via the GLTFLoader (though glTF 1.0 does // support this), so we pack them into uv1.w, assuming uv1 starts out as a three element UV // channel. if (!tbLayout.bUseVertexIds || suppressVertexId) { PackVertexIdIntoTexcoord1W = false; } else if (m_texcoord1Size == 3) { PackVertexIdIntoTexcoord1W = true; m_texcoord1Size = 4; } else { throw new InvalidOperationException("Can't have vertex ids unless texcoord1 size == 3'"); } }
public GlTF_Scene(GlTF_Globals globals, string name, IEnumerable <GlTF_Node> nodes, Dictionary <string, object> extras) : base(globals) { this.name = name; if (nodes != null) { m_nodes.AddRange(nodes); } if (extras != null) { foreach (var kvp in extras) { m_extras[kvp.Key] = kvp.Value; } } }
private static GlTF_Node GetOrCreate( GlTF_Globals globals, string name, Matrix4x4 mat, GlTF_Node parent, out bool created) { if (globals.nodes.ContainsKey(name)) { var ret = globals.nodes[name]; if (ret.matrix.unityMatrix != mat) { Debug.LogErrorFormat("Node {0} cannot have two different matrices", name); } created = false; } else { var ret = new GlTF_Node(globals, name, mat, parent); globals.nodes[name] = ret; created = true; return(ret); } return(globals.nodes[name]); }
// Private to force people to use the better-named CloneWithDifferentType() method. private GlTF_Accessor(GlTF_Globals G, GlTF_Accessor fromAccessor, Type newType) : base(G) { m_clonedFrom = fromAccessor; if (newType >= fromAccessor.type) { throw new ArgumentException("newType must be smaller than fromAccessor.type"); } this.name = $"{fromAccessor.name}_{newType}"; this.bufferView = fromAccessor.bufferView; this.byteStride = fromAccessor.byteStride; this.type = newType; this.componentType = fromAccessor.componentType; // Leave these null; at serialization time, we "inherit" a value from m_clonedFrom // this.count = fromAccessor.count; // this.byteOffset = fromAccessor.byteOffset; // These aren't nullables because the purity isn't worth the pain, but at least poison them this.maxFloat = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN); this.minFloat = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN); this.minInt = 0x0D00B015; this.maxInt = 0x0D00B015; SanityCheckBufferViewStride(); }
public GlTF_ColorRGB(GlTF_Globals globals, string n, Color c) : base(globals) { name = n; color = c; }