public IEnumerable <IReference> EnumerateCompileTimeDependencies(PackageSession session) { if (Prefab != null) { // Return the prefab itself yield return(Prefab); // Then we need to return used models and materials because they affects how the meshes are generated var prefab = session.FindAsset(Prefab.Location)?.Asset as PrefabAsset; if (prefab != null) { // Use a dictionary to ensure each reference is yielded only once var references = new Dictionary <Guid, IReference>(); foreach (var entity in prefab.Hierarchy.Parts) { // Gather all entities with a model component and a valid model var modelComponent = entity.Entity.Get <ModelComponent>(); if (modelComponent?.Model != null) { var modelReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model); var model = session.FindAsset(modelReference.Url)?.Asset as IModelAsset; if (model != null) { // Build the list of material for this model var materialList = model.Materials.Select(x => x.MaterialInstance.Material).ToList(); for (var i = 0; i < modelComponent.Materials.Count && i < materialList.Count; i++) { // Apply any material override from the model component var material = modelComponent.Materials[i]; if (material != null) { materialList[i] = material; } } // Add the model and the related materials to the list of reference references[modelReference.Id] = modelReference; foreach (var material in materialList) { var materialReference = AttachedReferenceManager.GetAttachedReference(material); references[materialReference.Id] = materialReference; } } } } // Finally return all the referenced models and materials foreach (var reference in references.Values) { yield return(reference); } } } }
/// <summary> /// This method is called when an asset needs to be tracked /// </summary> /// <returns>AssetDependencies.</returns> private void TrackAsset(AssetId assetId) { lock (ThisLock) { if (trackedAssets.ContainsKey(assetId)) { return; } // TODO provide an optimized version of TrackAsset method // taking directly a well known asset (loaded from a Package...etc.) // to avoid session.FindAsset var assetItem = session.FindAsset(assetId); if (assetItem == null) { return; } // Clone the asset before using it in this instance to make sure that // we have some kind of immutable state // TODO: This is not handling shadow registry // No need to clone assets from readonly package var clonedAsset = assetItem.Package.IsSystem ? assetItem.Asset : AssetCloner.Clone(assetItem.Asset); var trackedAsset = new TrackedAsset(this, assetItem.Asset, clonedAsset); // Adds to global list trackedAssets.Add(assetId, trackedAsset); } }
private bool ProcessMergeAssetBase(AssetBase assetBase, HashSet <Guid> beingProcessed, out AssetItem existingAsset) { var baseId = assetBase.Id; // Make sure that the base asset exist existingAsset = session.FindAsset(baseId); if (existingAsset == null) { log.Warning(package, assetBase, AssetMessageCode.AssetNotFound, assetBase); return(false); } // If the base asset hasn't been processed, continue on next asset if (!assetsProcessed.ContainsKey(baseId)) { // If asset is in the same package, we can process it right away if (existingAsset.Package == package) { if (!ProcessMergeAssetItem(existingAsset, beingProcessed)) { return(false); } } } return(true); }
public IEnumerable <IReference> EnumerateCompileTimeDependencies(PackageSession session) { if (Scene != null) { var reference = AttachedReferenceManager.GetAttachedReference(Scene); var sceneAsset = (SceneAsset)session.FindAsset(reference.Url)?.Asset; var referencedColliderShapes = new HashSet <AssetId>(); // Find collider assets to reference if (sceneAsset != null) { List <Entity> sceneEntities = sceneAsset.Hierarchy.Parts.Select(x => x.Entity).ToList(); foreach (var entity in sceneEntities) { StaticColliderComponent collider = entity.Get <StaticColliderComponent>(); bool colliderEnabled = collider != null && ((CollisionFilterGroupFlags)collider.CollisionGroup & IncludedCollisionGroups) != 0 && collider.Enabled; if (colliderEnabled) { var assetShapes = collider.ColliderShapes.OfType <ColliderShapeAssetDesc>(); foreach (var assetShape in assetShapes) { if (assetShape.Shape == null) { continue; } // Reference all asset collider shapes reference = AttachedReferenceManager.GetAttachedReference(assetShape.Shape); // Only need to reference each shape once if (referencedColliderShapes.Contains(reference.Id)) { continue; } yield return(new AssetReference(reference.Id, reference.Url)); referencedColliderShapes.Add(reference.Id); } } } } } }
public MaterialDescription Run(MaterialDescription material, UDirectory materialPath, PixelFormat outputFormat = PixelFormat.ETC1) { if (material == null) { throw new ArgumentNullException("material"); } var assetManager = new AssetManager(); var modifiedMaterial = material.Clone(); var textureVisitor = new MaterialTextureVisitor(modifiedMaterial); var nodeReplacer = new MaterialNodeReplacer(modifiedMaterial); var textureNodes = textureVisitor.GetAllModelTextureValues(); foreach (var textureNode in textureNodes) { var itemAsset = assetSession.FindAsset(textureNode.TextureReference.Id); if (itemAsset == null) { throw new InvalidOperationException("The referenced texture is not included in the project session."); } var textureAsset = (TextureAsset)itemAsset.Asset; if (textureAsset.Format != TextureFormat.Compressed || textureAsset.Alpha == AlphaFormat.None) { continue; // the texture has no alpha so there is no need to divide the texture into two sub-textures } var originalLocation = textureNode.TextureReference.Location; throw new NotImplementedException("TODO: Need to reimplement this with removed data layer."); using (var image = assetManager.Load <Image>(originalLocation)) { CreateAndSaveSeparateTextures(image, originalLocation, textureAsset.GenerateMipmaps, outputFormat); assetManager.Unload(image); // matching unload to the previous asset manager load call } // make new tree var colorNode = new MaterialTextureNode(GenerateColorTextureURL(originalLocation), textureNode.TexcoordIndex, Vector2.One, Vector2.Zero); var alphaNode = new MaterialTextureNode(GenerateAlphaTextureURL(originalLocation), textureNode.TexcoordIndex, Vector2.One, Vector2.Zero); var substituteAlphaNode = new MaterialShaderClassNode { MixinReference = new AssetReference <EffectShaderAsset>(Guid.Empty, "ComputeColorSubstituteAlphaWithColor") }; substituteAlphaNode.CompositionNodes.Add("color1", colorNode); substituteAlphaNode.CompositionNodes.Add("color2", alphaNode); // set the parameters of the children so that they match the original texture var children = new[] { colorNode, alphaNode }; foreach (var childTexture in children) { childTexture.Sampler.AddressModeU = textureNode.Sampler.AddressModeU; childTexture.Sampler.AddressModeV = textureNode.Sampler.AddressModeV; childTexture.Sampler.Filtering = textureNode.Sampler.Filtering; childTexture.Offset = textureNode.Offset; childTexture.Sampler.SamplerParameterKey = textureNode.Sampler.SamplerParameterKey; childTexture.Scale = textureNode.Scale; childTexture.TexcoordIndex = textureNode.TexcoordIndex; } // copy the parameter key on the color and let the one of the alpha null so that it is set automatically to available value later colorNode.Key = textureNode.Key; alphaNode.Key = null; // update all the material references to the new node nodeReplacer.Replace(textureNode, substituteAlphaNode); } return(modifiedMaterial); }
public AssetItem GetAssetById(AssetId assetId) { return(session.FindAsset(assetId)); }