Beispiel #1
0
        public void CompilerDependencyByIncludeTypeAnalysis()
        {
            var package = new Package();
            // ReSharper disable once UnusedVariable - we need a package session to compile
            var packageSession = new PackageSession(package);
            var asset1         = new AssetItem("content1", new MyAsset1(), package);   // Should be compiled (root)
            var asset2         = new AssetItem("content2", new MyAsset2(), package);   // Should be compiled (Runtime for Asset1)
            var asset31        = new AssetItem("content3_1", new MyAsset3(), package); // Should NOT be compiled (CompileAsset for Asset1)
            var asset32        = new AssetItem("content3_2", new MyAsset3(), package); // Should be compiled (Runtime for Asset2)

            ((MyAsset1)asset1.Asset).MyContent2 = AttachedReferenceManager.CreateProxyObject <MyContent2>(asset2.Id, asset2.Location);
            ((MyAsset1)asset1.Asset).MyContent3 = AttachedReferenceManager.CreateProxyObject <MyContent3>(asset31.Id, asset31.Location);
            ((MyAsset2)asset2.Asset).MyContent3 = AttachedReferenceManager.CreateProxyObject <MyContent3>(asset32.Id, asset32.Location);

            package.Assets.Add(asset1);
            package.Assets.Add(asset2);
            package.Assets.Add(asset31);
            package.Assets.Add(asset32);
            package.RootAssets.Add(new AssetReference(asset1.Id, asset1.Location));

            // Create context
            var context = new AssetCompilerContext {
                CompilationContext = typeof(AssetCompilationContext)
            };

            // Builds the project
            var assetBuilder = new PackageCompiler(new RootPackageAssetEnumerator(package));

            context.Properties.Set(BuildAssetNode.VisitRuntimeTypes, true);
            var assetBuildResult = assetBuilder.Prepare(context);

            // Total number of asset to compile = 3
            Assert.AreEqual(3, assetBuildResult.BuildSteps.Count);
        }
        public static ComputeTextureColor GenerateMaterialTextureNode(string vfsOutputPath, string sourceTextureFile, uint textureUVSetIndex, Vector2 textureUVscaling, TextureAddressMode addressModeU, TextureAddressMode addressModeV, Logger logger)
        {
            var textureFileName = Path.GetFileNameWithoutExtension(sourceTextureFile);
            var url             = vfsOutputPath + "_" + textureFileName;

            if (File.Exists(sourceTextureFile))
            {
                if (logger != null)
                {
                    logger.Warning($"The texture '{sourceTextureFile}' referenced in the mesh material can not be found on the system. Loading will probably fail at run time.", CallerInfo.Get());
                }
            }

            var uvScaling   = textureUVscaling;
            var textureName = textureFileName;

            var texture = AttachedReferenceManager.CreateProxyObject <Texture>(AssetId.Empty, textureName);

            var currentTexture = new ComputeTextureColor(texture, (TextureCoordinate)textureUVSetIndex, uvScaling, Vector2.Zero);

            currentTexture.AddressModeU = addressModeU;
            currentTexture.AddressModeV = addressModeV;

            return(currentTexture);
        }
Beispiel #3
0
        public static GameSettingsAsset Create()
        {
            var asset = new GameSettingsAsset();

            asset.SplashScreenTexture = AttachedReferenceManager.CreateProxyObject <Texture>(new AssetId("d26edb11-10bd-403c-b3c2-9c7fcccf25e5"), "StrideDefaultSplashScreen");
            asset.SplashScreenColor   = Color.Black;

            //add default filters, todo maybe a config file somewhere is better
            asset.PlatformFilters.Add("PowerVR SGX 54[0-9]");
            asset.PlatformFilters.Add("Adreno \\(TM\\) 2[0-9][0-9]");
            asset.PlatformFilters.Add("Adreno (TM) 320");
            asset.PlatformFilters.Add("Adreno (TM) 330");
            asset.PlatformFilters.Add("Adreno \\(TM\\) 4[0-9][0-9]");
            asset.PlatformFilters.Add("NVIDIA Tegra");
            asset.PlatformFilters.Add("Intel(R) HD Graphics");
            asset.PlatformFilters.Add("^Mali\\-4");
            asset.PlatformFilters.Add("^Mali\\-T6");
            asset.PlatformFilters.Add("^Mali\\-T7");

            asset.GetOrCreate <AudioEngineSettings>();
            asset.GetOrCreate <EditorSettings>();
            asset.GetOrCreate <RenderingSettings>();
            asset.GetOrCreate <StreamingSettings>();
            asset.GetOrCreate <TextureSettings>();

            return(asset);
        }
        public void CompilerVisitRuntimeType()
        {
            var package = new Package();
            // ReSharper disable once UnusedVariable - we need a package session to compile
            var packageSession = new PackageSession(package);
            var otherAssets    = new List <AssetItem>
            {
                new AssetItem("contentRB", new MyAssetContentType(0), package),
                new AssetItem("contentRA", new MyAssetContentType(1), package),
                new AssetItem("content0B", new MyAssetContentType(2), package),
                new AssetItem("content0M", new MyAssetContentType(3), package),
                new AssetItem("content0A", new MyAssetContentType(4), package),
                new AssetItem("content1B", new MyAssetContentType(5), package),
                new AssetItem("content1M", new MyAssetContentType(6), package),
                new AssetItem("content1A", new MyAssetContentType(7), package),
                new AssetItem("content2B", new MyAssetContentType(8), package),
                new AssetItem("content2M", new MyAssetContentType(9), package),
                new AssetItem("content2A", new MyAssetContentType(10), package),
                new AssetItem("content3B", new MyAssetContentType(11), package),
                new AssetItem("content3M", new MyAssetContentType(12), package),
                new AssetItem("content3A", new MyAssetContentType(13), package),
                new AssetItem("content4B", new MyAssetContentType(14), package),
                new AssetItem("content4M", new MyAssetContentType(15), package),
                new AssetItem("content4A", new MyAssetContentType(16), package),
            };

            var assetToVisit = new MyAsset1();

            assetToVisit.Before = AttachedReferenceManager.CreateProxyObject <MyContentType>(otherAssets[0].Id, otherAssets[0].Location);
            assetToVisit.Zafter = AttachedReferenceManager.CreateProxyObject <MyContentType>(otherAssets[1].Id, otherAssets[1].Location);
            assetToVisit.RuntimeTypes.Add(CreateRuntimeType(otherAssets[2], otherAssets[3], otherAssets[4]));
            assetToVisit.RuntimeTypes.Add(CreateRuntimeType(otherAssets[5], otherAssets[6], otherAssets[7]));
            assetToVisit.RuntimeTypes.Add(CreateRuntimeType(otherAssets[8], otherAssets[9], otherAssets[10]));
            assetToVisit.RuntimeTypes.Add(CreateRuntimeType(otherAssets[11], otherAssets[12], otherAssets[13]));
            assetToVisit.RuntimeTypes.Add(CreateRuntimeType(otherAssets[14], otherAssets[15], otherAssets[16]));
            assetToVisit.RuntimeTypes[0].A = assetToVisit.RuntimeTypes[1];
            assetToVisit.RuntimeTypes[0].B = assetToVisit.RuntimeTypes[2];
            assetToVisit.RuntimeTypes[1].A = assetToVisit.RuntimeTypes[3];
            assetToVisit.RuntimeTypes[1].B = assetToVisit.RuntimeTypes[4];

            otherAssets.ForEach(x => package.Assets.Add(x));
            var assetItem = new AssetItem("asset", assetToVisit, package);

            package.Assets.Add(assetItem);
            package.RootAssets.Add(new AssetReference(assetItem.Id, assetItem.Location));

            // Create context
            var context = new AssetCompilerContext {
                CompilationContext = typeof(AssetCompilationContext)
            };

            // Builds the project
            var assetBuilder = new PackageCompiler(new RootPackageAssetEnumerator(package));

            context.Properties.Set(BuildAssetNode.VisitRuntimeTypes, true);
            var assetBuildResult = assetBuilder.Prepare(context);

            Assert.AreEqual(16, assetBuildResult.BuildSteps.Count);
        }
        public ShaderSource Generate(MaterialGeneratorContext context)
        {
            var texture = context.GraphicsProfile >= GraphicsProfile.Level_10_0
                ? AttachedReferenceManager.CreateProxyObject <Texture>(new AssetId("a49995f8-2380-4baa-a03e-f8d1da35b79a"), "XenkoEnvironmentLightingDFGLUT16")
                : AttachedReferenceManager.CreateProxyObject <Texture>(new AssetId("87540190-ab97-4b4e-b3c2-d57d2fbb1ff3"), "XenkoEnvironmentLightingDFGLUT8");

            context.Parameters.Set(MaterialSpecularMicrofacetEnvironmentGGXLUTKeys.EnvironmentLightingDFG_LUT, texture);

            return(new ShaderClassSource("MaterialSpecularMicrofacetEnvironmentGGXLUT"));
        }
