public void Init() { rng = new Random(1); f = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * iterations, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { f[i] = new float2(0.0f); } }
/// <summary> /// Insert /// </summary> public Insertion(Entity obstacle, float4x4 ltw, float2 *vertices, int amount) { Type = InsertionType.Insert; Obstacle = obstacle; Ltw = ltw; Vertices = vertices; Amount = amount; Amounts = default; }
/// <summary> /// Bulk Insert /// </summary> public TreeOperation(float4x4 ltw, float2 *verts, int *amounts, int length) { Type = TreeOperationType.BulkInsert; Obstacle = default; Ltw = ltw; Vertices = verts; Amount = length; Amounts = amounts; }
/// <summary> /// Destroy /// </summary> public TreeOperation(Entity obstacle) { Type = TreeOperationType.Destroy; Obstacle = obstacle; Ltw = default; Vertices = default; Amount = default; Amounts = default; }
public void InsertObstacle(Entity key, float4x4 ltw, float2 *vertices, int amount) { Assert.IsTrue(amount > 1); Assert.IsTrue(key != Entity.Null); Assert.IsTrue(!Map.ContainsKey(key)); Assert.IsTrue(amount > 2 && math.all(vertices[0] == vertices[amount - 1]), "Obstacle needs to be counter cockwise wound and closed"); Obstacle *first = default; Obstacle *previous = default; var prevPos = Math.Mul2D(ltw, vertices[0]); var prevPos2 = Math.Mul2D(ltw, vertices[amount - 2]); for (var i = 0; i < amount - 1; ++i) { var obstacle = ObstaclePool.GetElementPointer(); obstacle->Point = prevPos; var pos = Math.Mul2D(ltw, vertices[i + 1]); var aabb = AABB.FromOpposingCorners(prevPos, pos); obstacle->Id = Tree.Insert(aabb, (IntPtr)obstacle); obstacle->Direction = math.normalize(pos - prevPos); if (amount == 2) { obstacle->Convex = true; } else { obstacle->Convex = LeftOf(prevPos2, prevPos, pos) >= 0; } prevPos2 = prevPos; prevPos = pos; if (i == 0) { first = obstacle; previous = obstacle; } else if (i < amount - 2) { obstacle->Previous = previous; previous->Next = obstacle; previous = obstacle; } else { obstacle->Previous = previous; previous->Next = obstacle; first->Previous = obstacle; obstacle->Next = first; } } Map.Add(key, (IntPtr)first);
public void Execute(int i) { Particle p = ps[i]; p.v = 0; uint2 cell_idx = (uint2)p.pos; float2 cell_diff = (p.pos - cell_idx) - 0.5f; float2 *w = stackalloc float2[3]; w[0] = 0.5f * math.pow(0.5f - cell_diff, 2); w[1] = 0.75f - math.pow(cell_diff, 2); w[2] = 0.5f * math.pow(0.5f + cell_diff, 2); float2x2 B = 0; for (uint x = 0; x < 3; ++x) { for (uint y = 0; y < 3; ++y) { float weight = w[x].x * w[y].y; uint2 current_cell_idx = math.uint2(cell_idx.x + x - 1, cell_idx.y + y - 1); float2 cell_dist = (current_cell_idx - p.pos) + 0.5f; int index_1d = (int)current_cell_idx.x * grid_res + (int)current_cell_idx.y; float2 weighted_velocity = grid[index_1d].v * weight; float2x2 term = math.float2x2(weighted_velocity * cell_dist.x, weighted_velocity * cell_dist.y); B += term; p.v += weighted_velocity; } } p.C = B * 4; p.pos += p.v * dt; p.pos = math.clamp(p.pos, 1, grid_res - 2); float2 x_n = p.pos + p.v; float wall_min = 3 - 1; float wall_max = (float)grid_res - 4 + 1; p.v.x += (x_n.x < wall_min) ? wall_min - x_n.x : 0; p.v.x += (x_n.x > wall_max) ? wall_max - x_n.x : 0; p.v.y += (x_n.y < wall_min) ? wall_min - x_n.y : 0; p.v.y += (x_n.y > wall_max) ? wall_max - x_n.y : 0; // if (x_n.x < wall_min) p.v.x += wall_min - x_n.x; // if (x_n.x > wall_max) p.v.x += wall_max - x_n.x; // if (x_n.y < wall_min) p.v.y += wall_min - x_n.y; // if (x_n.y > wall_max) p.v.y += wall_max - x_n.y; ps[i] = p; }
public void Execute(int i) { Particle p = particles[i]; // reset particle velocity p.v = 0; uint2 cell_index = (uint2)p.pos; float2 cell_diff = (p.pos - cell_index) - 0.5f; float2 *w = stackalloc float2[3]; w[0] = 0.5f * math.pow(0.5f - cell_diff, 2); w[1] = 0.75f - math.pow(cell_diff, 2); w[2] = 0.5f * math.pow(0.5f + cell_diff, 2); // C = B * (D^-1), D=1/4 * (delta_x)^2 * I when using quadratic interpolation float2x2 B = 0; for (uint x = 0; x < 3; ++x) { for (uint y = 0; y < 3; ++y) { float weight = w[x].x * w[y].y; uint2 current_index = math.uint2(cell_index.x + x - 1, cell_index.y + y - 1); int index = (int)current_index.x * grid_res + (int)current_index.y; float2 dist = (current_index - p.pos) + 0.5f; float2 weighted_velocity = grids[index].v * weight; // APIC paper equation 10, constructing inner term for B float2x2 term = math.float2x2(weighted_velocity * dist.x, weighted_velocity * dist.y); B += term; p.v += weighted_velocity; } } p.C = B * 4; p.pos += p.v * dt; p.pos = math.clamp(p.pos, 1, grid_res - 2); //deformation gradient update eqation-181 float2x2 F_new = math.float2x2( 1, 0, 0, 1 ); F_new += dt * p.C; Fs[i] = math.mul(F_new, Fs[i]); particles[i] = p; }
public void Execute(int i) { Particle p = particles[i]; float2x2 F = Fs[i]; float2x2 stress = 0; float J = math.determinant(F); float volume = p.volume0 * J; float2x2 F_T = math.transpose(F); float2x2 inv_F_T = math.inverse(F_T); float2x2 F_minus_inv_F_T = F - inv_F_T; float2x2 P = elastic_mu * F_minus_inv_F_T + elastic_lambda * math.log(J) * inv_F_T; stress = (1.0f / J) * math.mul(P, F_T); float2x2 eq_16_term_0 = -volume * 4 * stress * dt; uint2 cell_index = (uint2)p.pos; float2 cell_diff = (p.pos - cell_index) - 0.5f; float2 *w = stackalloc float2[3]; w[0] = 0.5f * math.pow(0.5f - cell_diff, 2); w[1] = 0.75f - math.pow(cell_diff, 2); w[2] = 0.5f * math.pow(0.5f + cell_diff, 2); for (uint x = 0; x < 3; ++x) { for (uint y = 0; y < 3; ++y) { float weight = w[x].x * w[y].y; uint2 current_index = math.uint2(cell_index.x + x - 1, cell_index.y + y - 1); float2 dist = (current_index - p.pos) + 0.5f; float2 Q = math.mul(p.C, dist); int index_1d = (int)current_index.x * grid_res + (int)current_index.y; Cell c = grids[index_1d]; float mass_contribute = weight * p.mass; c.mass += mass_contribute; c.v += mass_contribute * (p.v + Q); float2 momentum = math.mul(eq_16_term_0 * weight, dist); c.v += momentum; // current cell.v is w_ij * (dt * M^-1 * p.volume * p.stress + p.mass * p.C) grids[index_1d] = c; } } }
public void Init() { rng = (Random *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <Random>() * 10000, UnsafeUtility.AlignOf <Random>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { rng[i] = new Unity.Mathematics.Random(1); } f = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 10000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { f[i] = new float2(0.0f); } }
public void Init() { m1 = (float2x2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2x2>() * 10000, UnsafeUtility.AlignOf <float2x2>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { m1[i] = float2x2.identity; } m2 = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 10000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { m2[i] = new float2(1.0f, 0.0f); } }
public void Init() { sin = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 10000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { sin[i] = new float2(0.0f); } cos = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 10000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { cos[i] = new float2(1.0f); } }
public void Init() { v = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 100000; ++i) { v[i] = new float2(1.0f); } hash = (uint *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <uint>() * 100000, UnsafeUtility.AlignOf <uint>(), Allocator.Persistent); for (int i = 0; i < 100000; ++i) { hash[i] = 0; } }
private static unsafe void TessellateBurst(Allocator allocator, float2 *points, int pointCount, int2 *edges, int edgeCount, float2 *outVertices, int *outIndices, int2 *outEdges, int arrayCount, int3 *result) { NativeArray <int2> _edges = new NativeArray <int2>(edgeCount, allocator); for (int i = 0; i < _edges.Length; ++i) { _edges[i] = edges[i]; } NativeArray <float2> _points = new NativeArray <float2>(pointCount, allocator); for (int i = 0; i < _points.Length; ++i) { _points[i] = points[i]; } NativeArray <int> _outIndices = new NativeArray <int>(arrayCount, allocator); NativeArray <int2> _outEdges = new NativeArray <int2>(arrayCount, allocator); NativeArray <float2> _outVertices = new NativeArray <float2>(arrayCount, allocator); int outEdgeCount = 0; int outIndexCount = 0; int outVertexCount = 0; ModuleHandle.Tessellate(allocator, _points, _edges, ref _outVertices, ref outVertexCount, ref _outIndices, ref outIndexCount, ref _outEdges, ref outEdgeCount); for (int i = 0; i < outEdgeCount; ++i) { outEdges[i] = _outEdges[i]; } for (int i = 0; i < outIndexCount; ++i) { outIndices[i] = _outIndices[i]; } for (int i = 0; i < outVertexCount; ++i) { outVertices[i] = _outVertices[i]; } result->x = outVertexCount; result->y = outIndexCount; result->z = outEdgeCount; _outVertices.Dispose(); _outEdges.Dispose(); _outIndices.Dispose(); _points.Dispose(); _edges.Dispose(); }
public void Init() { rng = new Random(1); v = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * iterations, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { v[i] = new float2(1.0f); } hash = (uint *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <uint>() * iterations, UnsafeUtility.AlignOf <uint>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { hash[i] = 0; } }
public void Init() { rng = new Random(1); m1 = (float2x2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2x2>() * iterations, UnsafeUtility.AlignOf <float2x2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { m1[i] = float2x2.identity; } m2 = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * iterations, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { m2[i] = new float2(1.0f, 0.0f); } }
private static unsafe void SubdivideBurst(Allocator allocator, float2 *points, int pointCount, int2 *edges, int edgeCount, float2 *outVertices, int *outIndices, int2 *outEdges, int arrayCount, float areaFactor, float areaThreshold, int refineIterations, int smoothenIterations, int3 *result) { NativeArray <int2> _edges = new NativeArray <int2>(edgeCount, allocator); for (int i = 0; i < _edges.Length; ++i) { _edges[i] = edges[i]; } NativeArray <float2> _points = new NativeArray <float2>(pointCount, allocator); for (int i = 0; i < _points.Length; ++i) { _points[i] = points[i]; } NativeArray <int> _outIndices = new NativeArray <int>(arrayCount, allocator); NativeArray <int2> _outEdges = new NativeArray <int2>(arrayCount, allocator); NativeArray <float2> _outVertices = new NativeArray <float2>(arrayCount, allocator); int outEdgeCount = 0; int outIndexCount = 0; int outVertexCount = 0; ModuleHandle.Subdivide(allocator, _points, _edges, ref _outVertices, ref outVertexCount, ref _outIndices, ref outIndexCount, ref _outEdges, ref outEdgeCount, areaFactor, areaThreshold, refineIterations, smoothenIterations); for (int i = 0; i < outEdgeCount; ++i) { outEdges[i] = _outEdges[i]; } for (int i = 0; i < outIndexCount; ++i) { outIndices[i] = _outIndices[i]; } for (int i = 0; i < outVertexCount; ++i) { outVertices[i] = _outVertices[i]; } result->x = outVertexCount; result->y = outIndexCount; result->z = outEdgeCount; _outVertices.Dispose(); _outEdges.Dispose(); _outIndices.Dispose(); _points.Dispose(); _edges.Dispose(); }
public MTerrainBoundingTree(int treeLevel) { isCreate = false; this.treeLevel = treeLevel; offset = MUnsafeUtility.Malloc <long>(sizeof(long) * treeLevel, Unity.Collections.Allocator.Persistent); offset[0] = 0; int j = 1; for (int i = 1; i < treeLevel; ++i, j *= 2) { int ofst = (int)(0.1 + pow(2, i)); offset[i] = offset[i - 1] + j * j; } byteSize = (offset[treeLevel - 1] + j * j) * sizeof(float2); boundingValue = MUnsafeUtility.Malloc <float2>(byteSize, Unity.Collections.Allocator.Persistent); }
public void Init() { v1 = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 100000; ++i) { v1[i] = new float2(1.0f); } v2 = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 100000; ++i) { v2[i] = new float2(2.0f); } result = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent); for (int i = 0; i < 100000; ++i) { result[i] = new float2(1.0f); } }
public static bool IntersectTriangle(float3 orig, float3 dir, float3 v0, float3 v1, float3 v2 , float *t, float2 *uv) { float3 e1 = v1 - v0; float3 e2 = v2 - v0; float3 p = cross(dir, e2); float det = dot(e1, p); float3 T; if (det > 0) { T = orig - v0; } else { T = v0 - orig; det = -det; } if (det < 0.0001) { return(false); } uv->x = dot(T, p); if (uv->x < 0.0f || uv->x > det) { return(false); } float3 Q = cross(T, e1); uv->y = dot(dir, Q); if (uv->y < 0.0f || (uv->x + uv->y) > det) { return(false); } *t = dot(e2, Q); float fInvDet = 1 / det; *t *= fInvDet; *uv *= fInvDet; return(true); }
public static Mesh GeneratePlaneMeshFromCoord(NativeList <float4> coords, float4x4 localToModelMatrix, float2 startUV, float2 endUV) { List <Vector3> allVertices = new List <Vector3>(coords.Length * 4); List <Vector2> uvs = new List <Vector2>(allVertices.Capacity); List <Vector3> normals = new List <Vector3>(allVertices.Capacity); List <Vector4> tans = new List <Vector4>(allVertices.Capacity); List <int> triangles = new List <int>(allVertices.Capacity * 3 / 2 + 1); void AddPoint(float2 leftUpCorner, float2 rightDownCorner) { int * triangleCount = stackalloc int[] { 0, 1, 2, 1, 3, 2 }; float2 *verts = stackalloc float2[] { leftUpCorner, float2(rightDownCorner.x, leftUpCorner.y), float2(leftUpCorner.x, rightDownCorner.y), rightDownCorner }; int len = allVertices.Count; for (int i = 0; i < 6; ++i) { triangles.Add(triangleCount[i] + len); } for (int i = 0; i < 4; ++i) { allVertices.Add(mul(localToModelMatrix, float4(verts[i], 0, 1)).xyz); uvs.Add(lerp(startUV, endUV, verts[i])); normals.Add(mul(localToModelMatrix, float4(0, 0, 1, 0)).xyz); tans.Add(float4(mul(localToModelMatrix, float4(1, 0, 0, 0)).xyz, 1)); } } Mesh m = new Mesh(); foreach (var i in coords) { AddPoint(i.xy, i.zw); } m.SetVertices(allVertices); m.SetUVs(0, uvs); m.SetTangents(tans); m.SetNormals(normals); m.SetTriangles(triangles, 0); return(m); }
public void Init() { rng = new Random(1); v1 = (float2*)UnsafeUtility.Malloc(UnsafeUtility.SizeOf<float2>() * iterations, UnsafeUtility.AlignOf<float2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { v1[i] = new float2(1.0f); } v2 = (float2*)UnsafeUtility.Malloc(UnsafeUtility.SizeOf<float2>() * iterations, UnsafeUtility.AlignOf<float2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { v2[i] = new float2(2.0f); } result = (float2*)UnsafeUtility.Malloc(UnsafeUtility.SizeOf<float2>() * iterations, UnsafeUtility.AlignOf<float2>(), Allocator.Persistent); for (int i = 0; i < iterations; ++i) { result[i] = new float2(1.0f); } }
public unsafe void Draw() { if (VertexCount < 3) { return; } BeginLineStrip(Color); fixed(byte *array = Vertices) { float2 *vertexArray = (float2 *)array; for (var i = 0; i < VertexCount; ++i) { var vertex = PhysicsMath.mul(Transform, vertexArray[i]); DrawLineVertex(vertex); } DrawLineVertex(PhysicsMath.mul(Transform, vertexArray[0])); } EndDraw(); }
unsafe JobHandle?GetUvsJob( void *input, int count, GLTFComponentType inputType, int inputByteStride, float2 *output, int outputByteStride, bool normalized = false ) { Profiler.BeginSample("PrepareUVs"); JobHandle?jobHandle = null; switch (inputType) { case GLTFComponentType.Float: { var jobUv = new Jobs.ConvertUVsFloatToFloatInterleavedJob { inputByteStride = (inputByteStride > 0) ? inputByteStride : 8, input = (byte *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = jobUv.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount); #endif } break; case GLTFComponentType.UnsignedByte: if (normalized) { var jobUv = new Jobs.ConvertUVsUInt8ToFloatInterleavedNormalizedJob { inputByteStride = (inputByteStride > 0) ? inputByteStride : 2, input = (byte *)input, outputByteStride = outputByteStride, result = output }; jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount); } else { var jobUv = new Jobs.ConvertUVsUInt8ToFloatInterleavedJob { inputByteStride = (inputByteStride > 0) ? inputByteStride : 2, input = (byte *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = jobUv.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount); #endif } break; case GLTFComponentType.UnsignedShort: if (normalized) { var jobUv = new Jobs.ConvertUVsUInt16ToFloatInterleavedNormalizedJob { inputByteStride = (inputByteStride > 0) ? inputByteStride : 4, input = (byte *)input, outputByteStride = outputByteStride, result = output }; jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount); } else { var jobUv = new Jobs.ConvertUVsUInt16ToFloatInterleavedJob { inputByteStride = (inputByteStride > 0) ? inputByteStride : 4, input = (byte *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = jobUv.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount); #endif } break; case GLTFComponentType.Short: if (normalized) { var job = new Jobs.ConvertUVsInt16ToFloatInterleavedNormalizedJob { inputByteStride = inputByteStride > 0 ? inputByteStride : 4, input = (System.Int16 *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = job.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = job.Schedule(count, GltfImport.DefaultBatchCount); #endif } else { var job = new Jobs.ConvertUVsInt16ToFloatInterleavedJob { inputByteStride = inputByteStride > 0 ? inputByteStride : 4, input = (System.Int16 *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = job.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = job.Schedule(count, GltfImport.DefaultBatchCount); #endif } break; case GLTFComponentType.Byte: var byteStride = inputByteStride > 0 ? inputByteStride : 2; if (normalized) { var jobInt8 = new Jobs.ConvertUVsInt8ToFloatInterleavedNormalizedJob { inputByteStride = inputByteStride > 0 ? inputByteStride : 2, input = (sbyte *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = jobInt8.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = jobInt8.Schedule(count, GltfImport.DefaultBatchCount); #endif } else { var jobInt8 = new Jobs.ConvertUVsInt8ToFloatInterleavedJob { inputByteStride = inputByteStride > 0 ? inputByteStride : 2, input = (sbyte *)input, outputByteStride = outputByteStride, result = output }; #if UNITY_JOBS jobHandle = jobInt8.ScheduleBatch(count, GltfImport.DefaultBatchCount); #else jobHandle = jobInt8.Schedule(count, GltfImport.DefaultBatchCount); #endif } break; default: logger?.Error(LogCode.TypeUnsupported, "UV", inputType.ToString()); break; } Profiler.EndSample(); return(jobHandle); }
// This differs from CullIntermediateLights in 3 ways: // - tile-frustums/light intersection use different algorithm // - depth range of the light shape intersecting the tile-frustums is output in the tile list header section // - light indices written out are indexing visible_lights, rather than the array of PrePunctualLights. unsafe public void CullFinalLights(ref NativeArray <PrePunctualLight> punctualLights, ref NativeArray <ushort> lightIndices, int lightStartIndex, int lightCount, int istart, int iend, int jstart, int jend) { // Interestingly, 2-3% faster when using unsafe arrays. PrePunctualLight *_punctualLights = (PrePunctualLight *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(punctualLights); ushort * _lightIndices = (ushort *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(lightIndices); uint * _tileHeaders = (uint *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_TileHeaders); if (lightCount == 0) { for (int j = jstart; j < jend; ++j) { for (int i = istart; i < iend; ++i) { int headerOffset = GetTileHeaderOffset(i, j); _tileHeaders[headerOffset + 0] = 0; _tileHeaders[headerOffset + 1] = 0; _tileHeaders[headerOffset + 2] = 0; _tileHeaders[headerOffset + 3] = 0; } } return; } // Store culled lights in temporary buffer. Additionally store depth range of each light for a given tile too. // the depth range is a 32bit mask, but packed into a 16bits value since the range of the light is continuous // (only need to store first bit enabled, and count of enabled bits). ushort *tiles = stackalloc ushort[lightCount * 2]; float2 *depthRanges = stackalloc float2[lightCount]; int maxLightPerTile = 0; // for stats int lightEndIndex = lightStartIndex + lightCount; float2 tileSize = new float2((m_FrustumPlanes.right - m_FrustumPlanes.left) / m_TileXCount, (m_FrustumPlanes.top - m_FrustumPlanes.bottom) / m_TileYCount); float2 tileExtents = tileSize * 0.5f; float2 tileExtentsInv = new float2(1.0f / tileExtents.x, 1.0f / tileExtents.y); for (int j = jstart; j < jend; ++j) { float tileYCentre = m_FrustumPlanes.top - (tileExtents.y + j * tileSize.y); for (int i = istart; i < iend; ++i) { float tileXCentre = m_FrustumPlanes.left + tileExtents.x + i * tileSize.x; PreTile preTile = m_PreTiles[i + j * m_TileXCount]; int culledLightCount = 0; // For the current tile's light list, min&max depth range (absolute values). float listMinDepth = float.MaxValue; float listMaxDepth = -float.MaxValue; // Duplicate the inner loop twice. Testing for the ortographic case inside the inner loop would cost an extra 8% otherwise. // Missing C++ template argument here! if (!m_IsOrthographic) { for (int vi = lightStartIndex; vi < lightEndIndex; ++vi) { ushort lightIndex = _lightIndices[vi]; PrePunctualLight ppl = _punctualLights[lightIndex]; // Offset tileCentre toward the light to calculate a more conservative minMax depth bound, // but it must remains inside the tile and must not pass further than the light centre. float2 tileCentre = new float2(tileXCentre, tileYCentre); float2 dir = ppl.screenPos - tileCentre; float2 d = abs(dir * tileExtentsInv); float sInv = 1.0f / max3(d.x, d.y, 1.0f); float3 tileOffCentre = new float3(tileCentre.x + dir.x * sInv, tileCentre.y + dir.y * sInv, -m_FrustumPlanes.zNear); float3 tileOrigin = new float3(0.0f); float t0, t1; // This is more expensive than Clip() but allow to compute min&max depth range for the part of the light inside the tile. if (!IntersectionLineSphere(ppl.posVS, ppl.radius, tileOrigin, tileOffCentre, out t0, out t1)) { continue; } listMinDepth = listMinDepth < t0 ? listMinDepth : t0; listMaxDepth = listMaxDepth > t1 ? listMaxDepth : t1; depthRanges[culledLightCount] = new float2(t0, t1); // Because this always output to the finest tiles, contrary to CullLights(), // the result are indices into visibleLights, instead of indices into punctualLights. tiles[culledLightCount] = ppl.visLightIndex; ++culledLightCount; } } else { for (int vi = lightStartIndex; vi < lightEndIndex; ++vi) { ushort lightIndex = _lightIndices[vi]; PrePunctualLight ppl = _punctualLights[lightIndex]; // Offset tileCentre toward the light to calculate a more conservative minMax depth bound, // but it must remains inside the tile and must not pass further than the light centre. float2 tileCentre = new float2(tileXCentre, tileYCentre); float2 dir = ppl.screenPos - tileCentre; float2 d = abs(dir * tileExtentsInv); float sInv = 1.0f / max3(d.x, d.y, 1.0f); float3 tileOffCentre = new float3(0, 0, -m_FrustumPlanes.zNear); float3 tileOrigin = new float3(tileCentre.x + dir.x * sInv, tileCentre.y + dir.y * sInv, 0.0f); float t0, t1; // This is more expensive than Clip() but allow to compute min&max depth range for the part of the light inside the tile. if (!IntersectionLineSphere(ppl.posVS, ppl.radius, tileOrigin, tileOffCentre, out t0, out t1)) { continue; } listMinDepth = listMinDepth < t0 ? listMinDepth : t0; listMaxDepth = listMaxDepth > t1 ? listMaxDepth : t1; depthRanges[culledLightCount] = new float2(t0, t1); // Because this always output to the finest tiles, contrary to CullLights(), // the result are indices into visibleLights, instead of indices into punctualLights. tiles[culledLightCount] = ppl.visLightIndex; ++culledLightCount; } } // Post-multiply by zNear to get actual world unit absolute depth values, then clamp to valid depth range. listMinDepth = max2(listMinDepth * m_FrustumPlanes.zNear, m_FrustumPlanes.zNear); listMaxDepth = min2(listMaxDepth * m_FrustumPlanes.zNear, m_FrustumPlanes.zFar); // Calculate bitmask for 2.5D culling. uint bitMask = 0; float depthRangeInv = 1.0f / (listMaxDepth - listMinDepth); for (int culledLightIndex = 0; culledLightIndex < culledLightCount; ++culledLightIndex) { float lightMinDepth = max2(depthRanges[culledLightIndex].x * m_FrustumPlanes.zNear, m_FrustumPlanes.zNear); float lightMaxDepth = min2(depthRanges[culledLightIndex].y * m_FrustumPlanes.zNear, m_FrustumPlanes.zFar); int firstBit = (int)((lightMinDepth - listMinDepth) * 32.0f * depthRangeInv); int lastBit = (int)((lightMaxDepth - listMinDepth) * 32.0f * depthRangeInv); int bitCount = min(lastBit - firstBit + 1, 32 - firstBit); bitMask |= (uint)((0xFFFFFFFF >> (32 - bitCount)) << firstBit); tiles[culledLightCount + culledLightIndex] = (ushort)((uint)firstBit | (uint)(bitCount << 8)); } // As listMinDepth and listMaxDepth are used to calculate the geometry 2.5D bitmask, // we can optimize the shader execution (TileDepthInfo.shader) by refactoring the calculation. // int bitIndex = 32.0h * (geoDepth - listMinDepth) / (listMaxDepth - listMinDepth); // Equivalent to: // a = 32.0 / (listMaxDepth - listMinDepth) // b = -listMinDepth * 32.0 / (listMaxDepth - listMinDepth) // int bitIndex = geoDepth * a + b; float a = 32.0f * depthRangeInv; float b = -listMinDepth * a; int tileDataSize = culledLightCount * 2; int tileOffset = culledLightCount > 0 ? AddTileData(tiles, ref tileDataSize) : 0; int headerOffset = GetTileHeaderOffset(i, j); _tileHeaders[headerOffset + 0] = (uint)tileOffset; _tileHeaders[headerOffset + 1] = (uint)(tileDataSize == 0 ? 0 : culledLightCount); _tileHeaders[headerOffset + 2] = _f32tof16(a) | (_f32tof16(b) << 16); _tileHeaders[headerOffset + 3] = bitMask; maxLightPerTile = max(maxLightPerTile, culledLightCount); } } m_Counters[0] = max(m_Counters[0], maxLightPerTile); // TODO make it atomic }
protected static extern unsafe int DetailedOverlapInformationNative(IntPtr emr, Entity e, HitBoxOverlap overlap, float2 *result);
public TerrainDrawStreaming(int maximumLength, int meshSize, ComputeShader transformShader) { current = this; if (meshSize % 2 != 0) { Debug.LogError("Terrain panel's size should be even number!"); meshSize++; } this.meshSize = meshSize; //Initialize Mesh and triangles int vertexCount = meshSize + 1; vertSize = vertexCount; heightMapSize = vertSize * vertSize; NativeArray <float2> terrainVertexArray = new NativeArray <float2>(vertexCount * vertexCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); float2 *arrPtr = terrainVertexArray.Ptr(); for (int x = 0; x < vertexCount; ++x) { for (int y = 0; y < vertexCount; ++y) { arrPtr[y * vertexCount + x] = new float2(x, y) / meshSize - new float2(0.5f, 0.5f); } } verticesBuffer = new ComputeBuffer(terrainVertexArray.Length, sizeof(float2)); verticesBuffer.SetData(terrainVertexArray); heightMapBuffer = new ComputeBuffer(maximumLength * (vertexCount * vertexCount), sizeof(float)); NativeArray <int> triangles = new NativeArray <int>(6 * meshSize * meshSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); int *trianglePtr = triangles.Ptr(); for (int x = 0, count = 0; x < meshSize; ++x) { for (int y = 0; y < meshSize; ++y) { int4 indices = new int4(vertexCount * y + x, vertexCount * (y + 1) + x, vertexCount * y + (x + 1), vertexCount * (y + 1) + (x + 1)); trianglePtr[count] = indices.x; trianglePtr[count + 1] = indices.y; trianglePtr[count + 2] = indices.z; trianglePtr[count + 3] = indices.y; trianglePtr[count + 4] = indices.w; trianglePtr[count + 5] = indices.z; count += 6; } } triangleBuffer = new ComputeBuffer(triangles.Length, sizeof(int)); triangleBuffer.SetData(triangles); triangles.Dispose(); terrainVertexArray.Dispose(); removebuffer = new ComputeBuffer(100, sizeof(int2)); //Initialize indirect clusterBuffer = new ComputeBuffer(maximumLength, sizeof(TerrainPanel)); referenceBuffer = new NativeList <ulong>(maximumLength, Allocator.Persistent); this.transformShader = transformShader; resultBuffer = new ComputeBuffer(maximumLength, sizeof(int)); instanceCountBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments); NativeArray <int> indirect = new NativeArray <int>(5, Allocator.Temp, NativeArrayOptions.ClearMemory); indirect[0] = triangleBuffer.count; instanceCountBuffer.SetData(indirect); indirect.Dispose(); notUsedHeightmapIndices = new NativeList <int>(maximumLength, Allocator.Persistent); for (int i = 0; i < maximumLength; ++i) { notUsedHeightmapIndices.Add(i); } }
private async void Movie_CTF2DChanged(object sender, EventArgs e) { try { AdjustGridVisibility(); ImageSimulated2D.Visibility = Visibility.Hidden; if (Movie == null) { return; } if (Movie.OptionsCTF == null || Movie.CTF == null) { return; } this.Width = Movie.OptionsCTF.Window; this.Height = Movie.OptionsCTF.Window; ProgressCTF2D.Visibility = Visibility.Visible; int Width = Movie.OptionsCTF.Window / 2; CTF MovieCTF = Movie.CTF; //await Task.Delay(1000); await Task.Run(() => { ImageSource Simulated2D; unsafe { float2[] SimCoords = new float2[Width *Width]; fixed(float2 *SimCoordsPtr = SimCoords) { float2 *SimCoordsP = SimCoordsPtr; for (int y = 0; y < Width; y++) { int ycoord = Width - 1 - y; int ycoord2 = ycoord *ycoord; for (int x = 0; x < Width; x++) { int xcoord = x - Width; *SimCoordsP++ = new float2((float)Math.Sqrt(xcoord *xcoord + ycoord2) / (Width * 2), (float)Math.Atan2(ycoord, xcoord)); } } } float[] Sim2D = MovieCTF.Get2D(SimCoords, true, true, true); byte[] Sim2DBytes = new byte[Sim2D.Length]; fixed(byte *Sim2DBytesPtr = Sim2DBytes) fixed(float *Sim2DPtr = Sim2D) { byte *Sim2DBytesP = Sim2DBytesPtr; float *Sim2DP = Sim2DPtr; for (int i = 0; i < Width *Width; i++) { *Sim2DBytesP++ = (byte)(*Sim2DP++ *128f + 127f); } } Simulated2D = BitmapSource.Create(Width, Width, 96, 96, PixelFormats.Indexed8, BitmapPalettes.Gray256, Sim2DBytes, Width); Simulated2D.Freeze(); } Dispatcher.Invoke(() => { ImageSimulated2D.Source = Simulated2D; ImageSimulated2D.Visibility = Visibility.Visible; }); }); ProgressCTF2D.Visibility = Visibility.Hidden; } catch { } }
/// <summary> /// Creates a new CudaRegisteredHostMemory_float2 from an existing IntPtr. IntPtr must be page size aligned (4KBytes)! /// </summary> /// <param name="hostPointer">must be page size aligned (4KBytes)</param> /// <param name="size">In elements</param> public CudaRegisteredHostMemory_float2(IntPtr hostPointer, SizeT size) { _intPtr = hostPointer; _size = size; _typeSize = (SizeT)Marshal.SizeOf(typeof(float2)); _ptr = (float2*)_intPtr; }
public static unsafe void PopulateSpriteVertices(ref WorldSpaceMask rectMask, ref DynamicBuffer <ControlVertexData> vertices, ref DynamicBuffer <ControlVertexIndex> triangles, ref WorldSpaceRect rectData, ref SpriteVertexData spriteVertexData, float4 color) { float pixelsPerUnit = spriteVertexData.PixelsPerUnit / 100.0f; Rect rect = new Rect(rectData.Min, rectData.Max - rectData.Min); float4 adjustedBorders = GetAdjustedBorders(spriteVertexData.Border / pixelsPerUnit, rect); var padding = spriteVertexData.Padding / pixelsPerUnit; float2 *vertScratch = stackalloc float2[4]; float2 *uvScratch = stackalloc float2[4]; vertScratch[0] = new float2(padding.x, padding.y); vertScratch[3] = new float2(rect.width - padding.z, rect.height - padding.w); vertScratch[1].x = adjustedBorders.x; vertScratch[1].y = adjustedBorders.y; vertScratch[2].x = rect.width - adjustedBorders.z; vertScratch[2].y = rect.height - adjustedBorders.w; for (int i = 0; i < 4; ++i) { vertScratch[i].x += rect.x; vertScratch[i].y += rect.y; } uvScratch[0] = new Vector2(spriteVertexData.Outer.x, spriteVertexData.Outer.y); uvScratch[1] = new Vector2(spriteVertexData.Inner.x, spriteVertexData.Inner.y); uvScratch[2] = new Vector2(spriteVertexData.Inner.z, spriteVertexData.Inner.w); uvScratch[3] = new Vector2(spriteVertexData.Outer.z, spriteVertexData.Outer.w); // rect mask support var cut = GetRectangleMaskCut(vertScratch[0], vertScratch[3], ref rectMask); vertScratch[0] = vertScratch[0] + cut.Min - clamp(cut.Max - float2(rect.size), 0.0f, float.PositiveInfinity); vertScratch[1] = vertScratch[1] + math.clamp(cut.Min - adjustedBorders.xy, 0.0f, float.PositiveInfinity) - clamp(cut.Max - (float2(rect.size) - adjustedBorders.xy), 0.0f, float.PositiveInfinity); vertScratch[2] = vertScratch[2] + math.clamp(cut.Min - (float2(rect.size) - adjustedBorders.zw), 0.0f, float.PositiveInfinity) - math.clamp(cut.Max - adjustedBorders.wz, 0.0f, float.PositiveInfinity); vertScratch[3] = vertScratch[3] + clamp(cut.Min - float2(rect.size), 0.0f, float.PositiveInfinity) - cut.Max; int vertexOffset = vertices.Length; for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { vertices.Add(new ControlVertexData() { Position = new float3(vertScratch[x].x, vertScratch[y].y, 0.0f), TexCoord0 = new float2(uvScratch[x].x, uvScratch[y].y), Color = color }); } } for (int x = 0; x < 3; ++x) { int x2 = x + 1; for (int y = 0; y < 3; ++y) { int y2 = y + 1; // Ignore empty if (vertScratch[x2].x - vertScratch[x].x <= 0.0f) { continue; } if (vertScratch[y2].y - vertScratch[y].y <= 0.0f) { continue; } triangles.Add(vertexOffset + x * 4 + y); triangles.Add(vertexOffset + x * 4 + y2); triangles.Add(vertexOffset + x2 * 4 + y); triangles.Add(vertexOffset + x2 * 4 + y2); triangles.Add(vertexOffset + x2 * 4 + y); triangles.Add(vertexOffset + x * 4 + y2); } } // for (int x = 0; x < 3; ++x) // { // int x2 = x + 1; // // for (int y = 0; y < 3; ++y) // { // int y2 = y + 1; // // // AddQuad(ref rectMask, ref vertices, ref triangles, // new float2(vertScratch[x].x, vertScratch[y].y), // new float2(vertScratch[x2].x, vertScratch[y2].y), // color, // new float2(uvScratch[x].x, uvScratch[y].y), // new float2(uvScratch[x2].x, uvScratch[y2].y)); // } // } }
public void Execute(int i) { float2 * w = stackalloc float2[3]; Particle p = ps[i]; uint2 cell_idx = (uint2)p.pos; float2 cell_diff = (p.pos - cell_idx) - 0.5f; w[0] = 0.5f * math.pow(0.5f - cell_diff, 2); w[1] = 0.75f - math.pow(cell_diff, 2); w[2] = 0.5f * math.pow(0.5f + cell_diff, 2); float density = 0.0f; for (uint x = 0; x < 3; ++x) { for (uint y = 0; y < 3; ++y) { float weight = w[x].x * w[y].y; int index_1d = (int)(cell_idx.x + x - 1) * grid_res + (int)(cell_idx.y + y - 1); density += grid[index_1d].mass * weight; // m_0 / h^3 in this case h = 1 } } float volume = p.mass / density; float pressure = math.max(-0.1f, eos_stiffness * (math.pow(density / rest_density, eos_power) - 1)); float2x2 stress = math.float2x2( -pressure, 0, 0, -pressure ); float2x2 velocity_gradient = p.C; float2x2 velocity_gradient_T = math.transpose(velocity_gradient); float2x2 strain = velocity_gradient + velocity_gradient_T; //float trace = strain.c1.x + strain.c0.y; //strain.c0.y = strain.c1.x = trace; float2x2 viscosity_term = dynamic_viscosity * strain; stress += viscosity_term; float2x2 eq_16_term_0 = -volume * 4 * stress * dt; for (uint x = 0; x < 3; ++x) { for (uint y = 0; y < 3; ++y) { float weight = w[x].x * w[y].y; uint2 current_cell_idx = math.uint2(cell_idx.x + x - 1, cell_idx.y + y - 1); float2 cell_dist = (current_cell_idx - p.pos) + 0.5f; int index_1d = (int)current_cell_idx.x * grid_res + (int)current_cell_idx.y; Cell c = grid[index_1d]; float2 momentum = math.mul(eq_16_term_0 * weight, cell_dist); c.v += momentum; grid[index_1d] = c; } } }