public void Dispose() { UnsafeUtility.Free(v1, Allocator.Persistent); UnsafeUtility.Free(v2, Allocator.Persistent); UnsafeUtility.Free(result, Allocator.Persistent); }
public static void Initialize() { if (s_Types != null) { return; } ObjectOffset = UnsafeUtility.SizeOf <ObjectOffsetType>(); #if !UNITY_CSHARP_TINY s_CreateTypeLock = new SpinLock(); s_ManagedTypeToIndex = new Dictionary <Type, int>(1000); #endif s_Types = new TypeInfo[MaximumTypesCount]; #if !UNITY_CSHARP_TINY s_StableTypeHashToTypeIndex = new Dictionary <ulong, int>(); #endif s_Count = 0; #if !UNITY_CSHARP_TINY s_Types[s_Count++] = new TypeInfo(null, 0, 0, TypeCategory.ComponentData, FastEquality.TypeInfo.Null, null, null, 0, -1, 0, 1, 0, null, 0, int.MaxValue); // This must always be first so that Entity is always index 0 in the archetype AddTypeInfoToTables(new TypeInfo(typeof(Entity), 1, sizeof(Entity), TypeCategory.EntityData, FastEquality.CreateTypeInfo <Entity>(), EntityRemapUtility.CalculateEntityOffsets <Entity>(), null, 0, -1, sizeof(Entity), UnsafeUtility.AlignOf <Entity>(), CalculateStableTypeHash(typeof(Entity)), null, 0, int.MaxValue)); InitializeAllComponentTypes(); #else StaticTypeRegistry.StaticTypeRegistry.RegisterStaticTypes(); #endif }
static void CalculatBlobAssetRefOffsetsRecurse(ref List <EntityOffsetInfo> offsets, Type type, int baseOffset) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(BlobAssetReference <>)) { offsets.Add(new EntityOffsetInfo { Offset = baseOffset }); } else { var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (var field in fields) { if (field.FieldType.IsValueType && !field.FieldType.IsPrimitive) { CalculatBlobAssetRefOffsetsRecurse(ref offsets, field.FieldType, baseOffset + UnsafeUtility.GetFieldOffset(field)); } } } }
/// <summary> /// Create an empty hash set with a given capacity /// </summary> /// /// <param name="capacity"> /// Capacity of the hash set. If less than four, four is used. /// </param> /// /// <param name="allocator"> /// Allocator to allocate unmanaged memory with. Must be valid. /// </param> public NativeHashSet(int capacity, Allocator allocator) { // Require a valid allocator if (allocator <= Allocator.None) { throw new ArgumentException( "Allocator must be Temp, TempJob or Persistent", "allocator"); } RequireBlittable(); // Insist on a minimum capacity if (capacity < 4) { capacity = 4; } m_Allocator = allocator; // Allocate the state NativeHashSetState *state = (NativeHashSetState *)UnsafeUtility.Malloc( sizeof(NativeHashSetState), UnsafeUtility.AlignOf <NativeHashSetState>(), allocator); state->ItemCapacity = capacity; // To reduce collisions, use twice as many buckets int bucketLength = capacity * 2; bucketLength = NextHigherPowerOfTwo(bucketLength); state->BucketCapacityMask = bucketLength - 1; // Allocate state arrays int nextOffset; int bucketOffset; int totalSize = CalculateDataLayout( capacity, bucketLength, out nextOffset, out bucketOffset); state->Items = (byte *)UnsafeUtility.Malloc( totalSize, JobsUtility.CacheLineSize, allocator); state->Next = state->Items + nextOffset; state->Buckets = state->Items + bucketOffset; m_State = state; #if ENABLE_UNITY_COLLECTIONS_CHECKS #if UNITY_2018_3_OR_NEWER DisposeSentinel.Create( out m_Safety, out m_DisposeSentinel, 1, allocator); #else DisposeSentinel.Create( out m_Safety, out m_DisposeSentinel, 1); #endif #endif Clear(); }
/// <summary> /// Reallocate to grow the capacity of the set /// </summary> /// /// <param name="newCapacity"> /// Capacity to grow to. Must be larger than the current capacity. /// </param> private void Reallocate(int newCapacity) { int newBucketCapacity = newCapacity * 2; newBucketCapacity = NextHigherPowerOfTwo(newBucketCapacity); // No change in capacity if (m_State->ItemCapacity == newCapacity && m_State->BucketCapacityMask + 1 == newBucketCapacity) { return; } // Can't shrink if (newCapacity < m_State->ItemCapacity) { throw new Exception("NativeHashSet<T> can't shrink"); } // Allocate new data int nextOffset; int bucketOffset; int totalSize = CalculateDataLayout( newCapacity, newBucketCapacity, out nextOffset, out bucketOffset); byte *newData = (byte *)UnsafeUtility.Malloc( totalSize, JobsUtility.CacheLineSize, m_Allocator); byte *newItems = newData; byte *newNext = newData + nextOffset; byte *newBuckets = newData + bucketOffset; // The items are taken from a free-list and might not be tightly // packed, copy all of the old capacity UnsafeUtility.MemCpy( newItems, m_State->Items, m_State->ItemCapacity * UnsafeUtility.SizeOf <T>()); UnsafeUtility.MemCpy( newNext, m_State->Next, m_State->ItemCapacity * UnsafeUtility.SizeOf <int>()); for ( int emptyNext = m_State->ItemCapacity; emptyNext < newCapacity; ++emptyNext) { ((int *)newNext)[emptyNext] = -1; } // Re-hash the buckets, first clear the new bucket list, then insert // all values from the old list for (int bucket = 0; bucket < newBucketCapacity; ++bucket) { ((int *)newBuckets)[bucket] = -1; } for (int bucket = 0; bucket <= m_State->BucketCapacityMask; ++bucket) { int *buckets = (int *)m_State->Buckets; int *nextPtrs = (int *)newNext; while (buckets[bucket] >= 0) { int curEntry = buckets[bucket]; buckets[bucket] = nextPtrs[curEntry]; int newBucket = UnsafeUtility.ReadArrayElement <T>( m_State->Items, curEntry).GetHashCode() & (newBucketCapacity - 1); nextPtrs[curEntry] = ((int *)newBuckets)[newBucket]; ((int *)newBuckets)[newBucket] = curEntry; } } // Free the old state contents UnsafeUtility.Free(m_State->Items, m_Allocator); // Set the new state contents if (m_State->AllocatedIndexLength > m_State->ItemCapacity) { m_State->AllocatedIndexLength = m_State->ItemCapacity; } m_State->Items = newData; m_State->Next = newNext; m_State->Buckets = newBuckets; m_State->ItemCapacity = newCapacity; m_State->BucketCapacityMask = newBucketCapacity - 1; }
/// <inheritdoc /> public override unsafe void WriteValueIntoState(TouchState value, void *statePtr) { var valuePtr = (TouchState *)((byte *)statePtr + (int)m_StateBlock.byteOffset); UnsafeUtility.MemCpy(valuePtr, UnsafeUtility.AddressOf(ref value), UnsafeUtility.SizeOf <TouchState>()); }
public static unsafe int GrowBy <TValue>(ref NativeArray <TValue> array, int count, Allocator allocator = Allocator.Persistent) where TValue : struct { var length = array.Length; if (length == 0) { array = new NativeArray <TValue>(count, allocator); return(0); } var newArray = new NativeArray <TValue>(length + count, allocator); // CopyFrom() expects length to match. Copy manually. UnsafeUtility.MemCpy(newArray.GetUnsafePtr(), array.GetUnsafeReadOnlyPtr(), (long)length * UnsafeUtility.SizeOf <TValue>()); array.Dispose(); array = newArray; return(length); }
static void CopyArrayToBuffer <T>(DynamicBuffer <T> buffer, void *source, int length, int sizeOfT) where T : struct { buffer.ResizeUninitialized(length); UnsafeUtility.MemCpy(buffer.GetUnsafePtr(), source, length * sizeOfT); }
public static unsafe void *ConstructRootPtr <T>(this BlobBuilder builder) where T : struct { return(UnsafeUtility.AddressOf(ref builder.ConstructRoot <T>())); }
public void Dispose() { UnsafeUtility.Free(m1, Allocator.Persistent); }
static unsafe void ReadEtlFile(string etlPath, IEnumerable <string> pdbWhitelist, out ProfilerTrace profTrace, Allocator allocator) { var monoFunctions = new Dictionary <IntPtr, MonoJitInfo>(); var discoveredModules = DiscoveredData <DiscoveredModule> .Make(DiscoveredModule.Invalid); var discoveredStackFrames = DiscoveredData <CallStackIndex> .Make(CallStackIndex.Invalid); var discoveredFunctions = DiscoveredData <DiscoveredFunction> .Make(DiscoveredFunction.Invalid); var discoveredThreads = DiscoveredData <ThreadIndex> .Make(ThreadIndex.Invalid); var options = new TraceLogOptions() { AlwaysResolveSymbols = true, LocalSymbolsOnly = false, AllowUnsafeSymbols = true, #if UNITY_EDITOR AdditionalSymbolPath = Path.GetDirectoryName(EditorApplication.applicationPath), #endif ShouldResolveSymbols = path => { path = path.ToLowerInvariant(); return(pdbWhitelist.Any(x => path.EndsWith(x))); } }; profTrace = new ProfilerTrace(); using (var trace = TraceLog.OpenOrConvert(etlPath, options)) { var processIndex = FindUnityProcessIndex(trace.Processes); var processId = trace.Processes[processIndex].ProcessID; profTrace.Header = new ProfilerTraceHeader { SamplingInterval = trace.SampleProfileInterval.TotalMilliseconds, SessionStart = trace.SessionStartTime.Ticks, SessionEnd = trace.SessionEndTime.Ticks, }; using (var samples = new NativeList <SampleData>(Allocator.Temp)) { SampleData sampleData = default; foreach (var evt in trace.Events) { var sample = evt as SampledProfileTraceData; if (sample == null || sample.ProcessID != processId) { continue; } sampleData.Address = (long)sample.InstructionPointer; sampleData.ThreadIdx = discoveredThreads.AddData(sample.Thread()?.ThreadIndex ?? ThreadIndex.Invalid); sampleData.TimeStamp = sample.TimeStampRelativeMSec; sampleData.StackTrace = discoveredStackFrames.AddData(sample.CallStackIndex()); var codeAddress = sample.IntructionPointerCodeAddress(); sampleData.Function = GetFunctionIndex(codeAddress); samples.Add(sampleData); } profTrace.Samples = samples.ToArray(allocator); } using (var stackFrames = new NativeList <StackFrameData>(Allocator.Temp)) { StackFrameData stackTraceData = default; // N.B. this loop adds more stack frames as it executes for (int idx = 0; idx < discoveredStackFrames.Count; idx++) { var stack = trace.CallStacks[discoveredStackFrames.Data[idx]]; stackTraceData.Address = (long)stack.CodeAddress.Address; stackTraceData.Depth = stack.Depth; stackTraceData.CallerStackFrame = discoveredStackFrames.AddData(stack.Caller?.CallStackIndex ?? CallStackIndex.Invalid); stackTraceData.Function = GetFunctionIndex(stack.CodeAddress); stackFrames.Add(stackTraceData); } profTrace.StackFrames = stackFrames.ToArray(allocator); } using (var functions = new NativeList <FunctionData>(Allocator.Temp)) { FunctionData funcData = default; foreach (var func in discoveredFunctions.Data) { if (func.Index != MethodIndex.Invalid) { var method = trace.CodeAddresses.Methods[func.Index]; if (method.MethodRva > 0 && method.MethodModuleFile != null) { funcData.BaseAddress = method.MethodModuleFile.ImageBase + (ulong)method.MethodRva; } else { funcData.BaseAddress = 0; } funcData.Length = -1; funcData.Module = discoveredModules.AddData(DiscoveredModule.FromIndex(method.MethodModuleFileIndex)); funcData.Name.CopyFrom(method.FullMethodName); } else { var jitData = func.MonoMethod; funcData.BaseAddress = (ulong)jitData.CodeStart.ToInt64(); funcData.Length = jitData.CodeSize; funcData.Module = discoveredModules.AddData(DiscoveredModule.FromMonoModule(jitData.Method.Module)); var fullName = MonoFunctionName(jitData.Method); funcData.Name.CopyFrom(fullName); } functions.Add(funcData); } profTrace.Functions = functions.ToArray(allocator); } using (var modules = new NativeList <ModuleData>(Allocator.Temp)) { // make sure that all modules of the current process are included. foreach (var module in trace.Processes[processIndex].LoadedModules) { discoveredModules.AddData(new DiscoveredModule { Index = module.ModuleFile.ModuleFileIndex }); } ModuleData moduleData = default; foreach (var dm in discoveredModules.Data) { if (dm.MonoModule != null) { moduleData = default; moduleData.IsMono = true; moduleData.FilePath = dm.MonoModule.Assembly.Location; } else { var module = trace.ModuleFiles[dm.Index]; moduleData.IsMono = false; moduleData.Checksum = module.ImageChecksum; moduleData.ImageBase = module.ImageBase; moduleData.ImageEnd = module.ImageEnd; moduleData.PdbAge = module.PdbAge; moduleData.FilePath.CopyFrom(module.FilePath); moduleData.PdbName.CopyFrom(module.PdbName); var guidBytes = module.PdbSignature.ToByteArray(); fixed(byte *ptr = guidBytes) UnsafeUtility.MemCpy(moduleData.PdbGuid, ptr, 16); } modules.Add(moduleData); } profTrace.Modules = modules.ToArray(allocator); } using (var threads = new NativeList <ThreadData>(Allocator.Temp)) { ThreadData threadData = default; foreach (var t in discoveredThreads.Data) { var thread = trace.Threads[t]; threadData.ThreadName.CopyFrom(thread.ThreadInfo ?? ""); threads.Add(threadData); } profTrace.Threads = threads.ToArray(allocator); } } int GetFunctionIndex(TraceCodeAddress address) { var method = address.Method; if (method == null) { var jit = Mono.GetJitInfoAnyDomain(new IntPtr((long)address.Address), out _); if (jit.Method == null) { return(-1); } if (!monoFunctions.TryGetValue(jit.CodeStart, out var actualJit)) { monoFunctions.Add(jit.CodeStart, jit); actualJit = jit; } return(discoveredFunctions.AddData(DiscoveredFunction.FromMethod(actualJit))); } return(discoveredFunctions.AddData(new DiscoveredFunction { Index = method.MethodIndex })); } string MonoFunctionName(MethodBase method) { if (method == null) { return("???"); } if (method.DeclaringType.DeclaringType == null) { return(method.DeclaringType.Namespace + '.' + method.DeclaringType.Name + '.' + method.Name); } var outerMost = method.DeclaringType.DeclaringType; var outer = method.DeclaringType; return(outerMost.Namespace + '.' + outerMost.Name + '+' + outer.Name + '.' + method.Name); } }
public void Init() { m1 = (float4x4 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float4x4>() * 10000, UnsafeUtility.AlignOf <float4x4>(), Allocator.Persistent); for (int i = 0; i < 10000; ++i) { m1[i] = float4x4.identity; } }
public static void Run <T>(this T jobData, int arrayLength) where T : struct, IJobFor { JobsUtility.JobScheduleParameters jobScheduleParameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf <T>(ref jobData), IJobForExtensions.ForJobStruct <T> .Initialize(), default(JobHandle), ScheduleMode.Run); JobsUtility.ScheduleParallelFor(ref jobScheduleParameters, arrayLength, arrayLength); }
public static JobHandle ScheduleParallel <T>(this T jobData, int arrayLength, int innerloopBatchCount, JobHandle dependency) where T : struct, IJobFor { JobsUtility.JobScheduleParameters jobScheduleParameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf <T>(ref jobData), IJobForExtensions.ForJobStruct <T> .Initialize(), dependency, ScheduleMode.Batched); return(JobsUtility.ScheduleParallelFor(ref jobScheduleParameters, arrayLength, innerloopBatchCount)); }
unsafe static NativeArray <T> ArraySlice <T>(NativeArray <T> array, int startIndex, int count) where T : struct { var ptr = (byte *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(array); var sliced = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(ptr + startIndex * UnsafeUtility.SizeOf <T>(), count, Allocator.Invalid); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref sliced, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array)); return(sliced); }
public override void FrameUpdate(PipelineCamera cam, ref PipelineCommandData data) { PipelineBaseBuffer baseBuffer; if (!SceneController.current.GetBaseBufferAndCheck(out baseBuffer)) { return; } CommandBuffer buffer = data.buffer; cullJobHandler.Complete(); UnsafeUtility.ReleaseGCObject(gcHandler); pointLightMaterial.SetBuffer(ShaderIDs.verticesBuffer, sphereBuffer); //Un Shadow Point light buffer.SetRenderTarget(cam.targets.renderTargetIdentifier, cam.targets.depthIdentifier); for (int c = 0; c < unShadowCount; c++) { var i = cullJob.indices[cullJob.length - c]; MPointLight light = MPointLight.allPointLights[i]; buffer.SetGlobalVector(ShaderIDs._LightColor, light.color); buffer.SetGlobalVector(ShaderIDs._LightPos, new Vector4(light.position.x, light.position.y, light.position.z, light.range)); buffer.SetGlobalFloat(ShaderIDs._LightIntensity, light.intensity); buffer.DrawProceduralIndirect(Matrix4x4.identity, pointLightMaterial, 0, MeshTopology.Triangles, sphereIndirectBuffer, 0); } //TODO if (shadowCount > 0) { NativeArray <Vector4> positions = new NativeArray <Vector4>(shadowCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); for (int i = 0; i < shadowCount; i++) { MPointLight light = MPointLight.allPointLights[cullJob.indices[i]]; positions[i] = new Vector4(light.position.x, light.position.y, light.position.z, light.range); } CubeFunction.UpdateLength(ref cubeBuffer, shadowCount); var cullShader = data.resources.pointLightFrustumCulling; CubeFunction.UpdateData(ref cubeBuffer, baseBuffer, cullShader, buffer, positions); RenderClusterOptions opts = new RenderClusterOptions { cullingShader = cullShader, proceduralMaterial = cubeDepthMaterial, command = buffer, frustumPlanes = null, isOrtho = false }; for (int i = 0; i < shadowCount; i++) { MPointLight light = MPointLight.allPointLights[cullJob.indices[i]]; SceneController.current.DrawCubeMap(light, ref opts, ref cubeBuffer, i); buffer.SetRenderTarget(cam.targets.renderTargetIdentifier, cam.targets.depthIdentifier); buffer.SetGlobalVector(ShaderIDs._LightColor, light.color); buffer.SetGlobalVector(ShaderIDs._LightPos, positions[i]); buffer.SetGlobalFloat(ShaderIDs._LightIntensity, light.intensity); buffer.SetGlobalTexture(ShaderIDs._CubeShadowMap, light.shadowmapTexture); buffer.DrawProceduralIndirect(Matrix4x4.identity, pointLightMaterial, 1, MeshTopology.Triangles, sphereIndirectBuffer, 0); } positions.Dispose(); } //Shadow Point Light indicesArray.Dispose(); data.ExecuteCommandBuffer(); }
public VStringNativeWrapper(string aStr) { m_Ptr = (char *)(((byte *)UnsafeUtility.PinGCObjectAndGetAddress(aStr, out m_Handle)) + m_CharPtrOffset); m_Length = aStr.Length; }
public BlobAssetReference <T> CreateBlobAssetReference <T>(Allocator allocator) where T : struct { Assert.AreEqual(16, sizeof(BlobAssetHeader)); NativeArray <int> offsets = new NativeArray <int>(m_allocations.Length + 1, m_allocator); var sortedAllocs = new NativeArray <SortedIndex>(m_allocations.Length, m_allocator); offsets[0] = 0; for (int i = 0; i < m_allocations.Length; ++i) { offsets[i + 1] = offsets[i] + m_allocations[i].size; sortedAllocs[i] = new SortedIndex { p = m_allocations[i].p, index = i }; } int dataSize = offsets[m_allocations.Length]; sortedAllocs.Sort(); var sortedPatches = new NativeArray <SortedIndex>(m_patches.Length, m_allocator); for (int i = 0; i < m_patches.Length; ++i) { sortedPatches[i] = new SortedIndex { p = (byte *)m_patches[i].offsetPtr, index = i } } ; sortedPatches.Sort(); byte *buffer = (byte *)UnsafeUtility.Malloc(sizeof(BlobAssetHeader) + dataSize, 16, allocator); byte *data = buffer + sizeof(BlobAssetHeader); for (int i = 0; i < m_allocations.Length; ++i) { UnsafeUtility.MemCpy(data + offsets[i], m_allocations[i].p, m_allocations[i].size); } int iAlloc = 0; var allocStart = m_allocations[sortedAllocs[0].index].p; var allocEnd = allocStart + m_allocations[sortedAllocs[0].index].size; for (int i = 0; i < m_patches.Length; ++i) { int patchIndex = sortedPatches[i].index; int *offsetPtr = (int *)sortedPatches[i].p; while (offsetPtr > allocEnd) { ++iAlloc; allocStart = m_allocations[sortedAllocs[iAlloc].index].p; allocEnd = allocStart + m_allocations[sortedAllocs[iAlloc].index].size; } var patch = m_patches[patchIndex]; int offsetPtrInData = offsets[sortedAllocs[iAlloc].index] + (int)((byte *)offsetPtr - allocStart); int targetPtrInData = offsets[patch.target.allocIndex] + patch.target.offset; *(int *)(data + offsetPtrInData) = targetPtrInData - offsetPtrInData; if (patch.length != 0) { *(int *)(data + offsetPtrInData + 4) = patch.length; } } sortedPatches.Dispose(); sortedAllocs.Dispose(); BlobAssetHeader *header = (BlobAssetHeader *)buffer; *header = new BlobAssetHeader(); header->Length = (int)dataSize; header->Allocator = allocator; BlobAssetReference <T> blobAssetReference; header->ValidationPtr = blobAssetReference.m_data.m_Ptr = buffer + sizeof(BlobAssetHeader); return(blobAssetReference); }
public static unsafe long DeviceCommand <TCommand>(this IInputRuntime runtime, int deviceId, ref TCommand command) where TCommand : struct, IInputDeviceCommandInfo { return(runtime.DeviceCommand(deviceId, (InputDeviceCommand *)UnsafeUtility.AddressOf(ref command))); }
public ref T ConstructRoot <T>() where T : struct { var allocation = Allocate(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>()); return(ref UnsafeUtilityEx.AsRef <T>(AllocationToPointer(allocation))); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { var commandBuffer = barrier.CreateCommandBuffer().ToConcurrent(); var parentFromEntity = GetComponentDataFromEntity <Parent>(true); var localToWorldFromEntity = GetComponentDataFromEntity <LocalToWorld>(true); var jumpingFromEntity = GetComponentDataFromEntity <NavJumping>(true); var avoidantFromEntity = GetComponentDataFromEntity <NavAvoidant>(true); var pathBufferFromEntity = GetBufferFromEntity <NavPathBufferElement>(); var jumpBufferFromEntity = GetBufferFromEntity <NavJumpBufferElement>(); var navMeshQueryPointerArray = World.GetExistingSystem <NavMeshQuerySystem>().PointerArray; var job = Entities .WithAll <NavPlanning, Parent, LocalToParent>() .WithReadOnly(parentFromEntity) .WithReadOnly(localToWorldFromEntity) .WithReadOnly(jumpingFromEntity) .WithReadOnly(avoidantFromEntity) .WithNativeDisableParallelForRestriction(pathBufferFromEntity) .WithNativeDisableParallelForRestriction(jumpBufferFromEntity) .WithNativeDisableParallelForRestriction(navMeshQueryPointerArray) .ForEach((Entity entity, int entityInQueryIndex, int nativeThreadIndex, ref NavAgent agent) => { if (agent.Surface.Equals(Entity.Null)) { return; } var parent = parentFromEntity[agent.Surface].Value; if (!agent.DestinationSurface.Equals(Entity.Null)) { var destinationTransform = localToWorldFromEntity[agent.DestinationSurface].Value; agent.WorldDestination = NavUtil.MultiplyPoint3x4(destinationTransform, agent.LocalDestination); } var childTransform = localToWorldFromEntity[entity]; var parentTransform = localToWorldFromEntity[parent]; var worldPosition = childTransform.Position; var avoidant = avoidantFromEntity.Exists(entity); var worldDestination = avoidant ? (Vector3)agent.AvoidanceDestination : (Vector3)agent.WorldDestination; var jumping = jumpingFromEntity.Exists(entity); if (jumping) { worldPosition = agent.WorldDestination; worldDestination = childTransform.Position; } var navMeshQueryPointer = navMeshQueryPointerArray[nativeThreadIndex]; UnsafeUtility.CopyPtrToStructure(navMeshQueryPointer.Value, out NavMeshQuery navMeshQuery); var status = navMeshQuery.BeginFindPath( navMeshQuery.MapLocation(worldPosition, Vector3.one * NavConstants.PATH_SEARCH_MAX, agent.TypeID), navMeshQuery.MapLocation(worldDestination, Vector3.one * NavConstants.PATH_SEARCH_MAX, agent.TypeID), NavMesh.AllAreas ); while (status == PathQueryStatus.InProgress) { status = navMeshQuery.UpdateFindPath( NavConstants.ITERATION_MAX, out int iterationsPerformed ); } if (status != PathQueryStatus.Success) { return; } navMeshQuery.EndFindPath(out int pathLength); var polygonIdArray = new NativeArray <PolygonId>( NavConstants.PATH_NODE_MAX, Allocator.Temp ); navMeshQuery.GetPathResult(polygonIdArray); var len = pathLength + 1; var straightPath = new NativeArray <NavMeshLocation>(len, Allocator.Temp); var straightPathFlags = new NativeArray <StraightPathFlags>(len, Allocator.Temp); var vertexSide = new NativeArray <float>(len, Allocator.Temp); var straightPathCount = 0; status = PathUtils.FindStraightPath( navMeshQuery, worldPosition, worldDestination, polygonIdArray, pathLength, ref straightPath, ref straightPathFlags, ref vertexSide, ref straightPathCount, NavConstants.PATH_NODE_MAX ); var jumpBuffer = !jumpBufferFromEntity.Exists(entity) ? commandBuffer.AddBuffer <NavJumpBufferElement>(entityInQueryIndex, entity) : jumpBufferFromEntity[entity]; var pathBuffer = !pathBufferFromEntity.Exists(entity) ? commandBuffer.AddBuffer <NavPathBufferElement>(entityInQueryIndex, entity) : pathBufferFromEntity[entity]; if (jumping) { var lastValidPoint = float3.zero; for (int j = 0; j < straightPath.Length; ++j) { if (navMeshQuery.IsValid(straightPath[j].polygon)) { lastValidPoint = straightPath[j].position; } else { break; } } jumpBuffer.Add(NavUtil.MultiplyPoint3x4( math.inverse(parentTransform.Value), (float3)lastValidPoint + agent.Offset )); if (jumpBuffer.Length > 0) { commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity); commandBuffer.AddComponent <NavLerping>(entityInQueryIndex, entity); } } else if (status == PathQueryStatus.Success) { pathBuffer.Clear(); for (int j = 0; j < straightPathCount; ++j) { pathBuffer.Add(NavUtil.MultiplyPoint3x4( math.inverse(parentTransform.Value), (float3)straightPath[j].position + agent.Offset )); } if (pathBuffer.Length > 0) { commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity); commandBuffer.AddComponent <NavLerping>(entityInQueryIndex, entity); } } polygonIdArray.Dispose(); straightPath.Dispose(); straightPathFlags.Dispose(); vertexSide.Dispose(); }) .WithName("NavPlanJob") .Schedule(inputDeps); NavMeshWorld.GetDefaultWorld().AddDependency(job); barrier.AddJobHandleForProducer(job); return(job); }
/// <summary> /// Adds elements from a buffer to this list. /// </summary> /// <typeparam name="T">Source type of elements</typeparam> /// <param name="ptr">A pointer to the buffer.</param> /// <param name="length">The number of elements to add to the list.</param> /// <remarks> /// If the list has reached its current capacity, internal array won't be resized, and exception will be thrown. /// </remarks> public void AddRangeNoResize(void *ptr, int length) { AddRangeNoResize(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), ptr, length); }
/// <summary> /// Try to add an item to the set. /// /// This operation requires write access. /// </summary> /// /// <param name="item"> /// Item to add /// </param> /// /// <returns> /// If the item was added to the set. This is false only if the item was /// already in the set.</returns> public bool TryAdd(T item) { RequireWriteAccess(); NativeMultiHashSetIterator tempIt; if (TryGetFirstValueAtomic(m_State, item, out tempIt)) { return(false); } // Allocate an entry from the free list int idx; int *nextPtrs; if (m_State->AllocatedIndexLength >= m_State->ItemCapacity && m_State->FirstFreeTLS[0] < 0) { for (int tls = 1; tls < JobsUtility.MaxJobThreadCount; ++tls) { if (m_State->FirstFreeTLS[tls * NativeHashSetState.IntsPerCacheLine] >= 0) { idx = m_State->FirstFreeTLS[tls * NativeHashSetState.IntsPerCacheLine]; nextPtrs = (int *)m_State->Next; m_State->FirstFreeTLS[tls * NativeHashSetState.IntsPerCacheLine] = nextPtrs[idx]; nextPtrs[idx] = -1; m_State->FirstFreeTLS[0] = idx; break; } } if (m_State->FirstFreeTLS[0] < 0) { int capacity = m_State->ItemCapacity; int newCapacity = capacity == 0 ? 1 : capacity * 2; Reallocate(newCapacity); } } idx = m_State->FirstFreeTLS[0]; if (idx >= 0) { m_State->FirstFreeTLS[0] = ((int *)m_State->Next)[idx]; } else { idx = m_State->AllocatedIndexLength++; } // Write the new value to the entry UnsafeUtility.WriteArrayElement(m_State->Items, idx, item); int bucket = item.GetHashCode() & m_State->BucketCapacityMask; // Add the index to the hash-set int *buckets = (int *)m_State->Buckets; nextPtrs = (int *)m_State->Next; nextPtrs[idx] = buckets[bucket]; buckets[bucket] = idx; return(true); }
/// <summary> /// Adds elements from a list to this list. /// </summary> /// <typeparam name="T">Source type of elements</typeparam> /// <remarks> /// If the list has reached its current capacity, internal array won't be resized, and exception will be thrown. /// </remarks> public void AddRangeNoResize(UnsafeList list) { AddRangeNoResize(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), list.Ptr, list.Length); }
public void ReadBytes(void *data, int bytes) { UnsafeUtility.MemCpy(data, (byte *)content.GetUnsafePtr() + position, bytes); position += bytes; }
public override unsafe int GetHashCode() { unchecked { return((int)math.hash( new uint3(polygons.Length == 0 ? 0 : math.hash(polygons.GetUnsafePtr(), UnsafeUtility.SizeOf <Polygon>() * polygons.Length), localVertices.Length == 0 ? 0 : math.hash(localVertices.GetUnsafePtr(), UnsafeUtility.SizeOf <float3>() * localVertices.Length), halfEdges.Length == 0 ? 0 : math.hash(halfEdges.GetUnsafePtr(), UnsafeUtility.SizeOf <HalfEdge>() * halfEdges.Length)))); } }
static void InitializeAllComponentTypes() { var componentTypeSet = new HashSet <Type>(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!IsAssemblyReferencingEntities(assembly)) { continue; } foreach (var type in assembly.GetTypes()) { if (type.IsAbstract || !type.IsValueType) { continue; } if (!UnsafeUtility.IsUnmanaged(type)) { continue; } if (typeof(IComponentData).IsAssignableFrom(type) || typeof(ISharedComponentData).IsAssignableFrom(type) || typeof(IBufferElementData).IsAssignableFrom(type)) { componentTypeSet.Add(type); } } } var lockTaken = false; try { s_CreateTypeLock.Enter(ref lockTaken); var componentTypeCount = componentTypeSet.Count; var componentTypes = new Type[componentTypeCount]; componentTypeSet.CopyTo(componentTypes); var typeIndexByType = new Dictionary <Type, int>(); var writeGroupByType = new Dictionary <int, HashSet <int> >(); var startTypeIndex = s_Count; for (int i = 0; i < componentTypes.Length; i++) { typeIndexByType[componentTypes[i]] = startTypeIndex + i; } GatherWriteGroups(componentTypes, startTypeIndex, typeIndexByType, writeGroupByType); AddAllComponentTypes(componentTypes, startTypeIndex, writeGroupByType); } finally { if (lockTaken) { s_CreateTypeLock.Exit(true); } } }
public static unsafe void Execute(ref JobNativeMultiHashMapMergedSharedKeyIndicesProducer <TJob> jobProducer, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { while (true) { int begin; int end; if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out begin, out end)) { return; } var bucketData = jobProducer.HashMap.GetUnsafeBucketData(); var buckets = (int *)bucketData.buckets; var nextPtrs = (int *)bucketData.next; var keys = bucketData.keys; var values = bucketData.values; for (int i = begin; i < end; i++) { int entryIndex = buckets[i]; while (entryIndex != -1) { var key = UnsafeUtility.ReadArrayElement <int>(keys, entryIndex); var value = UnsafeUtility.ReadArrayElement <int>(values, entryIndex); int firstValue; NativeParallelMultiHashMapIterator <int> it; jobProducer.HashMap.TryGetFirstValue(key, out firstValue, out it); // [macton] Didn't expect a usecase for this with multiple same values // (since it's intended use was for unique indices.) // https://forum.unity.com/threads/ijobnativemultihashmapmergedsharedkeyindices-unexpected-behavior.569107/#post-3788170 if (entryIndex == it.GetEntryIndex()) { #if ENABLE_UNITY_COLLECTIONS_CHECKS JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf(ref jobProducer), value, 1); #endif jobProducer.JobData.ExecuteFirst(value); } else { #if ENABLE_UNITY_COLLECTIONS_CHECKS var startIndex = math.min(firstValue, value); var lastIndex = math.max(firstValue, value); var rangeLength = (lastIndex - startIndex) + 1; JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf(ref jobProducer), startIndex, rangeLength); #endif jobProducer.JobData.ExecuteNext(firstValue, value); } entryIndex = nextPtrs[entryIndex]; } } } }
internal static TypeInfo BuildComponentType(Type type, int *writeGroups, int writeGroupCount) { var componentSize = 0; TypeCategory category; var typeInfo = FastEquality.TypeInfo.Null; EntityOffsetInfo[] entityOffsets = null; EntityOffsetInfo[] blobAssetRefOffsets = null; int bufferCapacity = -1; var memoryOrdering = CalculateMemoryOrdering(type); var stableTypeHash = CalculateStableTypeHash(type); var maxChunkCapacity = int.MaxValue; var maxCapacityAttribute = type.GetCustomAttribute <MaximumChunkCapacityAttribute>(); if (maxCapacityAttribute != null) { maxChunkCapacity = maxCapacityAttribute.Capacity; } int elementSize = 0; int alignmentInBytes = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.IsInterface) { throw new ArgumentException($"{type} is an interface. It must be a concrete type."); } #endif if (typeof(IComponentData).IsAssignableFrom(type)) { CheckIsAllowedAsComponentData(type, nameof(IComponentData)); category = TypeCategory.ComponentData; if (TypeManager.IsZeroSizeStruct(type)) { componentSize = 0; } else { componentSize = UnsafeUtility.SizeOf(type); } typeInfo = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); blobAssetRefOffsets = CalculatBlobAssetRefOffsets(type); int sizeInBytes = UnsafeUtility.SizeOf(type); // TODO: Implement UnsafeUtility.AlignOf(type) alignmentInBytes = 16; if (sizeInBytes < 16 && (sizeInBytes & (sizeInBytes - 1)) == 0) { alignmentInBytes = sizeInBytes; } } else if (typeof(IBufferElementData).IsAssignableFrom(type)) { CheckIsAllowedAsComponentData(type, nameof(IBufferElementData)); category = TypeCategory.BufferData; elementSize = UnsafeUtility.SizeOf(type); var capacityAttribute = (InternalBufferCapacityAttribute)type.GetCustomAttribute(typeof(InternalBufferCapacityAttribute)); if (capacityAttribute != null) { bufferCapacity = capacityAttribute.Capacity; } else { bufferCapacity = 128 / elementSize; // Rather than 2*cachelinesize, to make it cross platform deterministic } componentSize = sizeof(BufferHeader) + bufferCapacity * elementSize; typeInfo = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); blobAssetRefOffsets = CalculatBlobAssetRefOffsets(type); int sizeInBytes = UnsafeUtility.SizeOf(type); // TODO: Implement UnsafeUtility.AlignOf(type) alignmentInBytes = 16; if (sizeInBytes < 16 && (sizeInBytes & (sizeInBytes - 1)) == 0) { alignmentInBytes = sizeInBytes; } } else if (typeof(ISharedComponentData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!type.IsValueType) { throw new ArgumentException($"{type} is an ISharedComponentData, and thus must be a struct."); } #endif entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); category = TypeCategory.ISharedComponentData; typeInfo = FastEquality.CreateTypeInfo(type); } else if (type.IsClass) { category = TypeCategory.Class; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.FullName == "Unity.Entities.GameObjectEntity") { throw new ArgumentException( "GameObjectEntity cannot be used from EntityManager. The component is ignored when creating entities for a GameObject."); } if (UnityEngineComponentType == null) { throw new ArgumentException( $"{type} cannot be used from EntityManager. If it inherits UnityEngine.Component, you must first register TypeManager.UnityEngineComponentType or include the Unity.Entities.Hybrid assembly in your build."); } if (!UnityEngineComponentType.IsAssignableFrom(type)) { throw new ArgumentException($"{type} must inherit {UnityEngineComponentType}."); } #endif } else { throw new ArgumentException($"{type} is not a valid component."); } #if ENABLE_UNITY_COLLECTIONS_CHECKS CheckComponentType(type); #endif int typeIndex = s_Count; return(new TypeInfo(type, typeIndex, componentSize, category, typeInfo, entityOffsets, blobAssetRefOffsets, memoryOrdering, bufferCapacity, elementSize > 0 ? elementSize : componentSize, alignmentInBytes, stableTypeHash, writeGroups, writeGroupCount, maxChunkCapacity)); }
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); } }