Beispiel #6
0
            public static bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList <PackageLoadingAssetFile> assetFiles)
            {
                var packageSharedProfile = dependentPackage.Profiles.FindSharedProfile();

                // Only do something if there is a default scene defined
                if (packageSharedProfile != null && packageSharedProfile.Properties.ContainsKey(DefaultScene))
                {
                    var defaultScene = Get(packageSharedProfile.Properties, DefaultScene);

                    var defaultGraphicsProfile = Get(packageSharedProfile.Properties, DefaultGraphicsProfile);

                    // If available, use graphics profile from Windows platform
                    foreach (var profile in dependentPackage.Profiles)
                    {
                        if (profile.Platform == PlatformType.Windows && profile.Properties.ContainsKey(DefaultGraphicsProfile))
                        {
                            defaultGraphicsProfile = Get(profile.Properties, DefaultGraphicsProfile);
                        }
                    }

                    // Create asset
                    var gameSettingsAsset = GameSettingsFactory.Create();
                    gameSettingsAsset.DefaultScene = AttachedReferenceManager.CreateProxyObject <Scene>(defaultScene.Id, defaultScene.Location);

                    var renderingSettings = gameSettingsAsset.Get <RenderingSettings>();
                    renderingSettings.DisplayOrientation      = (RequiredDisplayOrientation)Get(packageSharedProfile.Properties, DisplayOrientation);
                    renderingSettings.ColorSpace              = ColorSpace.Linear;
                    renderingSettings.DefaultBackBufferWidth  = Get(packageSharedProfile.Properties, BackBufferWidth);
                    renderingSettings.DefaultBackBufferHeight = Get(packageSharedProfile.Properties, BackBufferHeight);
                    renderingSettings.DefaultGraphicsProfile  = defaultGraphicsProfile;

                    // Add asset
                    using (var memoryStream = new MemoryStream())
                    {
                        AssetSerializer.Save(memoryStream, gameSettingsAsset, log);
                        assetFiles.Add(new PackageLoadingAssetFile(dependentPackage, GameSettingsLocation + FileExtension, null)
                        {
                            AssetContent = memoryStream.ToArray()
                        });
                    }

                    // Clean properties
                    foreach (var profile in dependentPackage.Profiles)
                    {
                        profile.Properties.Remove(DefaultScene.Name);
                        profile.Properties.Remove(BackBufferWidth.Name);
                        profile.Properties.Remove(BackBufferHeight.Name);
                        profile.Properties.Remove(DefaultGraphicsProfile.Name);
                        profile.Properties.Remove(DisplayOrientation.Name);
                    }
                }

                return(true);
            }
Beispiel #7
0
        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var url   = (string)value;
            var asset = SessionViewModel.Instance.AllAssets.FirstOrDefault(x => x.Url == url);

            if (asset == null)
            {
                return(null);
            }

            var contentType = AssetRegistry.GetContentType(asset.AssetType);

            return(AttachedReferenceManager.CreateProxyObject(contentType, asset.Id, asset.Url));
        }
Beispiel #8
0
        public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar)
        {
            AssetId guid;
            UFile   location;

            if (!AssetReference.TryParse(fromScalar.Value, out guid, out location))
            {
                throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to decode asset reference [{0}]. Expecting format GUID:LOCATION".ToFormat(fromScalar.Value));
            }

            var instance = AttachedReferenceManager.CreateProxyObject(context.Descriptor.Type, guid, location);

            return(instance);
        }
Beispiel #9
0
            public override void VisitCollectionItem(IEnumerable collection, CollectionDescriptor descriptor, int index, object item, ITypeDescriptor itemDescriptor)
            {
                base.VisitCollectionItem(collection, descriptor, index, item, itemDescriptor);
                var assetReference    = item as AssetReference;
                var attachedReference = AttachedReferenceManager.GetAttachedReference(item);

                // We cannot set links if we do not have indexer accessor
                if (!descriptor.HasIndexerAccessors)
                {
                    return;
                }

                if (assetReference != null)
                {
                    AddLink(assetReference, (guid, location) =>
                    {
                        var link = AssetReference.New(guid ?? assetReference.Id, location);
                        descriptor.SetValue(collection, index, link);
                        return(link);
                    });
                }
                else if (attachedReference != null)
                {
                    AddLink(attachedReference, (guid, location) =>
                    {
                        var link = guid.HasValue && guid.Value != AssetId.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ElementType, guid.Value, location) : null;
                        descriptor.SetValue(collection, index, link);
                        return(link);
                    });
                }
                else if (item is UFile)
                {
                    AddLink(item, (guid, location) =>
                    {
                        var link = new UFile(location);
                        descriptor.SetValue(collection, index, link);
                        return(link);
                    });
                }
                else if (item is UDirectory)
                {
                    AddLink(item, (guid, location) =>
                    {
                        var link = new UDirectory(location);
                        descriptor.SetValue(collection, index, link);
                        return(link);
                    });
                }
            }
Beispiel #10
0
        private static AssetItem ImportModel(List <AssetItem> assetReferences, UFile assetSource, UFile localPath, EntityInfo entityInfo, bool shouldPostFixName, AssetItem skeletonAsset)
        {
            var asset = new ModelAsset {
                Source = assetSource
            };

            if (entityInfo.Models != null)
            {
                var loadedMaterials = assetReferences.Where(x => x.Asset is MaterialAsset).ToList();
                foreach (var material in entityInfo.Materials)
                {
                    var modelMaterial = new ModelMaterial
                    {
                        Name             = material.Key,
                        MaterialInstance = new MaterialInstance()
                    };
                    var foundMaterial = loadedMaterials.FirstOrDefault(x => x.Location == new UFile(material.Key));
                    if (foundMaterial != null)
                    {
                        var reference = AttachedReferenceManager.CreateProxyObject <Material>(foundMaterial.Id, foundMaterial.Location);
                        modelMaterial.MaterialInstance.Material = reference;
                    }
                    //todo Instead of null material add a default xenko material
                    asset.Materials.Add(AttachId(modelMaterial));
                }
                //handle the case where during import we imported no materials at all
                //todo Instead of null material add a default xenko material
                if (entityInfo.Materials.Count == 0)
                {
                    var modelMaterial = new ModelMaterial {
                        Name = "Material", MaterialInstance = new MaterialInstance()
                    };
                    asset.Materials.Add(AttachId(modelMaterial));
                }
            }

            if (skeletonAsset != null)
            {
                asset.Skeleton = AttachedReferenceManager.CreateProxyObject <Skeleton>(skeletonAsset.Id, skeletonAsset.Location);
            }

            var modelUrl  = new UFile(localPath.GetFileName() + (shouldPostFixName?" Model": ""));
            var assetItem = new AssetItem(modelUrl, asset);

            assetReferences.Add(assetItem);
            return(assetItem);
        }
            public override void VisitSetItem(IEnumerable setObject, SetDescriptor descriptor, object item, ITypeDescriptor itemDescriptor)
            {
                base.VisitSetItem(setObject, descriptor, item, itemDescriptor);
                var assetReference    = item as AssetReference;
                var attachedReference = AttachedReferenceManager.GetAttachedReference(item);

                if (assetReference != null)
                {
                    AddLink(assetReference,
                            (guid, location) =>
                    {
                        var link = AssetReference.New(guid ?? assetReference.Id, location);
                        descriptor.Add(setObject, link);
                        return(link);
                    });
                }
                else if (attachedReference != null)
                {
                    AddLink(attachedReference,
                            (guid, location) =>
                    {
                        object link = guid.HasValue && guid.Value != AssetId.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ElementType, guid.Value, location) : null;
                        descriptor.Add(setObject, link);
                        return(link);
                    });
                }
                else if (item is UFile)
                {
                    AddLink(item,
                            (guid, location) =>
                    {
                        var link = new UFile(location);
                        descriptor.Add(setObject, link);
                        return(link);
                    });
                }
                else if (item is UDirectory)
                {
                    AddLink(item,
                            (guid, location) =>
                    {
                        var link = new UDirectory(location);
                        descriptor.Add(setObject, link);
                        return(link);
                    });
                }
            }
Beispiel #12
0
        /// <summary>
        /// Creates a reference to the given asset that matches the given reference type.
        /// </summary>
        /// <param name="asset">The target asset of the reference to create.</param>
        /// <param name="referenceType">The type of reference to create.</param>
        /// <returns>A reference to the given asset if it's not null and <paramref name="referenceType"/> is a valid reference type, null otherwise.</returns>
        /// <remarks>A reference type is either an <see cref="AssetReference"/> or a content type registered in the <see cref="AssetRegistry"/>.</remarks>
        public static object CreateReference(AssetViewModel asset, Type referenceType)
        {
            if (asset != null)
            {
                if (AssetRegistry.IsContentType(referenceType))
                {
                    var assetType   = asset.AssetItem.Asset.GetType();
                    var contentType = AssetRegistry.GetContentType(assetType);
                    return(referenceType.IsAssignableFrom(contentType) ? AttachedReferenceManager.CreateProxyObject(contentType, asset.Id, asset.Url) : null);
                }

                if (typeof(AssetReference).IsAssignableFrom(referenceType))
                {
                    return(new AssetReference(asset.AssetItem.Id, asset.AssetItem.Location));
                }
            }

            return(null);
        }
Beispiel #13
0
        private static void ImportAnimation(List <AssetItem> assetReferences, UFile localPath, List <string> animationNodes, bool shouldPostFixName, AssetItem skeletonAsset, TimeSpan animationStartTime, TimeSpan animationEndTime)
        {
            if (animationNodes != null && animationNodes.Count > 0)
            {
                var assetSource = localPath;

                var asset = new AnimationAsset {
                    Source = assetSource, AnimationTimeMaximum = animationEndTime, AnimationTimeMinimum = animationStartTime
                };
                var animUrl = localPath.GetFileNameWithoutExtension() + (shouldPostFixName ? " Animation" : "");

                if (skeletonAsset != null)
                {
                    asset.Skeleton = AttachedReferenceManager.CreateProxyObject <Skeleton>(skeletonAsset.Id, skeletonAsset.Location);
                }

                assetReferences.Add(new AssetItem(animUrl, asset));
            }
        }
Beispiel #14
0
        private void ParentPropertyChanged()
        {
            if (updatingParent || UndoRedoService.UndoRedoInProgress)
            {
                return;
            }

            try
            {
                updatingParent = true;
                var newValue = parent != null?AttachedReferenceManager.CreateProxyObject <Scene>(parent.Id, parent.AssetItem.Location) : null;

                parentNode.Update(newValue);
            }
            finally
            {
                updatingParent = false;
            }
        }
        public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar)
        {
            Guid  guid;
            UFile location;
            Guid  referenceId;

            if (!AssetReference.TryParse(fromScalar.Value, out referenceId, out guid, out location))
            {
                throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to decode asset reference [{0}]. Expecting format GUID:LOCATION".ToFormat(fromScalar.Value));
            }

            var instance = AttachedReferenceManager.CreateProxyObject(context.Descriptor.Type, guid, location);

            // If the referenceId is empty, force its creation, else attach it to the reference
            if (referenceId == Guid.Empty)
            {
                IdentifiableHelper.GetId(instance);
            }
            else
            {
                IdentifiableHelper.SetId(instance, referenceId);
            }
            return(instance);
        }
