Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
EntityCompilerParametersGenerator.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Concurrent;
5 using System.Collections.Generic;
6 using System.Linq;
7 
8 using SiliconStudio.Assets.Compiler;
9 using SiliconStudio.Core;
10 using SiliconStudio.Core.Diagnostics;
11 using SiliconStudio.Core.Serialization;
12 using SiliconStudio.Core.Serialization.Assets;
13 using SiliconStudio.Core.Storage;
14 using SiliconStudio.Paradox.Assets.Model;
15 using SiliconStudio.Paradox.Effects;
16 using SiliconStudio.Paradox.Effects.Data;
17 using SiliconStudio.Paradox.Engine.Data;
18 using SiliconStudio.Paradox.EntityModel.Data;
19 using SiliconStudio.Paradox.Shaders.Compiler;
20 
21 namespace SiliconStudio.Paradox.Assets.Effect.Generators
22 {
24  {
25  private static ParameterKey[] shadowKeys =
26  {
27  LightingKeys.CastShadows,
28  LightingKeys.ReceiveShadows
29  };
30 
31  public struct EntityParameters
32  {
37  };
38 
39  public override int GeneratorPriority
40  {
41  get
42  {
43  return 20;
44  }
45  }
46 
48 
50  {
51  // Cache all the entity parameters once
52  List<EntityParameters> entityParametersList;
53  var entityParametersSet = (ConcurrentDictionary<Guid, List<EntityParameters>>)context.Properties.GetOrAdd(EntityParametersKey, key => new ConcurrentDictionary<Guid, List<EntityParameters>>());
54  entityParametersList = entityParametersSet.GetOrAdd(context.Package.Id, key =>
55  {
56  var assetManager = new AssetManager();
57 
58  var settings = new AssetManagerLoaderSettings()
59  {
60  ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(ModelData), typeof(MeshData), typeof(MaterialData), typeof(LightingConfigurationsSetData)),
61  };
62 
63  var allEntityParameters = new List<EntityParameters>();
64  foreach (var entityAssetItem in context.Package.Assets.Where(item => item.Asset is EntityAsset))
65  {
66  var assetPath = entityAssetItem.Location.GetDirectoryAndFileName();
67  try
68  {
69  var entity = assetManager.Load<EntityData>(assetPath, settings);
70 
71  foreach (var modelComponent in entity.Components.Select(x => x.Value).OfType<ModelComponentData>())
72  {
73  foreach (var meshData in modelComponent.Model.Value.Meshes)
74  {
75  var lightingParameters = GetLightingParameters(meshData);
76  var materialParameters = GetMeshMaterialParameters(meshData);
77 
78  if (lightingParameters == null || lightingParameters.Count == 0)
79  {
80  EntityParameters entityParameters;
81  entityParameters.MaterialParameters = materialParameters;
82  entityParameters.ModelParameters = modelComponent.Parameters;
83  entityParameters.MeshParameters = meshData != null ? meshData.Parameters : null;
84  entityParameters.LightingParameters = null;
85  allEntityParameters.Add(entityParameters);
86  }
87  else
88  {
89  foreach (var lightConfig in lightingParameters)
90  {
91  EntityParameters entityParameters;
92  entityParameters.MaterialParameters = materialParameters;
93  entityParameters.ModelParameters = modelComponent.Parameters;
94  entityParameters.MeshParameters = meshData != null ? meshData.Parameters : null;
95  entityParameters.LightingParameters = lightConfig;
96  allEntityParameters.Add(entityParameters);
97  }
98  }
99  }
100  }
101  }
102  catch (Exception ex)
103  {
104  log.Error("Error while loading model mesh [{0}]", ex, assetPath);
105  }
106  }
107 
108  return allEntityParameters;
109  });
110 
111 
112  if (entityParametersList.Count != 0)
113  {
114  var useMeshParameters = baseParameters.Get(MeshKeys.UseParameters);
115  var useMaterialParameters = baseParameters.Get(MaterialAssetKeys.UseParameters) && !baseParameters.Get(MaterialAssetKeys.GenerateShader);
116  var hashParameters = new HashSet<ObjectId>();
117 
118  foreach (var entityParameters in entityParametersList)
119  {
120  // Add parameters in this order
121  // 1. Material
122  // 2. ModelComponent (Entity)
123  // 3. Mesh
124  // 4. Lighting
125 
126  var newParameters = new ParameterCollection();
127  if (useMaterialParameters)
128  AddToParameters(entityParameters.MaterialParameters, newParameters);
129 
130  AddToParameters(entityParameters.ModelParameters, newParameters);
131 
132  if (useMeshParameters)
133  AddToParameters(entityParameters.MeshParameters, newParameters);
134 
135  AddToParameters(entityParameters.LightingParameters, newParameters);
136 
137  byte[] buffer1;
138  var id = ObjectId.FromObject(newParameters, out buffer1);
139  if (!hashParameters.Contains(id))
140  {
141  hashParameters.Add(id);
142  var compilerParameters = baseParameters.Clone();
143  newParameters.CopyTo(compilerParameters);
144  yield return compilerParameters;
145  }
146  }
147  }
148  else
149  {
150  yield return baseParameters.Clone();
151  }
152  }
153 
154  /// <summary>
155  /// Get the parameters from the material.
156  /// </summary>
157  /// <param name="meshData">The mesh.</param>
158  /// <returns>The material parameters.</returns>
159  private ParameterCollectionData GetMeshMaterialParameters(MeshData meshData)
160  {
161  if (meshData != null)
162  {
163  var material = meshData.Material.Value;
164  if (material != null)
165  {
166  return material.Parameters;
167  }
168  }
169  return null;
170  }
171 
172  /// <summary>
173  /// Get the parameters from the lighting configurations.
174  /// </summary>
175  /// <param name="meshData">The mesh.</param>
176  /// <returns>The lighting configurations.</returns>
177  private List<ParameterCollectionData> GetLightingParameters(MeshData meshData)
178  {
179  if (meshData != null && meshData.Parameters != null && meshData.Parameters.ContainsKey(LightingKeys.LightingConfigurations))
180  {
181  var lightingDescContent = meshData.Parameters[LightingKeys.LightingConfigurations];
182  if (lightingDescContent != null && lightingDescContent is ContentReference<LightingConfigurationsSetData>)
183  {
184  var lightingDesc = ((ContentReference<LightingConfigurationsSetData>)lightingDescContent).Value;
185  if (lightingDesc != null)
186  {
187  var collection = new List<ParameterCollectionData>();
188  foreach (var config in lightingDesc.Configs)
189  {
190  var parameters = config.GetCollection();
191  SetShadowCasterReceiverConfiguration(meshData.Parameters, parameters, shadowKeys);
192  collection.Add(parameters);
193  }
194  return collection;
195  }
196  }
197  var defaultParameters = new ParameterCollectionData();
198  SetShadowCasterReceiverConfiguration(meshData.Parameters, defaultParameters, shadowKeys);
199  return new List<ParameterCollectionData> { defaultParameters };
200  }
201  return null;
202  }
203 
204  private static void SetShadowCasterReceiverConfiguration(ParameterCollectionData sourceParameters, ParameterCollectionData targetParameters, params ParameterKey[] keys)
205  {
206  if (sourceParameters != null)
207  {
208  foreach (var key in keys)
209  {
210  if (sourceParameters.ContainsKey(key))
211  targetParameters.Set(key, sourceParameters[key]);
212  }
213  }
214  }
215 
216  [ModuleInitializer]
217  internal static void Register()
218  {
219  // Register an instance of this generator to the effect asset compiler.
220  EffectLibraryAssetCompiler.RegisterCompilerParametersGenerator(new EntityCompilerParametersGenerator());
221  }
222  }
223 }
Key of an effect parameter.
Definition: ParameterKey.cs:15
SiliconStudio.Paradox.Effects.Data.ParameterCollectionData Parameters
Data field for SiliconStudio.Paradox.Effects.Mesh.Parameters.
Definition: EngineData.cs:212
static readonly ParameterKey< bool > GenerateShader
Allow material compilation without mesh.
Data type for SiliconStudio.Paradox.Effects.LightingConfigurationsSet.
Definition: EngineData.cs:139
Data type for SiliconStudio.Paradox.Effects.Material.
Definition: EngineData.cs:153
PackageAssetCollection Assets
Gets the assets stored in this package.
Definition: Package.cs:144
Specifies settings for AssetManager.Load{T} operations.
Data type for SiliconStudio.Paradox.Effects.ParameterCollection.
Definition: ParadoxData.cs:31
The context used when compiling an asset in a Package.
Defines keys associated with mesh used for compiling assets.
Data type for SiliconStudio.Paradox.EntityModel.Entity.
Definition: EngineData.cs:739
Data type for SiliconStudio.Paradox.Engine.ModelComponent.
Definition: EngineData.cs:674
PropertyCollection Properties
Gets the attributes attached to this context.
Data type for SiliconStudio.Paradox.Effects.Mesh.
Definition: EngineData.cs:197
Data type for SiliconStudio.Paradox.Effects.Model.
Definition: EngineData.cs:241
override IEnumerable< CompilerParameters > Generate(AssetCompilerContext context, CompilerParameters baseParameters, ILogger log)
Generates derived CompilerParameters from a base parameters.
static readonly ParameterKey< LightingConfigurationsSet > LightingConfigurations
Supported lighting configurations.
Definition: LightingKeys.cs:84
A class that represents a tag propety.
Definition: PropertyKey.cs:17
Interface for logging.
Definition: ILogger.cs:8
A container to handle a hierarchical collection of effect variables.