/// <summary> /// Converts a <see cref="BasicMaterialContent"/> to an equivalent /// <see cref="SkinnedMaterialContent"/>. /// </summary> /// <param name="material">The <see cref="BasicMaterialContent"/>.</param> /// <returns>The <see cref="SkinnedMaterialContent"/>.</returns> public static SkinnedMaterialContent ConvertToSkinnedMaterial(MaterialContent material) { var skinnedMaterial = material as SkinnedMaterialContent; if (skinnedMaterial != null) return skinnedMaterial; var basicMaterial = material as BasicMaterialContent; if (basicMaterial != null) { skinnedMaterial = new SkinnedMaterialContent { Name = basicMaterial.Name, Identity = basicMaterial.Identity, Alpha = basicMaterial.Alpha, DiffuseColor = basicMaterial.DiffuseColor, EmissiveColor = basicMaterial.EmissiveColor, SpecularColor = basicMaterial.SpecularColor, SpecularPower = basicMaterial.SpecularPower, WeightsPerVertex = null }; skinnedMaterial.Textures.AddRange(basicMaterial.Textures); return skinnedMaterial; } return null; }
public override MaterialContent Process(MaterialContent input, ContentProcessorContext context) { MaterialContent processedMaterial; if (context.TargetProfile == Microsoft.Xna.Framework.Graphics.GraphicsProfile.HiDef) { processedMaterial = new SkinnedModelMaterialContent(); } else { processedMaterial = new SkinnedMaterialContent(); } ProcessTextures(input, processedMaterial, context); // Processes surface material ProcessMaterial(input, processedMaterial, context); return processedMaterial; }
private static void SetSkinnedMaterial(NodeContent node, Dictionary<MaterialContent, SkinnedMaterialContent> swappedMaterials, SkinnedMaterialContent defaultMaterial) { var mesh = node as MeshContent; if (mesh != null) { foreach (var geometry in mesh.Geometry) { if (!ContentHelper.IsSkinned(geometry)) continue; if (geometry.Material == null) { // Happens if the model is exported without a material. (XNA only!) geometry.Material = defaultMaterial; continue; } SkinnedMaterialContent skinnedMaterial; if (!swappedMaterials.TryGetValue(geometry.Material, out skinnedMaterial)) { // Convert BasicMaterialContent to SkinnedMaterialContent. skinnedMaterial = ContentHelper.ConvertToSkinnedMaterial(geometry.Material); if (skinnedMaterial == null) continue; swappedMaterials[geometry.Material] = skinnedMaterial; } geometry.Material = skinnedMaterial; } } foreach (var child in node.Children) SetSkinnedMaterial(child, swappedMaterials, defaultMaterial); }
/// <summary> /// Sets a <see cref="SkinnedMaterialContent"/> for all skinned meshes. /// </summary> private void SetSkinnedMaterial() { var swappedMaterials = new Dictionary<MaterialContent, SkinnedMaterialContent>(); var defaultMaterial = new SkinnedMaterialContent() { Identity = _input.Identity }; SetSkinnedMaterial(_input, swappedMaterials, defaultMaterial); }
/// <summary> /// If a node is skinned, we need to use the skinned model /// effect rather than basic effect. This function runs through the /// geometry and finds the meshes that have bone weights associated /// and swaps in the skinned effect. /// </summary> /// <param name="node"></param> void SwapSkinnedMaterial(NodeContent node) { // It has to be a MeshContent node MeshContent mesh = node as MeshContent; if (mesh != null) { // In the geometry we have to find a vertex channel that // has a bone weight collection foreach (GeometryContent geometry in mesh.Geometry) { bool swap = false; foreach (VertexChannel vchannel in geometry.Vertices.Channels) { if (vchannel is VertexChannel<BoneWeightCollection>) { swap = true; break; } } if (swap) { if (toSkinnedMaterial.ContainsKey(geometry.Material)) { // We have already swapped it geometry.Material = toSkinnedMaterial[geometry.Material]; } else { SkinnedMaterialContent smaterial = new SkinnedMaterialContent(); BasicMaterialContent bmaterial = geometry.Material as BasicMaterialContent; // Copy over the data smaterial.Alpha = bmaterial.Alpha; smaterial.DiffuseColor = bmaterial.DiffuseColor; smaterial.EmissiveColor = bmaterial.EmissiveColor; smaterial.SpecularColor = bmaterial.SpecularColor; smaterial.SpecularPower = bmaterial.SpecularPower; smaterial.Texture = bmaterial.Texture; smaterial.WeightsPerVertex = 4; toSkinnedMaterial[geometry.Material] = smaterial; geometry.Material = smaterial; } } } } foreach (NodeContent child in node.Children) { SwapSkinnedMaterial(child); } }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { if (material is SkinnedMaterialContent) return base.ConvertMaterial(material, context); // ----- The material is not a SkinnedMaterialContent --> Convert it to SkinnedMaterialContent. var skinnedMaterial = new SkinnedMaterialContent(); // Copy all textures. foreach (KeyValuePair<string, ExternalReference<TextureContent>> item in material.Textures) skinnedMaterial.Textures.Add(item.Key, item.Value); // Copy properties required by the SkinnedEffect. object data; if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.AlphaKey, out data)) skinnedMaterial.Alpha = (float)data; if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.DiffuseColorKey, out data)) skinnedMaterial.DiffuseColor = (Vector3)data; if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.EmissiveColorKey, out data)) skinnedMaterial.EmissiveColor = (Vector3)data; if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.SpecularColorKey, out data)) skinnedMaterial.SpecularColor = (Vector3)data; if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.SpecularPowerKey, out data) && data is float) skinnedMaterial.SpecularPower = (float)data; if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.TextureKey, out data)) { skinnedMaterial.Texture = (ExternalReference<TextureContent>)data; } else { // OpaqueData does not contain a texture. --> Use the first available texture instead. if (skinnedMaterial.Textures.Count > 0) skinnedMaterial.Texture = skinnedMaterial.Textures.Values.First(); } if (material.OpaqueData.TryGetValue(SkinnedMaterialContent.WeightsPerVertexKey, out data)) skinnedMaterial.WeightsPerVertex = (int)data; material = skinnedMaterial; return base.ConvertMaterial(material, context); }