Beispiel #16
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService);

                assetManager.Serializer.RegisterSerializer(new ImageTextureSerializer());

                // Create atlas texture
                Dictionary <SpriteInfo, PackedSpriteInfo> spriteToPackedSprite = null;

                // Generate texture atlas
                var isPacking = Parameters.SheetAsset.Packing.Enabled;

                if (isPacking)
                {
                    var resultStatus = CreateAtlasTextures(commandContext, out spriteToPackedSprite);

                    if (resultStatus != ResultStatus.Successful)
                    {
                        return(Task.FromResult(resultStatus));
                    }
                }

                var imageGroupData = new SpriteSheet();

                // add the sprite data to the sprite list.
                foreach (var image in Parameters.SheetAsset.Sprites)
                {
                    string           textureUrl;
                    RectangleF       region;
                    ImageOrientation orientation;

                    var borders = image.Borders;
                    var center  = image.Center + (image.CenterFromMiddle ? new Vector2(image.TextureRegion.Width, image.TextureRegion.Height) / 2 : Vector2.Zero);

                    if (isPacking &&
                        spriteToPackedSprite.TryGetValue(image, out var packedSprite))    // ensure that unpackable elements (invalid because of null size/texture) are properly added in the sheet using the normal path
                    {
                        var isOriginalSpriteRotated = image.Orientation == ImageOrientation.Rotated90;

                        region      = packedSprite.Region;
                        orientation = (packedSprite.IsRotated ^ isOriginalSpriteRotated) ? ImageOrientation.Rotated90 : ImageOrientation.AsIs;
                        textureUrl  = SpriteSheetAsset.BuildTextureAtlasUrl(Url, spriteToPackedSprite[image].AtlasTextureIndex);

                        // update the center and border info, if the packer rotated the sprite
                        // note: X->Left, Y->Top, Z->Right, W->Bottom.
                        if (packedSprite.IsRotated)
                        {
                            // turned the sprite CCW
                            if (isOriginalSpriteRotated)
                            {
                                var oldCenterX = center.X;
                                center.X = center.Y;
                                center.Y = region.Height - oldCenterX;

                                var oldBorderW = borders.W;
                                borders.W = borders.X;
                                borders.X = borders.Y;
                                borders.Y = borders.Z;
                                borders.Z = oldBorderW;
                            }
                            else // turned the sprite CW
                            {
                                var oldCenterX = center.X;
                                center.X = region.Width - center.Y;
                                center.Y = oldCenterX;

                                var oldBorderW = borders.W;
                                borders.W = borders.Z;
                                borders.Z = borders.Y;
                                borders.Y = borders.X;
                                borders.X = oldBorderW;
                            }
                        }
                    }
                    else
                    {
                        region      = image.TextureRegion;
                        orientation = image.Orientation;
                        Parameters.ImageToTextureUrl.TryGetValue(image, out textureUrl);
                    }

                    // Affect the texture
                    Texture texture = null;
                    if (textureUrl != null)
                    {
                        texture = AttachedReferenceManager.CreateProxyObject <Texture>(AssetId.Empty, textureUrl);
                    }
                    else
                    {
                        commandContext.Logger.Warning($"Image '{image.Name}' has an invalid image source file '{image.Source}', resulting texture will be null.");
                    }

                    imageGroupData.Sprites.Add(new Graphics.Sprite
                    {
                        Name          = image.Name,
                        Region        = region,
                        Orientation   = orientation,
                        Center        = center,
                        Borders       = borders,
                        PixelsPerUnit = new Vector2(image.PixelsPerUnit),
                        Texture       = texture,
                        IsTransparent = false,
                    });
                }

                // set the transparency information to all the sprites
                if (Parameters.SheetAsset.Alpha != AlphaFormat.None) // Skip the calculation when format is forced without alpha.
                {
                    var urlToTexImage = new Dictionary <string, Tuple <TexImage, Image> >();
                    using (var texTool = new TextureTool())
                    {
                        foreach (var sprite in imageGroupData.Sprites)
                        {
                            if (sprite.Texture == null) // the sprite texture is invalid
                            {
                                continue;
                            }

                            var textureUrl = AttachedReferenceManager.GetOrCreateAttachedReference(sprite.Texture).Url;
                            if (!urlToTexImage.ContainsKey(textureUrl))
                            {
                                var image       = assetManager.Load <Image>(textureUrl);
                                var newTexImage = texTool.Load(image, false); // the sRGB mode does not impact on the alpha level
                                texTool.Decompress(newTexImage, false);       // the sRGB mode does not impact on the alpha level
                                urlToTexImage[textureUrl] = Tuple.Create(newTexImage, image);
                            }
                            var texImage = urlToTexImage[textureUrl].Item1;

                            var region = new Rectangle
                            {
                                X = (int)Math.Floor(sprite.Region.X),
                                Y = (int)Math.Floor(sprite.Region.Y)
                            };
                            region.Width  = (int)Math.Ceiling(sprite.Region.Right) - region.X;
                            region.Height = (int)Math.Ceiling(sprite.Region.Bottom) - region.Y;

                            var alphaLevel = texTool.GetAlphaLevels(texImage, region, null, commandContext.Logger); // ignore transparent color key here because the input image has already been processed
                            sprite.IsTransparent = alphaLevel != AlphaLevels.NoAlpha;
                        }

                        // free all the allocated images
                        foreach (var tuple in urlToTexImage.Values)
                        {
                            tuple.Item1.Dispose();
                            assetManager.Unload(tuple.Item2);
                        }
                    }
                }

                // save the imageData into the data base
                assetManager.Save(Url, imageGroupData);

                return(Task.FromResult(ResultStatus.Successful));
            }
Beispiel #17
0
            public override void VisitDictionaryKeyValue(object dictionaryObj, DictionaryDescriptor descriptor, object key, ITypeDescriptor keyDescriptor, object value, ITypeDescriptor valueDescriptor)
            {
                base.VisitDictionaryKeyValue(dictionaryObj, descriptor, key, keyDescriptor, value, valueDescriptor);
                var assetReference    = value as AssetReference;
                var attachedReference = AttachedReferenceManager.GetAttachedReference(value);

                if (assetReference != null)
                {
                    AddLink(assetReference,
                            (guid, location) =>
                    {
                        var newValue = AssetReference.New(guid ?? assetReference.Id, location);
                        descriptor.SetValue(dictionaryObj, key, newValue);
                        return(newValue);
                    });
                }
                else if (attachedReference != null)
                {
                    AddLink(attachedReference,
                            (guid, location) =>
                    {
                        object newValue = guid.HasValue && guid.Value != AssetId.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ValueType, guid.Value, location) : null;
                        descriptor.SetValue(dictionaryObj, key, newValue);
                        return(newValue);
                    });
                }
                else if (value is UFile)
                {
                    AddLink(value,
                            (guid, location) =>
                    {
                        var newValue = new UFile(location);
                        descriptor.SetValue(dictionaryObj, key, newValue);
                        return(newValue);
                    });
                }
                else if (value is UDirectory)
                {
                    AddLink(value,
                            (guid, location) =>
                    {
                        var newValue = new UDirectory(location);
                        descriptor.SetValue(dictionaryObj, key, newValue);
                        return(newValue);
                    });
                }
            }
Beispiel #18
0
            public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value)
            {
                base.VisitObjectMember(container, containerDescriptor, member, value);
                var assetReference    = value as AssetReference;
                var attachedReference = AttachedReferenceManager.GetAttachedReference(value);

                if (assetReference != null)
                {
                    AddLink(assetReference,
                            (guid, location) =>
                    {
                        var newValue = AssetReference.New(guid ?? assetReference.Id, location);
                        member.Set(container, newValue);
                        return(newValue);
                    });
                }
                else if (attachedReference != null)
                {
                    AddLink(attachedReference,
                            (guid, location) =>
                    {
                        object newValue = guid.HasValue && guid.Value != AssetId.Empty ? AttachedReferenceManager.CreateProxyObject(member.Type, guid.Value, location) : null;
                        member.Set(container, newValue);
                        return(newValue);
                    });
                }
                else if (value is UFile)
                {
                    AddLink(value,
                            (guid, location) =>
                    {
                        var newValue = new UFile(location);
                        member.Set(container, newValue);
                        return(newValue);
                    });
                }
                else if (value is UDirectory)
                {
                    AddLink(value,
                            (guid, location) =>
                    {
                        var newValue = new UDirectory(location);
                        member.Set(container, newValue);
                        return(newValue);
                    });
                }
            }
Beispiel #19
0
        public void TestMaterial()
        {
            var compiler = new EffectCompiler {
                UseFileSystem = true
            };
            var currentPath = Core.PlatformFolders.ApplicationBinaryDirectory;

            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Graphics\Shaders"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Shaders"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Core"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Lights"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Shadows"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Materials\Shaders"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Materials\ComputeColors\Shaders"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Skinning"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Shading"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Transformation"));
            compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\SiliconStudio.Xenko.Engine\Rendering\Utils"));
            var compilerParameters = new CompilerParameters {
                EffectParameters = { Platform = GraphicsPlatform.OpenGL }
            };

            var layers = new MaterialBlendLayers();

            layers.Add(new MaterialBlendLayer
            {
                BlendMap = new ComputeFloat(0.5f),
                Material = AttachedReferenceManager.CreateProxyObject <Material>(AssetId.Empty, "fake")
            });

            var materialAsset = new MaterialAsset
            {
                Attributes = new MaterialAttributes()
                {
                    Diffuse = new MaterialDiffuseMapFeature()
                    {
                        DiffuseMap = new ComputeColor(Color4.White)
                    },
                    DiffuseModel = new MaterialDiffuseLambertModelFeature()
                },
                Layers = layers
            };

            var fakeAsset = new MaterialAsset
            {
                Attributes = new MaterialAttributes()
                {
                    Diffuse = new MaterialDiffuseMapFeature()
                    {
                        DiffuseMap = new ComputeColor(Color.Blue)
                    },
                }
            };

            var context = new MaterialGeneratorContext {
                FindAsset = reference => fakeAsset
            };
            var result = MaterialGenerator.Generate(new MaterialDescriptor {
                Attributes = materialAsset.Attributes, Layers = materialAsset.Layers
            }, context, "TestMaterial");

            compilerParameters.Set(MaterialKeys.PixelStageSurfaceShaders, result.Material.Parameters.Get(MaterialKeys.PixelStageSurfaceShaders));
            var directionalLightGroup = new ShaderClassSource("LightDirectionalGroup", 1);

            compilerParameters.Set(LightingKeys.DirectLightGroups, new ShaderSourceCollection {
                directionalLightGroup
            });
            //compilerParameters.Set(LightingKeys.CastShadows, false);
            //compilerParameters.Set(MaterialParameters.HasSkinningPosition, true);
            //compilerParameters.Set(MaterialParameters.HasSkinningNormal, true);
            compilerParameters.Set(MaterialKeys.HasNormalMap, true);

            var results = compiler.Compile(new ShaderMixinGeneratorSource("XenkoEffectBase"), compilerParameters);

            Assert.IsFalse(results.HasErrors);
        }
 static Stride.Rendering.Material GetMaterial(MaterialAsset materialAsset, string name)
 {
     return(AttachedReferenceManager.CreateProxyObject <Stride.Rendering.Material>(materialAsset.Id, name));
 }
