Exemple #1
0
        void TransformVerts(LayerSubMesh mesh)
        {
            var offset  = Rot4.FromAngleFlat(target);
            var offseti = offset.AsInt;

            var uvs       = mesh.uvs;
            var vertsc    = mesh.verts.Count;
            var origVerts = NoAllocHelpers.ExtractArrayFromListT(mesh.verts);

            // Rotate around a center
            if (PrintPlanePatch.plantMats.Contains(mesh.material) ||
                GraphicPrintPatch.graphicSingle.Contains(mesh.material))
            {
                if (uvs.Count * 4 != vertsc)
                {
                    Log.ErrorOnce($"Carousel: Bad material {mesh.material}", mesh.material.GetHashCode());
                    return;
                }

                Util.ResizeIfNeeded(ref tempVerts, vertsc);

                for (int i = 0; i < vertsc; i += 4)
                {
                    // The mesh data lists are only used during mesh building and are otherwise unused
                    // In between mesh rebuilding, Carousel uses the uv list to store object centers for rotation
                    var c = uvs[i / 4];

                    tempVerts[i]     = c + (origVerts[i] - c).RotatedBy(offset);
                    tempVerts[i + 1] = c + (origVerts[i + 1] - c).RotatedBy(offset);
                    tempVerts[i + 2] = c + (origVerts[i + 2] - c).RotatedBy(offset);
                    tempVerts[i + 3] = c + (origVerts[i + 3] - c).RotatedBy(offset);
                }

                mesh.mesh.SetVertices(tempVerts, vertsc);
            }

            // Exchange vertices
            if (GraphicPrintPatch.matData.ContainsKey(mesh.material) ||
                LinkedPrintPatch.linkedMaterials.Contains(mesh.material))
            {
                Util.ResizeIfNeeded(ref tempVerts, vertsc);

                for (int i = 0; i < vertsc; i += 4)
                {
                    tempVerts[i].SetXZY(ref origVerts[i + (offseti & 3)], origVerts[i].y);
                    tempVerts[i + 1].SetXZY(ref origVerts[i + (offseti + 1 & 3)], origVerts[i + 1].y);
                    tempVerts[i + 2].SetXZY(ref origVerts[i + (offseti + 2 & 3)], origVerts[i + 2].y);
                    tempVerts[i + 3].SetXZY(ref origVerts[i + (offseti + 3 & 3)], origVerts[i + 3].y);
                }

                mesh.mesh.SetVertices(tempVerts, vertsc);
            }
        }
Exemple #2
0
        void TransformAtlas(LayerSubMesh mesh, TextureAtlasGroup group)
        {
            var offset   = Rot4.FromAngleFlat(target);
            var offseti  = offset.AsInt;
            var vertsc   = mesh.verts.Count / 5 * 4;
            var uvsc     = mesh.uvs.Count;
            var vertsArr = NoAllocHelpers.ExtractArrayFromListT(mesh.verts);
            var uvsArr   = NoAllocHelpers.ExtractArrayFromListT(mesh.uvs);

            Util.ResizeIfNeeded(ref tempVerts, vertsc);
            Util.ResizeIfNeeded(ref tempUVs, uvsc);

            for (int i = 0; i < vertsc; i += 4)
            {
                var data = vertsArr[vertsc + i / 4];

                if (data.x == PrintPlanePatch.SPECIAL_X)
                {
                    ExchangeVerts(tempVerts, vertsArr, i, offseti);

                    var rotData  = ((int)data.z & 0b1100) >> 2;
                    var flipData = (int)data.z & 0b0011;

                    var relRot  = GenMath.PositiveMod(rotData - Rot4.FromAngleFlat(target).AsInt, 4);
                    var flipped = relRot == 1 && ((flipData & 1) == 1) || relRot == 3 && ((flipData & 2) == 2) ? 1 : 0;

                    var rotatedMat = GraphicPrintPatch_SetData.intToGraphic[(int)data.y].mats[(rotData + Rot4.FromAngleFlat(-target).AsInt) % 4];
                    Graphic.TryGetTextureAtlasReplacementInfo(rotatedMat, group, false, false, out _, out var uvs, out _);

                    FixUVs(
                        tempUVs,
                        uvs,
                        i,
                        flipped
                        );
                }
                else if (data.x != PrintPlanePatch.EMPTY_X)
                {
                    RotateVerts(tempVerts, vertsArr, i, data, offset);
                    Array.Copy(uvsArr, i, tempUVs, i, 4);
                }
                else
                {
                    Array.Copy(vertsArr, i, tempVerts, i, 4);
                    Array.Copy(uvsArr, i, tempUVs, i, 4);
                }
            }

            mesh.mesh.SetVertices(tempVerts, vertsc);
            mesh.mesh.SetUVs(tempUVs, uvsc);
        }
        /// <summary>Box fills tiles and GameObjects into given bounds within the selected layers.</summary>
        /// <param name="gridLayout">Grid to box fill data to.</param>
        /// <param name="brushTarget">Target of the box fill operation. By default the currently selected GameObject.</param>
        /// <param name="position">The bounds to box fill data into.</param>
        public override void BoxFill(GridLayout gridLayout, GameObject brushTarget, BoundsInt position)
        {
            if (brushTarget == null)
            {
                return;
            }

            Tilemap map = brushTarget.GetComponent <Tilemap>();

            if (map == null)
            {
                return;
            }

            int count    = 0;
            var listSize = position.size.x * position.size.y * position.size.z;

            if (m_TileChangeDataList == null || m_TileChangeDataList.Capacity != listSize)
            {
                m_TileChangeDataList = new List <TileChangeData>(listSize);
            }
            m_TileChangeDataList.Clear();
            foreach (Vector3Int location in position.allPositionsWithin)
            {
                Vector3Int local = location - position.min;
                BrushCell  cell  = m_Cells[GetCellIndexWrapAround(local.x, local.y, local.z)];
                if (cell.tile == null)
                {
                    continue;
                }

                var tcd = new TileChangeData {
                    position = location, tile = cell.tile, transform = cell.matrix, color = cell.color
                };
                m_TileChangeDataList.Add(tcd);
                count++;
            }
            // Duplicate empty slots in the list, as ExtractArrayFromListT returns full list
            if (0 < count && count < listSize)
            {
                var tcd = m_TileChangeDataList[count - 1];
                for (int i = count; i < listSize; ++i)
                {
                    m_TileChangeDataList.Add(tcd);
                }
            }
            var tileChangeData = NoAllocHelpers.ExtractArrayFromListT(m_TileChangeDataList);

            map.SetTiles(tileChangeData, false);
        }
