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); } } }
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); } }
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)); }
public static bool IsRunningAndMeshNotReadWriteable(Mesh m) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.IsRunningAndMeshNotReadWriteable(m)); }
public static UnityEngine.Object[] FindSceneObjectsOfType(Type t) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.FindSceneObjectsOfType(t)); }
public static void SetActiveRecursively(GameObject go, bool isActive) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } MBVersion._MBVersion.SetActiveRecursively(go, isActive); }
public static bool GetActive(GameObject go) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.GetActive(go)); }
public static int GetMinorVersion() { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.GetMinorVersion()); }
public static string version() { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.version()); }
public static Transform[] GetBones(Renderer r) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.GetBones(r)); }
public static Vector4 GetLightmapTilingOffset(Renderer r) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } return(MBVersion._MBVersion.GetLightmapTilingOffset(r)); }
public static void MeshAssignUV4(Mesh m, Vector2[] uv4s) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } MBVersion._MBVersion.MeshAssignUV4(m, uv4s); }
public static void MeshClear(Mesh m, bool t) { if (MBVersion._MBVersion == null) { MBVersion._MBVersion = MBVersion._CreateMBVersionConcrete(); } MBVersion._MBVersion.MeshClear(m, t); }
/// <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(); }
//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; }
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; }
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); } } }
/// <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); }
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); * } * } */ }
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; }