Beispiel #21
0
        /// <summary>
        /// Creates default scene, with a ground plane, sphere, directional light and camera.
        /// If graphicsProfile is 10+, add cubemap light, otherwise ambient light.
        /// Also properly setup graphics pipeline depending on if HDR is set or not
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <param name="package">The package in which to create these assets.</param>
        private void CreateAndSetNewScene(SessionTemplateGeneratorParameters parameters, Package package, ProjectReference projectGameReference, string projectGameName)
        {
            var logger = parameters.Logger;

            var graphicsProfile = parameters.GetTag(GraphicsProfileKey);
            var isHDR           = parameters.GetTag(IsHDRKey);

            if (graphicsProfile < GraphicsProfile.Level_10_0)
            {
                isHDR = false;
            }

            // Create the material for the sphere
            var sphereMaterial = new MaterialAsset
            {
                Attributes =
                {
                    Diffuse      = new MaterialDiffuseMapFeature(new ComputeColor(Color.FromBgra(0xFF8C8C8C))),
                    DiffuseModel = new MaterialDiffuseLambertModelFeature(),
                }
            };

            if (isHDR)
            {
                // Create HDR part of material
                sphereMaterial.Attributes.Specular      = new MaterialMetalnessMapFeature(new ComputeFloat(1.0f));
                sphereMaterial.Attributes.SpecularModel = new MaterialSpecularMicrofacetModelFeature();
                sphereMaterial.Attributes.MicroSurface  = new MaterialGlossinessMapFeature(new ComputeFloat(0.65f));
            }

            var sphereMaterialAssetItem = new AssetItem("Sphere Material", sphereMaterial);

            package.Assets.Add(sphereMaterialAssetItem);
            sphereMaterialAssetItem.IsDirty = true;

            // Create the sphere model
            var sphereModel = new ProceduralModelAsset
            {
                Type = new SphereProceduralModel
                {
                    MaterialInstance = { Material = AttachedReferenceManager.CreateProxyObject <Material>(sphereMaterialAssetItem.Id, sphereMaterialAssetItem.Location) },
                    Tessellation     = 30,
                },
            };
            var sphereModelAssetItem = new AssetItem("Sphere", sphereModel);

            package.Assets.Add(sphereModelAssetItem);
            sphereModelAssetItem.IsDirty = true;

            // Create sphere entity
            var sphereEntity = new Entity("Sphere")
            {
                new ModelComponent(AttachedReferenceManager.CreateProxyObject <Model>(sphereModelAssetItem.Id, sphereModelAssetItem.Location))
            };

            sphereEntity.Transform.Position = new Vector3(0.0f, 0.5f, 0.0f);

            // Create the material for the ground
            var groundMaterial = new MaterialAsset
            {
                Attributes =
                {
                    Diffuse      = new MaterialDiffuseMapFeature(new ComputeColor(Color.FromBgra(0xFF242424))),
                    DiffuseModel = new MaterialDiffuseLambertModelFeature(),
                }
            };

            if (isHDR)
            {
                // Create HDR part of material
                groundMaterial.Attributes.Specular      = new MaterialMetalnessMapFeature(new ComputeFloat(0.0f));
                groundMaterial.Attributes.SpecularModel = new MaterialSpecularMicrofacetModelFeature();
                groundMaterial.Attributes.MicroSurface  = new MaterialGlossinessMapFeature(new ComputeFloat(0.1f));
            }

            var groundMaterialAssetItem = new AssetItem("Ground Material", groundMaterial);

            package.Assets.Add(groundMaterialAssetItem);
            groundMaterialAssetItem.IsDirty = true;

            // Create the ground model
            var groundModel = new ProceduralModelAsset
            {
                Type = new PlaneProceduralModel
                {
                    Size             = new Vector2(10.0f, 10.0f),
                    MaterialInstance = { Material = AttachedReferenceManager.CreateProxyObject <Material>(groundMaterialAssetItem.Id, groundMaterialAssetItem.Location) },
                },
            };
            var groundModelAssetItem = new AssetItem("Ground", groundModel);

            package.Assets.Add(groundModelAssetItem);
            groundModelAssetItem.IsDirty = true;

            // Create the ground entity
            var groundEntity = new Entity("Ground")
            {
                new ModelComponent(AttachedReferenceManager.CreateProxyObject <Model>(groundModelAssetItem.Id, groundModelAssetItem.Location))
            };

            // Copy file in Resources
            var skyboxFilename = (UFile)(isHDR ? "skybox_texture_hdr.dds" : "skybox_texture_ldr.dds");

            try
            {
                var resources = UPath.Combine(parameters.OutputDirectory, (UDirectory)"Resources");
                Directory.CreateDirectory(resources.ToWindowsPath());

                // TODO: Hardcoded due to the fact that part of the template is in another folder in dev build
                // We might want to extend TemplateFolder to support those cases
                var dataDirectory  = ProjectTemplateGeneratorHelper.GetTemplateDataDirectory(parameters.Description);
                var skyboxFullPath = UPath.Combine(dataDirectory, skyboxFilename).ToWindowsPath();
                File.Copy(skyboxFullPath, UPath.Combine(resources, skyboxFilename).ToWindowsPath(), true);
            }
            catch (Exception ex)
            {
                logger.Error("Unexpected exception while copying cubemap", ex);
            }

            // Create the texture asset
            var skyboxTextureAsset = new TextureAsset {
                Source = Path.Combine(@"..\..\Resources", skyboxFilename), IsCompressed = isHDR, Type = new ColorTextureType {
                    UseSRgbSampling = false
                }
            };
            var skyboxTextureAssetItem = new AssetItem("Skybox texture", skyboxTextureAsset);

            package.Assets.Add(skyboxTextureAssetItem);
            skyboxTextureAssetItem.IsDirty = true;

            // Create the skybox asset
            var skyboxAsset = new SkyboxAsset
            {
                CubeMap = AttachedReferenceManager.CreateProxyObject <Texture>(skyboxTextureAssetItem.Id, skyboxTextureAssetItem.Location)
            };
            var skyboxAssetItem = new AssetItem("Skybox", skyboxAsset);

            package.Assets.Add(skyboxAssetItem);
            skyboxAssetItem.IsDirty = true;

            // Create the scene
            var defaultSceneAsset = isHDR ? SceneHDRFactory.Create() : SceneLDRFactory.Create();

            defaultSceneAsset.Hierarchy.Parts.Add(new EntityDesign(groundEntity));
            defaultSceneAsset.Hierarchy.RootParts.Add(groundEntity);

            defaultSceneAsset.Hierarchy.Parts.Add(new EntityDesign(sphereEntity));
            defaultSceneAsset.Hierarchy.RootParts.Add(sphereEntity);

            var sceneAssetItem = new AssetItem(GameSettingsAsset.DefaultSceneLocation, defaultSceneAsset);

            package.Assets.Add(sceneAssetItem);
            sceneAssetItem.IsDirty = true;

            // Sets the scene created as default in the shared profile
            var gameSettingsAsset = package.Assets.Find(GameSettingsAsset.GameSettingsLocation);

            if (gameSettingsAsset != null)
            {
                ((GameSettingsAsset)gameSettingsAsset.Asset).DefaultScene = AttachedReferenceManager.CreateProxyObject <Scene>(sceneAssetItem.Id, sceneAssetItem.Location);
                gameSettingsAsset.IsDirty = true;
            }

            var skyboxEntity = defaultSceneAsset.Hierarchy.Parts.Select(x => x.Value.Entity).Single(x => x.Name == SceneBaseFactory.SkyboxEntityName);

            skyboxEntity.Get <BackgroundComponent>().Texture = skyboxAsset.CubeMap;
            if (isHDR)
            {
                skyboxEntity.Get <LightComponent>().Type = new LightSkybox
                {
                    Skybox = AttachedReferenceManager.CreateProxyObject <Skybox>(skyboxAssetItem.Id, skyboxAssetItem.Location)
                };
            }

            var cameraEntity       = defaultSceneAsset.Hierarchy.Parts.Select(x => x.Value.Entity).Single(x => x.Name == SceneBaseFactory.CameraEntityName);
            var graphicsCompositor = package.Assets.Select(x => x.Asset).OfType <GraphicsCompositorAsset>().Single();

            cameraEntity.Components.Get <CameraComponent>().Slot = graphicsCompositor.Cameras.Single().ToSlotId();

            // Let's add camera script
            CreateCameraScript(parameters, package, projectGameReference, projectGameName, cameraEntity, sceneAssetItem);
        }