Exemple #4
0
    /// <summary>
    /// View <paramref name="list"/> as a <see cref="NativeArray{T}"/> without having to copy it or doing all the boilerplate for getting the pointer out of a list.
    /// Useful for allowing a job to work on a list.
    ///
    /// <para>
    /// Put this thing in a disposable scope unless you can guarantee that the list will never change size or reallocate (in that case consider using a <see cref="NativeArray{T}"/> instead),
    /// as Unity will <b>not</b> tell you if you're out of bounds, accessing invalid data, or accessing stale data because you have a stale/invalid view of the list.
    /// The following changes to the list will turn a view invalid/stale:
    /// <list type="number">
    /// <item>The contents of the array will be stale (not reflect any changes to the values in the list) in case of a reallocation (changes to, or adding more items than, <see cref="List{T}.Capacity"/> or using <see cref="List{T}.TrimExcess"/>)</item>
    /// <item>The length of the array will be wrong if you add/remove elements from the list</item>
    /// </list>
    /// </para>
    ///
    /// <para>
    /// The <paramref name="nativeArray"/> itself does not need to be disposed, but you need to dispose the <see cref="NativeArrayViewHandle"/> you get back, Unity's Memory Leak Detection will tell you if you forget.
    /// Do not use the array after calling <see cref="NativeArrayViewHandle.Dispose"/> on the <see cref="NativeArrayViewHandle"/> returned from this function,
    /// as you can risk the garbage collector removing the data from down under you, Unity's Collections Safety Checks will tell you if you do this.
    /// There is <b>no</b> race detection for accessing multiple different views of the same list in different jobs concurrently, or modifying the list while a job is working on a view.
    /// </para>
    ///
    /// Usage:
    /// <code>
    /// List&lt;int&gt; list;
    /// using (list.ViewAsNativeArray(out var nativeArray))
    /// {
    ///     // work on nativeArray
    /// }
    /// </code>
    /// </summary>
    public unsafe static NativeArrayViewHandle ViewAsNativeArray <T>(this List <T> list, out NativeArray <T> nativeArray) where T : struct
    {
        var lArray = NoAllocHelpers.ExtractArrayFromListT(list);
        var ptr    = UnsafeUtility.PinGCArrayAndGetDataAddress(lArray, out var handle);

        nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(ptr, list.Count, Allocator.None);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
        DisposeSentinel.Create(out var safety, out var sentinel, 0, Allocator.None);
        NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref nativeArray, safety);
        return(new NativeArrayViewHandle(handle, safety, sentinel));
#else
        return(new NativeArrayViewHandle(handle));
