Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ModelRendererExtensions.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 
4 using System;
5 
6 using SiliconStudio.Core.Extensions;
7 using SiliconStudio.Core.Mathematics;
8 using SiliconStudio.Paradox.Effects.Modules;
9 
10 namespace SiliconStudio.Paradox.Effects
11 {
12  /// <summary>
13  /// Extensions filter for <see cref="ModelRenderer"/>
14  /// </summary>
15  public static class ModelRendererExtensions
16  {
17  // TODO: Add support for OR combination of filters
18 
19  /// <summary>
20  /// Adds a transparent filter for rendering meshes which are transparent.
21  /// </summary>
22  /// <param name="modelRenderer">The model renderer.</param>
23  /// <returns>ModelRenderer.</returns>
24  public static ModelRenderer AddTransparentFilter(this ModelRenderer modelRenderer)
25  {
26  modelRenderer.AcceptPrepareMeshForRendering.Add((model, mesh) => IsTransparent(mesh));
27  modelRenderer.AcceptRenderMesh.Add((context, effectMesh) => IsTransparent(effectMesh.Mesh));
28  modelRenderer.AppendDebugName("Transparent");
29  return modelRenderer;
30  }
31 
32  /// <summary>
33  /// Adds an opaque filter for rendering meshes which are opaque.
34  /// </summary>
35  /// <param name="modelRenderer">The model renderer.</param>
36  /// <returns>ModelRenderer.</returns>
37  public static ModelRenderer AddOpaqueFilter(this ModelRenderer modelRenderer)
38  {
39  modelRenderer.AcceptPrepareMeshForRendering.Add((model, mesh) => !IsTransparent(mesh));
40  modelRenderer.AcceptRenderMesh.Add((context, effectMesh) => !IsTransparent(effectMesh.Mesh));
41  modelRenderer.AppendDebugName("Opaque");
42  return modelRenderer;
43  }
44 
45  private static bool IsTransparent(Mesh mesh)
46  {
47  return mesh.Material.Parameters.Get(MaterialParameters.UseTransparent);
48  }
49 
50  /// <summary>
51  /// Adds a layer filter for rendering meshes only on the specified layer.
52  /// </summary>
53  /// <param name="modelRenderer">The model renderer.</param>
54  /// <param name="activelayers">The activelayers.</param>
55  /// <returns>ModelRenderer.</returns>
56  public static ModelRenderer AddLayerFilter(this ModelRenderer modelRenderer, RenderLayers activelayers)
57  {
58  modelRenderer.AcceptRenderMesh.Add((context, effectMesh) => (effectMesh.Mesh.Parameters.Get(RenderingParameters.RenderLayer) & activelayers) != RenderLayers.RenderLayerNone);
59  modelRenderer.AppendDebugName("Layer " + activelayers);
60  return modelRenderer;
61  }
62 
63  /// <summary>
64  /// Adds a layer filter for rendering meshes only on the context active layers.
65  /// </summary>
66  /// <param name="modelRenderer">The model renderer.</param>
67  /// <returns>ModelRenderer.</returns>
68  public static ModelRenderer AddContextActiveLayerFilter(this ModelRenderer modelRenderer)
69  {
70  modelRenderer.AcceptRenderMesh.Add((context, effectMesh) => (context.Parameters.Get(RenderingParameters.ActiveRenderLayer) & effectMesh.Mesh.Parameters.Get(RenderingParameters.RenderLayer)) != RenderLayers.RenderLayerNone);
71  modelRenderer.AppendDebugName("Active Layer");
72  return modelRenderer;
73  }
74 
75  /// <summary>
76  /// Adds a shadow caster filter for rendering only meshes that can cast shadows.
77  /// </summary>
78  /// <param name="modelRenderer">The model renderer.</param>
79  /// <returns>ModelRenderer.</returns>
80  public static ModelRenderer AddShadowCasterFilter(this ModelRenderer modelRenderer)
81  {
82  modelRenderer.AcceptPrepareMeshForRendering.Add((model, mesh) => mesh.Parameters.Get(LightingKeys.CastShadows));
83  modelRenderer.AcceptRenderMesh.Add((context, effectMesh) => effectMesh.Mesh.Parameters.Get(LightingKeys.CastShadows));
84  modelRenderer.AppendDebugName("ShadowMapCaster");
85  return modelRenderer;
86  }
87 
88  /// <summary>
89  /// Adds a default frustrum culling for rendering only meshes that are only inside the frustrum/
90  /// </summary>
91  /// <param name="modelRenderer">The model renderer.</param>
92  /// <returns>ModelRenderer.</returns>
93  public static ModelRenderer AddDefaultFrustrumCulling(this ModelRenderer modelRenderer)
94  {
95  return modelRenderer.UpdateMeshes.Add(
96  (context, meshes) =>
97  {
98  Matrix viewProjection, mat1, mat2;
99 
100  // Compute view * projection
101  modelRenderer.Pass.Parameters.Get(TransformationKeys.View, out mat1);
102  modelRenderer.Pass.Parameters.Get(TransformationKeys.Projection, out mat2);
103  Matrix.Multiply(ref mat1, ref mat2, out viewProjection);
104 
105  var frustum = new BoundingFrustum(ref viewProjection);
106 
107  for (var i = 0; i < meshes.Count; ++i)
108  {
109  var renderMesh = meshes[i];
110 
111  // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
112  // Get world matrix
113  renderMesh.Mesh.Parameters.Get(TransformationKeys.World, out mat1);
114 
115  // Compute transformed AABB (by world)
116  var boundingBox = renderMesh.Mesh.BoundingBox;
117  var center = boundingBox.Center;
118  var extent = boundingBox.Extent;
119 
120  Vector3.TransformCoordinate(ref center, ref mat1, out center);
121 
122  // Update world matrix into absolute form
123  unsafe
124  {
125  float* matrixData = &mat1.M11;
126  for (int j = 0; j < 16; ++j)
127  {
128  *matrixData = Math.Abs(*matrixData);
129  ++matrixData;
130  }
131  }
132 
133  Vector3.TransformNormal(ref extent, ref mat1, out extent);
134 
135  // Perform frustum culling
136  if (!Collision.FrustumContainsBox(ref frustum, ref center, ref extent))
137  {
138  meshes.SwapRemoveAt(i--);
139  }
140  }
141  }
142  );
143  }
144  }
145 }
static readonly ParameterKey< RenderLayers > RenderLayer
static ModelRenderer AddDefaultFrustrumCulling(this ModelRenderer modelRenderer)
Adds a default frustrum culling for rendering only meshes that are only inside the frustrum/ ...
static bool FrustumContainsBox(ref BoundingFrustum frustum, ref Vector3 center, ref Vector3 extent)
Determines whether a BoundingFrustum intersects or contains an AABB determined by its center and exte...
Definition: Collision.cs:1472
Contains static methods to help in determining intersections, containment, etc.
Definition: Collision.cs:60
static ModelRenderer AddOpaqueFilter(this ModelRenderer modelRenderer)
Adds an opaque filter for rendering meshes which are opaque.
static ModelRenderer AddContextActiveLayerFilter(this ModelRenderer modelRenderer)
Adds a layer filter for rendering meshes only on the context active layers.
static ModelRenderer AddTransparentFilter(this ModelRenderer modelRenderer)
Adds a transparent filter for rendering meshes which are transparent.
static readonly ParameterKey< bool > CastShadows
Flag stating if the mesh casts shadows.
Definition: LightingKeys.cs:68
This Renderer is responsible to prepare and render meshes for a specific pass.
static ModelRenderer AddLayerFilter(this ModelRenderer modelRenderer, RenderLayers activelayers)
Adds a layer filter for rendering meshes only on the specified layer.
static ModelRenderer AddShadowCasterFilter(this ModelRenderer modelRenderer)
Adds a shadow caster filter for rendering only meshes that can cast shadows.
static readonly ParameterKey< RenderLayers > ActiveRenderLayer
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47