示例#1
0
        void ApplyBlendShapeFramesToMeshAndBuildMap()
        {
            if (MBVersion.GetMajorVersion() > 5 ||
                (MBVersion.GetMajorVersion() == 5 && MBVersion.GetMinorVersion() >= 3))
            {
                if (blendShapesInCombined.Length != blendShapes.Length)
                {
                    blendShapesInCombined = new MBBlendShape[blendShapes.Length];
                }
                Vector3[] targVerts = new UnityEngine.Vector3[verts.Length];
                Vector3[] targNorms = new UnityEngine.Vector3[verts.Length];
                Vector3[] targTans  = new UnityEngine.Vector3[verts.Length];

                ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = null;

                MBVersion.ClearBlendShapes(_mesh);
                for (int bsIdx = 0; bsIdx < blendShapes.Length; bsIdx++)
                {
                    MBBlendShape         blendShape = blendShapes[bsIdx];
                    MB_DynamicGameObject dgo        = instance2Combined_MapGet(blendShape.gameObject);
                    if (dgo != null)
                    {
                        int destIdx = dgo.vertIdx;
                        for (int frmIdx = 0; frmIdx < blendShape.frames.Length; frmIdx++)
                        {
                            MBBlendShapeFrame frame = blendShape.frames[frmIdx];
                            Array.Copy(frame.vertices, 0, targVerts, destIdx, frame.vertices.Length);
                            Array.Copy(frame.normals, 0, targNorms, destIdx, frame.normals.Length);
                            Array.Copy(frame.tangents, 0, targTans, destIdx, frame.tangents.Length);
                            MBVersion.AddBlendShapeFrame(_mesh, ConvertBlendShapeNameToOutputName(blendShape.name) + blendShape.gameObjectID, frame.frameWeight, targVerts, targNorms, targTans);
                            // We re-use these arrays restore them to zero
                            _ZeroArray(targVerts, destIdx, frame.vertices.Length);
                            _ZeroArray(targNorms, destIdx, frame.normals.Length);
                            _ZeroArray(targTans, destIdx, frame.tangents.Length);
                        }
                    }
                    else
                    {
                        Debug.LogError("InstanceID in blend shape that was not in instance2combinedMap");
                    }
                    blendShapesInCombined[bsIdx] = blendShape;
                }

                //this is necessary to get the renderer to refresh its data about the blendshapes.
                ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = null;
                ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = _mesh;

                // Add the map to the target renderer.
                if (settings.doBlendShapes)
                {
                    MB_BlendShape2CombinedMap mapComponent = _targetRenderer.GetComponent <MB_BlendShape2CombinedMap>();
                    if (mapComponent == null)
                    {
                        mapComponent = _targetRenderer.gameObject.AddComponent <MB_BlendShape2CombinedMap>();
                    }
                    SerializableSourceBlendShape2Combined map = mapComponent.GetMap();
                    BuildSrcShape2CombinedMap(map, blendShapes);
                }
            }
        }
示例#2
0
        public void SetMeshIndexFormatAndClearMesh(Mesh m, int numVerts, bool vertices, bool justClearTriangles)
        {
#if UNITY_2017_3_OR_NEWER
            if (vertices && numVerts > 65534 && m.indexFormat == UnityEngine.Rendering.IndexFormat.UInt16)
            {
                MBVersion.MeshClear(m, false);
                m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                return;
            }
            else if (vertices && numVerts <= 65534 && m.indexFormat == UnityEngine.Rendering.IndexFormat.UInt32)
            {
                MBVersion.MeshClear(m, false);
                m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt16;
                return;
            }
#endif
            if (justClearTriangles)
            {
                MBVersion.MeshClear(m, true); //clear just triangles
            }
            else
            {//clear all the data and start with a blank mesh
                MBVersion.MeshClear(m, false);
            }
        }
示例#3
0
 public static Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.GetMeshUV3orUV4(m, get3, LOG_LEVEL));
 }
示例#4
0
 public static bool IsRunningAndMeshNotReadWriteable(Mesh m)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.IsRunningAndMeshNotReadWriteable(m));
 }
示例#5
0
 public static UnityEngine.Object[] FindSceneObjectsOfType(Type t)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.FindSceneObjectsOfType(t));
 }
示例#6
0
 public static void SetActiveRecursively(GameObject go, bool isActive)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     MBVersion._MBVersion.SetActiveRecursively(go, isActive);
 }
示例#7
0
 public static bool GetActive(GameObject go)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.GetActive(go));
 }
示例#8
0
 public static int GetMinorVersion()
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.GetMinorVersion());
 }
示例#9
0
 public static string version()
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.version());
 }
示例#10
0
 public static Transform[] GetBones(Renderer r)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.GetBones(r));
 }
示例#11
0
 public static Vector4 GetLightmapTilingOffset(Renderer r)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     return(MBVersion._MBVersion.GetLightmapTilingOffset(r));
 }
示例#12
0
 public static void MeshAssignUV4(Mesh m, Vector2[] uv4s)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     MBVersion._MBVersion.MeshAssignUV4(m, uv4s);
 }
示例#13
0
 public static void MeshClear(Mesh m, bool t)
 {
     if (MBVersion._MBVersion == null)
     {
         MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete();
     }
     MBVersion._MBVersion.MeshClear(m, t);
 }
