PCache ComputePCacheFromMesh() { var meshCache = ComputeDataCache(m_Mesh); Picker picker = null; if (m_Distribution == Distribution.Sequential) { if (m_MeshBakeMode == MeshBakeMode.Vertex) { picker = new SequentialPickerVertex(meshCache); } else if (m_MeshBakeMode == MeshBakeMode.Triangle) { picker = new SequentialPickerTriangle(meshCache); } } else if (m_Distribution == Distribution.Random) { if (m_MeshBakeMode == MeshBakeMode.Vertex) { picker = new RandomPickerVertex(meshCache, m_SeedMesh); } else if (m_MeshBakeMode == MeshBakeMode.Triangle) { picker = new RandomPickerTriangle(meshCache, m_SeedMesh); } } else if (m_Distribution == Distribution.RandomUniformArea) { picker = new RandomPickerUniformArea(meshCache, m_SeedMesh); } if (picker == null) { throw new InvalidOperationException("Unable to find picker"); } var positions = new List <Vector3>(); var normals = m_ExportNormals ? new List <Vector3>() : null; var colors = m_ExportColors ? new List <Vector4>() : null; var uvs = m_ExportUV ? new List <Vector4>() : null; for (int i = 0; i < m_OutputPointCount; ++i) { if (i % 64 == 0) { var cancel = EditorUtility.DisplayCancelableProgressBar("pCache bake tool", string.Format("Sampling data... {0}/{1}", i, m_OutputPointCount), (float)i / (float)m_OutputPointCount); if (cancel) { return(null); } } var vertex = picker.GetNext(); positions.Add(vertex.position); if (m_ExportNormals) { normals.Add(vertex.normal); } if (m_ExportColors) { colors.Add(vertex.color); } if (m_ExportUV) { uvs.Add(vertex.uvs.Any() ? vertex.uvs[0] : Vector4.zero); } } var file = new PCache(); file.AddVector3Property("position"); if (m_ExportNormals) { file.AddVector3Property("normal"); } if (m_ExportColors) { file.AddColorProperty("color"); } if (m_ExportUV) { file.AddVector4Property("uv"); } EditorUtility.DisplayProgressBar("pCache bake tool", "Generating pCache...", 0.0f); file.SetVector3Data("position", positions); if (m_ExportNormals) { file.SetVector3Data("normal", normals); } if (m_ExportColors) { file.SetColorData("color", colors); } if (m_ExportUV) { file.SetVector4Data("uv", uvs); } EditorUtility.ClearProgressBar(); return(file); }
public static PCache ComputePCacheFromMesh(Mesh mesh, int mapSize = 512, int pointCount = 4096, int seed = 0, Distribution distribution = Distribution.RandomUniformArea, MeshBakeMode meshBakeMode = MeshBakeMode.Triangle) { if (mapSize % 8 != 0) { Debug.LogError("Position map dimensions should be a multiple of 8."); return(null); } if (computeShader == null) { computeShader = computeShader = Resources.Load <ComputeShader>("Shaders/ComputeMeshToMap"); } PCache pCache = new PCache(); // From PointCacheBakeTool MeshData meshCache = ComputeDataCache(mesh); Picker picker = null; if (distribution == Distribution.Sequential) { if (meshBakeMode == MeshBakeMode.Vertex) { picker = new SequentialPickerVertex(meshCache); } else if (meshBakeMode == MeshBakeMode.Triangle) { picker = new SequentialPickerTriangle(meshCache); } } else if (distribution == Distribution.Random) { if (meshBakeMode == MeshBakeMode.Vertex) { picker = new RandomPickerVertex(meshCache, seed); } else if (meshBakeMode == MeshBakeMode.Triangle) { picker = new RandomPickerTriangle(meshCache, seed); } } else if (distribution == Distribution.RandomUniformArea) { picker = new RandomPickerUniformArea(meshCache, seed); } if (picker == null) { throw new InvalidOperationException("Unable to find picker"); } pCache.mesh = mesh; pCache.mapSize = mapSize; pCache.positions = new List <Vector3>(); pCache.normals = new List <Vector3>(); for (int i = 0; i < pointCount; ++i) { var vertex = picker.GetNext(); pCache.positions.Add(vertex.position); pCache.normals.Add(vertex.normal); } // From SMRVFX pCache.positionMap = new RenderTexture(mapSize, mapSize, 0, RenderTextureFormat.ARGBFloat); pCache.positionMap.enableRandomWrite = true; pCache.positionMap.Create(); pCache.normalMap = new RenderTexture(mapSize, mapSize, 0, RenderTextureFormat.ARGBFloat); pCache.normalMap.enableRandomWrite = true; pCache.normalMap.Create(); // Transfer data var vcount = pCache.positions.Count; var vcount_x3 = vcount * 3; pCache.positionBuffer = new ComputeBuffer(vcount_x3, sizeof(float)); pCache.normalBuffer = new ComputeBuffer(vcount_x3, sizeof(float)); computeShader.SetInt("VertexCount", vcount); pCache.positionBuffer.SetData(pCache.positions); pCache.normalBuffer.SetData(pCache.normals); computeShader.SetBuffer(0, "PositionBuffer", pCache.positionBuffer); computeShader.SetBuffer(0, "NormalBuffer", pCache.normalBuffer); computeShader.SetTexture(0, "PositionMap", pCache.positionMap); computeShader.SetTexture(0, "NormalMap", pCache.normalMap); computeShader.Dispatch(0, pCache.mapSize / 8, pCache.mapSize / 8, 1); return(pCache); }