void BakeSingleTile() { UpdateProgress(0f); int nverts = 0; float[] verts = null; int ntris = 0; int[] tris = null; ProcessTerrain(ref verts, ref nverts, ref tris, ref ntris); UpdateProgress(0.25f); config.walkableHeight = (int)Math.Ceiling(ecfg.AgentHeight / config.ch); config.walkableClimb = (int)Math.Floor(ecfg.AgentMaxClimb / config.ch); config.walkableRadius = (int)Math.Ceiling(ecfg.AgentRadius / config.cs); config.maxEdgeLen = (int)(EdgeLen / config.cs); config.minRegionArea = (int)Math.Pow(RegionMinSize, 2); config.mergeRegionArea = (int)Math.Pow(RegionMergeSize, 2); config.detailSampleDist = DetailSampleDist < 0.9f ? 0 : config.cs * DetailSampleDist; config.detailSampleMaxError = DetailSampleMaxError * config.ch; // Generate Recast Recast.handleBuild(ref config, verts, nverts, tris, ntris); // Fetch navmeshes IntPtr polyPtr = Recast.getPolyMesh(); IntPtr detailPtr = Recast.getPolyMeshDetail(); PolyMesh mesh = (PolyMesh)Marshal.PtrToStructure(polyPtr, typeof(PolyMesh)); PolyMeshDetail detail = (PolyMeshDetail)Marshal.PtrToStructure(detailPtr, typeof(PolyMeshDetail)); UpdateProgress(0.5f); // Create asset PolyMeshAsset asset = CustomAssetUtility.CreateAssetWithoutSaving <PolyMeshAsset>(); // Save config asset.config = config; // Set poly data asset.PolyMesh.nverts = mesh.nverts; asset.PolyMesh.npolys = mesh.npolys; asset.PolyMesh.maxpolys = mesh.maxpolys; asset.PolyMesh.nvp = mesh.nvp; CopyArray <float>(mesh.bmin, ref asset.PolyMesh.bmin, 3); CopyArray <float>(mesh.bmax, ref asset.PolyMesh.bmax, 3); asset.PolyMesh.cs = mesh.cs; asset.PolyMesh.ch = mesh.ch; asset.PolyMesh.borderSize = mesh.borderSize; asset.PolyMesh.verts = new ushort[3 * mesh.nverts]; CopyArray(mesh.verts, asset.PolyMesh.verts, 3 * mesh.nverts); asset.PolyMesh.polys = new ushort[mesh.maxpolys * 2 * mesh.nvp]; CopyArray(mesh.polys, asset.PolyMesh.polys, mesh.maxpolys * 2 * mesh.nvp); asset.PolyMesh.regs = new ushort[mesh.maxpolys]; CopyArray(mesh.regs, asset.PolyMesh.regs, mesh.maxpolys); asset.PolyMesh.flags = new ushort[mesh.npolys]; CopyArray(mesh.flags, asset.PolyMesh.flags, mesh.npolys); asset.PolyMesh.areas = new byte[mesh.maxpolys]; CopyArray(mesh.areas, asset.PolyMesh.areas, mesh.maxpolys); // Set detail data asset.PolyDetailMesh.nmeshes = detail.nmeshes; asset.PolyDetailMesh.nverts = detail.nverts; asset.PolyDetailMesh.ntris = detail.ntris; asset.PolyDetailMesh.meshes = new uint[4 * detail.nmeshes]; CopyArray(detail.meshes, asset.PolyDetailMesh.meshes, 4 * detail.nmeshes); asset.PolyDetailMesh.verts = new float[3 * detail.nverts]; CopyArray(detail.verts, asset.PolyDetailMesh.verts, 3 * detail.nverts); asset.PolyDetailMesh.tris = new byte[4 * detail.ntris]; CopyArray(detail.tris, asset.PolyDetailMesh.tris, 4 * detail.ntris); // Save asset again UpdateProgress(0.75f); CustomAssetUtility.SaveAsset <PolyMeshAsset>(asset); // Close window UpdateProgress(0f); EditorUtility.ClearProgressBar(); }
public static void ConvertToNonUMA(GameObject baseObject, UMAAvatarBase avatar, string Folder, bool ConvertNormalMaps, string CharName, bool AddStandaloneDNA) { Folder = Folder + "/" + CharName; if (!System.IO.Directory.Exists(Folder)) { System.IO.Directory.CreateDirectory(Folder); } SkinnedMeshRenderer[] renderers = avatar.umaData.GetRenderers(); int meshno = 0; foreach (SkinnedMeshRenderer smr in renderers) { Material[] mats = smr.sharedMaterials; int Material = 0; foreach (Material m in mats) { // get each texture. // if the texture has been generated (has no path) then we need to convert to Texture2D (if needed) save that asset. // update the material with that material. List <Texture> allTexture = new List <Texture>(); Shader shader = m.shader; for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { string propertyName = ShaderUtil.GetPropertyName(shader, i); Texture texture = m.GetTexture(propertyName); if (texture is Texture2D || texture is RenderTexture) { bool isNormal = false; string path = AssetDatabase.GetAssetPath(texture.GetInstanceID()); if (string.IsNullOrEmpty(path)) { if (ConvertNormalMaps) { if (propertyName.ToLower().Contains("bumpmap") || propertyName.ToLower().Contains("normal")) { // texture = ConvertNormalMap(texture); texture = sconvertNormalMap(texture); isNormal = true; } } string texName = Path.Combine(Folder, CharName + "_Mat_" + Material + propertyName + ".png"); SaveTexture(texture, texName); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); if (isNormal) { TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(texName); importer.isReadable = true; importer.textureType = TextureImporterType.NormalMap; importer.maxTextureSize = 1024; // or whatever importer.textureCompression = TextureImporterCompression.CompressedHQ; EditorUtility.SetDirty(importer); importer.SaveAndReimport(); } Texture2D tex = AssetDatabase.LoadAssetAtPath <Texture2D>(CustomAssetUtility.UnityFriendlyPath(texName)); m.SetTexture(propertyName, tex); } } } } string matname = Folder + "/" + CharName + "_Mat_" + Material + ".mat"; CustomAssetUtility.SaveAsset <Material>(m, matname); Material++; // Save the material to disk? // update the SMR } string meshName = Folder + "/" + CharName + "_Mesh_" + meshno + ".asset"; meshno++; // Save Mesh to disk. smr.sharedMesh.Optimize(); CustomAssetUtility.SaveAsset <Mesh>(smr.sharedMesh, meshName); smr.sharedMaterials = mats; smr.materials = mats; } // save Animator Avatar. var animator = baseObject.GetComponent <Animator>(); string avatarName = Folder + "/" + CharName + "_Avatar.asset"; CustomAssetUtility.SaveAsset <Avatar>(animator.avatar, avatarName); DestroyImmediate(avatar); var lod = baseObject.GetComponent <UMASimpleLOD>(); if (lod != null) { DestroyImmediate(lod); } if (AddStandaloneDNA) { UMAData uda = baseObject.GetComponent <UMAData>(); StandAloneDNA sda = baseObject.AddComponent <UMA.StandAloneDNA>(); sda.PackedDNA = UMAPackedRecipeBase.GetPackedDNA(uda._umaRecipe); if (avatar is DynamicCharacterAvatar) { DynamicCharacterAvatar avt = avatar as DynamicCharacterAvatar; sda.avatarDefinition = avt.GetAvatarDefinition(true); } sda.umaData = uda; } else { var ud = baseObject.GetComponent <UMAData>(); if (ud != null) { DestroyImmediate(ud); } } var ue = baseObject.GetComponent <UMAExpressionPlayer>(); if (ue != null) { DestroyImmediate(ue); } baseObject.name = CharName; string prefabName = Folder + "/" + CharName + ".prefab"; prefabName = CustomAssetUtility.UnityFriendlyPath(prefabName); PrefabUtility.SaveAsPrefabAssetAndConnect(baseObject, prefabName, InteractionMode.AutomatedAction); }
void BakeTileCache() { UpdateProgress(0f); int nverts = 0; float[] verts = null; int ntris = 0; int[] tris = null; ProcessTerrain(ref verts, ref nverts, ref tris, ref ntris); UpdateProgress(0.25f); IntPtr vertsPtr = Marshal.AllocHGlobal(verts.Length * sizeof(float)); Marshal.Copy(verts, 0, vertsPtr, verts.Length); IntPtr trisPtr = Marshal.AllocHGlobal(tris.Length * sizeof(int)); Marshal.Copy(tris, 0, trisPtr, tris.Length); InputGeometry geom = new InputGeometry() { verts = vertsPtr, tris = trisPtr, nverts = nverts, ntris = ntris }; UpdateProgress(0.5f); RecastConfig recastConfig = FindObjectOfType <RecastConfig>(); Dictionary <string, ushort> areas = new Dictionary <string, ushort>(); ushort k = 1; foreach (var layer in recastConfig.Layers) { areas.Add(layer.LayerID, k); TileCache.addFlag(k, 1); k *= 2; } DetourConvexVolume[] volumes = FindObjectsOfType <Pathfinding.DetourConvexVolume>(); foreach (var volume in volumes) { TileCache.addConvexVolume(volume.floatNodes(), volume.nodes.Count, volume.maxY, volume.minY, areas[volume.AreaID]); } IntPtr tileCache = new IntPtr(0); IntPtr navMesh = new IntPtr(0); IntPtr navQuery = new IntPtr(0); TileCache.handleTileCacheBuild(ref config, ref ecfg, ref geom, ref tileCache, ref navMesh, ref navQuery); UpdateProgress(0.75f); // Create asset TileCacheAsset asset = CustomAssetUtility.CreateAssetWithoutSaving <TileCacheAsset>(); IntPtr tilesHeader = new IntPtr(0); TileCache.getTileCacheHeaders(ref asset.header, ref tilesHeader, tileCache, navMesh); // Copy to asset asset.config = config; // Copy sizes int structSize = Marshal.SizeOf(typeof(TileCacheAsset.TileCacheTileHeader)); asset.tilesHeader = new TileCacheAsset.TileCacheTileHeader[asset.header.numTiles]; for (uint i = 0; i < asset.header.numTiles; ++i) { asset.tilesHeader[i] = (TileCacheAsset.TileCacheTileHeader)Marshal.PtrToStructure(new IntPtr(tilesHeader.ToInt64() + (structSize * i)), typeof(TileCacheAsset.TileCacheTileHeader)); } // Copy data int dataSize = 0; int start = 0; for (uint i = 0; i < asset.header.numTiles; ++i) { dataSize += asset.tilesHeader[i].dataSize; } asset.tilesData = new byte[dataSize]; for (uint i = 0; i < asset.header.numTiles; ++i) { IntPtr tilePtr = TileCache.getTileCacheTile(tileCache, (int)i); CompressedTile tile = (CompressedTile)Marshal.PtrToStructure(tilePtr, typeof(CompressedTile)); asset.tilesHeader[i] = (TileCacheAsset.TileCacheTileHeader)Marshal.PtrToStructure(new IntPtr(tilesHeader.ToInt64() + (structSize * i)), typeof(TileCacheAsset.TileCacheTileHeader)); if (asset.tilesHeader[i].dataSize > 0) { Marshal.Copy(tile.data, asset.tilesData, start, asset.tilesHeader[i].dataSize); start += asset.tilesHeader[i].dataSize; } } // Save asset CustomAssetUtility.SaveAsset <TileCacheAsset>(asset); // Close window UpdateProgress(0f); EditorUtility.ClearProgressBar(); }
public static void ConvertToNonUMA(GameObject baseObject, UMAAvatarBase avatar, string Folder, bool ConvertNormalMaps, string CharName) { Folder = Folder + "/" + CharName; if (!System.IO.Directory.Exists(Folder)) { System.IO.Directory.CreateDirectory(Folder); } SkinnedMeshRenderer[] renderers = avatar.umaData.GetRenderers(); int meshno = 0; foreach (SkinnedMeshRenderer smr in renderers) { Material[] mats = smr.sharedMaterials; int Material = 0; foreach (Material m in mats) { // get each texture. // if the texture has been generated (has no path) then we need to convert to Texture2D (if needed) save that asset. // update the material with that material. List <Texture> allTexture = new List <Texture>(); Shader shader = m.shader; for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { string propertyName = ShaderUtil.GetPropertyName(shader, i); Texture texture = m.GetTexture(propertyName); if (texture is Texture2D || texture is RenderTexture) { string path = AssetDatabase.GetAssetPath(texture.GetInstanceID()); if (string.IsNullOrEmpty(path)) { if (ConvertNormalMaps && propertyName.ToLower().Contains("bumpmap")) { // texture = ConvertNormalMap(texture); texture = sconvertNormalMap(texture); } string texName = Path.Combine(Folder, CharName + "_Mat_" + Material + propertyName + ".png"); SaveTexture(texture, texName); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); Texture2D tex = AssetDatabase.LoadAssetAtPath <Texture2D>(CustomAssetUtility.UnityFriendlyPath(texName)); m.SetTexture(propertyName, tex); } } } } string matname = Folder + "/" + CharName + "_Mat_" + Material + ".mat"; CustomAssetUtility.SaveAsset <Material>(m, matname); Material++; // Save the material to disk? // update the SMR } string meshName = Folder + "/" + CharName + "_Mesh_" + meshno + ".asset"; meshno++; // Save Mesh to disk. CustomAssetUtility.SaveAsset <Mesh>(smr.sharedMesh, meshName); smr.sharedMaterials = mats; smr.materials = mats; } // save Animator Avatar. var animator = baseObject.GetComponent <Animator>(); string avatarName = Folder + "/" + CharName + "_Avatar.asset"; CustomAssetUtility.SaveAsset <Avatar>(animator.avatar, avatarName); DestroyImmediate(avatar); var lod = baseObject.GetComponent <UMASimpleLOD>(); if (lod != null) { DestroyImmediate(lod); } var ud = baseObject.GetComponent <UMAData>(); if (ud != null) { DestroyImmediate(ud); } var ue = baseObject.GetComponent <UMAExpressionPlayer>(); if (ue != null) { DestroyImmediate(ue); } baseObject.name = CharName; string prefabName = Folder + "/" + CharName + ".prefab"; prefabName = CustomAssetUtility.UnityFriendlyPath(prefabName); PrefabUtility.SaveAsPrefabAssetAndConnect(baseObject, prefabName, InteractionMode.AutomatedAction); }