public override void OnInspectorGUI() { VertexLightingOverride source = target as VertexLightingOverride; BakeSettings settings = source.m_bakeSettingsOverride; DVLEditor.DrawShadowAndAOSettings(settings, source, true); if (GUILayout.Button("Copy Global Settings")) { source.m_bakeSettingsOverride.CopySettings(BakeData.Instance().GetBakeSettings().SelectedBakeSet); EditorUtility.SetDirty(source); } }
// Helper method for marshaling mesh data with sub mesh definition public static void BuildSceneContext(MeshFilter[] meshes, List <List <int> > subMeshIndices, List <List <int> > subMeshTriangleIndices, BakeContext ctx, IVertex vertex = null) { if (vertex == null) { vertex = new DefaultVertex(); } ctx.m_vertexEementCount = vertex.ElementCount; ctx.m_vertexDefinition = vertex.Definition.ToArray(); int totalVertCount = 0; int totalTriCount = 0; int meshCount = meshes.Length; // extract mesh renderer options MeshRenderer[] renderer = ctx.m_meshRenderers; // calculate mesh data size for (int i = 0; i < meshCount; ++i) { // if a sub mesh is defined use it for vert count if (subMeshIndices != null && subMeshIndices[i] != null) { totalVertCount += subMeshIndices[i].Count; } else { totalVertCount += meshes[i].sharedMesh.vertices.Length; } // if a sub mesh is defined use it for triangle index count if (subMeshTriangleIndices != null && subMeshTriangleIndices[i] != null) { totalTriCount += subMeshTriangleIndices[i].Count; } else { totalTriCount += meshes[i].sharedMesh.triangles.Length; } } // data size const int triangleSize = 3; const int matSize = 16; int totalMatrixDataSize = matSize * meshCount * SIZE_FLOAT; // mesh size depends on vertex definition int totalMeshDataSize = totalVertCount * SIZE_FLOAT * (vertex.VertexSize + meshCount); int totalTriangleDataSize = totalTriCount * triangleSize * SIZE_INT; VertexBakerLib instance = VertexBakerLib.Instance; ctx.m_meshIdsPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_vertexCountsPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_triangleCountPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_matDataPtr = instance.Alloc(totalMatrixDataSize); ctx.m_meshDataPtr = instance.Alloc(totalMeshDataSize); ctx.m_triangleDataPtr = instance.Alloc(totalTriangleDataSize); ctx.m_settingsIndicesPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_bakeOptionsPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_layerPtr = instance.Alloc(meshCount * SIZE_INT); // temp buffer for matrix float[] matArr = new float[16]; int matDestOffset = 0; int meshDestOffset = 0; int triangleDestOffset = 0; int[] vertexCounts = new int[meshCount]; int[] triangleCounts = new int[meshCount]; int[] ids = new int[meshCount]; uint[] perMeshBakeOpt = new uint[meshCount]; uint[] layerMask = new uint[meshCount]; // data for settings int[] settingsIdx = new int[meshCount]; List <IntPtr> settingsList = new List <IntPtr>(); // global settings int globalSettingsIdx = 0; IntPtr globalSettings = SettingsToIntPtr(BakeData.Instance().GetBakeSettings().SelectedBakeSet); settingsList.Add(globalSettings); for (int m = 0; m < meshCount; ++m) { bool processSubMesh = false; // assume sub mesh if (subMeshIndices != null && subMeshIndices[m] != null && subMeshTriangleIndices != null && subMeshTriangleIndices[m] != null) { processSubMesh = true; } // setup settings settingsIdx[m] = globalSettingsIdx; // check for override settings VertexLightingOverride ovrdSettings = meshes[m].GetComponent <VertexLightingOverride>(); if (ovrdSettings != null) { // point at this overrides index settingsIdx[m] = settingsList.Count; // ensure ambient settings (copy from global which contains the valid ambient settings for now) ovrdSettings.m_bakeSettingsOverride.CopyAmbient(BakeData.Instance().GetBakeSettings().SelectedBakeSet); IntPtr settingsPtr = SettingsToIntPtr(ovrdSettings.m_bakeSettingsOverride); settingsList.Add(settingsPtr); } Mesh mesh = meshes[m].sharedMesh; ids[m] = meshes[m].GetUniqueId(); // layer mask layerMask[m] = (uint)(1 << meshes[m].gameObject.layer); // clear data perMeshBakeOpt[m] = 0; // if mesh has no normals or tangents flag them for generation // should calculate normals if (meshes[m].sharedMesh.normals.Length == 0) { // set bit for normals perMeshBakeOpt[m] |= BakeOptions.kCalcNormals; } // should calculate tangents if (meshes[m].sharedMesh.tangents.Length == 0) { // set bit for tangents perMeshBakeOpt[m] |= BakeOptions.kCalcTangents; } // extract shadowing options from renderer switch (renderer[m].shadowCastingMode) { case UnityEngine.Rendering.ShadowCastingMode.Off: { perMeshBakeOpt[m] |= BakeOptions.kShadowsOff; } break; case UnityEngine.Rendering.ShadowCastingMode.TwoSided: { perMeshBakeOpt[m] |= BakeOptions.kTwoSided; } break; case UnityEngine.Rendering.ShadowCastingMode.On: { perMeshBakeOpt[m] |= BakeOptions.kShadowsOn; } break; case UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly: { perMeshBakeOpt[m] |= BakeOptions.kShadowsOnly; } break; default: break; } if (renderer[m].receiveShadows) { perMeshBakeOpt[m] |= BakeOptions.kReceiveShadow; } else { perMeshBakeOpt[m] &= ~BakeOptions.kReceiveShadow; } // use the list of unique indices of the sub mesh to find the count here unless its null then assume all vertices are being processed int vertexCount = processSubMesh ? subMeshIndices[m].Count : mesh.vertices.Length; // use the list of triangles from the sub mesh to find the count here unless its null then assume all triangles are being processed int triangleCount = processSubMesh ? subMeshTriangleIndices[m].Count : mesh.triangles.Length; vertexCounts[m] = vertexCount; triangleCounts[m] = triangleCount; // copy mesh data into mesh buffer starting with world matrix int matIndex = 0; AssignMat4(ref matArr, meshes[m].transform.localToWorldMatrix, ref matIndex); // 64 bytes IntPtr matDestPtr = new IntPtr(ctx.m_matDataPtr.ToInt64() + matDestOffset * SIZE_FLOAT); Marshal.Copy(matArr, 0, matDestPtr, 16); matDestOffset += 16; if (processSubMesh) { // build sub mesh BuildMesh(ctx, meshes[m].sharedMesh, vertex, subMeshIndices[m], ref meshDestOffset); } else { // build entire mesh BuildMesh(ctx, meshes[m].sharedMesh, vertex, ref meshDestOffset); } // triangles IntPtr indexPtr = new IntPtr(ctx.m_triangleDataPtr.ToInt64() + triangleDestOffset * SIZE_INT); if (processSubMesh) { // copy sub mesh triangle list Marshal.Copy(subMeshTriangleIndices[m].ToArray(), 0, indexPtr, triangleCount); } else { // copy entire triangle list Marshal.Copy(mesh.triangles, 0, indexPtr, triangleCount); } triangleDestOffset += triangleCount; } // copy the mesh into pointer instance.CopyArray(ctx.m_meshIdsPtr, meshCount * SIZE_INT, ids, meshCount * SIZE_INT); instance.CopyArray(ctx.m_vertexCountsPtr, meshCount * SIZE_INT, vertexCounts, meshCount * SIZE_INT); instance.CopyArray(ctx.m_triangleCountPtr, meshCount * SIZE_INT, triangleCounts, meshCount * SIZE_INT); instance.CopyUIntArray(ctx.m_bakeOptionsPtr, meshCount * SIZE_INT, perMeshBakeOpt, meshCount * SIZE_INT); instance.CopyUIntArray(ctx.m_layerPtr, meshCount * SIZE_INT, layerMask, meshCount * SIZE_INT); instance.CopyArray(ctx.m_settingsIndicesPtr, meshCount * SIZE_INT, settingsIdx, meshCount * SIZE_INT); ctx.m_settingsPtrs = settingsList.ToArray(); ctx.m_vertCounts = vertexCounts; }