Beispiel #22
0
        protected override bool Generate(SessionTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            // Structure of files to generate:
            //     $Name$.xkpkg
            //     $Name$.targets
            //     Assets\
            //     $Name$.Game\
            //     $Name$.Windows\
            //     $Name$.Android\
            //     $Name$.iOS\

            var logger          = parameters.Logger;
            var platforms       = parameters.GetTag(PlatformsKey);
            var name            = parameters.Name;
            var outputDirectory = parameters.OutputDirectory;
            var orientation     = parameters.GetTag(OrientationKey);

            // Generate the package
            var package = NewPackageTemplateGenerator.GeneratePackage(parameters);

            // Generate projects for this package
            var session = parameters.Session;

            var sharedProfile = package.Profiles.FindSharedProfile();

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            //write gitignore
            WriteGitIgnore(parameters);

            var previousCurrent = session.CurrentPackage;

            session.CurrentPackage = package;

            var projectGameName = Utilities.BuildValidNamespaceName(name) + ".Game";

            var stepIndex = 0;
            var stepCount = platforms.Count + 1;

            // Log progress
            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectGameName}...", stepIndex++, stepCount);

            // Generate the Game library
            var projectGameReference = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, platforms, package, "ProjectLibrary.Game/ProjectLibrary.Game.ttproj", projectGameName, PlatformType.Shared, null, null, ProjectType.Library, orientation);

            projectGameReference.Type = ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectGameReference);

            // Add Effects as an asset folder in order to load xksl
            sharedProfile.AssetFolders.Add(new AssetFolder(projectGameName + "/Effects"));

            // Generate executable projects for each platform
            ProjectTemplateGeneratorHelper.UpdatePackagePlatforms(parameters, platforms, orientation, projectGameReference.Id, name, package, false);

            // Add asset packages
            CopyAssetPacks(parameters);

            // Load assets from HDD
            package.LoadTemporaryAssets(logger);

            // Validate assets
            package.ValidateAssets(true, false, logger);

            // Setup GraphicsCompositor using DefaultGraphicsCompositor
            var graphicsProfile      = parameters.GetTag(GraphicsProfileKey);
            var defaultCompositorUrl = graphicsProfile >= GraphicsProfile.Level_10_0 ? XenkoPackageUpgrader.DefaultGraphicsCompositorLevel10Url : XenkoPackageUpgrader.DefaultGraphicsCompositorLevel9Url;
            var defaultCompositor    = session.FindAsset(defaultCompositorUrl);

            var graphicsCompositor = new AssetItem("GraphicsCompositor", defaultCompositor.CreateDerivedAsset());

            package.Assets.Add(graphicsCompositor);
            graphicsCompositor.IsDirty = true;

            // Setup GameSettingsAsset
            var gameSettingsAsset = GameSettingsFactory.Create();

            gameSettingsAsset.GetOrCreate <EditorSettings>().RenderingMode = parameters.GetTag(IsHDRKey) ? RenderingMode.HDR : RenderingMode.LDR;
            gameSettingsAsset.GraphicsCompositor = AttachedReferenceManager.CreateProxyObject <GraphicsCompositor>(graphicsCompositor.ToReference());

            var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>();

            renderingSettings.DefaultGraphicsProfile = parameters.GetTag(GraphicsProfileKey);
            renderingSettings.DisplayOrientation     = (RequiredDisplayOrientation)orientation;

            var gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset);

            package.Assets.Add(gameSettingsAssetItem);
            gameSettingsAssetItem.IsDirty = true;

            // Add assets to the package
            AddAssets(parameters, package, projectGameReference, projectGameName);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", stepCount, stepCount);

            session.CurrentPackage = previousCurrent;
            return(true);
        }
        private object ExportModel(ICommandContext commandContext, ContentManager contentManager)
        {
            // Read from model file
            var modelSkeleton = LoadSkeleton(commandContext, contentManager); // we get model skeleton to compare it to real skeleton we need to map to

            AdjustSkeleton(modelSkeleton);
            var model = LoadModel(commandContext, contentManager);

            // Apply materials
            foreach (var modelMaterial in Materials)
            {
                if (modelMaterial.MaterialInstance?.Material == null)
                {
                    commandContext.Logger.Warning($"The material [{modelMaterial.Name}] is null in the list of materials.");
                }
                model.Materials.Add(modelMaterial.MaterialInstance);
            }

            model.BoundingBox = BoundingBox.Empty;

            foreach (var mesh in model.Meshes)
            {
                if (TessellationAEN)
                {
                    // TODO: Generate AEN model view
                    commandContext.Logger.Error("TessellationAEN is not supported in {0}", ContextAsString);
                }
            }

            SkeletonMapping skeletonMapping;

            Skeleton skeleton;

            if (SkeletonUrl != null)
            {
                // Load skeleton and process it
                skeleton = contentManager.Load <Skeleton>(SkeletonUrl);

                // Assign skeleton to model
                model.Skeleton = AttachedReferenceManager.CreateProxyObject <Skeleton>(Guid.Empty, SkeletonUrl);
            }
            else
            {
                skeleton = null;
            }

            skeletonMapping = new SkeletonMapping(skeleton, modelSkeleton);

            // Refresh skeleton updater with model skeleton
            var hierarchyUpdater = new SkeletonUpdater(modelSkeleton);

            hierarchyUpdater.UpdateMatrices();

            // Move meshes in the new nodes
            foreach (var mesh in model.Meshes)
            {
                // Apply scale import on meshes
                if (!MathUtil.NearEqual(ScaleImport, 1.0f))
                {
                    var transformationMatrix = Matrix.Scaling(ScaleImport);
                    mesh.Draw.VertexBuffers[0].TransformBuffer(ref transformationMatrix);
                }

                var skinning = mesh.Skinning;
                if (skinning != null)
                {
                    // Update node mapping
                    // Note: we only remap skinning matrices, but we could directly remap skinning bones instead
                    for (int i = 0; i < skinning.Bones.Length; ++i)
                    {
                        var linkNodeIndex    = skinning.Bones[i].NodeIndex;
                        var newLinkNodeIndex = skeletonMapping.SourceToSource[linkNodeIndex];

                        var nodeIndex    = mesh.NodeIndex;
                        var newNodeIndex = skeletonMapping.SourceToSource[mesh.NodeIndex];

                        skinning.Bones[i].NodeIndex = skeletonMapping.SourceToTarget[linkNodeIndex];

                        // Adjust scale import
                        if (!MathUtil.NearEqual(ScaleImport, 1.0f))
                        {
                            skinning.Bones[i].LinkToMeshMatrix.TranslationVector = skinning.Bones[i].LinkToMeshMatrix.TranslationVector * ScaleImport;
                        }

                        // If it was remapped, we also need to update matrix
                        if (nodeIndex != newNodeIndex)
                        {
                            // Update mesh part
                            var transformMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, newNodeIndex, nodeIndex);
                            transformMatrix.Invert();
                            skinning.Bones[i].LinkToMeshMatrix = Matrix.Multiply(transformMatrix, skinning.Bones[i].LinkToMeshMatrix);
                        }

                        if (newLinkNodeIndex != linkNodeIndex)
                        {
                            // Update link part
                            var transformLinkMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, newLinkNodeIndex, linkNodeIndex);
                            skinning.Bones[i].LinkToMeshMatrix = Matrix.Multiply(skinning.Bones[i].LinkToMeshMatrix, transformLinkMatrix);
                        }
                    }
                }

                // Check if there was a remap using model skeleton
                if (skeletonMapping.SourceToSource[mesh.NodeIndex] != mesh.NodeIndex)
                {
                    // Transform vertices
                    var transformationMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, skeletonMapping.SourceToSource[mesh.NodeIndex], mesh.NodeIndex);
                    mesh.Draw.VertexBuffers[0].TransformBuffer(ref transformationMatrix);

                    // Check if geometry is inverted, to know if we need to reverse winding order
                    // TODO: What to do if there is no index buffer? We should create one... (not happening yet)
                    if (mesh.Draw.IndexBuffer == null)
                    {
                        throw new InvalidOperationException();
                    }

                    Matrix  rotation;
                    Vector3 scale, translation;
                    if (transformationMatrix.Decompose(out scale, out rotation, out translation) &&
                        scale.X * scale.Y * scale.Z < 0)
                    {
                        mesh.Draw.ReverseWindingOrder();
                    }
                }

                // Update new node index using real asset skeleton
                mesh.NodeIndex = skeletonMapping.SourceToTarget[mesh.NodeIndex];
            }

            // Merge meshes with same parent nodes, material and skinning
            var meshesByNodes = model.Meshes.GroupBy(x => x.NodeIndex).ToList();

            foreach (var meshesByNode in meshesByNodes)
            {
                // This logic to detect similar material is kept from old code; this should be reviewed/improved at some point
                foreach (var meshesPerDrawCall in meshesByNode.GroupBy(x => x,
                                                                       new AnonymousEqualityComparer <Mesh>((x, y) =>
                                                                                                            x.MaterialIndex == y.MaterialIndex && // Same material
                                                                                                            ArrayExtensions.ArraysEqual(x.Skinning?.Bones, y.Skinning?.Bones) && // Same bones
                                                                                                            CompareParameters(model, x, y) && // Same parameters
                                                                                                            CompareShadowOptions(model, x, y), // Same shadow parameters
                                                                                                            x => 0)).ToList())
                {
                    if (meshesPerDrawCall.Count() == 1)
                    {
                        // Nothing to group, skip to next entry
                        continue;
                    }

                    // Remove old meshes
                    foreach (var mesh in meshesPerDrawCall)
                    {
                        model.Meshes.Remove(mesh);
                    }

                    // Add new combined mesh(es)
                    var baseMesh    = meshesPerDrawCall.First();
                    var newMeshList = meshesPerDrawCall.Select(x => x.Draw).ToList().GroupDrawData(Allow32BitIndex);

                    foreach (var generatedMesh in newMeshList)
                    {
                        model.Meshes.Add(new Mesh(generatedMesh, baseMesh.Parameters)
                        {
                            MaterialIndex = baseMesh.MaterialIndex,
                            Name          = baseMesh.Name,
                            Draw          = generatedMesh,
                            NodeIndex     = baseMesh.NodeIndex,
                            Skinning      = baseMesh.Skinning,
                        });
                    }
                }
            }

            // split the meshes if necessary
            model.Meshes = SplitExtensions.SplitMeshes(model.Meshes, Allow32BitIndex);

            // Refresh skeleton updater with asset skeleton
            hierarchyUpdater = new SkeletonUpdater(skeleton);
            hierarchyUpdater.UpdateMatrices();

            // bounding boxes
            var modelBoundingBox    = model.BoundingBox;
            var modelBoundingSphere = model.BoundingSphere;

            foreach (var mesh in model.Meshes)
            {
                var vertexBuffers = mesh.Draw.VertexBuffers;
                if (vertexBuffers.Length > 0)
                {
                    // Compute local mesh bounding box (no node transformation)
                    Matrix matrix = Matrix.Identity;
                    mesh.BoundingBox = vertexBuffers[0].ComputeBounds(ref matrix, out mesh.BoundingSphere);

                    // Compute model bounding box (includes node transformation)
                    hierarchyUpdater.GetWorldMatrix(mesh.NodeIndex, out matrix);
                    BoundingSphere meshBoundingSphere;
                    var            meshBoundingBox = vertexBuffers[0].ComputeBounds(ref matrix, out meshBoundingSphere);
                    BoundingBox.Merge(ref modelBoundingBox, ref meshBoundingBox, out modelBoundingBox);
                    BoundingSphere.Merge(ref modelBoundingSphere, ref meshBoundingSphere, out modelBoundingSphere);
                }

                // TODO: temporary Always try to compact
                mesh.Draw.CompactIndexBuffer();
            }
            model.BoundingBox    = modelBoundingBox;
            model.BoundingSphere = modelBoundingSphere;

            // merges all the Draw VB and IB together to produce one final VB and IB by entity.
            var sizeVertexBuffer = model.Meshes.SelectMany(x => x.Draw.VertexBuffers).Select(x => x.Buffer.GetSerializationData().Content.Length).Sum();
            var sizeIndexBuffer  = 0;

            foreach (var x in model.Meshes)
            {
                // Let's be aligned (if there was 16bit indices before, we might be off)
                if (x.Draw.IndexBuffer.Is32Bit && sizeIndexBuffer % 4 != 0)
                {
                    sizeIndexBuffer += 2;
                }

                sizeIndexBuffer += x.Draw.IndexBuffer.Buffer.GetSerializationData().Content.Length;
            }
            var vertexBuffer = new BufferData(BufferFlags.VertexBuffer, new byte[sizeVertexBuffer]);
            var indexBuffer  = new BufferData(BufferFlags.IndexBuffer, new byte[sizeIndexBuffer]);

            // Note: reusing same instance, to avoid having many VB with same hash but different URL
            var vertexBufferSerializable = vertexBuffer.ToSerializableVersion();
            var indexBufferSerializable  = indexBuffer.ToSerializableVersion();

            var vertexBufferNextIndex = 0;
            var indexBufferNextIndex  = 0;

            foreach (var drawMesh in model.Meshes.Select(x => x.Draw))
            {
                // the index buffer
                var oldIndexBuffer = drawMesh.IndexBuffer.Buffer.GetSerializationData().Content;

                // Let's be aligned (if there was 16bit indices before, we might be off)
                if (drawMesh.IndexBuffer.Is32Bit && indexBufferNextIndex % 4 != 0)
                {
                    indexBufferNextIndex += 2;
                }

                Array.Copy(oldIndexBuffer, 0, indexBuffer.Content, indexBufferNextIndex, oldIndexBuffer.Length);

                drawMesh.IndexBuffer = new IndexBufferBinding(indexBufferSerializable, drawMesh.IndexBuffer.Is32Bit, drawMesh.IndexBuffer.Count, indexBufferNextIndex);

                indexBufferNextIndex += oldIndexBuffer.Length;

                // the vertex buffers
                for (int index = 0; index < drawMesh.VertexBuffers.Length; index++)
                {
                    var vertexBufferBinding = drawMesh.VertexBuffers[index];
                    var oldVertexBuffer     = vertexBufferBinding.Buffer.GetSerializationData().Content;

                    Array.Copy(oldVertexBuffer, 0, vertexBuffer.Content, vertexBufferNextIndex, oldVertexBuffer.Length);

                    drawMesh.VertexBuffers[index] = new VertexBufferBinding(vertexBufferSerializable, vertexBufferBinding.Declaration, vertexBufferBinding.Count, vertexBufferBinding.Stride,
                                                                            vertexBufferNextIndex);

                    vertexBufferNextIndex += oldVertexBuffer.Length;
                }
            }

            // Convert to Entity
            return(model);
        }
        protected override bool Generate(SessionTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            // Structure of files to generate:
            //     $Name$.sdpkg
            //     $Name$.targets
            //     Assets\
            //     $Name$.Game\
            //     $Name$.Windows\
            //     $Name$.Android\
            //     $Name$.iOS\

            var logger          = parameters.Logger;
            var platforms       = parameters.GetTag(PlatformsKey);
            var name            = parameters.Name;
            var outputDirectory = parameters.OutputDirectory;
            var orientation     = parameters.GetTag(OrientationKey);

            // Generate the package
            //var package = NewPackageTemplateGenerator.GeneratePackage(parameters);

            // Generate projects for this package
            var session = parameters.Session;

            var projectGameName = Utilities.BuildValidNamespaceName(name);

            var stepIndex = 0;
            var stepCount = platforms.Count + 1;

            // Log progress
            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectGameName}...", stepIndex++, stepCount);

            // Generate the Game library
            var project = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, platforms, "ProjectLibrary.Game/ProjectLibrary.Game.ttproj", projectGameName, PlatformType.Shared, null, ProjectType.Library, orientation);
            var package = project.Package;

            //write gitignore
            WriteGitIgnore(parameters);

            // Setup the assets folder
            //Directory.CreateDirectory(UPath.Combine(package.RootDirectory, (UDirectory)"Assets/Shared"));

            session.Projects.Add(project);

            // Load missing references
            session.LoadMissingDependencies(parameters.Logger);
            // Load dependency assets (needed for camera script template)
            session.LoadMissingAssets(parameters.Logger, project.FlattenedDependencies.Select(x => x.Package).NotNull());

            // Add Effects as an asset folder in order to load sdsl
            package.AssetFolders.Add(new AssetFolder("Effects"));

            var packageParameters = new PackageTemplateGeneratorParameters
            {
                Name            = package.Meta.Name,
                OutputDirectory = package.FullPath.GetFullDirectory(),
                Description     = parameters.Description,
                Package         = package,
                Logger          = parameters.Logger,
                Namespace       = parameters.Namespace
            };

            // Generate executable projects for each platform
            var platformProjects = ProjectTemplateGeneratorHelper.UpdatePackagePlatforms(packageParameters, platforms, orientation, false).ToList();

            // Add asset packages
            CopyAssetPacks(parameters, package);

            // Create camera script
            var cameraScriptTemplate = TemplateManager.FindTemplates(package.Session).OfType <TemplateAssetDescription>().FirstOrDefault(x => x.DefaultOutputName == CameraScriptDefaultOutputName);

            if (cameraScriptTemplate == null)
            {
                throw new InvalidOperationException($"Could not find template for script '{CameraScriptDefaultOutputName}'");
            }

            var cameraScriptParameters = new AssetTemplateGeneratorParameters(string.Empty)
            {
                Name        = cameraScriptTemplate.DefaultOutputName,
                Description = cameraScriptTemplate,
                Namespace   = parameters.Namespace,
                Package     = package,
                Logger      = logger,
                Unattended  = true,
            };

            ScriptTemplateGenerator.SetClassName(cameraScriptParameters, cameraScriptTemplate.DefaultOutputName);
            if (!ScriptTemplateGenerator.Default.PrepareForRun(cameraScriptParameters).Result || !ScriptTemplateGenerator.Default.Run(cameraScriptParameters))
            {
                throw new InvalidOperationException($"Could not create script '{CameraScriptDefaultOutputName}'");
            }

            // Force save after having created the script
            // Note: We do that AFTER GameSettings is dirty, otherwise it would ask for an assembly reload (game settings saved might mean new graphics API)
            SaveSession(parameters);

            // Load missing references
            session.LoadMissingReferences(parameters.Logger);

            // Setup GraphicsCompositor using DefaultGraphicsCompositor
            var graphicsProfile      = parameters.GetTag(GraphicsProfileKey);
            var defaultCompositorUrl = graphicsProfile >= GraphicsProfile.Level_10_0 ? StridePackageUpgrader.DefaultGraphicsCompositorLevel10Url : StridePackageUpgrader.DefaultGraphicsCompositorLevel9Url;
            var defaultCompositor    = session.FindAsset(defaultCompositorUrl);

            var graphicsCompositor = new AssetItem("GraphicsCompositor", defaultCompositor.CreateDerivedAsset());

            package.Assets.Add(graphicsCompositor);
            graphicsCompositor.IsDirty = true;

            // Setup GameSettingsAsset
            var gameSettingsAsset = GameSettingsFactory.Create();

            gameSettingsAsset.GetOrCreate <EditorSettings>().RenderingMode = parameters.GetTag(IsHDRKey) ? RenderingMode.HDR : RenderingMode.LDR;
            gameSettingsAsset.GraphicsCompositor = AttachedReferenceManager.CreateProxyObject <GraphicsCompositor>(graphicsCompositor.ToReference());

            var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>();

            renderingSettings.DefaultGraphicsProfile = parameters.GetTag(GraphicsProfileKey);
            renderingSettings.DisplayOrientation     = (RequiredDisplayOrientation)orientation;

            var gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset);

            package.Assets.Add(gameSettingsAssetItem);
            gameSettingsAssetItem.IsDirty = true;

            // Add assets to the package
            AddAssets(parameters, package, projectGameName);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", stepCount, stepCount);

            // Set current project
            session.CurrentProject = platformProjects.FirstOrDefault(x => x.Platform == PlatformType.Windows) ?? project;

            return(true);
        }
 static Texture GetTexture(TextureAsset asset)
 {
     return(AttachedReferenceManager.CreateProxyObject <Texture>(asset.Id, asset.Source.FullPath));
 }
        /// <summary>
        /// Checks if a default scene exists for this game package.
        /// </summary>
        /// <param name="log">The log to output the result of the validation.</param>
        public override void Run(ILogger log)
        {
            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }

            foreach (var package in Session.Packages)
            {
                // Make sure package has its assets loaded
                if (package.State < PackageState.AssetsReady)
                {
                    continue;
                }

                var hasGameExecutable = package.Profiles.SelectMany(profile => profile.ProjectReferences).Any(projectRef => projectRef.Type == ProjectType.Executable);
                if (!hasGameExecutable)
                {
                    continue;
                }

                // Find game settings
                var       gameSettingsAssetItem = package.Assets.Find(GameSettingsAsset.GameSettingsLocation);
                AssetItem defaultScene          = null;

                // If game settings is found, try to find default scene inside
                var defaultSceneRuntime   = ((GameSettingsAsset)gameSettingsAssetItem?.Asset)?.DefaultScene;
                var defaultSceneReference = AttachedReferenceManager.GetAttachedReference(defaultSceneRuntime);
                if (defaultSceneReference != null)
                {
                    // Find it either by Url or Id
                    defaultScene = package.Assets.Find(defaultSceneReference.Id) ?? package.Assets.Find(defaultSceneReference.Url);

                    // Check it is actually a scene asset
                    if (defaultScene != null && !(defaultScene.Asset is SceneAsset))
                    {
                        defaultScene = null;
                    }
                }

                // Find or create default scene
                if (defaultScene == null)
                {
                    defaultScene = package.Assets.Find(GameSettingsAsset.DefaultSceneLocation);
                    if (defaultScene != null && !(defaultScene.Asset is SceneAsset))
                    {
                        defaultScene = null;
                    }
                }

                // Otherwise, try to find any scene
                if (defaultScene == null)
                {
                    defaultScene = package.Assets.FirstOrDefault(x => x.Asset is SceneAsset);
                }

                // Nothing found, let's create an empty one
                if (defaultScene == null)
                {
                    log.Error(package, null, AssetMessageCode.DefaultSceneNotFound, null);

                    var defaultSceneName  = NamingHelper.ComputeNewName(GameSettingsAsset.DefaultSceneLocation, package.Assets, a => a.Location);
                    var defaultSceneAsset = DefaultAssetFactory <SceneAsset> .Create();

                    defaultScene = new AssetItem(defaultSceneName, defaultSceneAsset);
                    package.Assets.Add(defaultScene);
                    defaultScene.IsDirty = true;
                }

                // Create game settings if not done yet
                if (gameSettingsAssetItem == null)
                {
                    log.Error(package, null, AssetMessageCode.AssetForPackageNotFound, GameSettingsAsset.GameSettingsLocation, package.FullPath.GetFileName());

                    var gameSettingsAsset = GameSettingsFactory.Create();

                    gameSettingsAsset.DefaultScene = AttachedReferenceManager.CreateProxyObject <Scene>(defaultScene.Id, defaultScene.Location);

                    gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset);
                    package.Assets.Add(gameSettingsAssetItem);

                    gameSettingsAssetItem.IsDirty = true;
                }
            }
        }
