protected unsafe override void OnUpdate() { var current = new int2(Screen.width, Screen.height); if (res->Equals(current)) { return; } * res = current; int2 *local = res; var cmdBuffer = cmdBufferSystem.CreateCommandBuffer(); Dependency = Entities.ForEach((ref LocalToWorld c2, in ReferenceResolution c0, in WidthHeightRatio c1) => { var logWidth = math.log2(local->x / c0.Value.x); var logHeight = math.log2(local->y / c0.Value.y); var avg = math.lerp(logWidth, logHeight, c1.Value); var scale = math.pow(2, avg); var center = new float3(local->xy / 2, 0); c2 = new LocalToWorld { Value = float4x4.TRS(center, c2.Rotation, new float3(scale)) }; }).WithNativeDisableUnsafePtrRestriction(local).Schedule(Dependency);
protected override void OnDestroy() { if (res != null) { UnsafeUtility.Free(res, Allocator.Persistent); res = null; } }
protected override void OnCreate() { scaleQuery = GetEntityQuery(new EntityQueryDesc { All = new [] { ComponentType.ReadOnly <ReferenceResolution>(), ComponentType.ReadOnly <WidthHeightRatio>(), ComponentType.ReadWrite <LocalToWorld>() } }); evtArchetype = EntityManager.CreateArchetype(typeof(ResolutionChangeEvt)); cmdBufferSystem = World.GetOrCreateSystem <BeginPresentationEntityCommandBufferSystem>(); res = (int2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <int2>(), UnsafeUtility.AlignOf <int2>(), Allocator.Persistent); *res = new int2(Screen.width, Screen.height); }
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(); }
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 static unsafe void TestInt2ModUshort(int2 *o, ushort i) { *o = new int2(0, 0) % i; }
public static unsafe void TestUshortModInt2(int2 *o, ushort i) { *o = i % new int2(1, 1); }
public static unsafe void TestInt2DivUshort(int2 *o, ushort i) { *o = new int2(0, 0) / i; }
public static unsafe void TestUshortDivInt2(int2 *o, ushort i) { *o = i / new int2(1, 1); }
public static unsafe void TestUshortMulInt2(int2 *o, ushort i) { *o = i * new int2(0, 0); }
public static unsafe void TestInt2SubUshort(int2 *o, ushort i) { *o = new int2(0, 0) - i; }
public static unsafe void TestUshortSubInt2(int2 *o, ushort i) { *o = i - new int2(0, 0); }
public static unsafe void TestUshortAddInt2(int2 *o, ushort i) { *o = i + new int2(0, 0); }
public void RemoveQuadTrees(NativeList <ulong> removeList) { void ErasePoint(TerrainQuadTree.QuadTreeNode *node) { node->listPosition = -1; notUsedHeightmapIndices.Add(node->panel.heightMapIndex); } int length = removeList.Length; TerrainQuadTree.QuadTreeNode **tree = (TerrainQuadTree.QuadTreeNode * *)removeList.unsafePtr; int targetLength = referenceBuffer.Length - length; int len = 0; if (targetLength <= 0) { for (int i = 0; i < length; ++i) { ErasePoint(tree[i]); } referenceBuffer.Clear(); return; } for (int i = 0; i < length; ++i) { TerrainQuadTree.QuadTreeNode *currentNode = tree[i]; if (currentNode->listPosition >= targetLength) { referenceBuffer[currentNode->listPosition] = 0; ErasePoint(currentNode); } } NativeArray <int2> transformList = new NativeArray <int2>(length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); int2 *transformPtr = transformList.Ptr(); len = 0; int currentIndex = referenceBuffer.Length - 1; for (int i = 0; i < length; ++i) { TerrainQuadTree.QuadTreeNode *treeNode = tree[i]; if (treeNode->listPosition < 0) { continue; } while (referenceBuffer[currentIndex] == 0) { currentIndex--; if (currentIndex < 0) { goto FINALIZE; } } TerrainQuadTree.QuadTreeNode *lastNode = (TerrainQuadTree.QuadTreeNode *)referenceBuffer[currentIndex]; currentIndex--; transformPtr[len] = new int2(treeNode->listPosition, lastNode->listPosition); len++; lastNode->listPosition = treeNode->listPosition; referenceBuffer[lastNode->listPosition] = (ulong)lastNode; ErasePoint(treeNode); } FINALIZE: referenceBuffer.RemoveLast(length); if (len <= 0) { return; } if (len > removebuffer.count) { removebuffer.Dispose(); removebuffer = new ComputeBuffer(len, sizeof(int2)); } removebuffer.SetData(transformList, 0, 0, len); transformShader.SetBuffer(0, ShaderIDs._IndexBuffer, removebuffer); transformShader.SetBuffer(0, ShaderIDs.clusterBuffer, clusterBuffer); ComputeShaderUtility.Dispatch(transformShader, 0, len, 64); transformList.Dispose(); }
/// <summary> /// Creates a new CudaRegisteredHostMemory_int2 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_int2(IntPtr hostPointer, SizeT size) { _intPtr = hostPointer; _size = size; _typeSize = (SizeT)Marshal.SizeOf(typeof(int2)); _ptr = (int2*)_intPtr; }
// TODO: sort by using plane information instead of unreliable floating point math .. unsafe static void SortIndices(float3 *vertices, int2 *sortedStack, ushort *indices, int offset, int indicesCount, float3 normal) { // There's no point in trying to sort a point or a line if (indicesCount < 3) { return; } float3 tangentX, tangentY; if (normal.x > normal.y) { if (normal.x > normal.z) { tangentX = math.cross(normal, new float3(0, 1, 0)); tangentY = math.cross(normal, tangentX); } else { tangentX = math.cross(normal, new float3(0, 0, 1)); tangentY = math.cross(normal, tangentX); } } else { if (normal.y > normal.z) { tangentX = math.cross(normal, new float3(1, 0, 0)); tangentY = math.cross(normal, tangentX); } else { tangentX = math.cross(normal, new float3(0, 1, 0)); tangentY = math.cross(normal, tangentX); } } var centroid = FindPolygonCentroid(vertices, indices, offset, indicesCount); var center = new float2(math.dot(tangentX, centroid), // distance in direction of tangentX math.dot(tangentY, centroid)); // distance in direction of tangentY var sortedStackLength = 1; sortedStack[0] = new int2(0, indicesCount - 1); while (sortedStackLength > 0) { var top = sortedStack[sortedStackLength - 1]; sortedStackLength--; var l = top.x; var r = top.y; var left = l; var right = r; var va = vertices[indices[offset + (left + right) / 2]]; while (true) { var a_angle = math.atan2(math.dot(tangentX, va) - center.x, math.dot(tangentY, va) - center.y); { var vb = vertices[indices[offset + left]]; var b_angle = math.atan2(math.dot(tangentX, vb) - center.x, math.dot(tangentY, vb) - center.y); while (b_angle > a_angle) { left++; vb = vertices[indices[offset + left]]; b_angle = math.atan2(math.dot(tangentX, vb) - center.x, math.dot(tangentY, vb) - center.y); } } { var vb = vertices[indices[offset + right]]; var b_angle = math.atan2(math.dot(tangentX, vb) - center.x, math.dot(tangentY, vb) - center.y); while (a_angle > b_angle) { right--; vb = vertices[indices[offset + right]]; b_angle = math.atan2(math.dot(tangentX, vb) - center.x, math.dot(tangentY, vb) - center.y); } } if (left <= right) { if (left != right) { var t = indices[offset + left]; indices[offset + left] = indices[offset + right]; indices[offset + right] = t; } left++; right--; } if (left > right) { break; } } if (l < right) { sortedStack[sortedStackLength] = new int2(l, right); sortedStackLength++; } if (left < r) { sortedStack[sortedStackLength] = new int2(left, r); sortedStackLength++; } } }