示例#14
0
 /// <summary>
 /// Get the blend shapes from the source mesh
 /// </summary>
 public static MBBlendShape[] GetBlendShapes(Mesh m, int gameObjectID, GameObject gameObject, Dictionary <int, MeshChannels> meshID2MeshChannels)
 {
     if (MBVersion.GetMajorVersion() > 5 ||
         (MBVersion.GetMajorVersion() == 5 && MBVersion.GetMinorVersion() >= 3))
     {
         MeshChannels mc;
         if (!meshID2MeshChannels.TryGetValue(m.GetInstanceID(), out mc))
         {
             mc = new MeshChannels();
             meshID2MeshChannels.Add(m.GetInstanceID(), mc);
         }
         if (mc.blendShapes == null)
         {
             MBBlendShape[] shapes   = new MBBlendShape[m.blendShapeCount];
             int            arrayLen = m.vertexCount;
             for (int shapeIdx = 0; shapeIdx < shapes.Length; shapeIdx++)
             {
                 MBBlendShape shape = shapes[shapeIdx] = new MBBlendShape();
                 shape.frames        = new MBBlendShapeFrame[MBVersion.GetBlendShapeFrameCount(m, shapeIdx)];
                 shape.name          = m.GetBlendShapeName(shapeIdx);
                 shape.indexInSource = shapeIdx;
                 shape.gameObjectID  = gameObjectID;
                 shape.gameObject    = gameObject;
                 for (int frameIdx = 0; frameIdx < shape.frames.Length; frameIdx++)
                 {
                     MBBlendShapeFrame frame = shape.frames[frameIdx] = new MBBlendShapeFrame();
                     frame.frameWeight = MBVersion.GetBlendShapeFrameWeight(m, shapeIdx, frameIdx);
                     frame.vertices    = new Vector3[arrayLen];
                     frame.normals     = new Vector3[arrayLen];
                     frame.tangents    = new Vector3[arrayLen];
                     MBVersion.GetBlendShapeFrameVertices(m, shapeIdx, frameIdx, frame.vertices, frame.normals, frame.tangents);
                 }
             }
             mc.blendShapes = shapes;
             return(mc.blendShapes);
         }
         else
         { //copy cached blend shapes from same mesh assiged to a different gameObjectID
             MBBlendShape[] shapes = new MBBlendShape[mc.blendShapes.Length];
             for (int i = 0; i < shapes.Length; i++)
             {
                 shapes[i]               = new MBBlendShape();
                 shapes[i].name          = mc.blendShapes[i].name;
                 shapes[i].indexInSource = mc.blendShapes[i].indexInSource;
                 shapes[i].frames        = mc.blendShapes[i].frames;
                 shapes[i].gameObjectID  = gameObjectID;
                 shapes[i].gameObject    = gameObject;
             }
             return(shapes);
         }
     }
     else
     {
         return(new MBBlendShape[0]);
     }
 }
 internal MBBlendShape[] GetBlendShapes(Mesh m, int gameObjectID, GameObject gameObject)
 {
     if (MBVersion.GetMajorVersion() > 5 ||
         (MBVersion.GetMajorVersion() == 5 && MBVersion.GetMinorVersion() >= 3))
     {
         MeshChannels mc;
         if (!meshID2MeshChannels.TryGetValue(m.GetInstanceID(), out mc))
         {
             mc = new MeshChannels();
             meshID2MeshChannels.Add(m.GetInstanceID(), mc);
         }
         if (mc.blendShapes == null)
         {
             MBBlendShape[] shapes   = new MBBlendShape[m.blendShapeCount];
             int            arrayLen = m.vertexCount;
             for (int i = 0; i < shapes.Length; i++)
             {
                 MBBlendShape shape = shapes[i] = new MBBlendShape();
                 shape.frames        = new MBBlendShapeFrame[MBVersion.GetBlendShapeFrameCount(m, i)];
                 shape.name          = m.GetBlendShapeName(i);
                 shape.indexInSource = i;
                 shape.gameObjectID  = gameObjectID;
                 shape.gameObject    = gameObject;
                 for (int j = 0; j < shape.frames.Length; j++)
                 {
                     MBBlendShapeFrame frame = shape.frames[j] = new MBBlendShapeFrame();
                     frame.frameWeight = MBVersion.GetBlendShapeFrameWeight(m, i, j);
                     frame.vertices    = new Vector3[arrayLen];
                     frame.normals     = new Vector3[arrayLen];
                     frame.tangents    = new Vector3[arrayLen];
                     MBVersion.GetBlendShapeFrameVertices(m, i, j, frame.vertices, frame.normals, frame.tangents);
                 }
             }
             mc.blendShapes = shapes;
             return(mc.blendShapes);
         }
         else
         { //copy cached blend shapes assigning a different gameObjectID
             MBBlendShape[] shapes = new MBBlendShape[mc.blendShapes.Length];
             for (int i = 0; i < shapes.Length; i++)
             {
                 shapes[i]               = new MBBlendShape();
                 shapes[i].name          = mc.blendShapes[i].name;
                 shapes[i].indexInSource = mc.blendShapes[i].indexInSource;
                 shapes[i].frames        = mc.blendShapes[i].frames;
                 shapes[i].gameObjectID  = gameObjectID;
                 shapes[i].gameObject    = gameObject;
             }
             return(shapes);
         }
     }
     else
     {
         return(new MBBlendShape[0]);
     }
 }
        MB3_TextureCombinerPipeline.TexturePipelineData LoadPipelineData(Material resultMaterial,
                                                                         List <ShaderTextureProperty> texPropertyNames,
                                                                         List <GameObject> objsToMesh,
                                                                         List <Material> allowedMaterialsFilter,
                                                                         List <MB_TexSet> distinctMaterialTextures)
        {
            MB3_TextureCombinerPipeline.TexturePipelineData data = new MB3_TextureCombinerPipeline.TexturePipelineData();
            data._textureBakeResults = _textureBakeResults;
            data._atlasPadding       = _atlasPadding;
            if (_packingAlgorithm == MB2_PackingAlgorithmEnum.MeshBakerTexturePacker_Vertical && _useMaxAtlasHeightOverride)
            {
                data._maxAtlasHeight            = _maxAtlasHeightOverride;
                data._useMaxAtlasHeightOverride = true;
            }
            else
            {
                data._maxAtlasHeight = _maxAtlasSize;
            }

            if (_packingAlgorithm == MB2_PackingAlgorithmEnum.MeshBakerTexturePacker_Horizontal && _useMaxAtlasWidthOverride)
            {
                data._maxAtlasWidth            = _maxAtlasWidthOverride;
                data._useMaxAtlasWidthOverride = true;
            }
            else
            {
                data._maxAtlasWidth = _maxAtlasSize;
            }

            data._saveAtlasesAsAssets      = _saveAtlasesAsAssets;
            data.resultType                = _resultType;
            data._resizePowerOfTwoTextures = _resizePowerOfTwoTextures;
            data._fixOutOfBoundsUVs        = _fixOutOfBoundsUVs;
            data._maxTilingBakeSize        = _maxTilingBakeSize;
            data._packingAlgorithm         = _packingAlgorithm;
            data._layerTexturePackerFastV2 = _layerTexturePackerFastMesh;
            data._meshBakerTexturePackerForcePowerOfTwo = _meshBakerTexturePackerForcePowerOfTwo;
            data._customShaderPropNames        = _customShaderPropNames;
            data._normalizeTexelDensity        = _normalizeTexelDensity;
            data._considerNonTextureProperties = _considerNonTextureProperties;
            data.doMergeDistinctMaterialTexturesThatWouldExceedAtlasSize = _doMergeDistinctMaterialTexturesThatWouldExceedAtlasSize;
            data.nonTexturePropertyBlender = new MB3_TextureCombinerNonTextureProperties(LOG_LEVEL, _considerNonTextureProperties);
            data.resultMaterial            = resultMaterial;
            data.distinctMaterialTextures  = distinctMaterialTextures;
            data.allObjsToMesh             = objsToMesh;
            data.allowedMaterialsFilter    = allowedMaterialsFilter;
            data.texPropertyNames          = texPropertyNames;
            data.colorSpace = MBVersion.GetProjectColorSpace();
            return(data);
        }
            internal Vector2[] GetUv4(Mesh m)
            {
                MeshChannels mc;

                if (!meshID2MeshChannels.TryGetValue(m.GetInstanceID(), out mc))
                {
                    mc = new MeshChannels();
                    meshID2MeshChannels.Add(m.GetInstanceID(), mc);
                }
                if (mc.uv4 == null)
                {
                    mc.uv4 = MBVersion.GetMeshUV3orUV4(m, false, this.mc.LOG_LEVEL);
                }
                return(mc.uv4);
            }
        public void DrawGUI(MB_IMeshBakerSettings momm, bool settingsEnabled)
        {
            EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle);
            GUI.enabled = settingsEnabled;
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doNorm, gc_doNormGUIContent);
            EditorGUILayout.PropertyField(doTan, gc_doTanGUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doUV, gc_doUVGUIContent);
            EditorGUILayout.PropertyField(doUV3, gc_doUV3GUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doUV4, gc_doUV4GUIContent);
            EditorGUILayout.PropertyField(doCol, gc_doColGUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.PropertyField(doBlendShapes, gc_doBlendShapeGUIContent);

            if (momm.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping)
            {
                if (MBVersion.GetMajorVersion() == 5)
                {
                    EditorGUILayout.HelpBox("The best choice for Unity 5 is to Ignore_UV2 or Generate_New_UV2 layout. Unity's baked GI will create the UV2 layout it wants. See manual for more information.", MessageType.Warning);
                }
            }

            if (momm.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
            {
                EditorGUILayout.HelpBox("Generating new lightmap UVs can split vertices which can push the number of vertices over the 64k limit.", MessageType.Warning);
            }

            EditorGUILayout.PropertyField(lightmappingOption, gc_lightmappingOptionGUIContent);
            if (momm.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
            {
                EditorGUILayout.PropertyField(uv2OutputParamsHardAngle, gc_uv2HardAngleGUIContent);
                EditorGUILayout.PropertyField(uv2OutputParamsPackingMargin, gc_uv2PackingMarginUV3GUIContent);
                EditorGUILayout.Separator();
            }

            EditorGUILayout.PropertyField(renderType, gc_renderTypeGUIContent);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(clearBuffersAfterBake, gc_clearBuffersAfterBakeGUIContent);
            EditorGUILayout.PropertyField(centerMeshToBoundsCenter, gc_CenterMeshToBoundsCenter);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.PropertyField(optimizeAfterBake, gc_OptimizeAfterBake);
            GUI.enabled = true;
            EditorGUILayout.EndVertical();
        }
示例#19
0
        //float _maxTimePerFrameForCoroutine;
        public IEnumerator CombineTexturesIntoAtlasesCoroutine(ProgressUpdateDelegate progressInfo, MB_AtlasesAndRects resultAtlasesAndRects, Material resultMaterial, List <GameObject> objsToMesh, List <Material> allowedMaterialsFilter, MB2_EditorMethodsInterface textureEditorMethods = null, CombineTexturesIntoAtlasesCoroutineResult coroutineResult = null, float maxTimePerFrame = .01f, List <AtlasPackingResult> packingResults = null, bool onlyPackRects = false, bool splitAtlasWhenPackingIfTooBig = false)
        {
            if (!_RunCorutineWithoutPauseIsRunning && (MBVersion.GetMajorVersion() < 5 || (MBVersion.GetMajorVersion() == 5 && MBVersion.GetMinorVersion() < 3)))
            {
                Debug.LogError("Running the texture combiner as a coroutine only works in Unity 5.3 and higher");
                yield return(null);
            }
            coroutineResult.success    = true;
            coroutineResult.isFinished = false;
            if (maxTimePerFrame <= 0f)
            {
                Debug.LogError("maxTimePerFrame must be a value greater than zero");
                coroutineResult.isFinished = true;
                yield break;
            }
            //_maxTimePerFrameForCoroutine = maxTimePerFrame;
            yield return(_CombineTexturesIntoAtlases(progressInfo, coroutineResult, resultAtlasesAndRects, resultMaterial, objsToMesh, allowedMaterialsFilter, textureEditorMethods, packingResults, onlyPackRects, splitAtlasWhenPackingIfTooBig));

            coroutineResult.isFinished = true;
            yield break;
        }
示例#20
0
        internal void SetupCameraGameObject(GameObject camGameObject)
        {
            Debug.Assert(_initialized);
            Debug.Assert(LayerMask.LayerToName(camMaskLayer) != null || LayerMask.LayerToName(camMaskLayer) != "");
            LayerMask camMask  = 1 << camMaskLayer;
            Camera    myCamera = camGameObject.AddComponent <Camera>();

            myCamera.enabled          = false;
            myCamera.orthographic     = true;
            myCamera.orthographicSize = height / 2f;
            myCamera.aspect           = ((float)width) / height;
            myCamera.rect             = new Rect(0, 0, 1, 1);
            myCamera.clearFlags       = CameraClearFlags.Color;
            myCamera.cullingMask      = camMask;
            Transform camTransform = myCamera.GetComponent <Transform>();

            camTransform.localPosition = new Vector3(width / 2.0f, height / 2f, 0);
            camTransform.localRotation = Quaternion.Euler(0, 0, 0);

            MBVersion.DoSpecialRenderPipeline_TexturePackerFastSetup(camGameObject);

            _camSetup = true;
        }
示例#21
0
        void ApplyBlendShapeFramesToMeshAndBuildMap_MergeBlendShapesWithTheSameName()
        {
            if (MBVersion.GetMajorVersion() > 5 ||
                (MBVersion.GetMajorVersion() == 5 && MBVersion.GetMinorVersion() >= 3))
            {
                Vector3[] targVerts = new UnityEngine.Vector3[verts.Length];
                Vector3[] targNorms = new UnityEngine.Vector3[verts.Length];
                Vector3[] targTans  = new UnityEngine.Vector3[verts.Length];

                MBVersion.ClearBlendShapes(_mesh);

                // Group source that share the same blendShapeName
                bool numFramesError = false;
                Dictionary <string, List <MBBlendShape> > shapeName2objs = new Dictionary <string, List <MBBlendShape> >();
                {
                    for (int i = 0; i < blendShapes.Length; i++)
                    {
                        MBBlendShape        blendShape     = blendShapes[i];
                        string              blendShapeName = ConvertBlendShapeNameToOutputName(blendShape.name);
                        List <MBBlendShape> dgosUsingBlendShape;
                        if (!shapeName2objs.TryGetValue(blendShapeName, out dgosUsingBlendShape))
                        {
                            dgosUsingBlendShape = new List <MBBlendShape>();
                            shapeName2objs.Add(blendShapeName, dgosUsingBlendShape);
                        }

                        dgosUsingBlendShape.Add(blendShape);
                        if (dgosUsingBlendShape.Count > 1)
                        {
                            if (dgosUsingBlendShape[0].frames.Length != blendShape.frames.Length)
                            {
                                Debug.LogError("BlendShapes with the same name must have the same number of frames.");
                                numFramesError = true;
                            }
                        }
                    }
                }

                if (numFramesError)
                {
                    return;
                }

                if (blendShapesInCombined.Length != blendShapes.Length)
                {
                    blendShapesInCombined = new MBBlendShape[shapeName2objs.Keys.Count];
                }

                int bsInCombinedIdx = 0;
                foreach (string shapeName in shapeName2objs.Keys)
                {
                    List <MBBlendShape> groupOfSrcObjs  = shapeName2objs[shapeName];
                    MBBlendShape        firstBlendShape = groupOfSrcObjs[0];
                    int    numFrames        = firstBlendShape.frames.Length;
                    int    db_numVertsAdded = 0;
                    int    db_numObjsAdded  = 0;
                    string db_vIdx          = "";

                    for (int frmIdx = 0; frmIdx < numFrames; frmIdx++)
                    {
                        float firstFrameWeight = firstBlendShape.frames[frmIdx].frameWeight;

                        for (int dgoIdx = 0; dgoIdx < groupOfSrcObjs.Count; dgoIdx++)
                        {
                            MBBlendShape         blendShape = groupOfSrcObjs[dgoIdx];
                            MB_DynamicGameObject dgo        = instance2Combined_MapGet(blendShape.gameObject);
                            int destIdx = dgo.vertIdx;
                            Debug.Assert(blendShape.frames.Length == numFrames);
                            MBBlendShapeFrame frame = blendShape.frames[frmIdx];
                            Debug.Assert(frame.frameWeight == firstFrameWeight);
                            Array.Copy(frame.vertices, 0, targVerts, destIdx, frame.vertices.Length);
                            Array.Copy(frame.normals, 0, targNorms, destIdx, frame.normals.Length);
                            Array.Copy(frame.tangents, 0, targTans, destIdx, frame.tangents.Length);
                            if (frmIdx == 0)
                            {
                                db_numVertsAdded += frame.vertices.Length;
                                db_vIdx          += blendShape.gameObject.name + " " + destIdx + ":" + (destIdx + frame.vertices.Length) + ", ";
                            }
                        }

                        db_numObjsAdded += groupOfSrcObjs.Count;
                        MBVersion.AddBlendShapeFrame(_mesh, shapeName, firstFrameWeight, targVerts, targNorms, targTans);

                        // We re-use these arrays restore them to zero
                        _ZeroArray(targVerts, 0, targVerts.Length);
                        _ZeroArray(targNorms, 0, targNorms.Length);
                        _ZeroArray(targTans, 0, targTans.Length);
                    }

                    blendShapesInCombined[bsInCombinedIdx] = firstBlendShape;
                    bsInCombinedIdx++;
                }



                //this is necessary to get the renderer to refresh its data about the blendshapes.
                ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = null;
                ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = _mesh;

                // Add the map to the target renderer.
                if (settings.doBlendShapes)
                {
                    MB_BlendShape2CombinedMap mapComponent = _targetRenderer.GetComponent <MB_BlendShape2CombinedMap>();
                    if (mapComponent == null)
                    {
                        mapComponent = _targetRenderer.gameObject.AddComponent <MB_BlendShape2CombinedMap>();
                    }
                    SerializableSourceBlendShape2Combined map = mapComponent.GetMap();
                    BuildSrcShape2CombinedMap(map, blendShapesInCombined);
                }
            }
        }
示例#22
0
        /// <summary>
        /// Creates one texture array per texture property.
        /// </summary>
        /// <returns></returns>
        internal static Texture2DArray[] CreateTextureArraysForResultMaterial(TexturePropertyData texPropertyData, List <ShaderTextureProperty> masterListOfTexProperties, MB_AtlasesAndRects[] resultAtlasesAndRectSlices,
                                                                              bool[] hasTexForProperty, MB3_TextureCombiner combiner, MB2_LogLevel LOG_LEVEL)
        {
            Debug.Assert(texPropertyData.sizes.Length == hasTexForProperty.Length);

            // ASSUMPTION all slices in the same format and the same size, alpha channel and mipMapCount
            string[] texPropertyNames = resultAtlasesAndRectSlices[0].texPropertyNames;
            Debug.Assert(texPropertyNames.Length == hasTexForProperty.Length);
            Texture2DArray[] texArrays = new Texture2DArray[texPropertyNames.Length];

            // Each texture property (_MainTex, _Bump, ...) becomes a Texture2DArray
            for (int propIdx = 0; propIdx < texPropertyNames.Length; propIdx++)
            {
                if (!hasTexForProperty[propIdx])
                {
                    continue;
                }
                string        propName  = texPropertyNames[propIdx];
                int           numSlices = resultAtlasesAndRectSlices.Length;
                int           w         = (int)texPropertyData.sizes[propIdx].x;
                int           h         = (int)texPropertyData.sizes[propIdx].y;
                int           numMips   = (int)texPropertyData.numMipMaps[propIdx];
                TextureFormat format    = texPropertyData.formats[propIdx];
                bool          doMipMaps = texPropertyData.doMips[propIdx];

                Debug.Assert(QualitySettings.desiredColorSpace == QualitySettings.activeColorSpace, "Wanted to use color space " + QualitySettings.desiredColorSpace + " but the activeColorSpace was " + QualitySettings.activeColorSpace + " hardware may not support the desired color space.");

                bool isLinear = MBVersion.GetProjectColorSpace() == ColorSpace.Linear;
                {
                    if (IsLinearProperty(masterListOfTexProperties, propName))
                    {
                        isLinear = true;
                    }
                    else
                    {
                        isLinear = false;
                    }
                }

                Texture2DArray texArray = new Texture2DArray(w, h, numSlices, format, doMipMaps, isLinear);
                if (LOG_LEVEL >= MB2_LogLevel.info)
                {
                    Debug.LogFormat("Creating Texture2DArray for property: {0} w: {1} h: {2} format: {3} doMips: {4} isLinear: {5}", propName, w, h, format, doMipMaps, isLinear);
                }
                for (int sliceIdx = 0; sliceIdx < numSlices; sliceIdx++)
                {
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].atlases.Length == texPropertyNames.Length);
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].texPropertyNames[propIdx] == propName);
                    Texture2D srcTex = resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx];

                    if (LOG_LEVEL >= MB2_LogLevel.debug)
                    {
                        Debug.LogFormat("Slice: {0}  texture: {1}", sliceIdx, srcTex);
                    }
                    bool isCopy = false;
                    if (srcTex == null)
                    {
                        if (LOG_LEVEL >= MB2_LogLevel.trace)
                        {
                            Debug.LogFormat("Texture is null for slice: {0} creating temporary texture", sliceIdx);
                        }
                        // Slices might not have all textures create a dummy if needed.
                        srcTex = combiner._createTemporaryTexture(propName, w, h, format, doMipMaps, isLinear);
                    }

                    Debug.Assert(srcTex.width == texArray.width, "Source texture is not the same width as the texture array '" + srcTex + " srcWidth:" + srcTex.width + " texArrayWidth:" + texArray.width);
                    Debug.Assert(srcTex.height == texArray.height, "Source texture is not the same height as the texture array " + srcTex + " srcWidth:" + srcTex.height + " texArrayWidth:" + texArray.height);
                    Debug.Assert(srcTex.mipmapCount == numMips, "Source texture does have not the same number of mips as the texture array: " + srcTex + " numMipsTex: " + srcTex.mipmapCount + " numMipsTexArray: " + numMips + " texDims: " + srcTex.width + "x" + srcTex.height);
                    Debug.Assert(srcTex.format == format, "Formats should have been converted before this. Texture: " + srcTex + "Source: " + srcTex.format + " Targ: " + format);

                    for (int mipIdx = 0; mipIdx < numMips; mipIdx++)
                    {
                        Graphics.CopyTexture(srcTex, 0, mipIdx, texArray, sliceIdx, mipIdx);
                    }

                    if (isCopy)
                    {
                        MB_Utility.Destroy(srcTex);
                    }
                }

                texArray.Apply();
                texArrays[propIdx] = texArray;
            }

            return(texArrays);
        }