Beispiel #27
0
            public override void VisitArrayItem(Array array, ArrayDescriptor descriptor, int index, object item, ITypeDescriptor itemDescriptor)
            {
                base.VisitArrayItem(array, descriptor, index, item, itemDescriptor);
                var assetReference    = item as AssetReference;
                var attachedReference = AttachedReferenceManager.GetAttachedReference(item);

                if (assetReference != null)
                {
                    AddLink(item,
                            (guid, location) =>
                    {
                        var newValue = AssetReference.New(guid ?? assetReference.Id, location);
                        array.SetValue(newValue, index);
                        return(newValue);
                    });
                }
                else if (attachedReference != null)
                {
                    AddLink(attachedReference,
                            (guid, location) =>
                    {
                        object newValue = guid.HasValue && guid.Value != AssetId.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ElementType, guid.Value, location) : null;
                        array.SetValue(newValue, index);
                        return(newValue);
                    });
                }
                else if (item is UFile)
                {
                    AddLink(item,
                            (guid, location) =>
                    {
                        var newValue = new UFile(location);
                        array.SetValue(newValue, index);
                        return(newValue);
                    });
                }
                else if (item is UDirectory)
                {
                    AddLink(item,
                            (guid, location) =>
                    {
                        var newValue = new UFile(location);
                        array.SetValue(newValue, index);
                        return(newValue);
                    });
                }
            }
