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);
    }
Beispiel #3
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();
            }
        });
    }
Beispiel #7
0
    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);
    }