// Returns the gltf mesh that corresponds to the payload, or null.
    // Currently, null is only returned if the payload's 'geometry pool is empty.
    // Pass a localXf to override the default, which is to use base.xform
    public GlTF_Node ExportMeshPayload(
        SceneStatePayload payload,
        BaseMeshPayload meshPayload,
        [CanBeNull] GlTF_Node parent,
        Matrix4x4?localXf = null)
    {
        var node = ExportMeshPayload_NoMaterial(meshPayload, parent, localXf);

        if (node != null)
        {
            IExportableMaterial exportableMaterial = meshPayload.exportableMaterial;
            if (!G.materials.ContainsKey(exportableMaterial))
            {
                var prims = node.m_mesh?.primitives;
                var attrs = (prims != null && prims.Count > 0) ? prims[0].attributes : null;
                if (attrs != null)
                {
                    ExportMaterial(payload, meshPayload.MeshNamespace, exportableMaterial, attrs);
                    Debug.Assert(G.materials.ContainsKey(exportableMaterial));
                }
            }
        }

        return(node);
    }
    // Doesn't do material export; for that see ExportMeshPayload
    private GlTF_Node ExportMeshPayload_NoMaterial(
        BaseMeshPayload mesh,
        [CanBeNull] GlTF_Node parent,
        Matrix4x4?localXf = null)
    {
        ObjectName   meshNameAndId = new ObjectName(mesh.legacyUniqueName);
        GeometryPool pool          = mesh.geometry;
        Matrix4x4    xf            = localXf ?? mesh.xform;
        // Create a Node and (usually) a Mesh, both named after meshNameAndId.
        // This is safe because the namespaces for Node and Mesh are distinct.
        // If we have already seen the GeometryPool, the Mesh will be reused.
        // In this (less common) case, the Node and Mesh will have different names.

        // We don't actually ever use the "VERTEXID" attribute, even in gltf1.
        // It's time to cut it away.
        // Also, in gltf2, it needs to be called _VERTEXID anyway since it's a custom attribute
        GlTF_VertexLayout gltfLayout = new GlTF_VertexLayout(G, pool.Layout);

        int numTris = pool.NumTriIndices / 3;

        if (numTris < 1)
        {
            return(null);
        }

        NumTris += numTris;

        GlTF_Mesh gltfMesh;

        // Share meshes for any repeated geometry pool.
        if (!m_meshCache.TryGetValue(pool, out gltfMesh))
        {
            gltfMesh      = new GlTF_Mesh(G);
            gltfMesh.name = GlTF_Mesh.GetNameFromObject(meshNameAndId);
            gltfMesh.PresentationNameOverride = mesh.geometryName;
            m_meshCache.Add(pool, gltfMesh);

            // Populate mesh data only once.
            AddMeshDependencies(meshNameAndId, mesh.exportableMaterial, gltfMesh, gltfLayout);
            gltfMesh.Populate(pool);
            G.meshes.Add(gltfMesh);
        }

        // The mesh may or may not be shared, but every mesh will have a distinct node to allow them
        // to have unique transforms.
        GlTF_Node node = GlTF_Node.GetOrCreate(G, meshNameAndId, xf, parent, out _);

        node.m_mesh = gltfMesh;
        node.PresentationNameOverride = mesh.nodeName;
        return(node);
    }
Example #3
0
        // This writes out payload.xform
        static FbxNode ExportMeshPayload_Global(
            FbxExportGlobals G, BaseMeshPayload payload, FbxNode parentNode)
        {
            // If these aren't unique, either FBX or Unity will uniquify them for us -- not sure which.
            // So roll payload.id into the name.
            FbxNode fbxNode = FbxNode.Create(G.m_manager, payload.nodeName);

            fbxNode.SetLocalTransform(payload.xform);
            fbxNode.SetNodeAttribute(G.GetOrCreateFbxMesh(payload));
            fbxNode.AddMaterial(G.GetOrCreateFbxMaterial(
                                    payload.MeshNamespace, payload.exportableMaterial));

            parentNode.AddChild(fbxNode);
            return(fbxNode);
        }