Beispiel #28
0
        private object ExportModel(ICommandContext commandContext, ContentManager contentManager)
        {
            // Read from model file
            var modelSkeleton = LoadSkeleton(commandContext, contentManager); // we get model skeleton to compare it to real skeleton we need to map to

            AdjustSkeleton(modelSkeleton);
            var model = LoadModel(commandContext, contentManager);

            if (!CheckInputSlots(commandContext, model))
            {
                return(null);
            }

            // Apply materials
            foreach (var modelMaterial in Materials)
            {
                if (modelMaterial.MaterialInstance?.Material == null)
                {
                    commandContext.Logger.Verbose($"The material [{modelMaterial.Name}] is null in the list of materials.");
                }
                model.Materials.Add(modelMaterial.MaterialInstance);
            }

            model.BoundingBox = BoundingBox.Empty;

            Skeleton skeleton;

            if (SkeletonUrl != null || !MergeMeshes)
            {
                if (SkeletonUrl != null)
                {
                    // Load the skeleton
                    skeleton = contentManager.Load <Skeleton>(SkeletonUrl);
                }
                else
                {
                    skeleton    = modelSkeleton;
                    SkeletonUrl = Location + "_Skeleton_" + Guid.NewGuid();
                    contentManager.Save(SkeletonUrl, skeleton);
                }

                // Assign skeleton to model
                model.Skeleton = AttachedReferenceManager.CreateProxyObject <Skeleton>(AssetId.Empty, SkeletonUrl);
            }
            else
            {
                skeleton = null;
            }

            var skeletonMapping = new SkeletonMapping(skeleton, modelSkeleton);

            // Refresh skeleton updater with model skeleton
            var hierarchyUpdater = new SkeletonUpdater(modelSkeleton);

            hierarchyUpdater.UpdateMatrices();

            // Move meshes in the new nodes
            foreach (var mesh in model.Meshes)
            {
                // Apply scale import on meshes
                if (!MathUtil.NearEqual(ScaleImport, 1.0f))
                {
                    var transformationMatrix = Matrix.Scaling(ScaleImport);
                    for (int vbIdx = 0; vbIdx < mesh.Draw.VertexBuffers.Length; vbIdx++)
                    {
                        mesh.Draw.VertexBuffers[vbIdx].TransformBuffer(ref transformationMatrix);
                    }
                }

                var skinning = mesh.Skinning;
                if (skinning != null)
                {
                    // Update node mapping
                    // Note: we only remap skinning matrices, but we could directly remap skinning bones instead
                    for (int i = 0; i < skinning.Bones.Length; ++i)
                    {
                        var linkNodeIndex    = skinning.Bones[i].NodeIndex;
                        var newLinkNodeIndex = skeletonMapping.SourceToSource[linkNodeIndex];

                        var nodeIndex    = mesh.NodeIndex;
                        var newNodeIndex = skeletonMapping.SourceToSource[mesh.NodeIndex];

                        skinning.Bones[i].NodeIndex = skeletonMapping.SourceToTarget[linkNodeIndex];

                        // Adjust scale import
                        if (!MathUtil.NearEqual(ScaleImport, 1.0f))
                        {
                            skinning.Bones[i].LinkToMeshMatrix.TranslationVector = skinning.Bones[i].LinkToMeshMatrix.TranslationVector * ScaleImport;
                        }

                        // If it was remapped, we also need to update matrix
                        if (nodeIndex != newNodeIndex)
                        {
                            // Update mesh part
                            var transformMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, newNodeIndex, nodeIndex);
                            transformMatrix.Invert();
                            skinning.Bones[i].LinkToMeshMatrix = Matrix.Multiply(transformMatrix, skinning.Bones[i].LinkToMeshMatrix);
                        }

                        if (newLinkNodeIndex != linkNodeIndex)
                        {
                            // Update link part
                            var transformLinkMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, newLinkNodeIndex, linkNodeIndex);
                            skinning.Bones[i].LinkToMeshMatrix = Matrix.Multiply(skinning.Bones[i].LinkToMeshMatrix, transformLinkMatrix);
                        }
                    }
                }

                // Check if there was a remap using model skeleton
                if (skeletonMapping.SourceToSource[mesh.NodeIndex] != mesh.NodeIndex)
                {
                    // Transform vertices
                    var transformationMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, skeletonMapping.SourceToSource[mesh.NodeIndex], mesh.NodeIndex);
                    for (int vbIdx = 0; vbIdx < mesh.Draw.VertexBuffers.Length; vbIdx++)
                    {
                        mesh.Draw.VertexBuffers[vbIdx].TransformBuffer(ref transformationMatrix);
                    }

                    // Check if geometry is inverted, to know if we need to reverse winding order
                    // TODO: What to do if there is no index buffer? We should create one... (not happening yet)
                    if (mesh.Draw.IndexBuffer == null)
                    {
                        throw new InvalidOperationException();
                    }

                    Matrix  rotation;
                    Vector3 scale, translation;
                    if (transformationMatrix.Decompose(out scale, out rotation, out translation) &&
                        scale.X * scale.Y * scale.Z < 0)
                    {
                        mesh.Draw.ReverseWindingOrder();
                    }
                }

                // Update new node index using real asset skeleton
                mesh.NodeIndex = skeletonMapping.SourceToTarget[mesh.NodeIndex];
            }

            // Apply custom model modifiers
            if (ModelModifiers != null)
            {
                foreach (var modifier in ModelModifiers)
                {
                    modifier.Apply(commandContext, model);
                }
            }

            // Merge meshes with same parent nodes, material and skinning
            var meshesByNodes = model.Meshes.GroupBy(x => x.NodeIndex).ToList();

            foreach (var meshesByNode in meshesByNodes)
            {
                // This logic to detect similar material is kept from old code; this should be reviewed/improved at some point
                foreach (var meshesPerDrawCall in meshesByNode.GroupBy(x => x,
                                                                       new AnonymousEqualityComparer <Mesh>((x, y) =>
                                                                                                            x.MaterialIndex == y.MaterialIndex && // Same material
                                                                                                            ArrayExtensions.ArraysEqual(x.Skinning?.Bones, y.Skinning?.Bones) && // Same bones
                                                                                                            CompareParameters(model, x, y) && // Same parameters
                                                                                                            CompareShadowOptions(model, x, y), // Same shadow parameters
                                                                                                            x => 0)).ToList())
                {
                    if (meshesPerDrawCall.Count() == 1)
                    {
                        // Nothing to group, skip to next entry
                        continue;
                    }

                    // Remove old meshes
                    foreach (var mesh in meshesPerDrawCall)
                    {
                        model.Meshes.Remove(mesh);
                    }

                    // Add new combined mesh(es)
                    var baseMesh    = meshesPerDrawCall.First();
                    var newMeshList = meshesPerDrawCall.Select(x => x.Draw).ToList().GroupDrawData(Allow32BitIndex);

                    foreach (var generatedMesh in newMeshList)
                    {
                        model.Meshes.Add(new Mesh(generatedMesh, baseMesh.Parameters)
                        {
                            MaterialIndex = baseMesh.MaterialIndex,
                            Name          = baseMesh.Name,
                            Draw          = generatedMesh,
                            NodeIndex     = baseMesh.NodeIndex,
                            Skinning      = baseMesh.Skinning,
                        });
                    }
                }
            }

            // split the meshes if necessary
            model.Meshes = SplitExtensions.SplitMeshes(model.Meshes, Allow32BitIndex);

            // Refresh skeleton updater with asset skeleton
            hierarchyUpdater = new SkeletonUpdater(skeleton);
            hierarchyUpdater.UpdateMatrices();

            // bounding boxes
            var modelBoundingBox    = model.BoundingBox;
            var modelBoundingSphere = model.BoundingSphere;

            foreach (var mesh in model.Meshes)
            {
                var vertexBuffers = mesh.Draw.VertexBuffers;
                for (int vbIdx = 0; vbIdx < vertexBuffers.Length; vbIdx++)
                {
                    // Compute local mesh bounding box (no node transformation)
                    Matrix matrix = Matrix.Identity;
                    mesh.BoundingBox = vertexBuffers[vbIdx].ComputeBounds(ref matrix, out mesh.BoundingSphere);

                    // Compute model bounding box (includes node transformation)
                    hierarchyUpdater.GetWorldMatrix(mesh.NodeIndex, out matrix);
                    BoundingSphere meshBoundingSphere;
                    var            meshBoundingBox = vertexBuffers[vbIdx].ComputeBounds(ref matrix, out meshBoundingSphere);
                    BoundingBox.Merge(ref modelBoundingBox, ref meshBoundingBox, out modelBoundingBox);
                    BoundingSphere.Merge(ref modelBoundingSphere, ref meshBoundingSphere, out modelBoundingSphere);
                }

                // TODO: temporary Always try to compact
                mesh.Draw.CompactIndexBuffer();
            }
            model.BoundingBox    = modelBoundingBox;
            model.BoundingSphere = modelBoundingSphere;

            // Count unique meshes (they can be shared)
            var uniqueDrawMeshes = model.Meshes.Select(x => x.Draw).Distinct();

            // Count unique vertex buffers and squish them together in a single buffer
            var uniqueVB = uniqueDrawMeshes.SelectMany(x => x.VertexBuffers).Distinct().ToList();

            var vbMap                    = new Dictionary <VertexBufferBinding, VertexBufferBinding>();
            var sizeVertexBuffer         = uniqueVB.Select(x => x.Buffer.GetSerializationData().Content.Length).Sum();
            var vertexBuffer             = new BufferData(BufferFlags.VertexBuffer, new byte[sizeVertexBuffer]);
            var vertexBufferSerializable = vertexBuffer.ToSerializableVersion();

            var vertexBufferNextIndex = 0;

            foreach (var vbBinding in uniqueVB)
            {
                var oldVertexBuffer = vbBinding.Buffer.GetSerializationData().Content;
                Array.Copy(oldVertexBuffer, 0, vertexBuffer.Content, vertexBufferNextIndex, oldVertexBuffer.Length);

                vbMap.Add(vbBinding, new VertexBufferBinding(vertexBufferSerializable, vbBinding.Declaration, vbBinding.Count, vbBinding.Stride, vertexBufferNextIndex));

                vertexBufferNextIndex += oldVertexBuffer.Length;
            }

            // Count unique index buffers and squish them together in a single buffer
            var uniqueIB        = uniqueDrawMeshes.Select(x => x.IndexBuffer).NotNull().Distinct().ToList();
            var sizeIndexBuffer = 0;

            foreach (var ibBinding in uniqueIB)
            {
                // Make sure 32bit indices are properly aligned to 4 bytes in case the last alignment was 2 bytes
                if (ibBinding.Is32Bit && sizeIndexBuffer % 4 != 0)
                {
                    sizeIndexBuffer += 2;
                }

                sizeIndexBuffer += ibBinding.Buffer.GetSerializationData().Content.Length;
            }

            var ibMap = new Dictionary <IndexBufferBinding, IndexBufferBinding>();

            if (uniqueIB.Count > 0)
            {
                var indexBuffer             = new BufferData(BufferFlags.IndexBuffer, new byte[sizeIndexBuffer]);
                var indexBufferSerializable = indexBuffer.ToSerializableVersion();
                var indexBufferNextIndex    = 0;

                foreach (var ibBinding in uniqueIB)
                {
                    var oldIndexBuffer = ibBinding.Buffer.GetSerializationData().Content;

                    // Make sure 32bit indices are properly aligned to 4 bytes in case the last alignment was 2 bytes
                    if (ibBinding.Is32Bit && indexBufferNextIndex % 4 != 0)
                    {
                        indexBufferNextIndex += 2;
                    }

                    Array.Copy(oldIndexBuffer, 0, indexBuffer.Content, indexBufferNextIndex, oldIndexBuffer.Length);

                    ibMap.Add(ibBinding, new IndexBufferBinding(indexBufferSerializable, ibBinding.Is32Bit, ibBinding.Count, indexBufferNextIndex));

                    indexBufferNextIndex += oldIndexBuffer.Length;
                }
            }

            // Assign new vertex and index buffer bindings
            foreach (var drawMesh in uniqueDrawMeshes)
            {
                for (int i = 0; i < drawMesh.VertexBuffers.Length; i++)
                {
                    drawMesh.VertexBuffers[i] = vbMap[drawMesh.VertexBuffers[i]];
                }

                if (drawMesh.IndexBuffer != null)
                {
                    drawMesh.IndexBuffer = ibMap[drawMesh.IndexBuffer];
                }
            }

            vbMap.Clear();
            ibMap.Clear();

            // Convert to Entity
            return(model);
        }
