public void Damage(Vector3 position, float depth)
    {
        var local = position - transform.position;
        var nlocal = new Vector3(Mathf.InverseLerp(0f, data.size.x, local.x), 0f, Mathf.InverseLerp(0f, data.size.z, local.z));

        var job = new TerrainDeformerJob ();

        job.hx = Mathf.FloorToInt(nlocal.x * data.heightmapWidth);
        job.hy = Mathf.FloorToInt(nlocal.z * data.heightmapHeight);
        job.hw = Mathf.FloorToInt(craterSize / (data.size.x / data.heightmapWidth));
        job.hh = Mathf.FloorToInt(craterSize / (data.size.z / data.heightmapHeight));
        job.hx -= (job.hw / 2);
        job.hy -= (job.hh / 2);

        job.ax = Mathf.FloorToInt(nlocal.x * data.alphamapWidth);
        job.ay = Mathf.FloorToInt(nlocal.z * data.alphamapHeight);
        job.aw = Mathf.FloorToInt(craterSize / (data.size.x / data.alphamapWidth));
        job.ah = Mathf.FloorToInt(craterSize / (data.size.z / data.alphamapHeight));
        job.ax -= (job.aw / 2);
        job.ay -= (job.ah / 2);

        job.useLayer = Random.Range (0, 3);

        job.heights = data.GetHeights (job.hx, job.hy, job.hw, job.hh);
        job.splat = data.GetAlphamaps (job.ax, job.ay, job.aw, job.ah);
        job.depthScale = depth / data.size.y;
        job.alphamapLayers = data.alphamapLayers;
        lock (inbox) {
            inbox.Add (job);
        }
    }
    void ProcessJob(TerrainDeformerJob job)
    {
        for (var x = 0; x < job.hw; x++) {
            for (var y = 0; y < job.hh; y++) {
                var cx = Mathf.RoundToInt(Mathf.InverseLerp(0, job.hw, x) * craterWidth);
                var cy = Mathf.RoundToInt(Mathf.InverseLerp(0, job.hh, y) * craterHeight);
                var d = template[cy * craterWidth + cx][job.useLayer];
                job.heights[x, y] -= (d * job.depthScale);

            }
        }

        for (var x = 0; x < job.aw; x++) {
            for (var y = 0; y < job.ah; y++) {
                var cx = Mathf.RoundToInt(Mathf.InverseLerp(0, job.aw, x) * craterWidth);
                var cy = Mathf.RoundToInt(Mathf.InverseLerp(0, job.ah, y) * craterHeight);
                var d = template[cy * craterWidth + cx][job.useLayer];
                for (var z = 0; z < job.alphamapLayers; z++) {
                    job.splat[x, y, z] += z == 0 ? d : -d;
                }
            }
        }
    }
 void ApplyJob(TerrainDeformerJob job)
 {
     data.SetAlphamaps (job.ax, job.ay, job.splat);
     data.SetHeights (job.hx, job.hy, job.heights);
 }