示例#23
0
        internal static bool ConvertTexturesToReadableFormat(TexturePropertyData texturePropertyData,
                                                             MB_AtlasesAndRects[] resultAtlasesAndRectSlices,
                                                             bool[] hasTexForProperty, List <ShaderTextureProperty> textureShaderProperties,
                                                             MB3_TextureCombiner combiner,
                                                             MB2_LogLevel logLevel,
                                                             List <Texture2D> createdTemporaryTextureAssets,
                                                             MB2_EditorMethodsInterface textureEditorMethods)
        {
            for (int propIdx = 0; propIdx < hasTexForProperty.Length; propIdx++)
            {
                if (!hasTexForProperty[propIdx])
                {
                    continue;
                }

                TextureFormat format = texturePropertyData.formats[propIdx];

                if (!textureEditorMethods.TextureImporterFormatExistsForTextureFormat(format))
                {
                    Debug.LogError("Could not find target importer format matching " + format);
                    return(false);
                }

                int numSlices    = resultAtlasesAndRectSlices.Length;
                int targetWidth  = (int)texturePropertyData.sizes[propIdx].x;
                int targetHeight = (int)texturePropertyData.sizes[propIdx].y;
                for (int sliceIdx = 0; sliceIdx < numSlices; sliceIdx++)
                {
                    Texture2D sliceTex = resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx];

                    Debug.Assert(sliceTex != null, "sliceIdx " + sliceIdx + " " + propIdx);
                    if (sliceTex != null)
                    {
                        if (!MBVersion.IsTextureReadable(sliceTex))
                        {
                            textureEditorMethods.SetReadWriteFlag(sliceTex, true, true);
                        }

                        bool isAsset = textureEditorMethods.IsAnAsset(sliceTex);
                        if (logLevel >= MB2_LogLevel.trace)
                        {
                            Debug.Log("Considering format of texture: " + sliceTex + " format:" + sliceTex.format);
                        }
                        if ((sliceTex.width != targetWidth || sliceTex.height != targetHeight) ||
                            (!isAsset && sliceTex.format != format))
                        {
                            // Do this the horrible hard way. It is only possible to resize textures in TrueColor formats,
                            // And only possible to switch formats using the Texture importer.
                            // Create a resized temporary texture asset in ARGB32 format. Then set its texture format and reimport
                            resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx] = textureEditorMethods.CreateTemporaryAssetCopy(textureShaderProperties[propIdx], sliceTex, targetWidth, targetHeight, format, logLevel);
                            createdTemporaryTextureAssets.Add(resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx]);
                        }
                        else if (sliceTex.format != format)
                        {
                            textureEditorMethods.ConvertTextureFormat_PlatformOverride(sliceTex, format, textureShaderProperties[propIdx].isNormalMap);
                        }
                    }
                    else
                    {
                    }

                    if (resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx].format != format)
                    {
                        Debug.LogError("Could not convert texture to format " + format +
                                       ". This can happen if the target build platform in build settings does not support textures in this format." +
                                       " It may be necessary to switch the build platform in order to build texture arrays in this format.");
                        return(false);
                    }
                }
            }

            return(true);
        }
            internal Vector2[] GetUVChannel(int channel, Mesh m)
            {
                MeshChannels mc;

                if (!meshID2MeshChannels.TryGetValue(m.GetInstanceID(), out mc))
                {
                    mc = new MeshChannels();
                    meshID2MeshChannels.Add(m.GetInstanceID(), mc);
                }

                switch (channel)
                {
                case 0:
                    if (mc.uv0raw == null)
                    {
                        mc.uv0raw = GetUv0Raw(m);
                    }
                    return(mc.uv0raw);

                case 2:
                    if (mc.uv2 == null)
                    {
                        mc.uv2 = _getMeshUV2s(m);
                    }
                    return(mc.uv2);

                case 3:
                    if (mc.uv3 == null)
                    {
                        mc.uv3 = MBVersion.GetMeshChannel(channel, m, LOG_LEVEL);
                    }
                    return(mc.uv3);

                case 4:
                    if (mc.uv4 == null)
                    {
                        mc.uv4 = MBVersion.GetMeshChannel(channel, m, LOG_LEVEL);
                    }
                    return(mc.uv4);

                case 5:
                    if (mc.uv5 == null)
                    {
                        mc.uv5 = MBVersion.GetMeshChannel(channel, m, LOG_LEVEL);
                    }
                    return(mc.uv5);

                case 6:
                    if (mc.uv6 == null)
                    {
                        mc.uv6 = MBVersion.GetMeshChannel(channel, m, LOG_LEVEL);
                    }
                    return(mc.uv6);

                case 7:
                    if (mc.uv7 == null)
                    {
                        mc.uv7 = MBVersion.GetMeshChannel(channel, m, LOG_LEVEL);
                    }
                    return(mc.uv7);

                case 8:
                    if (mc.uv8 == null)
                    {
                        mc.uv8 = MBVersion.GetMeshChannel(channel, m, LOG_LEVEL);
                    }
                    return(mc.uv8);

                default:
                    Debug.LogError("Error mesh channel " + channel + " not supported");
                    break;
                }

                return(null);
            }
        public void DrawGUI(SerializedObject meshBaker, MB3_MeshBakerCommon target, System.Type editorWindowType)
        {
            if (meshBaker == null)
            {
                return;
            }
            meshBaker.Update();

            showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:");
            if (showInstructions)
            {
                EditorGUILayout.HelpBox("1. Bake combined material(s).\n\n" +
                                        "2. If necessary set the 'Texture Bake Results' field.\n\n" +
                                        "3. Add scene objects or prefabs to combine or check 'Same As Texture Baker'. For best results these should use the same shader as result material.\n\n" +
                                        "4. Select options and 'Bake'.\n\n" +
                                        "6. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" +
                                        "7. (optional) Disable renderers in source objects.", UnityEditor.MessageType.None);

                EditorGUILayout.Separator();
            }

            MB3_MeshBakerCommon momm = (MB3_MeshBakerCommon)target;

            //mom.meshCombiner.LOG_LEVEL = (MB2_LogLevel) EditorGUILayout.EnumPopup("Log Level", mom.meshCombiner.LOG_LEVEL);
            EditorGUILayout.PropertyField(logLevel, gc_logLevelContent);

            EditorGUILayout.PropertyField(textureBakeResults, gc_textureBakeResultsGUIContent);
            if (textureBakeResults.objectReferenceValue != null)
            {
                showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained");
                if (showContainsReport)
                {
                    EditorGUILayout.HelpBox(((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info);
                }
            }

            EditorGUILayout.BeginVertical(editorBoxBackgroundStyle);
            EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel);
            if (momm.GetTextureBaker() != null)
            {
                EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, gc_useTextureBakerObjsGUIContent);
            }
            else
            {
                useObjsToMeshFromTexBaker.boolValue = false;
                momm.useObjsToMeshFromTexBaker      = false;
                GUI.enabled = false;
                EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, gc_useTextureBakerObjsGUIContent);
                GUI.enabled = true;
            }

            if (!momm.useObjsToMeshFromTexBaker)
            {
                if (GUILayout.Button(gc_openToolsWindowLabelContent))
                {
                    MB3_MeshBakerEditorWindowInterface mmWin = (MB3_MeshBakerEditorWindowInterface)EditorWindow.GetWindow(editorWindowType);
                    mmWin.target = (MB3_MeshBakerRoot)target;
                }
                EditorGUILayout.PropertyField(objsToMesh, gc_objectsToCombineGUIContent, true);
                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Select Objects In Scene"))
                {
                    Selection.objects = momm.GetObjectsToCombine().ToArray();
                    if (momm.GetObjectsToCombine().Count > 0)
                    {
                        SceneView.lastActiveSceneView.pivot = momm.GetObjectsToCombine()[0].transform.position;
                    }
                }
                if (GUILayout.Button(gc_SortAlongAxis))
                {
                    MB3_MeshBakerRoot.ZSortObjects sorter = new MB3_MeshBakerRoot.ZSortObjects();
                    sorter.sortAxis = sortOrderAxis.vector3Value;
                    sorter.SortByDistanceAlongAxis(momm.GetObjectsToCombine());
                }
                EditorGUILayout.PropertyField(sortOrderAxis, GUIContent.none);
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                GUI.enabled = false;
                EditorGUILayout.PropertyField(objsToMesh, gc_objectsToCombineGUIContent, true);
                GUI.enabled = true;
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.LabelField("Output", EditorStyles.boldLabel);
            if (momm is MB3_MultiMeshBaker)
            {
                MB3_MultiMeshCombiner mmc = (MB3_MultiMeshCombiner)momm.meshCombiner;
                mmc.maxVertsInMesh = EditorGUILayout.IntField("Max Verts In Mesh", mmc.maxVertsInMesh);
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doNorm, gc_doNormGUIContent);
            EditorGUILayout.PropertyField(doTan, gc_doTanGUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doUV, gc_doUVGUIContent);
            EditorGUILayout.PropertyField(doUV3, gc_doUV3GUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doUV4, gc_doUV4GUIContent);
            EditorGUILayout.PropertyField(doCol, gc_doColGUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.PropertyField(doBlendShapes, gc_doBlendShapeGUIContent);

            if (momm.meshCombiner.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping)
            {
                if (MBVersion.GetMajorVersion() == 5)
                {
                    EditorGUILayout.HelpBox("The best choice for Unity 5 is to Ignore_UV2 or Generate_New_UV2 layout. Unity's baked GI will create the UV2 layout it wants. See manual for more information.", MessageType.Warning);
                }
            }
            if (momm.meshCombiner.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
            {
                EditorGUILayout.HelpBox("Generating new lightmap UVs can split vertices which can push the number of vertices over the 64k limit.", MessageType.Warning);
            }
            EditorGUILayout.PropertyField(lightmappingOption, gc_lightmappingOptionGUIContent);
            if (momm.meshCombiner.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
            {
                EditorGUILayout.PropertyField(uv2OutputParamsHardAngle, gc_uv2HardAngleGUIContent);
                EditorGUILayout.PropertyField(uv2OutputParamsPackingMargin, gc_uv2PackingMarginUV3GUIContent);
                EditorGUILayout.Separator();
            }

            EditorGUILayout.PropertyField(outputOptions, gc_outputOptoinsGUIContent);
            EditorGUILayout.PropertyField(renderType, gc_renderTypeGUIContent);
            if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject)
            {
                //todo switch to renderer
                momm.meshCombiner.resultSceneObject = (GameObject)EditorGUILayout.ObjectField("Combined Mesh Object", momm.meshCombiner.resultSceneObject, typeof(GameObject), true);
                if (momm is MB3_MeshBaker)
                {
                    string l = "Mesh";
                    if (mesh.objectReferenceValue != null)
                    {
                        l += " (" + mesh.objectReferenceValue.GetInstanceID() + ")";
                    }
                    EditorGUILayout.PropertyField(mesh, new GUIContent(l));
                }
            }
            else if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab)
            {
                momm.resultPrefab = (GameObject)EditorGUILayout.ObjectField(gc_combinedMeshPrefabGUIContent, momm.resultPrefab, typeof(GameObject), true);
                if (momm is MB3_MeshBaker)
                {
                    string l = "Mesh";
                    if (mesh.objectReferenceValue != null)
                    {
                        l += " (" + mesh.objectReferenceValue.GetInstanceID() + ")";
                    }
                    EditorGUILayout.PropertyField(mesh, new GUIContent(l));
                }
            }
            else if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace)
            {
                EditorGUILayout.HelpBox("NEW! Try the BatchPrefabBaker component. It makes preparing a batch of prefabs for static/ dynamic batching much easier.", MessageType.Info);
                if (GUILayout.Button("Choose Folder For Bake In Place Meshes"))
                {
                    string newFolder = EditorUtility.SaveFolderPanel("Folder For Bake In Place Meshes", Application.dataPath, "");
                    if (!newFolder.Contains(Application.dataPath))
                    {
                        Debug.LogWarning("The chosen folder must be in your assets folder.");
                    }
                    momm.bakeAssetsInPlaceFolderPath = "Assets" + newFolder.Replace(Application.dataPath, "");
                }
                EditorGUILayout.LabelField("Folder For Meshes: " + momm.bakeAssetsInPlaceFolderPath);
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(clearBuffersAfterBake, gc_clearBuffersAfterBakeGUIContent);
            EditorGUILayout.PropertyField(centerMeshToBoundsCenter, gc_CenterMeshToBoundsCenter);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.PropertyField(optimizeAfterBake, gc_OptimizeAfterBake);
            Color oldColor = GUI.backgroundColor;

            GUI.backgroundColor = buttonColor;
            if (GUILayout.Button("Bake"))
            {
                bake(momm);
            }
            GUI.backgroundColor = oldColor;

            string enableRenderersLabel;
            bool   disableRendererInSource = false;

            if (momm.GetObjectsToCombine().Count > 0)
            {
                Renderer r = MB_Utility.GetRenderer(momm.GetObjectsToCombine()[0]);
                if (r != null && r.enabled)
                {
                    disableRendererInSource = true;
                }
            }
            if (disableRendererInSource)
            {
                enableRenderersLabel = "Disable Renderers On Source Objects";
            }
            else
            {
                enableRenderersLabel = "Enable Renderers On Source Objects";
            }
            if (GUILayout.Button(enableRenderersLabel))
            {
                momm.EnableDisableSourceObjectRenderers(!disableRendererInSource);
            }

            meshBaker.ApplyModifiedProperties();
            meshBaker.SetIsDifferentCacheDirty();
        }
            public UVAdjuster_Atlas(MB2_TextureBakeResults tbr, MB2_LogLevel ll)
            {
                textureBakeResults = tbr;
                LOG_LEVEL          = ll;
                matsAndSrcUVRect   = tbr.materialsAndUVRects;

                {
                    compareNamesWhenComparingMaterials = false;
                    // This is an option if using addressables.
                    // At runtime the materials can be different instances but are the same material.
                    // We replaced this hack by adding the primary key (path to material asset) in the textureBakeResult
                    // User can use this key to find the runtimeMaterial. However somebody could be using something other than
                    // the path as the primary key. Could fall back to using this.
                    if (MBVersion.IsUsingAddressables() &&
                        Application.isPlaying)
                    {
                        compareNamesWhenComparingMaterials = true;
                    }
                    else
                    {
                        compareNamesWhenComparingMaterials = false;
                    }
                }

                //count the number of times a material appears in the atlas. used for fast lookup
                numTimesMatAppearsInAtlas = new int[matsAndSrcUVRect.Length];
                for (int i = 0; i < matsAndSrcUVRect.Length; i++)
                {
                    if (numTimesMatAppearsInAtlas[i] > 1)
                    {
                        continue;
                    }
                    int count = 1;
                    for (int j = i + 1; j < matsAndSrcUVRect.Length; j++)
                    {
                        if (matsAndSrcUVRect[i].material == matsAndSrcUVRect[j].material)
                        {
                            count++;
                        }
                    }
                    numTimesMatAppearsInAtlas[i] = count;
                    if (count > 1)
                    {
                        //allMatsAreUnique = false;
                        for (int j = i + 1; j < matsAndSrcUVRect.Length; j++)
                        {
                            if (matsAndSrcUVRect[i].material == matsAndSrcUVRect[j].material)
                            {
                                numTimesMatAppearsInAtlas[j] = count;
                            }
                        }
                    }
                }

                /*
                 * runtimeMat_2_buildtimeMap = new Dictionary<Material, Material>();
                 * for (int i = 0; i < matsAndSrcUVRect.Length; i++)
                 * {
                 *  if (matsAndSrcUVRect[i].runtimeMaterial != null)
                 *  {
                 *      runtimeMat_2_buildtimeMap.Add(matsAndSrcUVRect[i].runtimeMaterial, matsAndSrcUVRect[i].material);
                 *  } else
                 *  {
                 *      runtimeMat_2_buildtimeMap.Add(matsAndSrcUVRect[i].material, matsAndSrcUVRect[i].material);
                 *  }
                 * }
                 */
            }
示例#27
0
            internal static void BuildAtlas(
                AtlasPackingResult packedAtlasRects,
                List <MB_TexSet> distinctMaterialTextures,
                int propIdx,
                int atlasSizeX, int atlasSizeY,
                Mesh m,
                List <Material> generatedMats,
                ShaderTextureProperty property,
                MB3_TextureCombinerPipeline.TexturePipelineData data,
                MB3_TextureCombiner combiner,
                MB2_EditorMethodsInterface textureEditorMethods,
                MB2_LogLevel LOG_LEVEL)
            {
                // Collect vertices and quads for mesh that we will use for the atlas.
                Debug.Assert(generatedMats.Count == 0, "Previous mats should have been destroyed");
                generatedMats.Clear();
                List <Vector3> vs  = new List <Vector3>();
                List <Vector2> uvs = new List <Vector2>();

                // One submesh and material per texture that we are packing
                List <int>[] ts = new List <int> [distinctMaterialTextures.Count];
                for (int i = 0; i < ts.Length; i++)
                {
                    ts[i] = new List <int>();
                }

                MeshBakerMaterialTexture.readyToBuildAtlases = true;
                GC.Collect();
                MB3_TextureCombinerPackerRoot.CreateTemporaryTexturesForAtlas(data.distinctMaterialTextures, combiner, propIdx, data);

                Rect[] uvRects = packedAtlasRects.rects;
                for (int texSetIdx = 0; texSetIdx < distinctMaterialTextures.Count; texSetIdx++)
                {
                    MB_TexSet texSet = distinctMaterialTextures[texSetIdx];
                    MeshBakerMaterialTexture matTex = texSet.ts[propIdx];

                    if (LOG_LEVEL >= MB2_LogLevel.trace)
                    {
                        Debug.Log(string.Format("Adding texture {0} to atlas {1} for texSet {2} srcMat {3}", matTex.GetTexName(), property.name, texSetIdx, texSet.matsAndGOs.mats[0].GetMaterialName()));
                    }
                    Rect      r  = uvRects[texSetIdx];
                    Texture2D t  = matTex.GetTexture2D();
                    int       x  = Mathf.RoundToInt(r.x * atlasSizeX);
                    int       y  = Mathf.RoundToInt(r.y * atlasSizeY);
                    int       ww = Mathf.RoundToInt(r.width * atlasSizeX);
                    int       hh = Mathf.RoundToInt(r.height * atlasSizeY);
                    r = new Rect(x, y, ww, hh);
                    if (ww == 0 || hh == 0)
                    {
                        Debug.LogError("Image in atlas has no height or width " + r);
                    }
                    DRect samplingRect = texSet.ts[propIdx].GetEncapsulatingSamplingRect();
                    Debug.Assert(!texSet.ts[propIdx].isNull, string.Format("Adding texture {0} to atlas {1} for texSet {2} srcMat {3}", matTex.GetTexName(), property.name, texSetIdx, texSet.matsAndGOs.mats[0].GetMaterialName()));

                    AtlasPadding padding = packedAtlasRects.padding[texSetIdx];
                    AddNineSlicedRect(r, padding.leftRight, padding.topBottom, samplingRect.GetRect(), vs, uvs, ts[texSetIdx], t.width, t.height, t.name);

                    Material mt = new Material(Shader.Find("MeshBaker/Unlit/UnlitWithAlpha"));

                    bool isSavingAsANormalMapAssetThatWillBeImported = property.isNormalMap && data._saveAtlasesAsAssets;
                    MBVersion.PipelineType pipelineType = MBVersion.DetectPipeline();
                    if (pipelineType == MBVersion.PipelineType.URP)
                    {
                        ConfigureMaterial_DefaultPipeline(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                        //ConfigureMaterial_URP(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                    }
                    else if (pipelineType == MBVersion.PipelineType.HDRP)
                    {
                        ConfigureMaterial_DefaultPipeline(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                    }
                    else
                    {
                        ConfigureMaterial_DefaultPipeline(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                    }

                    generatedMats.Add(mt);
                }

                // Apply to the mesh
                m.Clear();
                m.vertices     = vs.ToArray();
                m.uv           = uvs.ToArray();
                m.subMeshCount = ts.Length;
                for (int i = 0; i < m.subMeshCount; i++)
                {
                    m.SetIndices(ts[i].ToArray(), MeshTopology.Triangles, i);
                }
                MeshBakerMaterialTexture.readyToBuildAtlases = false;
            }