Пример #1
0
        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
        }
Пример #2
0
        public int RebuildBVH(BVHHandle bvhHandle)
        {
            // build baker context
            m_baker.m_sourcePaths   = new string[] { AssetDatabase.GetAssetPath(bvhHandle.SourceMeshData.sharedMesh) };
            m_baker.m_guids         = new string[] { "" + m_baker.m_meshes[0].GetUniqueId() };
            m_baker.m_meshRenderers = new MeshRenderer[] { bvhHandle.SourceMeshData.GetComponent <MeshRenderer>() };

            // parse data and fill in missing context
            BakeContext.BuildSceneContext(new MeshFilter[] { bvhHandle.SourceMeshData }, m_baker);

#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _RebuildBVH>(bvhHandle.Ptr(), m_baker.m_meshIdsPtr, m_baker.m_vertexCountsPtr, m_baker.m_triangleCountPtr
                                                , m_baker.m_matDataPtr, m_baker.m_meshDataPtr, m_baker.m_triangleDataPtr, m_baker.m_bakeOptionsPtr, 1, m_baker.m_guids, m_baker.m_sourcePaths);
#else
            int err = _RebuildBVH(bvhHandle.Ptr(), m_baker.m_meshIdsPtr, m_baker.m_vertexCountsPtr, m_baker.m_triangleCountPtr
                                  , m_baker.m_matDataPtr, m_baker.m_meshDataPtr, m_baker.m_triangleDataPtr, m_baker.m_bakeOptionsPtr, 1, m_baker.m_guids, m_baker.m_sourcePaths);
#endif

            m_baker.FreeContext();

            if (err != 0)
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
            }

            return(err);
        }
Пример #3
0
 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");
             }
         }
     }
 }
Пример #4
0
        public bool LoadBVHScene(List <MeshFilter> meshes, out Handle bvhHandle)
        {
            // filter items
            meshes.RemoveAll(delegate(MeshFilter mf)
            {
                BakeFilter bf = mf.GetComponent <BakeFilter>();
                if (bf != null)
                {
                    return(bf.m_bakeFilter == BakeFilter.Filter.ExcludeFromBake);
                }

                return(false);
            });

            // find BVH to rebuild
            List <MeshFilter> rebuildList = new List <MeshFilter>();

            foreach (MeshFilter mf in meshes)
            {
                if (!IsValidBVH(mf))
                {
                    rebuildList.Add(mf);
                }
            }

            // build BVH for missing/out-of-date BVH's
            if (rebuildList.Count > 0)
            {
                BuildBVH(rebuildList.ToArray());
            }

            // build id list
            IntPtr meshIdsPtr = Alloc(meshes.Count * SIZE_INT);

            int[] ids = new int[meshes.Count];
            for (int m = 0; m < meshes.Count; ++m)
            {
                ids[m] = meshes[m].GetUniqueId();
            }
            CopyArray(meshIdsPtr, meshes.Count * SIZE_INT, ids, meshes.Count * SIZE_INT);

            IntPtr[] handle = new IntPtr[1];
#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _LoadBVHScene>(meshIdsPtr, meshes.Count, handle);
#else
            int err = _LoadBVHScene(meshIdsPtr, meshes.Count, handle);
#endif

            Free(meshIdsPtr);

            bvhHandle = new Handle(handle[0], this);
            if (err != 0)
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
                return(false);
            }

            return(true);
        }