Beispiel #29
0
 protected static TContentType CreateRef <TContentType>(AssetItem assetItem) where TContentType : class, new()
 {
     return(AttachedReferenceManager.CreateProxyObject <TContentType>(assetItem.Id, assetItem.Location));
 }
Beispiel #30
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var    nodes = new List <SpriteStudioNode>();
                string modelName;

                if (!SpriteStudioXmlImport.ParseModel(Parameters.Source, nodes, out modelName))
                {
                    return(null);
                }

                var cells    = new List <SpriteStudioCell>();
                var textures = new List <UFile>();

                if (!SpriteStudioXmlImport.ParseCellMaps(Parameters.Source, textures, cells))
                {
                    return(null);
                }

                var anims = new List <SpriteStudioAnim>();

                if (!SpriteStudioXmlImport.ParseAnimations(Parameters.Source, anims))
                {
                    return(null);
                }

                var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService);

                var sheet = new SpriteSheet();

                foreach (var cell in cells)
                {
                    var sprite = new Sprite(cell.Name, AttachedReferenceManager.CreateProxyObject <Texture>(AssetId.Empty, Parameters.BuildTextures[cell.TextureIndex]))
                    {
                        Region        = cell.Rectangle,
                        Center        = cell.Pivot,
                        IsTransparent = true
                    };
                    sheet.Sprites.Add(sprite);
                }

                var nodeMapping = nodes.Select((x, i) => new { Name = x.Name, Index = i }).ToDictionary(x => x.Name, x => x.Index);

                //fill up some basic data for our model using the first animation in the array
                var anim = anims[0];

                foreach (var data in anim.NodesData)
                {
                    int nodeIndex;
                    if (!nodeMapping.TryGetValue(data.Key, out nodeIndex))
                    {
                        continue;
                    }

                    var node = nodes[nodeIndex];

                    foreach (var pair in data.Value.Data)
                    {
                        var tag = pair.Key;
                        if (pair.Value.All(x => x["time"] != "0"))
                        {
                            continue;
                        }
                        var value = pair.Value.First()["value"]; //do we always have a frame 0? should be the case actually
                        switch (tag)
                        {
                        case "POSX":
                            node.BaseState.Position.X = float.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "POSY":
                            node.BaseState.Position.Y = float.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "ROTZ":
                            node.BaseState.RotationZ = MathUtil.DegreesToRadians(float.Parse(value, CultureInfo.InvariantCulture));
                            break;

                        case "PRIO":
                            node.BaseState.Priority = int.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "SCLX":
                            node.BaseState.Scale.X = float.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "SCLY":
                            node.BaseState.Scale.Y = float.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "ALPH":
                            node.BaseState.Transparency = float.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "HIDE":
                            node.BaseState.Hide = int.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "FLPH":
                            node.BaseState.HFlipped = int.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "FLPV":
                            node.BaseState.VFlipped = int.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "CELL":
                            node.BaseState.SpriteId = int.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "COLV":
                            var color = new Color4(Color.FromBgra(int.Parse(value, CultureInfo.InvariantCulture)));
                            node.BaseState.BlendColor = colorSpace == ColorSpace.Linear ? color.ToLinear() : color;
                            break;

                        case "COLB":
                            node.BaseState.BlendType = (SpriteStudioBlending)int.Parse(value, CultureInfo.InvariantCulture);
                            break;

                        case "COLF":
                            node.BaseState.BlendFactor = float.Parse(value, CultureInfo.InvariantCulture);
                            break;
                        }
                    }
                }

                var spriteStudioSheet = new SpriteStudioSheet
                {
                    NodesInfo   = nodes,
                    SpriteSheet = sheet
                };

                assetManager.Save(Url, spriteStudioSheet);

                return(Task.FromResult(ResultStatus.Successful));
            }