private void ConvertCompoundColliders() { Profiler.BeginSample("ConvertCompoundColliders"); m_nativeColliders = new NativeList <Collider>(128, Allocator.TempJob); m_nativeTransforms = new NativeList <RigidTransform>(128, Allocator.TempJob); m_compoundRanges = new NativeList <int2>(128, Allocator.TempJob); //Step 1: Find all colliders and construct parallel arrays m_authorings.Clear(); Entities.WithNone <DontConvertColliderTag>().ForEach((LatiosColliderAuthoring colliderAuthoring) => { //Do stuff if (colliderAuthoring.colliderType == AuthoringColliderTypes.None) { return; } if (colliderAuthoring.generateFromChildren) { m_unityColliders.Clear(); colliderAuthoring.GetComponentsInChildren(m_unityColliders); try { CreateChildrenColliders(colliderAuthoring, m_unityColliders, m_nativeColliders, m_nativeTransforms, m_compoundRanges); } catch (Exception e) { DisposeAndThrow(e); } } else { try { CreateChildrenColliders(colliderAuthoring, colliderAuthoring.colliders, m_nativeColliders, m_nativeTransforms, m_compoundRanges); } catch (Exception e) { DisposeAndThrow(e); } } m_authorings.Add(colliderAuthoring); }); if (m_authorings.Count > 0) { using (var computationContext = new BlobAssetComputationContext <CompoundColliderComputationData, CompoundColliderBlob>(BlobAssetStore, 128, Allocator.Temp)) { //Step 2: Compute hashes var hashes = new NativeArray <ColliderTransformHashPair>(m_compoundRanges.Length, Allocator.TempJob); new ComputeCompoundHashesJob { colliders = m_nativeColliders, transforms = m_nativeTransforms, ranges = m_compoundRanges, hashes = hashes }.ScheduleParallel(m_compoundRanges.Length, 1, default).Complete(); //Step 3: Check hashes against computationContext to see if blobs need to be built for (int i = 0; i < m_authorings.Count; i++) { var hash = hashes.ReinterpretLoad <Hash128>(i); computationContext.AssociateBlobAssetWithUnityObject(hash, m_authorings[i].gameObject); if (computationContext.NeedToComputeBlobAsset(hash)) { computationContext.AddBlobAssetToCompute(hash, new CompoundColliderComputationData { hash = hash, index = i }); } } //Step 4: Dispatch builder job using (var computationData = computationContext.GetSettings(Allocator.TempJob)) { new ComputeCompoundBlobs { colliders = m_nativeColliders, transforms = m_nativeTransforms, ranges = m_compoundRanges, computationData = computationData }.ScheduleParallel(computationData.Length, 1, default).Complete(); foreach (var data in computationData) { computationContext.AddComputedBlobAsset(data.hash, data.blob); } } //Step 5: Build Collider component var index = 0; Entities.ForEach((LatiosColliderAuthoring colliderAuthoring) => { computationContext.GetBlobAsset(hashes.ReinterpretLoad <Hash128>(index++), out var blob); var targetEntity = GetPrimaryEntity(colliderAuthoring); float3 scale = colliderAuthoring.transform.lossyScale; if (scale.x != scale.y || scale.x != scale.z) { throw new InvalidOperationException( $"GameObject Conversion Error: Failed to convert {colliderAuthoring}. Only uniform scale is permitted on Compound colliders."); } Collider icdCompound = new CompoundCollider { compoundColliderBlob = blob, scale = scale.x }; DstEntityManager.AddComponentData(targetEntity, icdCompound); }); hashes.Dispose(); } } m_nativeColliders.Dispose(); m_nativeTransforms.Dispose(); m_compoundRanges.Dispose(); Profiler.EndSample(); }
protected override void OnUpdate() { var processBlobAssets = new NativeList <Hash128>(Constants.PositionCount, Allocator.Temp); var blobFactoryPositions = new NativeList <float3>(Allocator.TempJob); var blobLength = 0; int currentIndex = 0; using (var positionContext = new BlobAssetComputationContext <SequenceSettings, SequentialPositionsBlobAsset>(BlobAssetStore, 32, Allocator.Temp)) { Entities.ForEach((T spawner) => { var filePathHash = (uint)spawner.FilePath.GetHashCode(); var isFirst = true; var dataLength = -1; for (var i = 0; i < Constants.PositionCount; ++i) { var hash = new Hash128(filePathHash, (uint)i, 0, 0); processBlobAssets.Add(hash); positionContext.AssociateBlobAssetWithUnityObject(hash, spawner.gameObject); if (positionContext.NeedToComputeBlobAsset(hash)) { if (isFirst) { isFirst = false; currentIndex = blobLength; var readToEnd = File.ReadAllLines(Path.Combine(Application.streamingAssetsPath, spawner.FilePath)); dataLength = readToEnd.Length - (spawner.HasHeader ? 1 : 0); blobLength += Constants.PositionCount * dataLength; blobFactoryPositions.Resize(blobLength, NativeArrayOptions.UninitializedMemory); Fill(blobFactoryPositions, readToEnd, spawner.HasHeader, currentIndex); } var sequentialSettings = new SequenceSettings { Hash = hash, StartIndex = currentIndex + i * dataLength, Count = dataLength }; positionContext.AddBlobAssetToCompute(hash, sequentialSettings); } } }); using (var positionSettings = positionContext.GetSettings(Allocator.TempJob)) { var positionJob = new ComputeSequentialPositionAssetJob(positionSettings, blobFactoryPositions); positionJob.Schedule(positionJob.Settings.Length, 1).Complete(); for (var i = 0; i < positionSettings.Length; ++i) { positionContext.AddComputedBlobAsset(positionSettings[i].Hash, positionJob.BlobAssets[i]); } positionJob.BlobAssets.Dispose(); } blobFactoryPositions.Dispose(); var settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, BlobAssetStore); var index = 0; Entities.ForEach((T spawner) => { var prefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(spawner.Prefab, settings); DstEntityManager.AddComponent <SequenceIndex>(prefab); DstEntityManager.AddComponentData(prefab, new SequenceFrequency { Value = spawner.FrequencyOfSequence }); using (var instances = DstEntityManager.Instantiate(prefab, Constants.PositionCount, Allocator.Temp)) { for (var i = 0; i < instances.Length; ++i) { positionContext.GetBlobAsset(processBlobAssets[index], out var positionBlob); DstEntityManager.AddComponentData(instances[i], new SequentialPositions { BlobData = positionBlob, Parent = GetPrimaryEntity(spawner) }); ++index; } InitHelenHayes(instances); } }); processBlobAssets.Dispose(); } }
protected override void OnUpdate() { if (GetEntityQuery(ComponentType.ReadOnly <UnityEngine.Shader>()).CalculateEntityCount() == 0) { return; } if (!TryGetBuildConfigurationComponent <DotsRuntimeBuildProfile>(out var profile)) { return; } bool includeAllPlatform = false; if (TryGetBuildConfigurationComponent <TinyShaderSettings>(out var shaderSettings)) { includeAllPlatform = shaderSettings.PackageShadersForAllPlatforms; } var platforms = ShaderCompilerClient.GetSupportedPlatforms(profile.Target, includeAllPlatform); var context = new BlobAssetComputationContext <ShaderSettings, PrecompiledShaderPipeline>(BlobAssetStore, 128, Allocator.Temp); Entities.ForEach((UnityEngine.Shader uShader) => { if (MaterialConversion.GetMaterialType(uShader) != MaterialConversion.SupportedMaterialType.Custom) { return; } var entity = GetPrimaryEntity(uShader); // Note: all shader stages are in a single source file string filepath = Path.GetFullPath(AssetDatabase.GetAssetPath(uShader)); if (!File.Exists(filepath)) { throw new InvalidDataException($"Could not open shader file '{filepath}'"); } string shaderSrc = File.ReadAllText(filepath); if (m_Client == null) { InitShaderCompiler(); } m_Client.Preprocess(shaderSrc, filepath, uShader.name, out string hlslSrc, out int startLine, out uint[] includeHash); Hash128 includeHash128 = new Hash128(includeHash[0], includeHash[1], includeHash[2], includeHash[3]); Hash128 hash = new Hash128(); unsafe { fixed(char *p = shaderSrc) { UnityEngine.HashUnsafeUtilities.ComputeHash128(p, (ulong)shaderSrc.Length, &hash); UnityEngine.HashUtilities.AppendHash(ref includeHash128, ref hash); } } context.AssociateBlobAssetWithUnityObject(hash, uShader); if (context.NeedToComputeBlobAsset(hash)) { context.AddBlobAssetToCompute(hash, default); var blobAsset = m_Client.CompileShaderForPlatforms(hlslSrc, platforms, filepath, startLine, uShader.name); if (!blobAsset.IsCreated) { return; } context.AddComputedBlobAsset(hash, blobAsset); } context.GetBlobAsset(hash, out var shaderBlob); DstEntityManager.AddComponentData(entity, new CustomShader { Status = ShaderStatus.Invalid, Name = Path.GetFileNameWithoutExtension(filepath) }); DstEntityManager.AddComponentData(entity, new ShaderBinData { shaders = shaderBlob }); }); ShutdownShaderCompiler(); context.Dispose(); }
protected override void OnUpdate() { var blobFactoryPoints = new NativeList <float3>(Allocator.TempJob); int curPointIndex = 0; var vertices = new List <Vector3>(4096); var processBlobAssets = new NativeList <Hash128>(32, Allocator.Temp); Profiler.BeginSample("Conv_BuildHashAndPush"); using (var context = new BlobAssetComputationContext <MeshBBFactorySettings, MeshBBBlobAsset>(BlobAssetStore, 128, Allocator.Temp)) { // First step: for all changed GameObjects we compute the hash of their blob asset then get the asset or register its computation Entities.ForEach((MeshToBoundingBoxAuthoring auth) => { // Compute the blob asset hash based on Authoring properties var hasMesh = auth.Mesh != null; var meshHashCode = hasMesh ? auth.Mesh.GetHashCode() : 0; var hash = new Hash128((uint)meshHashCode, (uint)auth.MeshScale.GetHashCode(), 0, 0); // Query the context to determine if we need to build the BlobAsset processBlobAssets.Add(hash); context.AssociateBlobAssetWithUnityObject(hash, auth.gameObject); if (context.NeedToComputeBlobAsset(hash)) { Profiler.BeginSample("CopyVertices"); float xp = float.MinValue, yp = float.MinValue, zp = float.MinValue; float xn = float.MaxValue, yn = float.MaxValue, zn = float.MaxValue; // Copy the mesh vertices into the point array if (hasMesh) { auth.Mesh.GetVertices(vertices); for (int i = 0; i < vertices.Count; i++) { var p = vertices[i]; xp = math.max(p.x, xp); yp = math.max(p.y, yp); zp = math.max(p.z, zp); xn = math.min(p.x, xn); yn = math.min(p.y, yn); zn = math.min(p.z, zn); blobFactoryPoints.Add(new float3(p.x, p.y, p.z)); } } else { xp = yp = zp = xn = yn = zn = 0; } Profiler.EndSample(); // Record this blob asset for computation var vertexCount = hasMesh ? auth.Mesh.vertexCount : 0; var setting = new MeshBBFactorySettings { Hash = hash, MeshScale = auth.MeshScale, PointStartIndex = curPointIndex, PointCount = vertexCount, MinBoundingBox = new float3(xn, yn, zn), MaxBoundingBox = new float3(xp, yp, zp) }; curPointIndex += vertexCount; context.AddBlobAssetToCompute(hash, setting); } }); Profiler.EndSample(); Profiler.BeginSample("Conv_CreateBlobAssets"); using (var settings = context.GetSettings(Allocator.TempJob)) { // Step two, compute BlobAssets var job = new ComputeMeshBBAssetJob(settings, blobFactoryPoints.AsArray()); job.Schedule(job.Settings.Length, 1).Complete(); for (int i = 0; i < settings.Length; i++) { context.AddComputedBlobAsset(settings[i].Hash, job.BlobAssets[i]); } job.BlobAssets.Dispose(); } Profiler.EndSample(); Profiler.BeginSample("Conv_CreateECS"); // Third step, create the ECS component with the associated blob asset var index = 0; Entities.ForEach((MeshToBoundingBoxAuthoring auth) => { context.GetBlobAsset(processBlobAssets[index++], out var blob); // Create the ECS component for the given GameObject var entity = GetPrimaryEntity(auth); DstEntityManager.AddComponentData(entity, new MeshBBComponent(blob)); DstEntityManager.AddComponentData(entity, new Translation { Value = auth.transform.position }); }); Profiler.EndSample(); blobFactoryPoints.Dispose(); processBlobAssets.Dispose(); } }
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { using (var context = new BlobAssetComputationContext <SequentialHelenHayesSettings, SequentialPositionsBlobAsset>(conversionSystem.BlobAssetStore, 1, Allocator.Temp)) { var hash = new Hash128((uint)FilePath.GetHashCode(), 0, 0, 0); context.AssociateBlobAssetWithUnityObject(hash, gameObject); if (context.NeedToComputeBlobAsset(hash)) { var indexes = new NativeArray <int>(Constants.PositionCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); indexes[Constants.FrontHeadIndex] = FrontHeadIndex; indexes[Constants.TopHeadIndex] = TopHeadIndex; indexes[Constants.RearHeadIndex] = RearHeadIndex; indexes[Constants.RightOffsetIndex] = RightOffsetIndex; indexes[Constants.VSacralIndex] = VSacralIndex; indexes[Constants.LeftShoulderIndex] = LeftShoulderIndex; indexes[Constants.LeftElbowIndex] = LeftElbowIndex; indexes[Constants.LeftWristIndex] = LeftWristIndex; indexes[Constants.RightShoulderIndex] = RightShoulderIndex; indexes[Constants.RightElbowIndex] = RightElbowIndex; indexes[Constants.RightWristIndex] = RightWristIndex; indexes[Constants.LeftAsisIndex] = LeftAsisIndex; indexes[Constants.LeftTightIndex] = LeftTightIndex; indexes[Constants.LeftKneeIndex] = LeftKneeIndex; indexes[Constants.LeftKneeMedIndex] = LeftKneeMedIndex; indexes[Constants.LeftShankIndex] = LeftShankIndex; indexes[Constants.LeftAnkleIndex] = LeftAnkleIndex; indexes[Constants.LeftAnkleMedIndex] = LeftAnkleMedIndex; indexes[Constants.LeftHeelIndex] = LeftHeelIndex; indexes[Constants.LeftToeIndex] = LeftToeIndex; indexes[Constants.RightAsisIndex] = RightAsisIndex; indexes[Constants.RightTightIndex] = RightTightIndex; indexes[Constants.RightKneeIndex] = RightKneeIndex; indexes[Constants.RightKneeMedIndex] = RightKneeMedIndex; indexes[Constants.RightShankIndex] = RightShankIndex; indexes[Constants.RightAnkleIndex] = RightAnkleIndex; indexes[Constants.RightAnkleMedIndex] = RightAnkleMedIndex; indexes[Constants.RightHeelIndex] = RightHeelIndex; indexes[Constants.RightToeIndex] = RightToeIndex; Assert.AreEqual(29, indexes.Distinct().Count()); var readToEnd = File.ReadAllLines(Path.Combine(Application.streamingAssetsPath, FilePath)); var headSkip = (HasHeader ? 1 : 0); var dataLength = readToEnd.Length - headSkip; var positions = new NativeArray <float3>(dataLength * Constants.PositionCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); for (var i = 0; i < dataLength; ++i) { var data = Array.ConvertAll(readToEnd[i + headSkip].Split(','), (string s) => { if (float.TryParse(s, out var f)) { return(f); } else { return(float.NaN); } }); for (var j = 0; j < Constants.PositionCount; ++j) { // Convert coordinate system, and 0.001f means milli metre to metre positions[i * Constants.PositionCount + j] = new float3(data[j * 3], data[j * 3 + 2], data[j * 3 + 1]) * 0.001f; } } context.AddBlobAssetToCompute(hash, new SequentialHelenHayesSettings()); var job = new SequentialHelenHayesJob(positions, indexes); job.Schedule().Complete(); context.AddComputedBlobAsset(hash, job.BlobAssets[0]); job.BlobAssets.Dispose(); } context.GetBlobAsset(hash, out var blob); dstManager.AddComponentData(entity, new SequentialHelenHayesData { BlobData = blob }); } }
void ConvertBatchedClips() { var clipList = new List <AudioClip>(); using (var computationContext = new BlobAssetComputationContext <AudioClipComputationData, AudioClipBlob>(BlobAssetStore, 128, Allocator.Temp)) { var hashes = new NativeList <Hash128>(Allocator.Persistent); var jobs = new List <ComputeAudioClipHashesJob>(); var jobHandles = new NativeList <JobHandle>(Allocator.Persistent); Entities.ForEach((AudioSourceAuthoring authoring) => { if (authoring.clip != null) { int frequency = authoring.clip.frequency; var arr = new float[authoring.clip.samples * authoring.clip.channels]; authoring.clip.GetData(arr, 0); var job = new ComputeAudioClipHashesJob { samples = new NativeArray <float>(arr, Allocator.Persistent), hash = new NativeReference <uint2>(Allocator.Persistent), frequency = frequency }; jobs.Add(job); jobHandles.Add(job.Schedule()); } }); JobHandle.CompleteAll(jobHandles); jobHandles.Dispose(); int index = 0; Entities.ForEach((AudioSourceAuthoring authoring) => { if (authoring.clip != null) { var hash = new Hash128(jobs[index].hash.Value.x, jobs[index].hash.Value.y, (uint)authoring.clip.channels, (uint)math.select(0, authoring.voices, authoring.looping)); computationContext.AssociateBlobAssetWithUnityObject(hash, authoring.gameObject); if (computationContext.NeedToComputeBlobAsset(hash)) { computationContext.AddBlobAssetToCompute(hash, new AudioClipComputationData { hash = hash, index = index }); } index++; clipList.Add(authoring.clip); hashes.Add(hash); } }); foreach (var job in jobs) { job.samples.Dispose(); job.hash.Dispose(); } using (var computationDataArray = computationContext.GetSettings(Allocator.TempJob)) { var samples = new NativeList <float>(Allocator.TempJob); var ranges = new NativeArray <int2>(computationDataArray.Length, Allocator.TempJob); var rates = new NativeArray <int>(computationDataArray.Length, Allocator.TempJob); var channelCounts = new NativeArray <int>(computationDataArray.Length, Allocator.TempJob); var offsets = new NativeArray <int>(computationDataArray.Length, Allocator.TempJob); var names = new NativeArray <FixedString128>(computationDataArray.Length, Allocator.TempJob); for (int i = 0; i < computationDataArray.Length; i++) { var clip = clipList[computationDataArray[i].index]; var samplesManaged = new float[clip.samples * clip.channels]; clip.GetData(samplesManaged, 0); var samplesUnmanaged = new NativeArray <float>(samplesManaged, Allocator.Temp); ranges[i] = new int2(samples.Length, samplesUnmanaged.Length); samples.AddRange(samplesUnmanaged); rates[i] = clip.frequency; channelCounts[i] = clip.channels; offsets[i] = (int)computationDataArray[i].hash.Value.w; names[i] = clip.name; } new ComputeAudioClipBlobsJob { samples = samples, ranges = ranges, rates = rates, channelCounts = channelCounts, computationDataArray = computationDataArray, offsetCounts = offsets, names = names }.ScheduleParallel(ranges.Length, 1, default).Complete(); foreach (var data in computationDataArray) { computationContext.AddComputedBlobAsset(data.hash, data.blob); } samples.Dispose(); ranges.Dispose(); rates.Dispose(); channelCounts.Dispose(); offsets.Dispose(); names.Dispose(); index = 0; Entities.ForEach((AudioSourceAuthoring authoring) => { if (authoring.clip != null) { var hash = hashes[index]; computationContext.GetBlobAsset(hash, out var blob); var entity = GetPrimaryEntity(authoring); if (!authoring.looping) { DstEntityManager.AddComponentData(entity, new AudioSourceOneShot { clip = blob, innerRange = authoring.innerRange, outerRange = authoring.outerRange, rangeFadeMargin = authoring.rangeFadeMargin, volume = authoring.volume }); if (authoring.autoDestroyOnFinish) { DstEntityManager.AddComponent <AudioSourceDestroyOneShotWhenFinished>(entity); } } else { DstEntityManager.AddComponentData(entity, new AudioSourceLooped { m_clip = blob, innerRange = authoring.innerRange, outerRange = authoring.outerRange, rangeFadeMargin = authoring.rangeFadeMargin, volume = authoring.volume, }); } if (authoring.useCone) { DstEntityManager.AddComponentData(entity, new AudioSourceEmitterCone { cosInnerAngle = math.cos(math.radians(authoring.innerAngle)), cosOuterAngle = math.cos(math.radians(authoring.outerAngle)), outerAngleAttenuation = authoring.outerAngleVolume }); } index++; } }); } hashes.Dispose(); } }
protected override void OnUpdate() { var simpleMeshContext = new BlobAssetComputationContext <UMeshSettings, SimpleMeshData>(BlobAssetStore, 128, Allocator.Temp); var litMeshContext = new BlobAssetComputationContext <UMeshSettings, LitMeshData>(BlobAssetStore, 128, Allocator.Temp); JobHandle combinedJH = new JobHandle(); int simpleIndex = 0; int litIndex = 0; // Init blobasset arrays Entities.ForEach((UnityEngine.Mesh uMesh) => { CheckForMeshLimitations(uMesh); var entity = GetPrimaryEntity(uMesh); if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleIndex++; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litIndex++; } }); NativeArray <BlobAssetReference <SimpleMeshData> > simpleblobs = new NativeArray <BlobAssetReference <SimpleMeshData> >(simpleIndex, Allocator.TempJob); NativeArray <BlobAssetReference <LitMeshData> > litblobs = new NativeArray <BlobAssetReference <LitMeshData> >(litIndex, Allocator.TempJob); simpleIndex = 0; litIndex = 0; // Check which blob assets to re-compute Entities.ForEach((UnityEngine.Mesh uMesh) => { var hash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); var entity = GetPrimaryEntity(uMesh); //Schedule blob asset recomputation jobs if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleMeshContext.AssociateBlobAssetWithUnityObject(hash, uMesh); if (simpleMeshContext.NeedToComputeBlobAsset(hash)) { var singleMeshData = new UMeshDataCache(); singleMeshData.RetrieveSimpleMeshData(uMesh); UMeshSettings uMeshSettings = new UMeshSettings(hash, uMesh, simpleIndex++); simpleMeshContext.AddBlobAssetToCompute(hash, uMeshSettings); var job = new SimpleMeshConversionJob(uMeshSettings, singleMeshData, simpleblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litMeshContext.AssociateBlobAssetWithUnityObject(hash, uMesh); if (litMeshContext.NeedToComputeBlobAsset(hash)) { var litMeshData = new UMeshDataCache(); if (DstEntityManager.HasComponent <NeedGenerateGPUSkinnedMeshRenderer>(entity)) { litMeshData.RetrieveLitSkinnedMeshData(uMesh, entity, DstEntityManager); } else { litMeshData.RetrieveLitMeshData(uMesh); } UMeshSettings uMeshSettings = new UMeshSettings(hash, uMesh, litIndex++); litMeshContext.AddBlobAssetToCompute(hash, uMeshSettings); var job = new LitMeshConversionJob(uMeshSettings, litMeshData, litblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } }); // Re-compute the new blob assets combinedJH.Complete(); // Update the BlobAssetStore using (var simpleMeshSettings = simpleMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < simpleMeshSettings.Length; i++) { simpleMeshContext.AddComputedBlobAsset(simpleMeshSettings[i].hash, simpleblobs[simpleMeshSettings[i].blobIndex]); } } using (var litMeshSettings = litMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < litMeshSettings.Length; i++) { litMeshContext.AddComputedBlobAsset(litMeshSettings[i].hash, litblobs[litMeshSettings[i].blobIndex]); } } // Use blob assets in the conversion Entities.ForEach((UnityEngine.Mesh uMesh) => { var entity = GetPrimaryEntity(uMesh); bool addBounds = false; if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleMeshContext.GetBlobAsset(new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0), out var blob); DstEntityManager.AddComponentData(entity, new SimpleMeshRenderData() { Mesh = blob }); addBounds = true; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litMeshContext.GetBlobAsset(new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0), out var blob); DstEntityManager.AddComponentData(entity, new LitMeshRenderData() { Mesh = blob }); addBounds = true; } if (addBounds) { DstEntityManager.AddComponentData(entity, new MeshBounds { Bounds = new AABB { Center = uMesh.bounds.center, Extents = uMesh.bounds.extents } }); } }); simpleMeshContext.Dispose(); litMeshContext.Dispose(); simpleblobs.Dispose(); litblobs.Dispose(); }
protected override void OnUpdate() { var simpleMeshContext = new BlobAssetComputationContext <UMeshSettings, SimpleMeshData>(BlobAssetStore, 128, Allocator.Temp); var litMeshContext = new BlobAssetComputationContext <UMeshSettings, LitMeshData>(BlobAssetStore, 128, Allocator.Temp); var blendShapeContext = new BlobAssetComputationContext <UMeshSettings, BlendShapeData>(BlobAssetStore, 128, Allocator.Temp); var skinnedMeshContext = new BlobAssetComputationContext <UMeshSettings, SkinnedMeshData>(BlobAssetStore, 128, Allocator.Temp); JobHandle combinedJH = new JobHandle(); int simpleIndex = 0; int litIndex = 0; int blendShapeIndex = 0; int skinnedMeshIndex = 0; // Init blobasset arrays Entities.ForEach((UnityEngine.Mesh uMesh) => { CheckForMeshLimitations(uMesh); var entity = GetPrimaryEntity(uMesh); if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleIndex++; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litIndex++; } if (uMesh.blendShapeCount > 0) { blendShapeIndex++; } if (uMesh.boneWeights.Length > 0) { skinnedMeshIndex++; } }); NativeArray <BlobAssetReference <SimpleMeshData> > simpleblobs = new NativeArray <BlobAssetReference <SimpleMeshData> >(simpleIndex, Allocator.TempJob); NativeArray <BlobAssetReference <LitMeshData> > litblobs = new NativeArray <BlobAssetReference <LitMeshData> >(litIndex, Allocator.TempJob); NativeArray <BlobAssetReference <BlendShapeData> > blendshapeblobs = new NativeArray <BlobAssetReference <BlendShapeData> >(blendShapeIndex, Allocator.TempJob); NativeArray <BlobAssetReference <SkinnedMeshData> > skinnedMeshBlobs = new NativeArray <BlobAssetReference <SkinnedMeshData> >(litIndex, Allocator.TempJob); simpleIndex = 0; litIndex = 0; blendShapeIndex = 0; skinnedMeshIndex = 0; // Check which blob assets to re-compute Entities.ForEach((UnityEngine.Mesh uMesh) => { var verticesHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); uint boneCount = (uint)uMesh.bindposes.Length; var skinnedDataHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)boneCount.GetHashCode()); var entity = GetPrimaryEntity(uMesh); //Schedule blob asset recomputation jobs if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleMeshContext.AssociateBlobAssetWithUnityObject(verticesHash, uMesh); if (simpleMeshContext.NeedToComputeBlobAsset(verticesHash)) { var simpleMeshData = new UMeshDataCache(); if (boneCount > 0) { simpleMeshData.RetrieveSkinnedMeshData(uMesh, entity, DstEntityManager, false); if (skinnedMeshContext.NeedToComputeBlobAsset(skinnedDataHash)) { UMeshSettings uSkinnedMeshSettings = new UMeshSettings(skinnedDataHash, uMesh, skinnedMeshIndex++); skinnedMeshContext.AddBlobAssetToCompute(skinnedDataHash, uSkinnedMeshSettings); var skinningJob = new SkinningDataConversionJob(simpleMeshData, uSkinnedMeshSettings.blobIndex, skinnedMeshBlobs); combinedJH = JobHandle.CombineDependencies(combinedJH, skinningJob.Schedule(combinedJH)); } } else { simpleMeshData.RetrieveSimpleMeshData(uMesh); } UMeshSettings uMeshSettings = new UMeshSettings(verticesHash, uMesh, simpleIndex++); simpleMeshContext.AddBlobAssetToCompute(verticesHash, uMeshSettings); var job = new SimpleMeshConversionJob(simpleMeshData, uMeshSettings.blobIndex, simpleblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litMeshContext.AssociateBlobAssetWithUnityObject(verticesHash, uMesh); if (litMeshContext.NeedToComputeBlobAsset(verticesHash)) { var litMeshData = new UMeshDataCache(); if (boneCount > 0) { litMeshData.RetrieveSkinnedMeshData(uMesh, entity, DstEntityManager, true); if (skinnedMeshContext.NeedToComputeBlobAsset(skinnedDataHash)) { UMeshSettings uSkinnedMeshSettings = new UMeshSettings(skinnedDataHash, uMesh, skinnedMeshIndex++); skinnedMeshContext.AddBlobAssetToCompute(skinnedDataHash, uSkinnedMeshSettings); var skinningJob = new SkinningDataConversionJob(litMeshData, uSkinnedMeshSettings.blobIndex, skinnedMeshBlobs); combinedJH = JobHandle.CombineDependencies(combinedJH, skinningJob.Schedule(combinedJH)); } } else { litMeshData.RetrieveLitMeshData(uMesh); } UMeshSettings uMeshSettings = new UMeshSettings(verticesHash, uMesh, litIndex++); litMeshContext.AddBlobAssetToCompute(verticesHash, uMeshSettings); var job = new LitMeshConversionJob(litMeshData, uMeshSettings.blobIndex, litblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } if (uMesh.blendShapeCount > 0) { verticesHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)uMesh.blendShapeCount); blendShapeContext.AssociateBlobAssetWithUnityObject(verticesHash, uMesh); if (blendShapeContext.NeedToComputeBlobAsset(verticesHash)) { var blendShapeDataCache = new UBlendShapeDataCache(); blendShapeDataCache.RetrieveBlendShapeData(uMesh); UMeshSettings uMeshSettings = new UMeshSettings(verticesHash, uMesh, blendShapeIndex++); blendShapeContext.AddBlobAssetToCompute(verticesHash, uMeshSettings); var job = new BlendShapeConversionJob(uMeshSettings, blendShapeDataCache, blendshapeblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } }); // Re-compute the new blob assets combinedJH.Complete(); // Update the BlobAssetStore using (var simpleMeshSettings = simpleMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < simpleMeshSettings.Length; i++) { simpleMeshContext.AddComputedBlobAsset(simpleMeshSettings[i].hash, simpleblobs[simpleMeshSettings[i].blobIndex]); } } using (var litMeshSettings = litMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < litMeshSettings.Length; i++) { litMeshContext.AddComputedBlobAsset(litMeshSettings[i].hash, litblobs[litMeshSettings[i].blobIndex]); } } using (var meshSettings = blendShapeContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < meshSettings.Length; i++) { blendShapeContext.AddComputedBlobAsset(meshSettings[i].hash, blendshapeblobs[meshSettings[i].blobIndex]); } } using (var meshSettings = skinnedMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < meshSettings.Length; i++) { skinnedMeshContext.AddComputedBlobAsset(meshSettings[i].hash, skinnedMeshBlobs[meshSettings[i].blobIndex]); } } // Use blob assets in the conversion Entities.ForEach((UnityEngine.Mesh uMesh) => { var entity = GetPrimaryEntity(uMesh); bool addBounds = false; if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { Hash128 hash128 = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); simpleMeshContext.GetBlobAsset(hash128, out var blob); DstEntityManager.AddComponentData(entity, new SimpleMeshRenderData() { Mesh = blob }); addBounds = true; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { Hash128 hash128 = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); litMeshContext.GetBlobAsset(hash128, out var blob); DstEntityManager.AddComponentData(entity, new LitMeshRenderData() { Mesh = blob }); addBounds = true; } if (addBounds) { DstEntityManager.AddComponentData(entity, new MeshBounds { Bounds = new AABB { Center = uMesh.bounds.center, Extents = uMesh.bounds.extents } }); } if (uMesh.blendShapeCount > 0) { Hash128 hash128 = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)uMesh.blendShapeCount); blendShapeContext.GetBlobAsset(hash128, out var blendShapeBlob); DstEntityManager.AddComponentData(entity, new MeshBlendShapeData() { BlendShapeDataRef = blendShapeBlob }); } if (uMesh.bindposes.Length > 0) { var skinnedDataHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)uMesh.bindposes.Length.GetHashCode()); skinnedMeshContext.GetBlobAsset(skinnedDataHash, out var skinnedMeshBlob); DstEntityManager.AddComponentData(entity, new SkinnedMeshRenderData() { SkinnedMeshDataRef = skinnedMeshBlob }); } }); simpleMeshContext.Dispose(); litMeshContext.Dispose(); blendShapeContext.Dispose(); simpleblobs.Dispose(); litblobs.Dispose(); blendshapeblobs.Dispose(); skinnedMeshBlobs.Dispose(); }