private GenerateMeshJob PrepareGenerateMeshJob() { splineMesh.BezierSpline.GetEvenlySpacedPoints(splineMesh.Spacing, splinePath, SplinePathPrecision, false); var bezierSpline = splineMesh.BezierSpline; var leftCurveScales = new float[splinePath.Points.Count]; var rightCurveScales = new float[splinePath.Points.Count]; for (var i = 0; i < leftCurveScales.Length; i++) { var t = splinePath.ParametersT[i]; leftCurveScales[i] = splineMesh.LeftSideCurve.Evaluate(t); rightCurveScales[i] = splineMesh.RightSideCurve.Evaluate(t); } var width = splineMesh.Width; var scales = new NativeArray <Vector3>(splinePath.Scales.ToArray(), Allocator.TempJob); var normals = new NativeArray <Vector3>(splinePath.Normals.ToArray(), Allocator.TempJob); var tangents = new NativeArray <Vector3>(splinePath.Tangents.ToArray(), Allocator.TempJob); var positions = new NativeArray <Vector3>(splinePath.Points.ToArray(), Allocator.TempJob); var leftScale = new NativeArray <float>(leftCurveScales, Allocator.TempJob); var rightScale = new NativeArray <float>(rightCurveScales, Allocator.TempJob); var numTris = (2 * (positions.Length - 1)) + (bezierSpline.IsLoop ? 2 : 1); var indicesResult = new NativeArray <int>(numTris * 3, Allocator.TempJob); var uvsResult = new NativeArray <Vector2>(positions.Length * 2, Allocator.TempJob); var vertsResult = new NativeArray <Vector3>(positions.Length * 2, Allocator.TempJob); var normalsResult = new NativeArray <Vector3>(positions.Length * 2, Allocator.TempJob); GenerateMeshJob generateMeshJob = new GenerateMeshJob() { // Input data Width = width, UsePointsScale = splineMesh.UsePointsScale, UseAsymetricWidthCurve = splineMesh.UseAsymetricWidthCurve, UvMode = (int)splineMesh.UvMode, MirrorUv = splineMesh.MirrorUV, IsLoop = bezierSpline.IsLoop, Scales = scales, Normals = normals, Tangents = tangents, Positions = positions, LeftScales = leftScale, RightScales = rightScale, // Output data IndicesResult = indicesResult, UvsResult = uvsResult, VertsResult = vertsResult, NormalsResult = normalsResult, }; return(generateMeshJob); }
private void OnJobCompleted(ref GenerateMeshJob generateMeshJob, Mesh mesh) { #if UNITY_EDITOR Undo.RecordObject(splineMesh, "Generate Mesh"); #endif mesh.Clear(); mesh.SetVertices(generateMeshJob.VertsResult); mesh.SetNormals(generateMeshJob.NormalsResult); mesh.SetUVs(0, generateMeshJob.UvsResult); mesh.SetTriangles(generateMeshJob.IndicesResult.ToArray(), 0); }
public Job StartJob(Chunk c, TerrainGenerator.Job terrGen) { var j = new Job { chunk = c }; c.SurfaceEdgePositions = new NativeList <int>(Chunk.VOXELS * Chunk.VOXELS, Allocator.Persistent); c.SurfaceEdges = new NativeList <Edge>(Chunk.VOXELS * Chunk.VOXELS, Allocator.Persistent); c.SurfaceCells = new NativeList <int>(Chunk.VOXELS * Chunk.VOXELS, Allocator.Persistent); c.Cells = new NativeArray <Cell>(CELLS_TOTAL, Allocator.Persistent, NativeArrayOptions.ClearMemory); j.MeshData = new MeshData(); var findSurface = new FindSurfaceEdgesJob { Voxels = c.Voxels, }; var calcEdges = new CalcEdgesJob { Voxels = c.Voxels, SurfaceEdgePositions = c.SurfaceEdgePositions, SurfaceEdges = c.SurfaceEdges, SurfaceCells = c.SurfaceCells, Cells = c.Cells, }; var calcVertices = new CalcVerticesJob { DCIterStrength = DCIterStrength, DCMaxIterations = DCMaxIterations, SurfaceEdges = c.SurfaceEdges, SurfaceCells = c.SurfaceCells, Voxels = c.Voxels, Cells = c.Cells, }; var genMesh = new GenerateMeshJob { SurfaceEdgePositions = c.SurfaceEdgePositions, SurfaceEdges = c.SurfaceEdges, Cells = c.Cells, vertices = j.MeshData.vertices, normals = j.MeshData.normals, //uv = j.MeshData.uv , colors = j.MeshData.colors, triangles = j.MeshData.triangles, materials = j.MeshData.materials, }; var findSurfaceH = findSurface.ScheduleAppend(c.SurfaceEdgePositions, EDGES_TOTAL, 64, terrGen?.Handle ?? default); var calcEdgesH = calcEdges.Schedule(findSurfaceH); var calcVertsH = calcVertices.Schedule(c.SurfaceCells, 64, calcEdgesH); j.FinalJob = genMesh.Schedule(calcVertsH); return(j); }
/// <summary> /// Prepares and generates new mesh using Jobs system. /// On mesh generation completion it is stored in the given mesh and onMeshGenerated action is invoked. /// </summary> /// <param name="mesh">Mesh to be generated.</param> /// <param name="onMeshGenerated">Action invoked on mesh generation completion.</param> /// <param name="immediate">Should mesh generation be forced to be executed in the same frame (on the main thread).</param> public void GenerateMesh(Mesh mesh, Action <Mesh> onMeshGenerated, bool immediate) { if (isJobScheduled) { scheduleNextJob = true; return; } isJobScheduled = true; scheduleNextJob = false; StopOngoingJob(); ongoingJob = PrepareGenerateMeshJob(); StartJob(ongoingJob, splineMesh, mesh, onMeshGenerated, immediate); }
private void StartJob(GenerateMeshJob generateMeshJob, SplineMesh splineMesh, Mesh mesh, Action <Mesh> onMeshGenerated, bool immediate) { if (immediate) { generateMeshJob.ScheduleAndComplete(generateMeshJob.Positions.Length, JobBatchSize, (generateMeshJob) => { OnJobCompleted(ref generateMeshJob, mesh); onMeshGenerated?.Invoke(mesh); isJobScheduled = false; }); } else { StartJobCoroutine(generateMeshJob, splineMesh, mesh, onMeshGenerated); } }
private void StartJobCoroutine(GenerateMeshJob generateMeshJob, SplineMesh splineMesh, Mesh mesh, Action <Mesh> onMeshGenerated) { generateMeshCoroutine = generateMeshJob.ScheduleAndCompleteAsync(generateMeshJob.Positions.Length, JobBatchSize, splineMesh, (jobHandle) => { ongoingJobHandle = jobHandle; }, (generateMeshJob) => { OnJobCompleted(ref generateMeshJob, mesh); onMeshGenerated?.Invoke(mesh); isJobScheduled = false; if (scheduleNextJob) { splineMesh.GenerateMesh(); } }); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { var job = new GenerateMeshJob { Vertices = GetBufferFromEntity <Vertex>(false), Normals = GetBufferFromEntity <Normal>(false), Tris = GetBufferFromEntity <Triangle>(false), Uvs = GetBufferFromEntity <Uv>(false), blocks = GetBufferFromEntity <BlockIDBuffer>(true), CommandBuffer = system.CreateCommandBuffer().ToConcurrent(), EntityType = GetArchetypeChunkEntityType(), meshesThisFrame = 0, ChunkEntities = Main.chunkEntities, chunk = GetComponentDataFromEntity <Chunk>(true) }; inputDeps = job.Schedule <GenerateMeshJob>(query, inputDeps); system.AddJobHandleForProducer(inputDeps); return(inputDeps); }