Beispiel #1
0
 // 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;
 }
Beispiel #2
0
 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]);
 }
Beispiel #3
0
        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;
 }
Beispiel #5
0
 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;
 }
Beispiel #6
0
    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]);
    }
Beispiel #7
0
    /// 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);
    }
Beispiel #9
0
    // 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);
    }
Beispiel #10
0
    /// 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]);
    }
Beispiel #11
0
    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));
    }
Beispiel #12
0
    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("}");
    }
Beispiel #13
0
 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;
 }
Beispiel #14
0
    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;
        }
    }
Beispiel #15
0
 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
     };
 }
Beispiel #16
0
    // 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();
    }
Beispiel #17
0
    /// 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'");
        }
    }
Beispiel #18
0
 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;
         }
     }
 }
Beispiel #19
0
 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]);
 }
Beispiel #20
0
    // 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();
    }
Beispiel #21
0
 public GlTF_ColorRGB(GlTF_Globals globals, string n, Color c) : base(globals)
 {
     name = n; color = c;
 }