protected override void OnUpdate() { var entities = m_ComponentGroup.ToEntityArray(Allocator.TempJob); List <SpriteSkin> spriteSkinComponents = new List <SpriteSkin>(); List <SpriteComponent> spriteComponents = new List <SpriteComponent>(); Entities.ForEach((SpriteSkin spriteSkin) => { spriteSkinComponents.Add(spriteSkin); }); Entities.ForEach((SpriteComponent sprite) => { spriteComponents.Add(sprite); }); var worldToLocalComponents = m_ComponentGroup.ToComponentDataArray <WorldToLocal>(Allocator.TempJob); for (var i = 0; i < entities.Length; ++i) { var vertexBuffer = EntityManager.GetBuffer <Vertex>(entities[i]); var boneTransformBuffer = EntityManager.GetBuffer <BoneTransform>(entities[i]); var currentSprite = spriteComponents[i].Value; var currentWorldToLocal = worldToLocalComponents[i]; Sprite sprite = null; var entity = entities[i]; var spriteSkin = spriteSkinComponents[i]; if (spriteSkin == null) { continue; } var spriteRenderer = spriteSkin.spriteRenderer; var isValid = spriteRenderer.enabled && spriteSkin.isValid; var isVisible = spriteRenderer.isVisible || spriteSkin.ForceSkinning; if (!isValid) { SpriteRendererDataAccessExtensions.DeactivateDeformableBuffer(spriteRenderer); } else if (isVisible) { spriteSkin.ForceSkinning = false; sprite = spriteRenderer.sprite; float4x4 worldToLocal = spriteSkin.transform.worldToLocalMatrix; if (vertexBuffer.Length != sprite.GetVertexCount()) { vertexBuffer = PostUpdateCommands.SetBuffer <Vertex>(entity); vertexBuffer.ResizeUninitialized(sprite.GetVertexCount()); } InternalEngineBridge.SetDeformableBuffer(spriteRenderer, vertexBuffer.Reinterpret <Vector3>().AsNativeArray()); if (boneTransformBuffer.Length != spriteSkin.boneTransforms.Length) { boneTransformBuffer = PostUpdateCommands.SetBuffer <BoneTransform>(entity); boneTransformBuffer.ResizeUninitialized(spriteSkin.boneTransforms.Length); } for (var j = 0; j < boneTransformBuffer.Length; ++j) { boneTransformBuffer[j] = new BoneTransform() { Value = spriteSkin.boneTransforms[j].localToWorldMatrix } } ; PostUpdateCommands.SetComponent <WorldToLocal>(entity, new WorldToLocal() { Value = worldToLocal }); } if (currentSprite != sprite) { PostUpdateCommands.SetSharedComponent <SpriteComponent>(entity, new SpriteComponent() { Value = sprite }); } if (!spriteRenderer.enabled) { spriteSkin.ForceSkinning = true; } } entities.Dispose(); worldToLocalComponents.Dispose(); } }
protected override void OnUpdate() { // Camera.main may not be available when the system is created, so need this to set it for the first time if (MainCamera == null) { if (Camera.main != null) { MainCamera = Camera.main; } else { GameDebug.LogWarning("PartOwner update: No camera.main"); return; } } var camPos = (float3)MainCamera.transform.position; // TODO: Jobified ForEach blocked by PrefabAssetRegistry.CreateEntity Entities.ForEach((Entity partOwnerEntity, ref Translation translation, ref RegistryAsset registryAsset, ref InputState inputState, ref State state) => { var registry = PartRegistry.GetPartRegistry(World, registryAsset.Value); // Calc lod var charPos = translation.Value; var dist = math.distance(camPos, charPos); var newLod = -1; // TODO (mogensh) add threshold that needs to be passed before change (so it does not flicker) for (int lod = 0; lod < registry.Value.LODLevels.Length; lod++) { if (dist <= registry.Value.LODLevels[lod].EndDist) { newLod = lod; break; } } // TODO (mogensh) hack: force LOD 0 newLod = 0; // Handle out of lod distance specifically if (newLod == -1) { if (state.currentLOD != newLod) { state.currentLOD = newLod; GameDebug.Log(Part.ShowLifetime, "Out of LOD distance"); var partBuf = EntityManager.GetBuffer <PartElement>(partOwnerEntity) .ToNativeArray(Allocator.Temp); var partOutBuf = PostUpdateCommands.SetBuffer <PartElement>(partOwnerEntity); partOutBuf.ResizeUninitialized(partBuf.Length); for (int j = 0; j < partBuf.Length; j++) { var partElement = partBuf[j]; // Destroy old part if (partElement.PartId != 0) { if (partElement.PartEntity != Entity.Null) { GameDebug.Log(Part.ShowLifetime, "Destroying part. Category:{0} partId:{1}", j, partElement.PartId); PostUpdateCommands.DestroyEntity(partElement.PartEntity); } partElement.PartEntity = Entity.Null; partElement.PartId = 0; partElement.Asset = WeakAssetReference.Default; } partOutBuf[j] = partElement; } PostUpdateCommands.SetComponent(partOwnerEntity, state); } return; } var newRig = BlobAssetReference <RigDefinition> .Null; if (EntityManager.HasComponent <SharedRigDefinition>(partOwnerEntity)) { newRig = EntityManager.GetSharedComponentData <SharedRigDefinition>(partOwnerEntity).Value; } // Change bodypart if LOD or rig changed var packedPartIds = inputState.PackedPartIds; if (packedPartIds != state.CurrentPackedPartIds || newLod != state.currentLOD || (newRig != BlobAssetReference <RigDefinition> .Null && newRig != state.currentRig)) { var partBuf = EntityManager.GetBuffer <PartElement>(partOwnerEntity).ToNativeArray(Allocator.Temp); var partIds = new NativeArray <int>(partBuf.Length, Allocator.Temp); registry.Value.UnpackPartsList(inputState.PackedPartIds, partIds); GameDebug.Log(World, Part.ShowLifetime, "Property changed. Lod:{0}", newLod); var partOutBuf = PostUpdateCommands.SetBuffer <PartElement>(partOwnerEntity); partOutBuf.ResizeUninitialized(partBuf.Length); for (int j = 0; j < partBuf.Length; j++) { var partId = partIds[j]; var partElement = partBuf[j]; // Find new asset given the new properties var asset = new WeakAssetReference(); if (partId > 0) { var skeletonHash = newRig.IsCreated ? newRig.Value.GetHashCode() : 0; var found = registry.Value.FindAsset(j, partId, skeletonHash, newLod, ref asset); if (!found) { GameDebug.Log(World, Part.ShowLifetime, "Failed to find valid part. Category:{0} PartId:{1}", j, partId); } } // No change if asset has not changed if (partElement.Asset == asset) { partOutBuf[j] = partElement; continue; } // Destroy old part if (partElement.PartId != 0) { if (partElement.PartEntity != Entity.Null) { GameDebug.Log(World, Part.ShowLifetime, "Destroying part. Category:{0} partId:", j, partElement.PartId); PostUpdateCommands.DestroyEntity(partElement.PartEntity); } partElement.PartEntity = Entity.Null; partElement.PartId = 0; partElement.Asset = WeakAssetReference.Default; } // Create new part if (partId != 0 && asset.IsSet()) { partElement.PartEntity = PrefabAssetManager.CreateEntity(EntityManager, asset); partElement.PartId = partId; partElement.Asset = asset; if (partElement.PartEntity != Entity.Null) { GameDebug.Log(World, Part.ShowLifetime, "Creating part. Owner:{0} Cat:{1} PartId:{2} Asset:{3} part:{4}", partOwnerEntity, j, partId, asset.ToGuidStr(), partElement.PartEntity); var part = Part.Owner.Default; part.Value = partOwnerEntity; PostUpdateCommands.SetComponent(partElement.PartEntity, part); // TODO (mogensh) add "static" property on owner (or get somehow). If static just set world transform PostUpdateCommands.AddComponent(partElement.PartEntity, new Parent { Value = partOwnerEntity }); PostUpdateCommands.AddComponent(partElement.PartEntity, new LocalToParent()); } else { GameDebug.LogError("Failed to create part. Asset:" + asset.ToGuidStr()); } } partOutBuf[j] = partElement; } state.CurrentPackedPartIds = packedPartIds; state.currentRig = newRig; state.currentLOD = newLod; PostUpdateCommands.SetComponent(partOwnerEntity, state); } }); }
protected override void OnUpdate() { var conToColor = new NativeHashMap <Entity, int>(SystemConstants.MapNodeSize, Allocator.Temp); var colorToColor = new NativeHashMap <int, int>(SystemConstants.MapNodeSize, Allocator.Temp); int newColor = 0; var connections = _query.ToComponentDataArray <Connection>(Allocator.TempJob); var conEnts = _query.ToEntityArray(Allocator.TempJob); for (int i = 0; i < connections.Length; i++) { var conA = connections[i]; var entA = conEnts[i]; for (int j = 0; j < connections.Length; j++) { var conB = connections[j]; var entB = conEnts[j]; if (!conToColor.TryGetValue(entA, out int startColor)) { startColor = int.MaxValue; } ; if (!conToColor.TryGetValue(entB, out int endColor)) { endColor = int.MaxValue; } if (startColor == endColor) { if (startColor == int.MaxValue) { conToColor.TryAdd(entA, newColor); conToColor.TryAdd(entB, newColor); newColor++; } } else { int minColor = math.min(startColor, endColor); int maxColor = math.max(startColor, endColor); var changedCon = startColor > endColor ? entA : entB; int trueColor = minColor; while (colorToColor.TryGetValue(trueColor, out int nextColor)) { trueColor = nextColor; } if (maxColor < int.MaxValue) { conToColor.Remove(changedCon); } conToColor.TryAdd(changedCon, trueColor); if (maxColor < int.MaxValue) { if (colorToColor.TryGetValue(maxColor, out int temp)) { colorToColor.Remove(maxColor); } colorToColor.TryAdd(maxColor, trueColor); } } } } connections.Dispose(); conEnts.Dispose(); if (conToColor.Length > 0) { var finalColor = new NativeHashMap <Entity, int>(SystemConstants.MapNodeSize, Allocator.Temp); var colorToNetwork = new NativeHashMap <int, Entity>(SystemConstants.MapNodeSize, Allocator.Temp); var keys = conToColor.GetKeyArray(Allocator.Temp); var values = conToColor.GetValueArray(Allocator.Temp); for (int i = 0; i < keys.Length; i++) { var con = keys[i]; int trueColor = values[i]; while (colorToColor.TryGetValue(trueColor, out int nextColor)) { trueColor = nextColor; } finalColor.TryAdd(con, trueColor); if (!colorToNetwork.TryGetValue(trueColor, out var network)) { network = PostUpdateCommands.CreateEntity(_networkArchetype); colorToNetwork.TryAdd(trueColor, network); } } keys.Dispose(); values.Dispose(); var networkToBuffer = new NativeHashMap <Entity, DynamicBuffer <NetAdjust> >(SystemConstants.MapNodeSize, Allocator.Temp); Entities.WithNone <NetworkGroup>().ForEach((Entity connectionEnt, ref Connection connection, ref ConnectionLengthInt conLength, ref ConnectionSpeedInt conSpeed) => { int color = finalColor[connectionEnt]; var network = colorToNetwork[color]; PostUpdateCommands.AddSharedComponent(connectionEnt, new NetworkGroup { NetworkId = network.Index }); DynamicBuffer <NetAdjust> buffer; if (!networkToBuffer.TryGetValue(network, out buffer)) { buffer = PostUpdateCommands.SetBuffer <NetAdjust>(network); networkToBuffer.TryAdd(network, buffer); } buffer.Add(new NetAdjust { Connection = connectionEnt, Cost = (float)conLength.Length / conSpeed.Speed, StartNode = connection.StartNode, EndNode = connection.EndNode }); }); colorToNetwork.Dispose(); networkToBuffer.Dispose(); finalColor.Dispose(); } conToColor.Dispose(); colorToColor.Dispose(); }