#endif
    }
        private static NativeArray <int> ArrayFromList(List <int> list, Allocator allocator)
        {
            if (list == null || list.Count == 0)
            {
                return(new NativeArray <int>());
            }

            var array = new NativeArray <int>(list.Count, allocator, NativeArrayOptions.UninitializedMemory);

            // Use explicit copy length because the internal list might be longer than Count, which causes an error
            NativeArray <int> .Copy(NoAllocHelpers.ExtractArrayFromListT(list), array, list.Count);

            return(array);
        }
Exemple #6
0
    public unsafe static int PointerDefaultIndexOf(List <int> list, int target)
    {
        var len = list.Count;

        fixed(int *p = NoAllocHelpers.ExtractArrayFromListT(list))
        for (int i = 0; i < len; i++)
        {
            if (p[i] == target)
            {
                return(i);
            }
        }
        return(-1);
    }
Exemple #7
0
        public void ExtractArrayFromListTReturnsInternalList()
        {
            var list = new List <int>(5);

            for (var i = 0; i < 5; i++)
            {
                list.Add(0);
            }

            var array = NoAllocHelpers.ExtractArrayFromListT(list);

            array[3] = 4;

            Assert.AreEqual(4, list[3]);
        }
Exemple #8
0
        void TransformVerts(LayerSubMesh mesh)
        {
            var offset  = Rot4.FromAngleFlat(target);
            var offseti = offset.AsInt;

            // Rotate around a center
            if (PrintPlanePatch.plantMats.Contains(mesh.material) ||
                GraphicPrintPatch_TransformMats.graphicSingle.Contains(mesh.material))
            {
                var vertsc   = mesh.verts.Count / 5 * 4;
                var vertsArr = NoAllocHelpers.ExtractArrayFromListT(mesh.verts);

                Util.ResizeIfNeeded(ref tempVerts, vertsc);

                for (int i = 0; i < vertsc; i += 4)
                {
                    // The mesh data lists are only used during mesh building and are otherwise unused.
                    // In between mesh rebuilding, Carousel reuses the lists to recalculate the meshes
                    // but also appends additional information to the end of the vertex list
                    var center = vertsArr[vertsc + i / 4];

                    RotateVerts(tempVerts, vertsArr, i, center, offset);
                }

                mesh.mesh.SetVertices(tempVerts, vertsc);
            }

            // Exchange vertices
            // This doesn't change the set of their values but changes their order
            if (GraphicPrintPatch_TransformMats.exchangeMats.ContainsKey(mesh.material) ||
                LinkedPrintPatch.linkedMaterials.Contains(mesh.material))
            {
                var vertsc   = mesh.verts.Count;
                var vertsArr = NoAllocHelpers.ExtractArrayFromListT(mesh.verts);

                Util.ResizeIfNeeded(ref tempVerts, vertsc);

                for (int i = 0; i < vertsc; i += 4)
                {
                    ExchangeVerts(tempVerts, vertsArr, i, offseti);
                }

                mesh.mesh.SetVertices(tempVerts, vertsc);
            }
        }
Exemple #9
0
    public unsafe static int PointerDefaultIndexOfThrows(List <int> list, int target)
    {
        var len = list.Count;

        fixed(int *p = NoAllocHelpers.ExtractArrayFromListT(list))
        for (int i = 0; i < len; i++)
        {
            if (i < 0 || i >= len)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (p[i] == target)
            {
                return(i);
            }
        }

        return(-1);
    }
Exemple #10
0
    // https://forum.unity.com/threads/nativearray-and-mesh.522951/
    // avoid having to call NativeList.ToArray() when assigning a Mesh attribute which results in garbage
    //  There seems some GCAllocs still happen, but CPU spikes seem to be improved alot
    // NOTE: that the buffer resizes up to the size of native, and does not shrink to avoid allocations -> Potential Memory Hog
    // TODO: This HACK will go away with the official support of NativeArrays / NativeLists? in https://forum.unity.com/threads/feedback-wanted-mesh-scripting-api-improvements.684670/
    static unsafe void assignNativeListToBuffer <TNative, T> (NativeList <TNative> native, ref List <T> buffer) where TNative : struct where T : struct
    {
        //Debug.Assert(buffer.Count == 0);
        Debug.Assert(UnsafeUtility.SizeOf <TNative>() == UnsafeUtility.SizeOf <T>());

        if (native.Length > 0)
        {
            if (buffer.Capacity < native.Length)
            {
                buffer.Capacity = native.Length;
            }

            var arr  = NoAllocHelpers.ExtractArrayFromListT(buffer);
            var size = UnsafeUtility.SizeOf <T>();

            var ptr = (byte *)UnsafeUtility.AddressOf(ref arr[0]);

            UnsafeUtility.MemCpy(ptr, native.GetUnsafePtr(), native.Length * (long)size);
        }
        NoAllocHelpers.ResizeList(buffer, native.Length);
    }