Пример #5
0
        public void BVHToLineSegment(Handle bvhSceneHandle, Vector3 startPoint, Vector3 endPoint, List <Vector3> outCenters, List <Vector3> outSizes)
        {
            IntPtr[] outCenterSizePtr = new IntPtr[1];
            outCenterSizePtr[0] = IntPtr.Zero;
            int[] outCount = new int[1];
            outCount[0] = 0;
#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _BVHToLineSegment>(bvhSceneHandle.Ptr(), startPoint, endPoint, outCenterSizePtr, outCount);
#else
            int err = _BVHToLineSegment(bvhSceneHandle.Ptr(), ToFloatArray(startPoint), ToFloatArray(endPoint), outCenterSizePtr, outCount);
#endif
            if (err == 0)
            {
                int    count   = outCount[0];
                IntPtr dataPtr = outCenterSizePtr[0];

                if (outCount[0] > 0 && dataPtr != IntPtr.Zero)
                {
                    float[] rawData = new float[outCount[0]];
                    Marshal.Copy(dataPtr, rawData, 0, outCount[0]);
                    for (int i = 0; i < count; i += 6)
                    {
                        outCenters.Add(new Vector3(rawData[i], rawData[i + 1], rawData[i + 2]));
                        outSizes.Add(new Vector3(rawData[i + 3], rawData[i + 4], rawData[i + 5]));
                    }

                    Free(dataPtr);
                }
            }
            else
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
            }
        }
            public void GetAsVec2(Mesh mesh, List <int> subMeshIndices, ref Vector2[] outData)
            {
                VertexElementType elType = (VertexElementType)m_elType;

                Vector2[] data = null;
                switch (elType)
                {
                case VertexElementType.kPosition:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kNormal:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kTangent:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kColor:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kUV0:
                    data = mesh.uv;
                    break;

                case VertexElementType.kUV1:
                    data = mesh.uv2;
                    break;

                case VertexElementType.kUV2:
                    data = mesh.uv3;
                    break;

                case VertexElementType.kUV3:
                    data = mesh.uv4;
                    break;

                default:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    outData = null;
                    break;
                }

                if (subMeshIndices != null)
                {
                    outData = new Vector2[subMeshIndices.Count];
                    for (int i = 0, k = subMeshIndices.Count; i < k; ++i)
                    {
                        outData[i] = data[subMeshIndices[i]];
                    }
                }
                else
                {
                    outData = data;
                }
            }
Пример #7
0
        public int TessellateTriangles(BVHHandle bvhHandle, Vector3 startPoint, Vector3 endPoint)
        {
            m_baker.m_sourcePaths   = new string[] { AssetDatabase.GetAssetPath(bvhHandle.SourceMeshData.sharedMesh) };
            m_baker.m_guids         = new string[] { "" + m_baker.m_meshes[0].GetUniqueId() };
            m_baker.m_meshRenderers = new MeshRenderer[] { bvhHandle.SourceMeshData.GetComponent <MeshRenderer>() };
            List <MeshFilter> meshes = new List <MeshFilter>()
            {
                bvhHandle.SourceMeshData
            };

            m_baker.InitBakeContext(meshes, null);
            BakeContext.IVertex vertexFormat = new BakeContext.DefaultVertex();
            BakeContext.BuildSceneContext(m_baker.m_meshes.ToArray(), m_baker, vertexFormat);

            int[] outIndex = new int[1];
            outIndex[0] = -1;
#if DDR_RUNTIME_DLL_LINKING_
            bool success = Invoke <bool, _TessellateTriangles>(bvhHandle.Ptr()
                                                               , m_baker.m_meshIdsPtr
                                                               , m_baker.m_vertexCountsPtr
                                                               , m_baker.m_triangleCountPtr
                                                               , vertexFormat.ElementCount
                                                               , vertexFormat.Definition.ToArray()
                                                               , m_baker.m_matDataPtr
                                                               , m_baker.m_meshDataPtr
                                                               , m_baker.m_triangleDataPtr
                                                               , m_baker.m_bakeOptionsPtr
                                                               , m_baker.m_guids
                                                               , m_baker.m_sourcePaths
                                                               , m_baker.m_settingsPtrs);
            #else
            bool success = _TessellateTriangles(bvhHandle.Ptr()
                                                , m_baker.m_meshIdsPtr
                                                , m_baker.m_vertexCountsPtr
                                                , m_baker.m_triangleCountPtr
                                                , vertexFormat.ElementCount
                                                , vertexFormat.Definition.ToArray()
                                                , m_baker.m_matDataPtr
                                                , m_baker.m_meshDataPtr
                                                , m_baker.m_triangleDataPtr
                                                , m_baker.m_bakeOptionsPtr
                                                , m_baker.m_guids
                                                , m_baker.m_sourcePaths
                                                , m_baker.m_settingsPtrs);
            #endif
            if (!success)
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
            }

            return(outIndex[0]);
        }
        //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);
        }
Пример #9
0
        public int CopyVector4(IntPtr dest, int destSize, Vector4 src, int byteCount)
        {
#if DDR_RUNTIME_DLL_LINKING_
            int errno = Invoke <int, _CopyVector4>(dest, destSize, src, byteCount);
#else
            int errno = _CopyVector4(dest, destSize, ref src, byteCount);
#endif
            if (errno != 0)
            {
                VertexBakerLib.LogError("Error copying data in memcpy_s, errno " + errno);
            }
            return(errno == 0 ? byteCount : 0);
        }
