public void Execute(T context, ICancelToken token) { foreach (var stage in mStages) { stage.Execute(context, token); if (token.Cancelled) { break; } } }
private object CompleteLoad(object input, ICancelToken token) { UnityEngine.Profiling.Profiler.BeginSample("CompleteLoad"); GrassPatch node = (GrassPatch)input; if (node == null) { Debug.LogError("CompleteMesh: Cannot complete, node is null"); return(null); } if (_meshPool.Count == 0) { Debug.LogError("CompleteMesh: PatchPool is empty. This shouldn't happen!"); // Cleanup RecycleJobData(node); node.State = NodeState.Unloaded; return(node); } var patch = _meshPool.Dequeue(); node.Mesh = patch; MeshData meshData = node.JobData.MeshData; node.Mesh.Mesh.vertices = meshData.Vertices; patch.Mesh.triangles = meshData.Triangles; patch.Mesh.normals = meshData.Normals; patch.Mesh.uv = meshData.Uvs; patch.Mesh.bounds = meshData.Bounds; patch.Mesh.UploadMeshData(false); // Offset coords because world center is in middle of quadtree extents // Todo: The quadtree could help us do pos conversion var coord = node.Coord; int totalPatches = _terrain.Config.PatchesPerTile * _terrain.Config.NumTiles; coord -= new IntVector2(totalPatches / 2, totalPatches / 2); patch.Transform.position = CoordsToWorldPoint2D(_terrain.Config.PatchSize, coord); patch.gameObject.SetActive(true); RecycleJobData(node); node.State = NodeState.Loaded; UnityEngine.Profiling.Profiler.EndSample(); return(node); }
public override void Execute(int context, ICancelToken token) { LastContext = context; LastToken = token; }
public int PeformFFT_DoublePacked(int startIdx, IList<Vector4[]> data0, ICancelToken token) { int x; int y; int i; int idx = 0; int idx1; int bftIdx; int X; int Y; float wx, wy; int ii, xi, yi, si, sy; int j = startIdx; for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; Vector4[] write0 = data0[idx]; Vector4[] read0 = data0[idx1]; si = i * m_size; for (x = 0; x < m_size; x++) { bftIdx = x + si; X = m_butterflyLookupTable[bftIdx].j1; Y = m_butterflyLookupTable[bftIdx].j2; wx = m_butterflyLookupTable[bftIdx].wr; wy = m_butterflyLookupTable[bftIdx].wi; for (y = 0; y < m_size; y++) { if (token.Cancelled) return -1; sy = y * m_size; ii = x + sy; xi = X + sy; yi = Y + sy; write0[ii].x = read0[xi].x + wx * read0[yi].x - wy * read0[yi].y; write0[ii].y = read0[xi].y + wy * read0[yi].x + wx * read0[yi].y; write0[ii].z = read0[xi].z + wx * read0[yi].z - wy * read0[yi].w; write0[ii].w = read0[xi].w + wy * read0[yi].z + wx * read0[yi].w; } } } for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; Vector4[] write0 = data0[idx]; Vector4[] read0 = data0[idx1]; si = i * m_size; for (y = 0; y < m_size; y++) { bftIdx = y + si; X = m_butterflyLookupTable[bftIdx].j1 * m_size; Y = m_butterflyLookupTable[bftIdx].j2 * m_size; wx = m_butterflyLookupTable[bftIdx].wr; wy = m_butterflyLookupTable[bftIdx].wi; for (x = 0; x < m_size; x++) { if (token.Cancelled) return -1; ii = x + y * m_size; xi = x + X; yi = x + Y; write0[ii].x = read0[xi].x + wx * read0[yi].x - wy * read0[yi].y; write0[ii].y = read0[xi].y + wy * read0[yi].x + wx * read0[yi].y; write0[ii].z = read0[xi].z + wx * read0[yi].z - wy * read0[yi].w; write0[ii].w = read0[xi].w + wy * read0[yi].z + wx * read0[yi].w; } } } return idx; }
public int PeformFFT_DoublePacked(int startIdx, IList <Vector4[]> data0, ICancelToken token) { int num = 0; int num2 = startIdx; int i = 0; while (i < this.m_passes) { num = num2 % 2; int index = (num2 + 1) % 2; Vector4[] array = data0[num]; Vector4[] array2 = data0[index]; int num3 = i * this.m_size; for (int j = 0; j < this.m_size; j++) { int num4 = j + num3; int num5 = this.m_butterflyLookupTable[num4].j1; int num6 = this.m_butterflyLookupTable[num4].j2; float wr = this.m_butterflyLookupTable[num4].wr; float wi = this.m_butterflyLookupTable[num4].wi; for (int k = 0; k < this.m_size; k++) { if (token.Cancelled) { return(-1); } int num7 = k * this.m_size; int num8 = j + num7; int num9 = num5 + num7; int num10 = num6 + num7; array[num8].x = array2[num9].x + wr * array2[num10].x - wi * array2[num10].y; array[num8].y = array2[num9].y + wi * array2[num10].x + wr * array2[num10].y; array[num8].z = array2[num9].z + wr * array2[num10].z - wi * array2[num10].w; array[num8].w = array2[num9].w + wi * array2[num10].z + wr * array2[num10].w; } } i++; num2++; } i = 0; while (i < this.m_passes) { num = num2 % 2; int index = (num2 + 1) % 2; Vector4[] array3 = data0[num]; Vector4[] array4 = data0[index]; int num3 = i * this.m_size; for (int k = 0; k < this.m_size; k++) { int num4 = k + num3; int num5 = this.m_butterflyLookupTable[num4].j1 * this.m_size; int num6 = this.m_butterflyLookupTable[num4].j2 * this.m_size; float wr = this.m_butterflyLookupTable[num4].wr; float wi = this.m_butterflyLookupTable[num4].wi; for (int j = 0; j < this.m_size; j++) { if (token.Cancelled) { return(-1); } int num8 = j + k * this.m_size; int num9 = j + num5; int num10 = j + num6; array3[num8].x = array4[num9].x + wr * array4[num10].x - wi * array4[num10].y; array3[num8].y = array4[num9].y + wi * array4[num10].x + wr * array4[num10].y; array3[num8].z = array4[num9].z + wr * array4[num10].z - wi * array4[num10].w; array3[num8].w = array4[num9].w + wi * array4[num10].z + wr * array4[num10].w; } } i++; num2++; } return(num); }
public abstract void Execute(T context, ICancelToken token);
public static Vector4 MaxRange(IList <InterpolatedArray2f> displacements, Vector4 choppyness, Vector2 gridScale, ICancelToken token) { if (displacements.Count != GRIDS) { throw new InvalidOperationException("Query Displacements requires a displacement buffer for each of the " + GRIDS + " grids."); } if (displacements[0].Channels != CHANNELS) { throw new InvalidOperationException("Query Displacements requires displacement buffers have " + CHANNELS + " channels."); } int size = displacements[0].SX; Vector3 ninf = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); Vector3 pinf = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); Vector3[] max = new Vector3[] { ninf, ninf, ninf, ninf }; Vector3[] min = new Vector3[] { pinf, pinf, pinf, pinf }; float[] h = new float[CHANNELS]; int grids = GRIDS; //There are 4 grids but the last ones waves are to small to really //count towards the range so dont sample. grids = 3; for (int i = 0; i < grids; i++) { float[] data = displacements[i].Data; for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { if (token != null && token.Cancelled) { return(Vector4.zero); } int idx = (x + y * size) * CHANNELS; h[0] = data[idx + 0]; h[1] = data[idx + 1]; h[2] = data[idx + 2]; if (h[0] < min[i].x) { min[i].x = h[0]; } if (h[0] > max[i].x) { max[i].x = h[0]; } if (h[1] < min[i].y) { min[i].y = h[1]; } if (h[1] > max[i].y) { max[i].y = h[1]; } if (h[2] < min[i].z) { min[i].z = h[2]; } if (h[2] > max[i].z) { max[i].z = h[2]; } } } } Vector4 result = Vector4.zero; for (int i = 0; i < grids; i++) { result.x += Mathf.Max(max[i].x, Mathf.Abs(min[i].x)) * choppyness[i]; result.y += Mathf.Max(max[i].y, Mathf.Abs(min[i].y)); result.z += Mathf.Max(max[i].z, Mathf.Abs(min[i].z)) * choppyness[i]; } result.x *= gridScale.x; result.y *= gridScale.y; result.z *= gridScale.x; return(result); }
public static Vector4 MaxRange(IList <InterpolatedArray2f> displacements, Vector4 choppyness, Vector2 gridScale, ICancelToken token) { if (displacements.Count != QueryDisplacements.GRIDS) { throw new InvalidOperationException("Query Displacements requires a displacement buffer for each of the " + QueryDisplacements.GRIDS + " grids."); } if (displacements[0].Channels != QueryDisplacements.CHANNELS) { throw new InvalidOperationException("Query Displacements requires displacement buffers have " + QueryDisplacements.CHANNELS + " channels."); } int sX = displacements[0].SX; Vector3 vector = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); Vector3 vector2 = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); Vector3[] array = new Vector3[] { vector, vector, vector, vector }; Vector3[] array2 = new Vector3[] { vector2, vector2, vector2, vector2 }; float[] array3 = new float[QueryDisplacements.CHANNELS]; int num = QueryDisplacements.GRIDS; num = 3; for (int i = 0; i < num; i++) { float[] data = displacements[i].Data; for (int j = 0; j < sX; j++) { for (int k = 0; k < sX; k++) { if (token != null && token.Cancelled) { return(Vector4.zero); } int num2 = (k + j * sX) * QueryDisplacements.CHANNELS; array3[0] = data[num2]; array3[1] = data[num2 + 1]; array3[2] = data[num2 + 2]; if (array3[0] < array2[i].x) { array2[i].x = array3[0]; } if (array3[0] > array[i].x) { array[i].x = array3[0]; } if (array3[1] < array2[i].y) { array2[i].y = array3[1]; } if (array3[1] > array[i].y) { array[i].y = array3[1]; } if (array3[2] < array2[i].z) { array2[i].z = array3[2]; } if (array3[2] > array[i].z) { array[i].z = array3[2]; } } } } Vector4 zero = Vector4.zero; for (int l = 0; l < num; l++) { zero.x += Mathf.Max(array[l].x, Mathf.Abs(array2[l].x)) * choppyness[l]; zero.y += Mathf.Max(array[l].y, Mathf.Abs(array2[l].y)); zero.z += Mathf.Max(array[l].z, Mathf.Abs(array2[l].z)) * choppyness[l]; } zero.x *= gridScale.x; zero.y *= gridScale.y; zero.z *= gridScale.x; return(zero); }
public override void Execute(T context, ICancelToken token) { DoExecute(context); }
private static object GenerateMesh(object input, ICancelToken token) { GrassPatch node = (GrassPatch)input; if (node == null) { throw new ArgumentException("GenerateMesh Failed: Node is null"); } TerrainData terrainData = node.JobData.TerrainData; MeshData mesh = node.JobData.MeshData; // Todo: Initialize both of these with average patch height or something float minHeight = float.MaxValue; float maxHeight = float.MinValue; float dimensions = Mathf.Sqrt(mesh.MaxInstances); float dimInv = 1f / dimensions; int dimensionsInt = (int)dimensions; int i = 0; for (int x = 0; x < dimensionsInt && !token.IsCanceled; x++) { for (int z = 0; z < dimensionsInt && !token.IsCanceled; z++) { // Todo: move magic numbers to a config struct, expose in inspector Vector2 localIndex = new Vector2(x * dimInv, z * dimInv); localIndex.x += mesh.Random.NextSingle() * dimInv; localIndex.y += mesh.Random.NextSingle() * dimInv; Vector3 localPos = new Vector3(localIndex.x * mesh.Size, 0f, localIndex.y * mesh.Size); float height = terrainData.SampleInterpolatedHeight(localIndex); float snowHighFalloff = Mathf.InverseLerp(node.SnowAltitude + 300f, node.SnowAltitude + 200f, height); float snowLowFalloff = Mathf.InverseLerp(node.SnowAltitude - 50f, node.SnowAltitude - 250f, height); Vector2 splat = terrainData.SampleInterpolatedSplat(localIndex); // Massage splat values to make them more suitable for rendering grass sprites splat.x = Mathf.Pow(splat.x, 0.5f); splat.x = Mathf.Max(0f, splat.x - splat.y * (1f - snowLowFalloff) * 2f); splat.x *= snowHighFalloff; if (splat.x > 0.63f + mesh.Random.NextSingle() * 0.37f) { localPos.y = height; minHeight = Mathf.Min(minHeight, height); maxHeight = Mathf.Max(maxHeight, height); Quaternion rot = Quaternion.Euler(-60f + mesh.Random.NextSingle() * 120f, mesh.Random.NextSingle() * 180f, 0f); Vector3 normal = terrainData.SampleInterpolatedNormal(localIndex); Vector2 scale = new Vector2(0.5f + mesh.Random.NextSingle() * 0.5f, 0.5f + mesh.Random.NextSingle() * 0.5f) * Mathf.Min(1f, splat.x * 3f); CreateQuad(mesh, i++, localPos, rot, normal, scale); } } } // If a patch doesn't feature any grass we need to still create valid bounds if (minHeight == float.MaxValue) { minHeight = 0f; } if (maxHeight == float.MinValue) { maxHeight = 1f; } // Zero out unused verts for (; i < mesh.MaxInstances; i++) { int vertIndex = i * MeshData.VertsPerQuad; mesh.Vertices[vertIndex + 0] = Vector3.zero; mesh.Vertices[vertIndex + 1] = Vector3.zero; mesh.Vertices[vertIndex + 2] = Vector3.zero; mesh.Vertices[vertIndex + 3] = Vector3.zero; } mesh.Bounds = new Bounds( new Vector3(mesh.Size * 0.5f, Mathf.Lerp(minHeight, maxHeight, 0.5f), mesh.Size * 0.5f), new Vector3(mesh.Size, maxHeight - minHeight, mesh.Size)); return(node); }
private static object LoadTerrainData(object input, ICancelToken token) { GrassPatch node = (GrassPatch)input; if (node == null) { throw new ArgumentException("GrassNode is null"); } var terrainData = node.JobData.TerrainData; var reader = terrainData.Reader; if (reader == null) { throw new ArgumentException("cannot be null", "reader"); } if (terrainData == null) { throw new ArgumentException("cannot be null", "terrainData"); } var cfg = terrainData.Config; // Offset coords by half world size, since serialized state is indexed from 0 up, not from -worldRadius int totalPatches = cfg.PatchesPerTile * cfg.NumTiles; // coords += new IntVector2(totalPatches / 2, totalPatches / 2); long linearPatchIndex = node.Coord.X * totalPatches + node.Coord.Y; long startPos = linearPatchIndex * ( cfg.PatchHeightRes * cfg.PatchHeightRes * 2 + cfg.PatchHeightRes * cfg.PatchHeightRes * 3 + cfg.PatchSplatRes * cfg.PatchSplatRes * 2); reader.BaseStream.Seek(startPos, SeekOrigin.Begin); // Read heights for (int x = 0; x < terrainData.Config.PatchHeightRes; x++) { for (int z = 0; z < terrainData.Config.PatchHeightRes; z++) { // Todo: Understand why I have to do swizzled x/z reads here terrainData.Heights[z, x] = reader.ReadUInt16() / 65000f * cfg.TerrainHeight; // terrainData.Heights[z, x] = node.Height; } } // Read normals for (int x = 0; x < terrainData.Config.PatchHeightRes; x++) { for (int z = 0; z < terrainData.Config.PatchHeightRes; z++) { Vector3 n = Vector3.zero; n.x = (reader.ReadByte() / 250f) * 2.0f - 1.0f; n.y = (reader.ReadByte() / 250f) * 2.0f - 1.0f; n.z = (reader.ReadByte() / 250f) * 2.0f - 1.0f; terrainData.Normals[x, z] = n; // terrainData.Normals[x, z] = Vector3.up; } } // Read splats for (int x = 0; x < terrainData.Config.PatchSplatRes; x++) { for (int z = 0; z < terrainData.Config.PatchSplatRes; z++) { terrainData.Splats[x, z] = new Vector2( Mathf.Pow(reader.ReadByte() / 250f, 0.66f), reader.ReadByte() / 250f); // terrainData.Splats[x, z] = new Vector2(1f, 0f); } } return(node); }
public static Vector4 MaxRange(IList<InterpolatedArray2f> displacements, Vector4 choppyness, Vector2 gridScale, ICancelToken token) { if(displacements.Count != GRIDS) throw new InvalidOperationException("Query Displacements requires a displacement buffer for each of the " + GRIDS + " grids."); if(displacements[0].Channels != CHANNELS) throw new InvalidOperationException("Query Displacements requires displacement buffers have " + CHANNELS + " channels."); int size = displacements[0].SX; Vector3 ninf = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); Vector3 pinf = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); Vector3[] max = new Vector3[] { ninf, ninf, ninf, ninf }; Vector3[] min = new Vector3[] { pinf, pinf, pinf, pinf }; float[] h = new float[CHANNELS]; int grids = GRIDS; //There are 4 grids but the last ones waves are to small to really //count towards the range so dont sample. grids = 3; for(int i = 0; i < grids; i++) { float[] data = displacements[i].Data; for(int y = 0; y < size; y++) { for(int x = 0; x < size; x++) { if (token != null && token.Cancelled) return Vector4.zero; int idx = (x+y*size)*CHANNELS; h[0] = data[idx + 0]; h[1] = data[idx + 1]; h[2] = data[idx + 2]; if(h[0] < min[i].x) min[i].x = h[0]; if(h[0] > max[i].x) max[i].x = h[0]; if(h[1] < min[i].y) min[i].y = h[1]; if(h[1] > max[i].y) max[i].y = h[1]; if(h[2] < min[i].z) min[i].z = h[2]; if(h[2] > max[i].z) max[i].z = h[2]; } } } Vector4 result = Vector4.zero; for(int i = 0; i < grids; i++) { result.x += Mathf.Max(max[i].x, Mathf.Abs(min[i].x)) * choppyness[i]; result.y += Mathf.Max(max[i].y, Mathf.Abs(min[i].y)); result.z += Mathf.Max(max[i].z, Mathf.Abs(min[i].z)) * choppyness[i]; } result.x *= gridScale.x; result.y *= gridScale.y; result.z *= gridScale.x; return result; }
public int PeformFFT_DoublePacked(int startIdx, IList <Vector4[]> data0, ICancelToken token) //OYM: 二次封装? { int x; int y; int i; int idx = 0; int idx1; int bftIdx; int X; int Y; float wx, wy; int ii, xi, yi, si, sy; int j = startIdx; for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; Vector4[] write0 = data0[idx]; Vector4[] read0 = data0[idx1]; si = i * m_passSize; for (x = 0; x < m_passSize; x++) { bftIdx = x + si; X = m_butterflyLookupTable[bftIdx].targetX; Y = m_butterflyLookupTable[bftIdx].targetY; wx = m_butterflyLookupTable[bftIdx].wr; wy = m_butterflyLookupTable[bftIdx].wi; for (y = 0; y < m_passSize; y++) { if (token.Cancelled) { return(-1); } sy = y * m_passSize; ii = x + sy; xi = X + sy; yi = Y + sy; write0[ii].x = read0[xi].x + wx * read0[yi].x - wy * read0[yi].y; write0[ii].y = read0[xi].y + wy * read0[yi].x + wx * read0[yi].y; write0[ii].z = read0[xi].z + wx * read0[yi].z - wy * read0[yi].w; write0[ii].w = read0[xi].w + wy * read0[yi].z + wx * read0[yi].w; } } } for (i = 0; i < m_passes; i++, j++) { idx = j % 2; idx1 = (j + 1) % 2; Vector4[] write0 = data0[idx]; Vector4[] read0 = data0[idx1]; si = i * m_passSize; for (y = 0; y < m_passSize; y++) { bftIdx = y + si; X = m_butterflyLookupTable[bftIdx].targetX * m_passSize; Y = m_butterflyLookupTable[bftIdx].targetY * m_passSize; wx = m_butterflyLookupTable[bftIdx].wr; wy = m_butterflyLookupTable[bftIdx].wi; for (x = 0; x < m_passSize; x++) { if (token.Cancelled) { return(-1); } ii = x + y * m_passSize; xi = x + X; yi = x + Y; write0[ii].x = read0[xi].x + wx * read0[yi].x - wy * read0[yi].y; write0[ii].y = read0[xi].y + wy * read0[yi].x + wx * read0[yi].y; write0[ii].z = read0[xi].z + wx * read0[yi].z - wy * read0[yi].w; write0[ii].w = read0[xi].w + wy * read0[yi].z + wx * read0[yi].w; } } } return(idx); }
/// <summary> /// Initializes a new instance of the <see cref="CheckMutationQueueJob" /> class. /// </summary> /// <param name="bus">A reference to the bus.</param> /// <param name="dbMutationQueueAccess">The db access class.</param> /// <param name="cancelToken">A token for canceling a (long) running check process.</param> public CheckMutationQueueJob(IBus bus, IDbMutationQueueAccess dbMutationQueueAccess, ICancelToken cancelToken) { this.bus = bus; this.dbMutationQueueAccess = dbMutationQueueAccess; this.cancelToken = cancelToken; }
public static Vector4 MaxRange(IList<InterpolatedArray2f> displacements, Vector4 choppyness, Vector2 gridScale, ICancelToken token) { if (displacements.Count != QueryDisplacements.GRIDS) { throw new InvalidOperationException("Query Displacements requires a displacement buffer for each of the " + QueryDisplacements.GRIDS + " grids."); } if (displacements[0].Channels != QueryDisplacements.CHANNELS) { throw new InvalidOperationException("Query Displacements requires displacement buffers have " + QueryDisplacements.CHANNELS + " channels."); } int sX = displacements[0].SX; Vector3 vector = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); Vector3 vector2 = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); Vector3[] array = new Vector3[] { vector, vector, vector, vector }; Vector3[] array2 = new Vector3[] { vector2, vector2, vector2, vector2 }; float[] array3 = new float[QueryDisplacements.CHANNELS]; int num = QueryDisplacements.GRIDS; num = 3; for (int i = 0; i < num; i++) { float[] data = displacements[i].Data; for (int j = 0; j < sX; j++) { for (int k = 0; k < sX; k++) { if (token != null && token.Cancelled) { return Vector4.zero; } int num2 = (k + j * sX) * QueryDisplacements.CHANNELS; array3[0] = data[num2]; array3[1] = data[num2 + 1]; array3[2] = data[num2 + 2]; if (array3[0] < array2[i].x) { array2[i].x = array3[0]; } if (array3[0] > array[i].x) { array[i].x = array3[0]; } if (array3[1] < array2[i].y) { array2[i].y = array3[1]; } if (array3[1] > array[i].y) { array[i].y = array3[1]; } if (array3[2] < array2[i].z) { array2[i].z = array3[2]; } if (array3[2] > array[i].z) { array[i].z = array3[2]; } } } } Vector4 zero = Vector4.zero; for (int l = 0; l < num; l++) { zero.x += Mathf.Max(array[l].x, Mathf.Abs(array2[l].x)) * choppyness[l]; zero.y += Mathf.Max(array[l].y, Mathf.Abs(array2[l].y)); zero.z += Mathf.Max(array[l].z, Mathf.Abs(array2[l].z)) * choppyness[l]; } zero.x *= gridScale.x; zero.y *= gridScale.y; zero.z *= gridScale.x; return zero; }