Exemple #11
0
    public static unsafe void CopyIntegers(NativeList <int> src, List <int> dst)
    {
        if (dst.Capacity < src.Length)
        {
            dst.Capacity = src.Length;
        }

        var array = NoAllocHelpers.ExtractArrayFromListT(dst);

        fixed(int *arrayPtr = array)
        {
            var dstSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <int>(arrayPtr, sizeof(int), src.Length);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref dstSlice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
#endif
            dstSlice.CopyFrom((NativeArray <int>)src);
        }

        NoAllocHelpers.ResizeList(dst, src.Length);
    }
    static unsafe void NativeAddRange <T>(this List <T> list, NativeSlice <T> nativeSlice) where T : struct
    {
        var index     = list.Count;
        var newLength = index + nativeSlice.Length;

        // Resize our list if we require
        if (list.Capacity < newLength)
        {
            list.Capacity = newLength;
        }

        var items = NoAllocHelpers.ExtractArrayFromListT(list);
        var size  = UnsafeUtility.SizeOf <T>();

        // Get the pointer to the end of the list
        var bufferStart = (IntPtr)UnsafeUtility.AddressOf(ref items[0]);
        var buffer      = (byte *)(bufferStart + (size * index));

        UnsafeUtility.MemCpy(buffer, nativeSlice.GetUnsafePtr(), nativeSlice.Length * (long)size);

        NoAllocHelpers.ResizeList(list, newLength);
    }
    private static GameObject CreateMesh(string ifcGuid, IFCObjectID ifcObjectData, MemoryMap map)
    {
        var dimensions = map.Dimensions;
        int offset     = 0;

        for (int i = 0; i < ifcObjectData.Voxel.Layer; i++)
        {
            offset += dimensions[i].x * dimensions[i].y * dimensions[i].z;
        }

        var begin = map.Contains[offset + ifcObjectData.Voxel.Index].Begin;

        var vertexInfo  = map.VerticesInfo[begin + ifcObjectData.Index].Vertex;
        var vertexCount = vertexInfo.End - vertexInfo.Begin;
        var indexInfo   = map.VerticesInfo[begin + ifcObjectData.Index].Indices;
        var indexCount  = indexInfo.End - indexInfo.Begin;

        Debug.Assert(indexCount > 0);

        var vertices = new List <Vector3>(vertexCount);

        NoAllocHelpers.ResizeList(vertices, vertexCount);
        fixed(Vector3 *p = NoAllocHelpers.ExtractArrayFromListT(vertices))
        {
            UnsafeUtility.MemCpy(p, &map.Vertices[vertexInfo.Begin], vertexCount * sizeof(Vector3));
        }

        var normals = new List <Vector3>(vertexCount);

        NoAllocHelpers.ResizeList(normals, vertexCount);
        fixed(Vector3 *p = NoAllocHelpers.ExtractArrayFromListT(normals))
        {
            UnsafeUtility.MemCpy(p, &map.Normals[vertexInfo.Begin], vertexCount * sizeof(Vector3));
        }

        var colors = new List <Color32>(vertexCount);

        NoAllocHelpers.ResizeList(colors, vertexCount);
        for (int i = 0; i < colors.Count; i++)
        {
            colors[i] = Color.magenta;
        }

        var indices = new List <int>(indexCount);

        NoAllocHelpers.ResizeList(indices, indexCount);
        fixed(int *p = NoAllocHelpers.ExtractArrayFromListT(indices))
        {
            UnsafeUtility.MemCpy(p, &map.Indices[indexInfo.Begin], indexCount * sizeof(int));
        }

        for (int i = 0; i < indices.Count; i++)
        {
            vertices[indices[i]] += normals[indices[i]] * 0.01f;
        }

        var mesh = new Mesh();

        mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        mesh.SetVertices(vertices);
        mesh.SetNormals(normals);
        mesh.SetColors(colors);
        mesh.SetTriangles(indices, 0);

        var go = GameObject.CreatePrimitive(PrimitiveType.Cube);

        go.name = ifcGuid;
        var filter = go.GetComponent <MeshFilter>();

        filter.mesh = mesh;

        var renderer = go.GetComponent <MeshRenderer>();

        renderer.material = Globals.Instance.data.OpaqueMaterial;

        return(go);
    }
Exemple #14
0
 public static T[] array <T>(this List <T> list)
 {
     return(NoAllocHelpers <T> .ExtractArrayFromListT(list));
 }
Exemple #15
0
        public static ref T refAt <T>(this List <T> list, int index)
        {
            var array = NoAllocHelpers <T> .ExtractArrayFromListT(list);

            return(ref array[index]);
        }