Пример #10
0
        public IntPtr Alloc(int size)
        {
#if DDR_RUNTIME_DLL_LINKING_
            IntPtr ptr = Invoke <IntPtr, _Alloc>(size);
#else
            IntPtr ptr = _Alloc(size);
#endif
            if (ptr == IntPtr.Zero)
            {
                VertexBakerLib.LogError("Alloc null");
            }

            return(ptr);
        }
Пример #11
0
        public bool LoadBVH(MeshFilter mesh, ref BVHHandle bvhHandle)
        {
            IntPtr[] handle = new IntPtr[1];
#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _LoadBVH>(mesh.GetUniqueId(), handle);
#else
            int err = _LoadBVH(mesh.GetUniqueId(), handle);
#endif
            bvhHandle = new BVHHandle(mesh, handle[0], this);
            if (err != 0)
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
                return(false);
            }
            return(true);
        }
Пример #12
0
        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");
            }
        }
Пример #13
0
        public int RayToIndex(Handle bvhSceneHandle, Vector3 startPoint, Vector3 endPoint)
        {
            int[] outIndex = new int[1];
            outIndex[0] = -1;
#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _RayToIndex>(bvhSceneHandle.Ptr(), ToFloatArray(startPoint), ToFloatArray(endPoint), outIndex);
#else
            int err = _RayToIndex(bvhSceneHandle.Ptr(), ToFloatArray(startPoint), ToFloatArray(endPoint), outIndex);
#endif
            if (err != 0)
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
            }

            return(outIndex[0]);
        }
            public void GetAsColor(Mesh mesh, List <int> subMeshIndices, ref Color[] outData)
            {
                Color[]           data   = null;
                VertexElementType elType = (VertexElementType)m_elType;

                switch (elType)
                {
                case VertexElementType.kPosition:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kNormal:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kTangent:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kColor:
                    data = mesh.colors;
                    break;

                case VertexElementType.kUV0:
                case VertexElementType.kUV1:
                case VertexElementType.kUV2:
                case VertexElementType.kUV3:
                default:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    data = null;
                    break;
                }
                if (subMeshIndices != null)
                {
                    outData = new Color[subMeshIndices.Count];
                    for (int i = 0, k = subMeshIndices.Count; i < k; ++i)
                    {
                        outData[i] = data[subMeshIndices[i]];
                    }
                }
                else
                {
                    outData = data;
                };
            }
Пример #15
0
        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);
        }
Пример #16
0
        public void OccludersAtVertex(Handle bvhhandle, int vertIndex, Vector3 worldPos, Vector3 worldNorm
                                      , ref List <Vector3> testPoints, ref List <Vector3> colPoints, ref float accessability, ref Vector3 accumulatedRayDir)
        {
            // dest points data
            IntPtr[] testPointsPtr  = new IntPtr[1];
            int[]    testPointCount = new int[1];
            testPointsPtr[0]  = IntPtr.Zero;
            testPointCount[0] = 0;

            // col Points data
            IntPtr[] colPointsPtr = new IntPtr[1];
            int[]    colCount     = new int[1];
            colPointsPtr[0] = IntPtr.Zero;
            colCount[0]     = 0;

            // data to hold accessability
            float[] accessabilityOut = new float[1] {
                0f
            };

            // data to hold accumulated ray dir
            Vector3[] accumulatedRayDirOut = new Vector3[1] {
                Vector3.zero
            };

#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _OccludersAtVertex>(bvhhandle.Ptr(), vertIndex, worldPos, worldNorm, testPointsPtr, testPointCount, colPointsPtr, colCount, accessabilityOut, accumulatedRayDirOut);
#else
            int err = _OccludersAtVertex(bvhhandle.Ptr(), vertIndex, worldPos, worldNorm, testPointsPtr, testPointCount, colPointsPtr, colCount, accessabilityOut, accumulatedRayDirOut);
#endif
            if (err == 0)
            {
                CopyFloatPtrToVectorList(testPointsPtr[0], testPointCount[0], ref testPoints);
                CopyFloatPtrToVectorList(colPointsPtr[0], colCount[0], ref colPoints);
                accessability     = accessabilityOut[0];
                accumulatedRayDir = accumulatedRayDirOut[0];
            }
            else
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
            }
        }
