✨ Add water shader by Atlas and, flip some faces and experiment with animations
This commit is contained in:
parent
bf6da1e7c9
commit
c50e9258cf
1764 changed files with 303341 additions and 66722 deletions
964
Assets/Bakery/ftLightmaps.cs
Normal file
964
Assets/Bakery/ftLightmaps.cs
Normal file
|
@ -0,0 +1,964 @@
|
|||
#define USE_TERRAINS
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.IO;
|
||||
#endif
|
||||
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoad]
|
||||
#endif
|
||||
public class ftLightmaps {
|
||||
|
||||
struct LightmapAdditionalData
|
||||
{
|
||||
public Texture2D rnm0, rnm1, rnm2;
|
||||
public int mode;
|
||||
};
|
||||
|
||||
static List<int> lightmapRefCount;
|
||||
static List<LightmapAdditionalData> globalMapsAdditional;
|
||||
static int directionalMode; // -1 undefined, 0 off, 1 on
|
||||
//static List<ftLightmapsStorage> loadedStorages;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static bool mustReloadRenderSettings = false;
|
||||
static ftGlobalStorage gstorage;
|
||||
static ftLocalStorage lstorage;
|
||||
static BakeryProjectSettings pstorage;
|
||||
static bool editorUpdateCalled = false;
|
||||
|
||||
public static string _bakeryRuntimePath = "";
|
||||
public static string _bakeryEditorPath = "";
|
||||
public static string GetRuntimePath()
|
||||
{
|
||||
if (_bakeryRuntimePath.Length == 0)
|
||||
{
|
||||
// Try default path
|
||||
// (start with AssetDatabase assuming it's faster than GetFiles)
|
||||
var a = AssetDatabase.LoadAssetAtPath("Assets/Bakery/ftDefaultAreaLightMat.mat", typeof(Material)) as Material;
|
||||
if (a == null)
|
||||
{
|
||||
// Find elsewhere
|
||||
var assetGUIDs = AssetDatabase.FindAssets("ftDefaultAreaLightMat", null);
|
||||
if (assetGUIDs.Length == 0)
|
||||
{
|
||||
// No extra data present - find the script at least
|
||||
var res = Directory.GetFiles(Application.dataPath, "ftLightmaps.cs", SearchOption.AllDirectories);
|
||||
if (res.Length == 0)
|
||||
{
|
||||
Debug.LogError("Can't locate Bakery folder");
|
||||
return "";
|
||||
}
|
||||
return "Assets" + res[0].Replace("ftLightmaps.cs", "").Replace("\\", "/").Replace(Application.dataPath, "");
|
||||
}
|
||||
if (assetGUIDs.Length > 1)
|
||||
{
|
||||
Debug.LogError("ftDefaultAreaLightMat was found in more than one folder. Do you have multiple installations of Bakery?");
|
||||
}
|
||||
var guid = assetGUIDs[0];
|
||||
_bakeryRuntimePath = System.IO.Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(guid)) + "/";
|
||||
return _bakeryRuntimePath;
|
||||
}
|
||||
_bakeryRuntimePath = "Assets/Bakery/";
|
||||
}
|
||||
return _bakeryRuntimePath;
|
||||
}
|
||||
|
||||
public static string GetEditorPath()
|
||||
{
|
||||
if (_bakeryEditorPath.Length == 0)
|
||||
{
|
||||
// Try default path
|
||||
var a = AssetDatabase.LoadAssetAtPath("Assets/Editor/x64/Bakery/NormalsFittingTexture_dds", typeof(Object));
|
||||
if (a == null)
|
||||
{
|
||||
// Find elsewhere
|
||||
var assetGUIDs = AssetDatabase.FindAssets("NormalsFittingTexture_dds", null);
|
||||
if (assetGUIDs.Length == 0)
|
||||
{
|
||||
// No extra data present - find ftModelPostProcessor at least (minimum required editor script)
|
||||
var res = Directory.GetFiles(Application.dataPath, "ftModelPostProcessor.cs", SearchOption.AllDirectories);
|
||||
if (res.Length == 0)
|
||||
{
|
||||
Debug.LogError("Can't locate Bakery folder");
|
||||
return "";
|
||||
}
|
||||
return "Assets" + res[0].Replace("ftModelPostProcessor.cs", "").Replace("\\", "/").Replace(Application.dataPath, "");
|
||||
}
|
||||
if (assetGUIDs.Length > 1)
|
||||
{
|
||||
Debug.LogError("NormalsFittingTexture_dds was found in more than one folder. Do you have multiple installations of Bakery?");
|
||||
}
|
||||
var guid = assetGUIDs[0];
|
||||
_bakeryEditorPath = System.IO.Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(guid)) + "/";
|
||||
return _bakeryEditorPath;
|
||||
}
|
||||
_bakeryEditorPath = "Assets/Editor/x64/Bakery/";
|
||||
}
|
||||
return _bakeryEditorPath;
|
||||
}
|
||||
|
||||
public static string GetProjectSettingsPathOld()
|
||||
{
|
||||
return "Assets/Settings/";
|
||||
}
|
||||
|
||||
public static string GetProjectSettingsPathNew()
|
||||
{
|
||||
var path = GetRuntimePath();
|
||||
for(int i=path.Length-2; i>=0; i--)
|
||||
{
|
||||
char c = path[i];
|
||||
if (c == '/' || c == '\\')
|
||||
{
|
||||
path = path.Substring(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path + "/Settings/";
|
||||
}
|
||||
|
||||
public static ftGlobalStorage GetGlobalStorage()
|
||||
{
|
||||
if (gstorage != null) return gstorage;
|
||||
var bakeryRuntimePath = GetRuntimePath();
|
||||
gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
if (gstorage == null && editorUpdateCalled) // if editorUpdateCalled==false, it may be not imported yet
|
||||
{
|
||||
var gstorageDefault = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftDefaultGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
|
||||
if (gstorageDefault != null)
|
||||
{
|
||||
if (AssetDatabase.CopyAsset(bakeryRuntimePath + "ftDefaultGlobalStorage.asset", bakeryRuntimePath + "ftGlobalStorage.asset"))
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
}
|
||||
}
|
||||
|
||||
if (gstorage == null)
|
||||
{
|
||||
Debug.Log("Created Bakery GlobalStorage");
|
||||
gstorage = ScriptableObject.CreateInstance<ftGlobalStorage>();
|
||||
AssetDatabase.CreateAsset(gstorage, bakeryRuntimePath + "ftGlobalStorage.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Created Bakery GlobalStorage from DefaultGlobalStorage");
|
||||
}
|
||||
}
|
||||
|
||||
if (gstorage != null)
|
||||
{
|
||||
if (gstorage.modifiedMeshList.Count > 0)
|
||||
{
|
||||
gstorage.ConvertFromLegacy();
|
||||
}
|
||||
}
|
||||
|
||||
return gstorage;
|
||||
}
|
||||
|
||||
static ftLocalStorage GetLocalStorage()
|
||||
{
|
||||
if (lstorage != null) return lstorage;
|
||||
var bakeryRuntimePath = GetRuntimePath();
|
||||
lstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftLocalStorage.asset", typeof(ftLocalStorage)) as ftLocalStorage;
|
||||
if (lstorage == null)
|
||||
{
|
||||
Debug.Log("Created Bakery LocalStorage");
|
||||
lstorage = ScriptableObject.CreateInstance<ftLocalStorage>();
|
||||
AssetDatabase.CreateAsset(lstorage, bakeryRuntimePath + "ftLocalStorage.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
return lstorage;
|
||||
}
|
||||
|
||||
public static BakeryProjectSettings GetProjectSettings()
|
||||
{
|
||||
if (pstorage != null) return pstorage;
|
||||
var path = GetProjectSettingsPathOld();
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
path = GetProjectSettingsPathNew();
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
}
|
||||
pstorage = AssetDatabase.LoadAssetAtPath(path + "BakeryProjectSettings.asset", typeof(BakeryProjectSettings)) as BakeryProjectSettings;
|
||||
if (pstorage == null)
|
||||
{
|
||||
Debug.Log("Created Bakery ProjectSettings");
|
||||
pstorage = ScriptableObject.CreateInstance<BakeryProjectSettings>();
|
||||
AssetDatabase.CreateAsset(pstorage, path + "BakeryProjectSettings.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
return pstorage;
|
||||
}
|
||||
|
||||
static void CreateGlobalStorageAsset()
|
||||
{
|
||||
if (gstorage == null) gstorage = GetGlobalStorage();
|
||||
if (lstorage == null) lstorage = GetLocalStorage();
|
||||
|
||||
if (Application.isPlaying) return;
|
||||
|
||||
var listToProccess = gstorage.modifiedAssetPathList;
|
||||
var listToProcessHash = gstorage.modifiedAssetPaddingHash;
|
||||
var listProcessed = lstorage.modifiedAssetPathList;
|
||||
var listProcessedHash = lstorage.modifiedAssetPaddingHash;
|
||||
for(int i=0; i<listToProccess.Count; i++)
|
||||
{
|
||||
int localID = listProcessed.IndexOf(listToProccess[i]);
|
||||
if (localID >= 0)
|
||||
{
|
||||
if (listToProcessHash.Count > i)
|
||||
{
|
||||
int globalPaddingHash = listToProcessHash[i];
|
||||
if (listProcessedHash.Count > localID)
|
||||
{
|
||||
int localPaddingHash = listProcessedHash[localID];
|
||||
if (globalPaddingHash == localPaddingHash)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hash is not initialized = legacy
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
var importer = AssetImporter.GetAtPath(listToProccess[i]) as ModelImporter;
|
||||
if (importer != null)
|
||||
{
|
||||
var props = importer.extraUserProperties;
|
||||
int propID = -1;
|
||||
for(int p=0; p<props.Length; p++)
|
||||
{
|
||||
if (props[p].Substring(0,7) == "#BAKERY")
|
||||
{
|
||||
propID = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (propID >= 0) continue; // should be fine without additional reimport - metadata is always loaded with model
|
||||
}
|
||||
#endif
|
||||
|
||||
var asset = AssetDatabase.LoadAssetAtPath(listToProccess[i], typeof(GameObject)) as GameObject;
|
||||
if (asset == null) continue;
|
||||
if (asset.tag == "BakeryProcessed") continue; // legacy
|
||||
//if (asset.tag != "BakeryProcessed") AssetDatabase.ImportAsset(list[i], ImportAssetOptions.ForceUpdate);
|
||||
Debug.Log("Reimporting to adjust UVs: " + listToProccess[i]);
|
||||
AssetDatabase.ImportAsset(listToProccess[i], ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
/*public static bool IsModelProcessed(string path)
|
||||
{
|
||||
if (lstorage == null) lstorage = GetLocalStorage();
|
||||
var listProcessed = lstorage.modifiedAssetPathList;
|
||||
return listProcessed.Contains(path);
|
||||
}*/
|
||||
|
||||
public static void MarkModelProcessed(string path, bool enabled)
|
||||
{
|
||||
if (lstorage == null) lstorage = GetLocalStorage();
|
||||
if (gstorage == null) gstorage = GetGlobalStorage();
|
||||
if (enabled)
|
||||
{
|
||||
int gid = gstorage.modifiedAssetPathList.IndexOf(path);
|
||||
if (gid < 0) return;
|
||||
int hash = gstorage.CalculatePaddingHash(gid);
|
||||
while(gstorage.modifiedAssetPaddingHash.Count <= gid) gstorage.modifiedAssetPaddingHash.Add(0);
|
||||
gstorage.modifiedAssetPaddingHash[gid] = hash;
|
||||
|
||||
int id = lstorage.modifiedAssetPathList.IndexOf(path);
|
||||
if (id < 0)
|
||||
{
|
||||
lstorage.modifiedAssetPathList.Add(path);
|
||||
id = lstorage.modifiedAssetPathList.Count - 1;
|
||||
}
|
||||
while(lstorage.modifiedAssetPaddingHash.Count <= id) lstorage.modifiedAssetPaddingHash.Add(0);
|
||||
lstorage.modifiedAssetPaddingHash[id] = hash;
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
EditorSceneManager.MarkAllScenesDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
int id = lstorage.modifiedAssetPathList.IndexOf(path);
|
||||
if (id >= 0)
|
||||
{
|
||||
lstorage.modifiedAssetPathList.RemoveAt(id);
|
||||
if (lstorage.modifiedAssetPaddingHash.Count > id) lstorage.modifiedAssetPaddingHash.RemoveAt(id);
|
||||
}
|
||||
}
|
||||
EditorUtility.SetDirty(lstorage);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static ftLightmaps() {
|
||||
|
||||
#if UNITY_EDITOR
|
||||
EditorSceneManager.sceneOpening -= OnSceneOpening; // Andrew fix
|
||||
EditorSceneManager.sceneOpening += OnSceneOpening;
|
||||
|
||||
EditorApplication.update -= FirstUpdate; // Andrew fix
|
||||
EditorApplication.update += FirstUpdate;
|
||||
|
||||
EditorApplication.hierarchyWindowChanged -= OnSceneChangedEditor;
|
||||
EditorApplication.hierarchyWindowChanged += OnSceneChangedEditor;
|
||||
#endif
|
||||
|
||||
SceneManager.activeSceneChanged -= OnSceneChangedPlay;
|
||||
SceneManager.activeSceneChanged += OnSceneChangedPlay;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
static void FirstUpdate()
|
||||
{
|
||||
editorUpdateCalled = true;
|
||||
CreateGlobalStorageAsset();
|
||||
GetProjectSettings();
|
||||
EditorApplication.update -= FirstUpdate;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SetDirectionalMode()
|
||||
{
|
||||
if (directionalMode >= 0) LightmapSettings.lightmapsMode = directionalMode==1 ? LightmapsMode.CombinedDirectional : LightmapsMode.NonDirectional;
|
||||
}
|
||||
|
||||
static void OnSceneChangedPlay(Scene prev, Scene next) {
|
||||
//if (Lightmapping.lightingDataAsset == null) {
|
||||
SetDirectionalMode();
|
||||
//}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
static void OnSceneChangedEditor() {
|
||||
// Unity can modify directional mode on scene change, have to force the correct one
|
||||
// activeSceneChangedInEditMode isn't always available
|
||||
//if (Lightmapping.lightingDataAsset == null) {
|
||||
SetDirectionalMode();
|
||||
//}
|
||||
}
|
||||
|
||||
// using Opening instead of Opened because it's called before lightmap data is loaded and proper directional mode is set
|
||||
//static void OnSceneOpened(Scene scene, OpenSceneMode mode) {
|
||||
static void OnSceneOpening(string path, OpenSceneMode mode) {
|
||||
//Refresh();
|
||||
//if (scene.name == "_tempScene") return;
|
||||
if (Path.GetFileNameWithoutExtension(path) == "_tempScene") return;
|
||||
mustReloadRenderSettings = true;
|
||||
directionalMode = -1;
|
||||
/*if (!finalInitDone)
|
||||
{
|
||||
CreateGlobalStorageAsset();
|
||||
finalInitDone = true;
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void RefreshFull() {
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var sceneCount = SceneManager.sceneCount;
|
||||
|
||||
for(int i=0; i<sceneCount; i++)
|
||||
{
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
if (!scene.isLoaded) continue;
|
||||
SceneManager.SetActiveScene(scene);
|
||||
LightmapSettings.lightmaps = new LightmapData[0];
|
||||
}
|
||||
|
||||
for(int i=0; i<sceneCount; i++)
|
||||
{
|
||||
RefreshScene(SceneManager.GetSceneAt(i), null, true);
|
||||
}
|
||||
SceneManager.SetActiveScene(activeScene);
|
||||
}
|
||||
|
||||
public static GameObject FindInScene(string nm, Scene scn)
|
||||
{
|
||||
var objs = scn.GetRootGameObjects();
|
||||
for(int i=0; i<objs.Length; i++)
|
||||
{
|
||||
if (objs[i].name == nm) return objs[i];
|
||||
var obj = objs[i].transform.Find(nm);
|
||||
if (obj != null) return obj.gameObject;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* public static void RefreshScene(int sceneID, ref List<LightmapData> lmaps, int lmCounter) {
|
||||
RefreshScene(scene);
|
||||
}*/
|
||||
|
||||
static Texture2D GetEmptyDirectionTex(ftLightmapsStorage storage)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (storage.emptyDirectionTex == null)
|
||||
{
|
||||
var bakeryRuntimePath = GetRuntimePath();
|
||||
storage.emptyDirectionTex = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "emptyDirection.tga", typeof(Texture2D)) as Texture2D;
|
||||
}
|
||||
#endif
|
||||
return storage.emptyDirectionTex;
|
||||
}
|
||||
|
||||
public static void RefreshScene(Scene scene, ftLightmapsStorage storage = null, bool updateNonBaked = false) {
|
||||
var sceneCount = SceneManager.sceneCount;
|
||||
|
||||
if (globalMapsAdditional == null) globalMapsAdditional = new List<LightmapAdditionalData>();
|
||||
|
||||
var lmaps = new List<LightmapData>();
|
||||
var lmapsAdditional = new List<LightmapAdditionalData>();
|
||||
var existingLmaps = LightmapSettings.lightmaps;
|
||||
var existingLmapsAdditional = globalMapsAdditional;
|
||||
|
||||
// Acquire storage
|
||||
if (storage == null)
|
||||
{
|
||||
if (!scene.isLoaded)
|
||||
{
|
||||
//Debug.LogError("dbg: Scene not loaded");
|
||||
return;
|
||||
}
|
||||
SceneManager.SetActiveScene(scene);
|
||||
|
||||
var go = FindInScene("!ftraceLightmaps", scene);
|
||||
if (go==null) {
|
||||
//Debug.LogError("dbg: no storage");
|
||||
return;
|
||||
}
|
||||
|
||||
storage = go.GetComponent<ftLightmapsStorage>();
|
||||
if (storage == null) {
|
||||
//Debug.LogError("dbg: no storage 2");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (storage.idremap == null || storage.idremap.Length != storage.maps.Count)
|
||||
{
|
||||
storage.idremap = new int[storage.maps.Count];
|
||||
}
|
||||
|
||||
// Decide which global engine lightmapping mode to use
|
||||
// TODO: allow mixing different modes
|
||||
directionalMode = storage.dirMaps.Count != 0 ? 1 : 0;
|
||||
bool patchedDirection = false;
|
||||
SetDirectionalMode();
|
||||
|
||||
// Set dummy directional tex for non-directional lightmaps in directional mode
|
||||
if (directionalMode == 1)
|
||||
{
|
||||
for(int i=0; i<existingLmaps.Length; i++)
|
||||
{
|
||||
if (existingLmaps[i].lightmapDir == null)
|
||||
{
|
||||
var lm = existingLmaps[i];
|
||||
lm.lightmapDir = GetEmptyDirectionTex(storage);
|
||||
existingLmaps[i] = lm;
|
||||
patchedDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detect if changes to lightmap array are necessary
|
||||
bool sameArray = false;
|
||||
if (existingLmaps.Length == storage.maps.Count)
|
||||
{
|
||||
sameArray = true;
|
||||
for(int i=0; i<storage.maps.Count; i++)
|
||||
{
|
||||
if (existingLmaps[i].lightmapColor != storage.maps[i])
|
||||
{
|
||||
sameArray = false;
|
||||
break;
|
||||
}
|
||||
if (storage.rnmMaps0.Count > i && (existingLmapsAdditional.Count <= i || existingLmapsAdditional[i].rnm0 != storage.rnmMaps0[i]))
|
||||
{
|
||||
sameArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sameArray) // create new lightmap array
|
||||
{
|
||||
if (sceneCount >= 1)
|
||||
{
|
||||
// first add old
|
||||
for(int i=0; i<existingLmaps.Length; i++) {
|
||||
// skip empty lightmaps (can be created by 5.6 ldata asset or vertex color)
|
||||
// ... unless there are valid lightmaps around them
|
||||
bool lightmapIsEmpty = existingLmaps[i] == null || (existingLmaps[i].lightmapColor == null && existingLmaps[i].shadowMask == null);
|
||||
bool lightmapCanBeSkipped = lightmapIsEmpty && (i == 0 || i == existingLmaps.Length - 1);
|
||||
if (!lightmapCanBeSkipped)
|
||||
{
|
||||
lmaps.Add(existingLmaps[i]);
|
||||
if (existingLmapsAdditional.Count > i) lmapsAdditional.Add(existingLmapsAdditional[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<storage.maps.Count; i++) {
|
||||
|
||||
var texlm = storage.maps[i];
|
||||
Texture2D texmask = null;
|
||||
Texture2D texdir = null;
|
||||
Texture2D texrnm0 = null;
|
||||
Texture2D texrnm1 = null;
|
||||
Texture2D texrnm2 = null;
|
||||
int mapMode = 0;
|
||||
if (storage.masks.Count > i) texmask = storage.masks[i];
|
||||
if (storage.dirMaps.Count > i) texdir = storage.dirMaps[i];
|
||||
if (storage.rnmMaps0.Count > i)
|
||||
{
|
||||
texrnm0 = storage.rnmMaps0[i];
|
||||
texrnm1 = storage.rnmMaps1[i];
|
||||
texrnm2 = storage.rnmMaps2[i];
|
||||
mapMode = storage.mapsMode[i];
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
int firstEmpty = -1;
|
||||
for(int j=0; j<lmaps.Count; j++) {
|
||||
if (lmaps[j].lightmapColor == texlm && lmaps[j].shadowMask == texmask)
|
||||
{
|
||||
// lightmap already added - reuse
|
||||
storage.idremap[i] = j;
|
||||
found = true;
|
||||
|
||||
//Debug.LogError("reused "+j);
|
||||
|
||||
// additional maps array could be flushed due to script recompilation - recover
|
||||
if (texrnm0 != null && (lmapsAdditional.Count <= j || lmapsAdditional[j].rnm0 == null))
|
||||
{
|
||||
while(lmapsAdditional.Count <= j) lmapsAdditional.Add(new LightmapAdditionalData());
|
||||
var l = new LightmapAdditionalData();
|
||||
l.rnm0 = texrnm0;
|
||||
l.rnm1 = texrnm1;
|
||||
l.rnm2 = texrnm2;
|
||||
l.mode = mapMode;
|
||||
lmapsAdditional[j] = l;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (firstEmpty < 0 && lmaps[j].lightmapColor == null && lmaps[j].shadowMask == null)
|
||||
{
|
||||
// free (deleted) entry in existing lightmap list - possibly reuse
|
||||
storage.idremap[i] = j;
|
||||
firstEmpty = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LightmapData lm;
|
||||
if (firstEmpty >= 0)
|
||||
{
|
||||
lm = lmaps[firstEmpty];
|
||||
}
|
||||
else
|
||||
{
|
||||
lm = new LightmapData();
|
||||
}
|
||||
|
||||
lm.lightmapColor = texlm;
|
||||
if (storage.masks.Count > i)
|
||||
{
|
||||
lm.shadowMask = texmask;
|
||||
}
|
||||
if (storage.dirMaps.Count > i && texdir != null)
|
||||
{
|
||||
lm.lightmapDir = texdir;
|
||||
}
|
||||
else if (directionalMode == 1)
|
||||
{
|
||||
lm.lightmapDir = GetEmptyDirectionTex(storage);
|
||||
}
|
||||
|
||||
if (firstEmpty < 0)
|
||||
{
|
||||
lmaps.Add(lm);
|
||||
storage.idremap[i] = lmaps.Count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lmaps[firstEmpty] = lm;
|
||||
}
|
||||
|
||||
if (storage.rnmMaps0.Count > i)
|
||||
{
|
||||
var l = new LightmapAdditionalData();
|
||||
l.rnm0 = texrnm0;
|
||||
l.rnm1 = texrnm1;
|
||||
l.rnm2 = texrnm2;
|
||||
l.mode = mapMode;
|
||||
|
||||
if (firstEmpty < 0)
|
||||
{
|
||||
//Debug.LogError("added "+(lmaps.Count-1));
|
||||
while(lmapsAdditional.Count < lmaps.Count-1) lmapsAdditional.Add(new LightmapAdditionalData());
|
||||
lmapsAdditional.Add(l);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.LogError("set " + firstEmpty);
|
||||
while(lmapsAdditional.Count < firstEmpty+1) lmapsAdditional.Add(new LightmapAdditionalData());
|
||||
lmapsAdditional[firstEmpty] = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // reuse existing lightmap array, only remap IDs
|
||||
{
|
||||
for(int i=0; i<storage.maps.Count; i++) {
|
||||
storage.idremap[i] = i;
|
||||
|
||||
//Debug.LogError("full reuse");
|
||||
|
||||
/*if (storage.rnmMaps0.Count > i)
|
||||
{
|
||||
var l = new LightmapAdditionalData();
|
||||
l.rnm0 = storage.rnmMaps0[i];
|
||||
l.rnm1 = storage.rnmMaps1[i];
|
||||
l.rnm2 = storage.rnmMaps2[i];
|
||||
l.mode = storage.mapsMode[i];
|
||||
lmapsAdditional.Add(l);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Set editor lighting mode
|
||||
if (storage.bakedRenderers != null && storage.bakedRenderers.Count > 0)
|
||||
{
|
||||
Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand;
|
||||
Lightmapping.realtimeGI = storage.usesRealtimeGI;
|
||||
//Lightmapping.bakedGI = true; // ? only used for enlighten ? makes editor laggy ?
|
||||
}
|
||||
#endif
|
||||
|
||||
// Replace the lightmap array if needed
|
||||
if (sameArray && patchedDirection) LightmapSettings.lightmaps = existingLmaps;
|
||||
if (!sameArray)
|
||||
{
|
||||
LightmapSettings.lightmaps = lmaps.ToArray();
|
||||
globalMapsAdditional = lmapsAdditional;
|
||||
}
|
||||
|
||||
/*
|
||||
// Debug
|
||||
var lms = LightmapSettings.lightmaps;
|
||||
for(int i=0; i<lms.Length; i++)
|
||||
{
|
||||
var name1 = ((lms[i]==null || lms[i].lightmapColor==null) ? "-" : lms[i].lightmapColor.name);
|
||||
var name2 = (globalMapsAdditional.Count > i ?(globalMapsAdditional[i].rnm0==null?"x":globalMapsAdditional[i].rnm0.name) : "-");
|
||||
Debug.LogError(i+" "+name1+" "+name2);
|
||||
}
|
||||
*/
|
||||
|
||||
// Attempt to update skybox probe
|
||||
if (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Skybox)// && Lightmapping.lightingDataAsset == null)
|
||||
{
|
||||
var probe = RenderSettings.ambientProbe ;
|
||||
int isEmpty = -1;
|
||||
for(int i=0; i<3; i++)
|
||||
{
|
||||
for(int j=0; j<9; j++)
|
||||
{
|
||||
// default bugged probes are [almost] black or 1302?
|
||||
float a = Mathf.Abs(probe[i,j]);
|
||||
if (a > 1000.0f || a < 0.000001f)
|
||||
{
|
||||
isEmpty = 1;
|
||||
break;
|
||||
}
|
||||
if (probe[i,j] != 0)
|
||||
{
|
||||
isEmpty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isEmpty >= 0) break;
|
||||
}
|
||||
if (isEmpty != 0)
|
||||
{
|
||||
DynamicGI.UpdateEnvironment();
|
||||
}
|
||||
}
|
||||
|
||||
// Set lightmap data on mesh renderers
|
||||
var emptyVec4 = new Vector4(1,1,0,0);
|
||||
for(int i=0; i<storage.bakedRenderers.Count; i++)
|
||||
{
|
||||
var r = storage.bakedRenderers[i];
|
||||
if (r == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
//if (r.isPartOfStaticBatch) continue;
|
||||
var id = storage.bakedIDs[i];
|
||||
Mesh vmesh = null;
|
||||
if (i < storage.bakedVertexColorMesh.Count) vmesh = storage.bakedVertexColorMesh[i];
|
||||
|
||||
if (vmesh != null)
|
||||
{
|
||||
var r2 = r as MeshRenderer;
|
||||
if (r2 == null)
|
||||
{
|
||||
Debug.LogError("Unity cannot use additionalVertexStreams on non-MeshRenderer");
|
||||
}
|
||||
else
|
||||
{
|
||||
r2.additionalVertexStreams = vmesh;
|
||||
r2.lightmapIndex = 0xFFFF;
|
||||
var prop = new MaterialPropertyBlock();
|
||||
prop.SetFloat("bakeryLightmapMode", 1);
|
||||
r2.SetPropertyBlock(prop);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
int globalID = (id < 0 || id >= storage.idremap.Length) ? id : storage.idremap[id];
|
||||
r.lightmapIndex = globalID;
|
||||
|
||||
if (!r.isPartOfStaticBatch)
|
||||
{
|
||||
// scaleOffset is baked on static batches already
|
||||
var scaleOffset = id < 0 ? emptyVec4 : storage.bakedScaleOffset[i];
|
||||
r.lightmapScaleOffset = scaleOffset;
|
||||
}
|
||||
|
||||
if (r.lightmapIndex >= 0 && globalID < globalMapsAdditional.Count)
|
||||
{
|
||||
var lmap = globalMapsAdditional[globalID];
|
||||
if (lmap.rnm0 != null)
|
||||
{
|
||||
var prop = new MaterialPropertyBlock();
|
||||
prop.SetTexture("_RNM0", lmap.rnm0);
|
||||
prop.SetTexture("_RNM1", lmap.rnm1);
|
||||
prop.SetTexture("_RNM2", lmap.rnm2);
|
||||
prop.SetFloat("bakeryLightmapMode", lmap.mode);
|
||||
r.SetPropertyBlock(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set lightmap data on definitely-not-baked mesh renderers (can be possibly avoided)
|
||||
if (updateNonBaked)
|
||||
{
|
||||
for(int i=0; i<storage.nonBakedRenderers.Count; i++)
|
||||
{
|
||||
var r = storage.nonBakedRenderers[i];
|
||||
if (r == null) continue;
|
||||
if (r.isPartOfStaticBatch) continue;
|
||||
r.lightmapIndex = 0xFFFE;
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_TERRAINS
|
||||
// Set lightmap data on terrains
|
||||
for(int i=0; i<storage.bakedRenderersTerrain.Count; i++)
|
||||
{
|
||||
var r = storage.bakedRenderersTerrain[i];
|
||||
if (r == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var id = storage.bakedIDsTerrain[i];
|
||||
r.lightmapIndex = (id < 0 || id >= storage.idremap.Length) ? id : storage.idremap[id];
|
||||
|
||||
var scaleOffset = id < 0 ? emptyVec4 : storage.bakedScaleOffsetTerrain[i];
|
||||
r.lightmapScaleOffset = scaleOffset;
|
||||
|
||||
if (r.lightmapIndex >= 0 && r.lightmapIndex < globalMapsAdditional.Count)
|
||||
{
|
||||
var lmap = globalMapsAdditional[r.lightmapIndex];
|
||||
if (lmap.rnm0 != null)
|
||||
{
|
||||
var prop = new MaterialPropertyBlock();
|
||||
prop.SetTexture("_RNM0", lmap.rnm0);
|
||||
prop.SetTexture("_RNM1", lmap.rnm1);
|
||||
prop.SetTexture("_RNM2", lmap.rnm2);
|
||||
prop.SetFloat("bakeryLightmapMode", lmap.mode);
|
||||
r.SetSplatMaterialPropertyBlock(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set shadowmask parameters on lights
|
||||
for(int i=0; i<storage.bakedLights.Count; i++)
|
||||
{
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
if (storage.bakedLights[i] == null) continue;
|
||||
|
||||
int channel = storage.bakedLightChannels[i];
|
||||
var output = new LightBakingOutput();
|
||||
output.isBaked = true;
|
||||
if (channel < 0)
|
||||
{
|
||||
output.lightmapBakeType = LightmapBakeType.Baked;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.lightmapBakeType = LightmapBakeType.Mixed;
|
||||
output.mixedLightingMode = channel > 100 ? MixedLightingMode.Subtractive : MixedLightingMode.Shadowmask;
|
||||
output.occlusionMaskChannel = channel > 100 ? -1 : channel;
|
||||
output.probeOcclusionLightIndex = storage.bakedLights[i].bakingOutput.probeOcclusionLightIndex;
|
||||
}
|
||||
storage.bakedLights[i].bakingOutput = output;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Increment lightmap refcounts
|
||||
if (lightmapRefCount == null) lightmapRefCount = new List<int>();
|
||||
for(int i=0; i<storage.idremap.Length; i++)
|
||||
{
|
||||
int currentID = storage.idremap[i];
|
||||
while(lightmapRefCount.Count <= currentID) lightmapRefCount.Add(0);
|
||||
if (lightmapRefCount[currentID] < 0) lightmapRefCount[currentID] = 0;
|
||||
lightmapRefCount[currentID]++;
|
||||
}
|
||||
//if (loadedStorages == null) loadedStorages = new List<ftLightmapsStorage>();
|
||||
//if (loadedStorages.Contains(storage)) loadedStorages.Add(storage);
|
||||
|
||||
//return appendOffset;
|
||||
}
|
||||
|
||||
public static void UnloadScene(ftLightmapsStorage storage)
|
||||
{
|
||||
if (lightmapRefCount == null) return;
|
||||
if (storage.idremap == null) return;
|
||||
|
||||
//int idx = loadedStorages.IndexOf(storage);
|
||||
//if (idx >= 0) loadedStorages.RemoveAt(idx);
|
||||
|
||||
LightmapData[] existingLmaps = null;
|
||||
List<LightmapAdditionalData> existingLmapsAdditional = null;
|
||||
//bool rebuild = false;
|
||||
for(int i=0; i<storage.idremap.Length; i++)
|
||||
{
|
||||
int currentID = storage.idremap[i];
|
||||
|
||||
// just never unload the 1st lightmap to prevent Unity from losing LM encoding settings
|
||||
// remapping all IDs at runtime would introduce a perf hiccup
|
||||
if (currentID == 0) continue;
|
||||
|
||||
if (lightmapRefCount.Count <= currentID) continue;
|
||||
lightmapRefCount[currentID]--;
|
||||
//Debug.LogError("rem: "+currentID+" "+lightmapRefCount[currentID]);
|
||||
if (lightmapRefCount[currentID] == 0)
|
||||
{
|
||||
if (existingLmaps == null) existingLmaps = LightmapSettings.lightmaps;
|
||||
|
||||
if (existingLmaps.Length > currentID)
|
||||
{
|
||||
existingLmaps[currentID].lightmapColor = null;
|
||||
existingLmaps[currentID].lightmapDir = null;
|
||||
existingLmaps[currentID].shadowMask = null;
|
||||
|
||||
if (existingLmapsAdditional == null) existingLmapsAdditional = globalMapsAdditional;
|
||||
if (existingLmapsAdditional != null && existingLmapsAdditional.Count > currentID)
|
||||
{
|
||||
var emptyEntry = new LightmapAdditionalData();
|
||||
existingLmapsAdditional[currentID] = emptyEntry;
|
||||
}
|
||||
}
|
||||
//if (currentID == 0) rebuild = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// If the first lightmap was unloaded, we need to rebuild the lightmap array
|
||||
// because Unity uses 1st lightmap to determine encoding
|
||||
if (rebuild)
|
||||
{
|
||||
int newLength = 0;
|
||||
for(int i=0; i<existingLmaps.Length; i++)
|
||||
{
|
||||
if (existingLmaps[i].lightmapColor != null) newLength++;
|
||||
}
|
||||
var existingLmaps2 = new LightmapData[newLength];
|
||||
int ctr = 0;
|
||||
for(int i=0; i<existingLmaps.Length; i++)
|
||||
{
|
||||
if (existingLmaps[i].lightmapColor != null)
|
||||
{
|
||||
existingLmaps2[ctr] = existingLmaps[i];
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
existingLmaps = existingLmaps2;
|
||||
|
||||
for(int i=0; i<)
|
||||
}
|
||||
*/
|
||||
|
||||
if (existingLmaps != null) LightmapSettings.lightmaps = existingLmaps;
|
||||
}
|
||||
|
||||
public static void RefreshScene2(Scene scene, ftLightmapsStorage storage)
|
||||
{
|
||||
Renderer r;
|
||||
int id;
|
||||
for(int i=0; i<storage.bakedRenderers.Count; i++)
|
||||
{
|
||||
r = storage.bakedRenderers[i];
|
||||
if (r == null) continue;
|
||||
|
||||
id = storage.bakedIDs[i];
|
||||
r.lightmapIndex = (id < 0 || id >= storage.idremap.Length) ? id : storage.idremap[id];
|
||||
}
|
||||
|
||||
#if USE_TERRAINS
|
||||
Terrain r2;
|
||||
for(int i=0; i<storage.bakedRenderersTerrain.Count; i++)
|
||||
{
|
||||
r2 = storage.bakedRenderersTerrain[i];
|
||||
if (r2 == null) continue;
|
||||
|
||||
id = storage.bakedIDsTerrain[i];
|
||||
r2.lightmapIndex = (id < 0 || id >= storage.idremap.Length) ? id : storage.idremap[id];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (storage.anyVolumes)
|
||||
{
|
||||
if (storage.compressedVolumes)
|
||||
{
|
||||
Shader.EnableKeyword("BAKERY_COMPRESSED_VOLUME");
|
||||
}
|
||||
else
|
||||
{
|
||||
Shader.DisableKeyword("BAKERY_COMPRESSED_VOLUME");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue