// Used for gltf imports public void Add(GltfMaterialConverter.UnityMaterial um, GltfMaterialBase gltfMaterial) { if (m_MaterialToIem.ContainsKey(um.material)) { return; } if (um.exportableMaterial == null) { Debug.LogWarning($"gltf imported a non-exportable material {um.material.name}"); return; } IExportableMaterial iem; if (um.material == um.template) { // No customizations made, so we can use the IEM we're given instead of making a child IEM. // This must be a "global" material (ie, Blocks, or Tilt Brush brush) iem = um.exportableMaterial; } else if (gltfMaterial is Gltf2Material gltf2Material) { // It's hard to introspect UnityEngine.Materials to see how um.material was customized from // um.template, so instead we make guesses based on what we find in the gltf. var pbr = gltf2Material.pbrMetallicRoughness; if (pbr == null) { Debug.LogWarning($"{um.material.name} looks like a generated material, but has no pbr"); iem = null; } else { iem = new DynamicExportableMaterial( parent: um.exportableMaterial, durableName: gltf2Material.name, uniqueName: MakeDeterministicUniqueName(m_numAdded++, gltf2Material.name), uriBase: m_AssetLocation) { BaseColorFactor = pbr.baseColorFactor, BaseColorTex = pbr.baseColorTexture?.texture?.SourcePtr?.uri, MetallicFactor = pbr.metallicFactor, RoughnessFactor = pbr.roughnessFactor }; } } else { // The only source of gltf1 is TB-on-poly, or the first revision of Quest export-to-glb. // Neither is worth the effort of supporting? Debug.LogWarning($"{um.material.name}: no support for non-global materials in gltf1"); iem = null; } if (iem != null) { m_MaterialToIem.Add(um.material, iem); } }
// widget.ReferenceImage must be != null // Never returns null // id is an instance id static ImageQuadPayload BuildImageQuadPayload( SceneStatePayload payload, ImageWidget widget, DynamicExportableMaterial material, int id) { string nodeName = $"image_{widget.GetExportName()}_{id}"; // The child has no T or R but has some non-uniform S that we need to preserve. // I'm going to do this by baking it into the GeometryPool GameObject widgetChild = widget.m_ImageQuad.gameObject; Matrix4x4 xform = ExportUtils.ChangeBasis(widget.transform, payload); Vector3 localScale = widgetChild.transform.localScale; // localScale is a muddle of aspect ratio and overall size. We don't know which of x or y // was modified to set the aspect ratio, so get the size from z. if (localScale.z > 0) { float overallSize = localScale.z; localScale /= overallSize; xform = xform * Matrix4x4.Scale(Vector3.one * overallSize); } // Create pool and bake in the leftover non-uniform scale GeometryPool pool = new GeometryPool(); pool.Layout = material.VertexLayout; pool.Append(widgetChild.GetComponent <MeshFilter>().sharedMesh, fallbackColor: Color.white); pool.ApplyTransform( Matrix4x4.Scale(localScale), Matrix4x4.identity, 1f, 0, pool.NumVerts); // Important: This transform should only be applied once, since the pools are shared, and // cannot include any mesh-local transformations. ExportUtils.ConvertUnitsAndChangeBasis(pool, payload); if (payload.reverseWinding) { // Note: this triangle flip intentionally un-does the Unity FBX import flip. ExportUtils.ReverseTriangleWinding(pool, 1, 2); } return(new ExportUtils.ImageQuadPayload(payload.groupIdMapping.GetId(widget.Group)) { // because Count always increments, this is guaranteed unique even if two different images // have the same export name legacyUniqueName = $"refimage_i{payload.imageQuads.Count}", // We could (but don't) share the same aspect-ratio'd-quad for all instances of a refimage. // Since the mesh is unique to the node, it can have the same name as the node. geometryName = nodeName, nodeName = nodeName, xform = xform, geometry = pool, exportableMaterial = material, }); }