Пример #17
0
        public void LightBlockersAtVertex(Handle bvhhandle, int vertIndex, Vector3 worldPos, Vector3 worldNorm, Vector3 worldLightPos, Vector3 worldLightDir,
                                          Vector3 lightColor, Vector4 lightRIAT, ref List <Vector3> outStartPoints, ref List <Vector3> outEndPoints, ref List <Vector3> outColPoints)
        {
            IntPtr[] startPoints = new IntPtr[1];
            IntPtr[] endPoints   = new IntPtr[1];
            int[]    pointCount  = new int[1];
            startPoints[0] = IntPtr.Zero;
            endPoints[0]   = IntPtr.Zero;
            pointCount[0]  = 0;

            IntPtr[] colPoints = new IntPtr[1];
            int[]    colCount  = new int[1];
            colPoints[0] = IntPtr.Zero;
            colCount[0]  = 0;


#if DDR_RUNTIME_DLL_LINKING_
            int err = Invoke <int, _LightBlockersAtVertex>(bvhhandle.Ptr(), vertIndex, worldPos, worldNorm, worldLightPos, worldLightDir
                                                           , lightColor, lightRIAT, startPoints, endPoints, pointCount, colPoints, colCount);
#else
            float[] wPosArr       = ToFloatArray(worldPos);
            float[] wNormArr      = ToFloatArray(worldNorm);
            float[] wLightPosArr  = ToFloatArray(worldLightPos);
            float[] wLightDirArr  = ToFloatArray(worldLightDir);
            float[] lightColorArr = ToFloatArray(lightColor);
            float[] lightRIATArr  = ToFloatArray(lightRIAT);

            int err = _LightBlockersAtVertex(bvhhandle.Ptr(), vertIndex, wPosArr, wNormArr, wLightPosArr, wLightDirArr
                                             , lightColorArr, lightRIATArr, startPoints, endPoints, pointCount, colPoints, colCount);
#endif
            if (err == 0)
            {
                CopyFloatPtrToVectorList(startPoints[0], pointCount[0], ref outStartPoints);
                CopyFloatPtrToVectorList(endPoints[0], pointCount[0], ref outEndPoints);
                CopyFloatPtrToVectorList(colPoints[0], colCount[0], ref outColPoints);
            }
            else
            {
                string error = GetLastError();
                VertexBakerLib.LogError(error);
            }
        }
        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 void Bake()
        {
            try
            {
#if DDR_RUNTIME_DLL_LINKING_
                m_result = VertexBakerLib.Instance.InvokeAsync <int, _Bake>(m_meshIdsPtr, m_vertexCountsPtr, m_triangleCountPtr, m_matDataPtr
                                                                            , m_meshDataPtr, m_triangleDataPtr, m_bakeOptionsPtr, m_layerPtr, m_meshCount, m_vertexEementCount, m_vertexDefinition, m_guids
                                                                            , m_sourcePaths, m_settingsIndicesPtr, m_settingsPtrs, m_lightsDataPtr, m_lightsOptPtr
                                                                            , m_lightCount, m_outBasis0, m_outBasis1, m_outBasis2);
#else
                m_result = _Bake(m_meshIdsPtr, m_vertexCountsPtr, m_triangleCountPtr, m_matDataPtr
                                 , m_meshDataPtr, m_triangleDataPtr, m_bakeOptionsPtr, m_layerPtr, m_meshCount, m_vertexEementCount, m_vertexDefinition, m_guids
                                 , m_sourcePaths, m_settingsIndicesPtr, m_settingsPtrs, m_lightsDataPtr, m_lightsOptPtr
                                 , m_lightCount, m_outBasis0, m_outBasis1, m_outBasis2);
#endif
                m_run = false;
                m_callback();
            }
            catch (Exception e)
            {
                VertexBakerLib.LogError(e.Message);
                VertexBakerLib.LogError(e.StackTrace);
            }
        }
        // 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;
        }
        static void BuildLightContext(MeshFilter[] meshes, List <Light> lights, BakeContext ctx)
        {
            int lightCount = lights.Count;

            // light data size
            const int lightPosSize   = 3; // padded with extra float
            const int LightDirSize   = 3; // padded with extra float
            const int lightColorSize = 3; // padded with extra float (don't need alpha)
            const int lightRIATSize  = 4; // range, intensity, angle, type

            int totalLightSize = lightCount * SIZE_FLOAT * (lightPosSize + LightDirSize + lightColorSize + lightRIATSize);

            VertexBakerLib instance = VertexBakerLib.Instance;

            ctx.m_lightsDataPtr = instance.Alloc(totalLightSize);
            ctx.m_lightsOptPtr  = instance.Alloc(lightCount * SIZE_LONG);
            int lightDestOffset = 0;

            float[] riat = new float[4];
            long[]  data = new long[lightCount];

            // light layout
            for (int l = 0; l < lightCount; ++l)
            {
                Light light = lights[l];
                riat[0] = light.range;
                riat[1] = light.intensity;
                riat[2] = light.spotAngle;
                riat[3] = (float)light.type;

                // position data
                IntPtr lightPosPtr = new IntPtr(ctx.m_lightsDataPtr.ToInt64() + lightDestOffset * SIZE_FLOAT);
                instance.CopyVector4(lightPosPtr, lightPosSize * SIZE_FLOAT, light.transform.position.ToVector4(1f), lightPosSize * SIZE_FLOAT);
                lightDestOffset += lightPosSize;

                // direction data
                IntPtr lightDirPtr = new IntPtr(ctx.m_lightsDataPtr.ToInt64() + lightDestOffset * SIZE_FLOAT);
                instance.CopyVector4(lightDirPtr, LightDirSize * SIZE_FLOAT, light.transform.forward.ToVector4(0f), LightDirSize * SIZE_FLOAT);
                lightDestOffset += LightDirSize;

                // color data
                IntPtr lightColorPtr = new IntPtr(ctx.m_lightsDataPtr.ToInt64() + lightDestOffset * SIZE_FLOAT);
                instance.CopyVector4(lightColorPtr, lightColorSize * SIZE_FLOAT, light.color.ToVector4(1f), lightColorSize * SIZE_FLOAT);
                lightDestOffset += LightDirSize;

                // IRAT data
                IntPtr lightIRATPtr = new IntPtr(ctx.m_lightsDataPtr.ToInt64() + lightDestOffset * SIZE_FLOAT);
                instance.CopyFloatArray(lightIRATPtr, lightRIATSize * SIZE_FLOAT, riat, lightRIATSize * SIZE_FLOAT);
                lightDestOffset += lightRIATSize;

                // set lighting options
                ulong dataValue = 0;
                // 3 bits
                dataValue |= (ulong)lights[l].shadows;
                // 32 bits max
                dataValue |= (ulong)(((long)lights[l].cullingMask) << 3);

                data[l] |= (long)dataValue;
            }

            Marshal.Copy(data, 0, ctx.m_lightsOptPtr, lightCount);
        }
        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);
        }
            public void GetAsVec4(Mesh mesh, List <int> subMeshIndices, ref Vector4[] outData)
            {
                Vector4[]         data   = null;
                VertexElementType elType = (VertexElementType)m_elType;

                switch (elType)
                {
                case VertexElementType.kPosition:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kNormal:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    break;

                case VertexElementType.kTangent:
                    data = mesh.tangents;
                    break;

                case VertexElementType.kColor:
                case VertexElementType.kUV0:
                {
                    List <Vector4> v = new List <Vector4>();
                    mesh.GetUVs(0, v);
                    data = v.ToArray();
                    break;
                }

                case VertexElementType.kUV1:
                {
                    List <Vector4> v = new List <Vector4>();
                    mesh.GetUVs(1, v);
                    data = v.ToArray();
                    break;
                }

                case VertexElementType.kUV2:
                {
                    List <Vector4> v = new List <Vector4>();
                    mesh.GetUVs(2, v);
                    data = v.ToArray();
                    break;
                }

                case VertexElementType.kUV3:
                {
                    List <Vector4> v = new List <Vector4>();
                    mesh.GetUVs(3, v);
                    data = v.ToArray();
                    break;
                }

                default:
                    VertexBakerLib.LogError("Type Not Supported: " + elType);
                    data = null;
                    break;
                }
                if (subMeshIndices != null)
                {
                    outData = new Vector4[subMeshIndices.Count];
                    for (int i = 0, k = subMeshIndices.Count; i < k; ++i)
                    {
                        outData[i] = data[subMeshIndices[i]];
                    }
                }
                else
                {
                    outData = data;
                }
            }
Пример #24
0
 public Handle(IntPtr handle, VertexBakerLib lib)
 {
     m_handle = handle;
     m_lib    = lib;
 }
        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);
            }
        }
Пример #26
0
 public BVHHandle(MeshFilter source, IntPtr handle, VertexBakerLib lib) : base(handle, lib)
 {
     SourceMeshData = source;
 }