protected static void TryLoadBVH(MeshFilter meshFilter) { if (meshFilter != null && meshFilter.sharedMesh != null) { if (!VertexBakerLib.Instance.LoadBVH(meshFilter, ref s_bvhHandle)) { // Load from scratch VertexBakerLib.Log("Could not load BVH data, building from scratch"); VertexBakerLib.BVHHandle[] bvhHandles = new VertexBakerLib.BVHHandle[1]; // build BVH and get handle VertexBakerLib.Instance.BuildBVH(new MeshFilter[] { meshFilter }, ref bvhHandles); // make sure its good if (bvhHandles != null && VertexBakerLib.Instance.ValidHandle(bvhHandles[0].Ptr())) { s_bvhHandle = bvhHandles[0]; if (VertexBakerLib.s_logging == VertexBakerLib.Logging.kVerbose) { VertexBakerLib.Log("BVH build success!"); } } else { s_bvhHandle = null; VertexBakerLib.LogError("Invalid BVH Handle, BVH not built"); } } } }
protected static void Init(MeshFilter meshFilter, Mesh untessellatedMesh) { if (!Directory.Exists(FBSConstants.BasePath + "/Cache/")) { Directory.CreateDirectory(FBSConstants.BasePath + "/Cache/"); } if (!Directory.Exists(FBSConstants.BasePath + "/BVHCache/")) { Directory.CreateDirectory(FBSConstants.BasePath + "/BVHCache/"); } if (meshFilter.sharedMesh == null) { Debug.LogWarning(meshFilter.gameObject.GetPath() + " is missing its source mesh"); return; } s_debugState = BakeData.Instance().GetDebugState(); #if _DAYDREAM_STATIC_LIGHTING_DEBUG DateTime start = DateTime.Now; // if we still have a handle for some reason try to free it if (s_lastInstanceId != meshFilter.GetUniqueId()) { if (s_bvhHandle != null) { VertexBakerLib.Instance.FreeHandle(s_bvhHandle.Ptr()); } s_bvhHandle = null; BuildWorldVertices(meshFilter); s_debugState.m_tessFaces = null; } TryLoadBVH(meshFilter); s_lastInstanceId = meshFilter.GetUniqueId(); if (s_bvhWrapper == null) { s_bvhWrapper = new BVHNode_FBWrapper(); } string sourceAssetPath = AssetDatabase.GetAssetPath(untessellatedMesh); if (!string.IsNullOrEmpty(sourceAssetPath) && !Application.isPlaying) { Debug.LogWarning("Could not find asset " + untessellatedMesh.name + " the asset may be an instance. Some debug data may not be available."); } string path = BVH.ConvertMeshIdToBVHPath(s_lastInstanceId); s_bvhWrapper.SetPath(path); s_bvhWrapper.Validate(); s_cacheWrapper.SetPath("" + s_lastInstanceId); s_cacheWrapper.Validate(); VertexBakerLib.Log("Debug setup time: " + (DateTime.Now - start).TotalSeconds + " seconds"); #endif }
//private static void BuildWorldVertices(DaydreamVertexLighting source) //{ // s_debugState.m_worldVerPos = source.m_sourceMesh.vertices; // s_debugState.m_worldNormals = source.m_sourceMesh.normals; // for (int i = 0; i < s_debugState.m_worldNormals.Length; ++i) // { // s_debugState.m_worldVerPos[i] = source.transform.TransformPoint(s_debugState.m_worldVerPos[i]); // s_debugState.m_worldNormals[i] = source.transform.TransformVector(s_debugState.m_worldNormals[i]).normalized; // } //} #region Test Methods public void TestBuildBVHNative(DaydreamVertexLighting source) { DateTime start = DateTime.Now; MeshFilter meshFilter = source.GetComponent <MeshFilter>(); if (meshFilter != null) { VertexBakerLib.Instance.BuildBVH(new MeshFilter[] { meshFilter });; } VertexBakerLib.Log("Seconds to complete: " + (DateTime.Now - start).TotalSeconds); }
public void TestFileSystem() { #if DDR_RUNTIME_DLL_LINKING_ bool pass = Invoke <bool, _TestFileSystem>(); #else bool pass = _TestFileSystem(); #endif if (!pass) { VertexBakerLib.LogError("TestFileSystem failed"); } else { VertexBakerLib.Log("TestFileSystem pass"); } }
public string TestArrayOfInts(Matrix4x4 matrix) { int[] matrixArr = new int[16]; for (int i = 0; i < 16; ++i) { matrixArr[i] = (int)matrix[i]; } int size = matrixArr.Length; string msg = Marshal.PtrToStringAnsi(Invoke <IntPtr, _TestArrayOfInts>(matrixArr, size)); for (int i = 0; i < 16; ++i) { VertexBakerLib.Log("val " + matrixArr[i]); } return(msg); }
public void TestLoadBVH(DaydreamVertexLighting source) { DateTime start = DateTime.Now; MeshFilter meshFilter = source.GetComponent <MeshFilter>(); if (meshFilter != null) { try { VertexBakerLib.BVHHandle bvhHandle = null; if (VertexBakerLib.Instance.LoadBVH(meshFilter, ref bvhHandle)) { VertexBakerLib.Instance.FreeHandle(bvhHandle.Ptr()); } } catch (Exception e) { Debug.LogError(e.Message + "\n" + e.StackTrace); } } VertexBakerLib.Log("Seconds to complete: " + (DateTime.Now - start).TotalSeconds); }
public int BakeFinish(OnFinishedUpdate onUpdate) { VertexBakerLib.Assert(this != null && !m_run, "BakeFinished called but bake is still in process"); string outputPath = BakeData.DataPath; if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } if (m_result != 0) { string error = VertexBakerLib.Instance.GetLastError(); VertexBakerLib.LogError(error); } else if (!m_cancel && m_outBasis0[0] != IntPtr.Zero && m_outBasis1[0] != IntPtr.Zero && m_outBasis2[0] != IntPtr.Zero) { string bakeSetId = BakeData.Instance().GetBakeSettings().SelectedBakeSet.m_settingsId; BakeSets bakeSets = BakeData.Instance().GetBakeSets(); MeshContainer meshContainer = BakeData.Instance().GetMeshContainer(bakeSetId); EditorUtility.SetDirty(meshContainer); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); AssetDatabase.StartAssetEditing(); try { int ptrOffset = 0; int meshOffset = 0; for (int m = 0; m < m_meshes.Count; ++m) { int count = m_vertCounts[m]; int floatCount = count * 3; // the ID used to look up this mesh later string objectId = "" + m_lightBakers[m].GetUniqueId(); m_lightBakers[m].m_currentContainer = meshContainer; Mesh outputMesh = meshContainer.m_list.Find(delegate(Mesh mesh) { if (mesh != null) { return(mesh.name == bakeSetId + "_" + objectId); } return(false); }); if (outputMesh == null) { if (m_lightBakers[m].VertexLighting != null) { // if we are here than the mesh name may have changed, try and remove the stale data string oldName = m_lightBakers[m].VertexLighting.name; Mesh found = meshContainer.m_list.Find(delegate(Mesh mesh) { // remove the old reference if (mesh != null) { return(mesh.name == oldName); } // remove null mesh return(false); }); if (found != null) { GameObject.DestroyImmediate(found, true); } } // if no mesh exists for this target create it here outputMesh = new Mesh(); BakeData.Instance().AddToMeshContainer(meshContainer, outputMesh); //meshContainer.m_list.Add(outputMesh); //// add to the container asset //string outputFileName = bakeSetId + "_lighting"; //AssetDatabase.AddObjectToAsset(outputMesh, outputPath + "/" + outputFileName + ".asset"); } outputMesh.name = bakeSetId + "_" + objectId; // HACK: Work around to make Unity happy. If vertices are not found the additional vertex stream fails //outMeshes[m].vertices = m_meshes[m].sharedMesh.vertices; outputMesh.vertices = m_meshes[m].sharedMesh.vertices; // 3 floats per vector float[] rawData0 = new float[floatCount]; float[] rawData1 = new float[floatCount]; float[] rawData2 = new float[floatCount]; // offset pointer to next mesh IntPtr basis0 = new IntPtr(m_outBasis0[0].ToInt64() + ptrOffset * SIZE_FLOAT); IntPtr basis1 = new IntPtr(m_outBasis1[0].ToInt64() + ptrOffset * SIZE_FLOAT); IntPtr basis2 = new IntPtr(m_outBasis2[0].ToInt64() + ptrOffset * SIZE_FLOAT); ptrOffset += floatCount; // marshal data into float arrays Marshal.Copy(basis0, rawData0, 0, floatCount); Marshal.Copy(basis1, rawData1, 0, floatCount); Marshal.Copy(basis2, rawData2, 0, floatCount); // lists to hold output vectors List <Color> colorList0 = new List <Color>(); colorList0.Resize(count, Color.black); List <Vector3> colorList1 = new List <Vector3>(); colorList1.Resize(count, Vector3.zero); List <Vector3> colorList2 = new List <Vector3>(); colorList2.Resize(count, Vector3.zero); // copy float arrays into mesh data for (int i = 0; i < count; ++i) { int idx = i * 3; colorList0[i] = new Color(rawData0[idx], rawData0[idx + 1], rawData0[idx + 2], 1.0f); colorList1[i] = new Vector3(rawData1[idx], rawData1[idx + 1], rawData1[idx + 2]); colorList2[i] = new Vector3(rawData2[idx], rawData2[idx + 1], rawData2[idx + 2]); } // this offset is target uv sets 1, 2, and 3 for data destination const int uvOffset = 1; outputMesh.SetColors(colorList0); outputMesh.SetUVs(uvOffset + 1, colorList1); outputMesh.SetUVs(uvOffset + 2, colorList2); //outputMesh.UploadMeshData(true); meshOffset += count; EditorUtility.SetDirty(meshContainer); m_meshRenderers[m].additionalVertexStreams = outputMesh; m_lightBakers[m].m_bakeSets = bakeSets; m_lightBakers[m].VertexLighting = outputMesh; m_lightBakers[m].m_bakeId = objectId; EditorUtility.SetDirty(m_lightBakers[m]); onUpdate("Uploading Mesh Data", m_meshCount / (float)m); } // remove any null slots meshContainer.m_list.RemoveAll(delegate(Mesh m) { return(m == null); }); // aggregate containers under one super container int existingIdx = bakeSets.m_containers.FindIndex(delegate(MeshContainer mc) { return(mc.name == meshContainer.name); }); if (existingIdx != -1) { // replace existing entry bakeSets.m_containers[existingIdx] = meshContainer; } else { bakeSets.m_containers.Add(meshContainer); } BakeSetsInspector.CleanupStaleReferences(bakeSets); EditorUtility.SetDirty(bakeSets); AssetDatabase.SaveAssets(); } finally { onUpdate("Uploading Mesh Data", 1f); AssetDatabase.StopAssetEditing(); } } else { VertexBakerLib.LogWarning("Bake completed successfully but there was no output data available"); } // free data FreeContext(true); // since basis memory was allocated in one chunk // freeing this handle frees all basis memory VertexBakerLib.Instance.Free(m_outBasis0[0]); EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene()); VertexBakerLib.Log("Bake time: " + (DateTime.Now - m_bakeStart).TotalSeconds + " seconds"); while (VertexBakerLib.Instance.GetErrorCount() > 0) { string err = VertexBakerLib.Instance.GetLastError(); VertexBakerLib.LogError(err); } GC.Collect(); return(m_result); }
private static void BakeHelper(GameObject[] bakeRoots) { VertexBakerLib.Instance.BakeReset(); DateTime bakeStart = DateTime.Now; List <MeshFilter> meshes = new List <MeshFilter>(); s_meshRenderers = new List <MeshRenderer>(); // gather meshes in selection foreach (GameObject go in bakeRoots) { MeshFilter[] filters = go.GetComponentsInChildren <MeshFilter>(); foreach (MeshFilter filter in filters) { MeshRenderer mr = filter.GetComponent <MeshRenderer>(); if (filter.sharedMesh == null) { Debug.LogWarning(filter.gameObject.GetPath() + " has a missing mesh"); } bool staticLit = (StaticEditorFlags.LightmapStatic & GameObjectUtility.GetStaticEditorFlags(filter.gameObject)) > 0; if (filter.sharedMesh != null && filter.gameObject.activeSelf && staticLit && mr != null && mr.enabled) { s_meshRenderers.Add(mr); meshes.Add(filter); } } } if (meshes.Count == 0) { EditorUtility.DisplayDialog(Styles.kEditorTitle, Styles.kNoStaticMeshes, "ok"); return; } if (meshes.Count != s_meshRenderers.Count) { EditorUtility.DisplayDialog(Styles.kEditorTitle, "MeshRenderers are not 1 to 1 with Mesh Filters", "ok"); return; } List <Light> lights = new List <Light>(); DDRSettings settingsData = BakeData.Instance().GetBakeSettings(); if (settingsData.SelectedBakeSet.m_forceAllLights) { List <GameObject> sceneRoots = Utilities.GetAllRoots(); foreach (GameObject go in sceneRoots) { Light[] lightList = go.GetComponentsInChildren <Light>(); foreach (Light light in lightList) { if (light.IsLightmapLight()) { lights.Add(light); } } } } else { List <LightEntry> lightFilter = settingsData.SelectedBakeSet.m_lightList; Dictionary <int, Light> localFileIdToLight = Utilities.LightsByLocalFileId(); foreach (LightEntry lightEntry in lightFilter) { Light light = null; // group if lights if (!string.IsNullOrEmpty(lightEntry.m_group)) { // get parent objects for each path that matches the group path List <GameObject> parents = Utilities.FindAll(lightEntry.m_group); // gather all lights under group if (parents.Count > 0) { // add lights to the new group foreach (GameObject parent in parents) { for (int i = 0; i < parent.transform.childCount; ++i) { GameObject child = parent.transform.GetChild(i).gameObject; light = child.GetComponent <Light>(); if (light.IsLightmapLight()) { lights.Add(light); } } } } } else { // ungrouped light if (localFileIdToLight.TryGetValue(lightEntry.m_idInFile, out light)) { if (light.IsLightmapLight()) { lights.Add(light); } } } } } VertexBakerLib.Log("Collect data time: " + (DateTime.Now - bakeStart).TotalSeconds + " seconds"); /////////////// // native bake /////////////// try { // stop listening for changes m_ignoreNextChange = true; // int activeLightCount = DaydreamRendererSceneData.GetActiveLightCount(); // DaydreamRendererSceneData sceneData = TypeExtensions.FindOrCreateScriptableAsset<DaydreamRendererSceneData>(VertexBakerLib.DataPath, "scenedata"); s_bakeInProgress = true; VertexBakerLib.Instance.Bake(meshes, lights, delegate() { s_bakeIsFinished = true; }); } catch (Exception e) { Debug.LogError(e.Message); Debug.LogError(e.StackTrace); } }