public static void ClearValues <T>(ref ChiselBlobArray <T> array) where T : unmanaged { if (array.Length == 0) { return; } UnsafeUtility.MemSet(array.GetUnsafePtr(), 0, array.Length * sizeof(T)); }
/// <summary> /// Copies an array of structs to an array in a blob asset after allocating the necessary memory. /// </summary> /// <param name="blobArray">A reference to a BlobArray field in a blob asset.</param> /// <param name="data">An array containing structs of type <typeparamref name="T"/>.</param> /// <typeparam name="T">The struct data type.</typeparam> /// <returns>A reference to the newly constructed array as a mutable BlobBuilderArray instance.</returns> public ChiselBlobBuilderArray <T> Construct <T>(ref ChiselBlobArray <T> blobArray, params T[] data) where T : unmanaged { var constructBlobArray = Allocate(ref blobArray, data.Length); for (int i = 0; i != data.Length; i++) { constructBlobArray[i] = data[i]; } return(constructBlobArray); }
public static bool Contains <T>(ref ChiselBlobArray <T> array, T value) where T : unmanaged { for (int i = 0; i < array.Length; i++) { if (EqualityComparer <T> .Default.Equals(array[i], value)) { return(true); } } return(false); }
public unsafe void ReplaceIfExists(ref ChiselBlobArray <float3> uniqueVertices) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckWriteAndThrow(m_Safety); #endif // Add Unique vertex for (int i = 0; i < uniqueVertices.Length; i++) { var vertex = uniqueVertices[i]; HashedVerticesUtility.ReplaceIfExists((ushort *)m_HashTable, m_ChainedIndices, m_Vertices, vertex); } }
public HashedVertices(ref ChiselBlobArray <float3> uniqueVertices, Allocator allocator = Allocator.Persistent) : this(uniqueVertices.Length, allocator) { // Add Unique vertex for (int i = 0; i < uniqueVertices.Length; i++) { var vertex = uniqueVertices[i]; var centerIndex = new int3((int)(vertex.x / kCellSize), (int)(vertex.y / kCellSize), (int)(vertex.z / kCellSize)); var hashCode = HashedVerticesUtility.GetHash(centerIndex); var prevChainIndex = ((ushort *)m_HashTable)[hashCode]; var newChainIndex = m_ChainedIndices->Length; m_Vertices->AddNoResize(vertex); m_ChainedIndices->AddNoResize((ushort)prevChainIndex); ((ushort *)m_HashTable)[(int)hashCode] = (ushort)(newChainIndex + 1); } }
public static unsafe T2[] ToArray <T1, T2>(ref ChiselBlobArray <T1> array) where T1 : unmanaged where T2 : unmanaged { var newArray = new T2[array.Length]; if (array.Length > 0) { if (sizeof(T1) != sizeof(T2)) throw new InvalidOperationException(); fixed(T2 *newArrayPtr = &newArray[0]) { UnsafeUtility.MemCpy(newArrayPtr, array.GetUnsafePtr(), array.Length * sizeof(T2)); } } return(newArray); }
public unsafe void AddUniqueVertices(ref ChiselBlobArray <float3> uniqueVertices) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckWriteAndThrow(m_Safety); #endif // Add Unique vertex for (int i = 0; i < uniqueVertices.Length; i++) { var vertex = uniqueVertices[i]; var centerIndex = new int3((int)(vertex.x / kCellSize), (int)(vertex.y / kCellSize), (int)(vertex.z / kCellSize)); var hashCode = HashedVerticesUtility.GetHash(centerIndex); var prevChainIndex = ((ushort *)m_HashTable)[hashCode]; var newChainIndex = m_ChainedIndices->Length; m_Vertices->AddNoResize(vertex); m_ChainedIndices->AddNoResize((ushort)prevChainIndex); ((ushort *)m_HashTable)[(int)hashCode] = (ushort)(newChainIndex + 1); } }
/// <summary> /// Allocates enough memory to store <paramref name="length"/> elements of struct <typeparamref name="T"/>. /// </summary> /// <param name="ptr">A reference to a BlobArray field in a blob asset.</param> /// <param name="length">The number of elements to allocate.</param> /// <typeparam name="T">The struct data type.</typeparam> /// <returns>A reference to the newly allocated array as a mutable BlobBuilderArray instance.</returns> public ChiselBlobBuilderArray <T> Allocate <T>(ref ChiselBlobArray <T> ptr, int length) where T : unmanaged { if (length <= 0) { return(new ChiselBlobBuilderArray <T>(null, 0)); } var offsetPtr = (int *)UnsafeUtility.AddressOf(ref ptr.m_OffsetPtr); ValidateAllocation(offsetPtr); var allocation = Allocate(UnsafeUtility.SizeOf <T>() * length, UnsafeUtility.AlignOf <T>()); var patch = new OffsetPtrPatch { offsetPtr = offsetPtr, target = allocation, length = length }; m_patches.Add(patch); return(new ChiselBlobBuilderArray <T>(AllocationToPointer(allocation), length)); }
public static void TransformOtherIntoBrushSpace(ref float4x4 treeToBrushSpaceMatrix, ref float4x4 brushToTreeSpaceMatrix, ref ChiselBlobArray <float4> srcPlanes, NativeArray <float4> dstPlanes) { var brush1ToBrush0LocalLocalSpace = math.transpose(math.mul(treeToBrushSpaceMatrix, brushToTreeSpaceMatrix)); for (int plane_index = 0; plane_index < srcPlanes.Length; plane_index++) { ref var srcPlane = ref srcPlanes[plane_index]; dstPlanes[plane_index] = math.mul(brush1ToBrush0LocalLocalSpace, srcPlane); }
public static ChiselBlobBuilderArray <T> Construct <T>(this ChiselBlobBuilder builder, ref ChiselBlobArray <T> blobArray, NativeArray <T> data, int length) where T : unmanaged { length = math.max(length, 0); var blobBuilderArray = builder.Allocate(ref blobArray, length); if (length > 0) { var srcPtr = data.GetUnsafeReadOnlyPtr(); var dstPtr = blobBuilderArray.GetUnsafePtr(); UnsafeUtility.MemCpy(dstPtr, srcPtr, blobBuilderArray.Length * sizeof(T)); } return(blobBuilderArray); }
public static ChiselBlobBuilderArray <T> Construct <T>(this ChiselBlobBuilder builder, ref ChiselBlobArray <T> blobArray, T[] data, int length) where T : unmanaged { var blobBuilderArray = builder.Allocate(ref blobArray, length); for (int i = 0; i < length; i++) { blobBuilderArray[i] = data[i]; } return(blobBuilderArray); }
public static ChiselBlobBuilderArray <T> Construct <T>(this ChiselBlobBuilder builder, ref ChiselBlobArray <T> blobArray, List <T> data) where T : unmanaged { var blobBuilderArray = builder.Allocate(ref blobArray, data.Count); for (int i = 0; i < data.Count; i++) { blobBuilderArray[i] = data[i]; } return(blobBuilderArray); }
public static ChiselBlobBuilderArray <T> Construct <T>(this ChiselBlobBuilder builder, ref ChiselBlobArray <T> blobArray, NativeArray <T> data) where T : unmanaged { var blobBuilderArray = builder.Allocate(ref blobArray, data.Length); if (data.Length > 0) { UnsafeUtility.MemCpy(blobBuilderArray.GetUnsafePtr(), data.GetUnsafeReadOnlyPtr(), blobBuilderArray.Length * sizeof(T)); } return(blobBuilderArray); }
public static unsafe uint GetHashCode <T>(ChiselBlobArray <T> value) where T : unmanaged { return(math.hash(value.GetUnsafePtr(), sizeof(T) * value.Length)); }
bool CopyPolygonToIndices(ChiselBlobAssetReference <BrushMeshBlob> mesh, ref ChiselBlobArray <float3> treeSpaceVertices, int polygonIndex, HashedVertices hashedTreeSpaceVertices, NativeArray <Edge> edges, ref int edgeCount) { ref var halfEdges = ref mesh.Value.halfEdges;
// TODO: turn into job static void GetIntersectingPlanes(IntersectionType type, [NoAlias] ref ChiselBlobArray <float4> localPlanes, int localPlaneCount, [NoAlias] ref ChiselBlobArray <float3> vertices, ChiselAABB selfBounds, float4x4 treeToNodeSpaceInverseTransposed, [NoAlias] ref NativeArray <int> intersectingPlaneIndices, [NoAlias] out int intersectingPlaneLength, [NoAlias] out int intersectingPlanesAndEdgesLength) { NativeCollectionHelpers.EnsureMinimumSize(ref intersectingPlaneIndices, localPlanes.Length); if (type != IntersectionType.Intersection) { intersectingPlaneLength = localPlaneCount; intersectingPlanesAndEdgesLength = localPlanes.Length; for (int i = 0; i < intersectingPlaneLength; i++) { intersectingPlaneIndices[i] = i; } return; } var min = selfBounds.Min; var max = selfBounds.Max; //Debug.Log($"{localPlanes.Length}"); intersectingPlaneLength = 0; intersectingPlanesAndEdgesLength = 0; var verticesLength = vertices.Length; for (int i = 0; i < localPlanes.Length; i++) { // bring plane into local space of mesh, the same space as the bounds of the mesh var localPlane = localPlanes[i]; // note: a transpose is part of this transformation var transformedPlane = math.mul(treeToNodeSpaceInverseTransposed, localPlane); //var normal = transformedPlane.xyz; // only need the signs, so don't care about normalization //transformedPlane /= math.length(normal); // we don't have to normalize the plane var corner = new float4((transformedPlane.x < 0) ? max.x : min.x, (transformedPlane.y < 0) ? max.y : min.y, (transformedPlane.z < 0) ? max.z : min.z, 1.0f); float forward = math.dot(transformedPlane, corner); if (forward > kFatPlaneWidthEpsilon) // closest point is outside { intersectingPlaneLength = 0; intersectingPlanesAndEdgesLength = 0; return; } // do a bounds check corner = new float4((transformedPlane.x >= 0) ? max.x : min.x, (transformedPlane.y >= 0) ? max.y : min.y, (transformedPlane.z >= 0) ? max.z : min.z, 1.0f); float backward = math.dot(transformedPlane, corner); if (backward < -kFatPlaneWidthEpsilon) // closest point is inside { continue; } float minDistance = float.PositiveInfinity; float maxDistance = float.NegativeInfinity; int onCount = 0; for (int v = 0; v < verticesLength; v++) { float distance = math.dot(transformedPlane, new float4(vertices[v], 1)); minDistance = math.min(distance, minDistance); maxDistance = math.max(distance, maxDistance); onCount += (distance >= -kFatPlaneWidthEpsilon && distance <= kFatPlaneWidthEpsilon) ? 1 : 0; } // if all vertices are 'inside' this plane, then we're not truly intersecting with it if ((minDistance > kFatPlaneWidthEpsilon || maxDistance < -kFatPlaneWidthEpsilon)) { continue; } if (i < localPlaneCount) { intersectingPlaneIndices[intersectingPlaneLength] = i; intersectingPlaneLength++; intersectingPlanesAndEdgesLength++; } else { intersectingPlaneIndices[intersectingPlanesAndEdgesLength] = i; intersectingPlanesAndEdgesLength++; } } }
unsafe static ChiselBlobAssetReference <BrushTreeSpaceVerticesBlob> Build(ref ChiselBlobArray <float3> localVertices, float4x4 nodeToTreeSpaceMatrix) { var totalSize = localVertices.Length * sizeof(float3); var builder = new ChiselBlobBuilder(Allocator.Temp, math.max(4, totalSize)); ref var root = ref builder.ConstructRoot <BrushTreeSpaceVerticesBlob>();
public static ChiselBlobBuilderArray <T> Construct <T>(this ChiselBlobBuilder builder, ref ChiselBlobArray <T> blobArray, T *data, int length) where T : unmanaged { length = math.max(length, 0); var blobBuilderArray = builder.Allocate(ref blobArray, length); if (length > 0) { UnsafeUtility.MemCpy(blobBuilderArray.GetUnsafePtr(), data, blobBuilderArray.Length * sizeof(T)); } return(blobBuilderArray); }