Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
TransformationProcessor.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.Generic;
5 using System.Collections.Specialized;
6 using SiliconStudio.Paradox.EntityModel;
7 using SiliconStudio.Paradox.Games;
8 using SiliconStudio.Core;
9 using SiliconStudio.Core.Collections;
10 using SiliconStudio.Core.Mathematics;
11 using SiliconStudio.Paradox.Threading;
12 
13 namespace SiliconStudio.Paradox.Engine
14 {
15  /// <summary>
16  /// Updates <see cref="TransformationComponent.WorldMatrix"/> of entities.
17  /// </summary>
18  public class TransformationProcessor : EntityProcessor<TransformationProcessor.AssociatedData>
19  {
20  /// <summary>
21  /// List of <see cref="TransformationComponent"/> of every <see cref="Entity"/> in <see cref="EntitySystem.RootEntities"/>.
22  /// </summary>
23  private readonly TrackingHashSet<TransformationComponent> transformationRoots = new TrackingHashSet<TransformationComponent>();
24 
25  /// <summary>
26  /// The list of the components that are not special roots.
27  /// </summary>
28  /// <remarks>This field is instantiated here to avoid reallocation at each frames</remarks>
29  private readonly FastCollection<TransformationComponent> notSpecialRootComponents = new FastCollection<TransformationComponent>();
30 
31  /// <summary>
32  /// Initializes a new instance of the <see cref="TransformationProcessor" /> class.
33  /// </summary>
35  : base(new PropertyKey[] { TransformationComponent.Key })
36  {
37  }
38 
39  /// <inheritdoc/>
40  protected override AssociatedData GenerateAssociatedData(Entity entity)
41  {
42  return new AssociatedData { TransformationComponent = entity.Transformation };
43  }
44 
45  /// <inheritdoc/>
46  protected internal override void OnSystemAdd()
47  {
48  var rootEntities = EntitySystem.GetProcessor<HierarchicalProcessor>().RootEntities;
49  ((ITrackingCollectionChanged)rootEntities).CollectionChanged += rootEntities_CollectionChanged;
50 
51  // Add transformation of existing root entities
52  foreach (var entity in rootEntities)
53  {
54  transformationRoots.Add(entity.Transformation);
55  }
56  }
57 
58  /// <inheritdoc/>
59  protected internal override void OnSystemRemove()
60  {
61  transformationRoots.Clear();
62  }
63 
64  internal static void UpdateTransformations(FastCollection<TransformationComponent> transformationComponents, bool skipSpecialRoots)
65  {
66  // To avoid GC pressure (due to lambda), parallelize only if required
67  if (transformationComponents.Count >= 1024)
68  {
69  TaskList.Dispatch(
70  transformationComponents,
71  8,
72  1024,
73  (i, transformation) =>
74  {
75  if (skipSpecialRoots && transformation.isSpecialRoot)
76  return;
77 
78  UpdateTransformation(transformation);
79 
80  // Recurse
81  if (transformation.Children.Count > 0)
82  UpdateTransformations(transformation.Children, true);
83  }
84  );
85  }
86  else
87  {
88  foreach (var transformation in transformationComponents)
89  {
90  if (skipSpecialRoots && transformation.isSpecialRoot)
91  return;
92 
93  UpdateTransformation(transformation);
94 
95  // Recurse
96  if (transformation.Children.Count > 0)
97  UpdateTransformations(transformation.Children, true);
98  }
99  }
100  }
101 
102  private static void UpdateTransformation(TransformationComponent transformation)
103  {
104  // Update transformation
105  transformation.UpdateLocalMatrix();
106  transformation.UpdateWorldMatrixNonRecursive();
107  }
108 
109  /// <summary>
110  /// Updates all the <see cref="TransformationComponent.WorldMatrix"/>.
111  /// </summary>
112  /// <param name="time"></param>
113  public override void Draw(GameTime time)
114  {
115  notSpecialRootComponents.Clear();
116  foreach (var t in transformationRoots)
117  if(!t.isSpecialRoot)
118  notSpecialRootComponents.Add(t);
119 
120  // Special roots are already filtered out
121  UpdateTransformations(notSpecialRootComponents, false);
122  }
123 
124  /// <summary>
125  /// Creates a matrix that contains the X, Y and Z rotation.
126  /// </summary>
127  /// <param name="rotation">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param>
128  /// <param name="result">When the method completes, contains the created rotation matrix.</param>
129  public static void CreateMatrixR(ref Vector3 rotation, out Matrix result)
130  {
131  // Equivalent to:
132  //result =
133  // *Matrix.RotationX(rotation.X)
134  // *Matrix.RotationY(rotation.Y)
135  // *Matrix.RotationZ(rotation.Z)
136 
137  // Precompute cos and sin
138  var cosX = (float)Math.Cos(rotation.X);
139  var sinX = (float)Math.Sin(rotation.X);
140  var cosY = (float)Math.Cos(rotation.Y);
141  var sinY = (float)Math.Sin(rotation.Y);
142  var cosZ = (float)Math.Cos(rotation.Z);
143  var sinZ = (float)Math.Sin(rotation.Z);
144 
145  // Precompute some multiplications
146  var sinZY = sinZ * sinY;
147  var cosXZ = cosZ * cosX;
148  var cosZsinY = cosZ * sinX;
149 
150  // Rotation
151  result.M11 = cosZ * cosY;
152  result.M21 = cosZsinY * sinY - cosX * sinZ;
153  result.M31 = sinZ * sinX + cosXZ * sinY;
154  result.M12 = cosY * sinZ;
155  result.M22 = cosXZ + sinZY * sinX;
156  result.M32 = cosX * sinZY - cosZsinY;
157  result.M13 = -sinY;
158  result.M23 = cosY * sinX;
159  result.M33 = cosY * cosX;
160 
161  // Translation
162  result.M41 = 0;
163  result.M42 = 0;
164  result.M43 = 0;
165 
166  result.M14 = 0.0f;
167  result.M24 = 0.0f;
168  result.M34 = 0.0f;
169  result.M44 = 1.0f;
170  }
171 
172  public struct AssociatedData
173  {
175  }
176 
177  private void rootEntities_CollectionChanged(object sender, TrackingCollectionChangedEventArgs e)
178  {
179  switch (e.Action)
180  {
181  case NotifyCollectionChangedAction.Add:
182  transformationRoots.Add(((Entity)e.Item).Transformation);
183  break;
184  case NotifyCollectionChangedAction.Remove:
185  transformationRoots.Remove(((Entity)e.Item).Transformation);
186  break;
187  }
188  }
189  }
190 }
override void Draw(GameTime time)
Updates all the TransformationComponent.WorldMatrix.
static void CreateMatrixR(ref Vector3 rotation, out Matrix result)
Creates a matrix that contains the X, Y and Z rotation.
Game entity. It usually aggregates multiple EntityComponent
Definition: Entity.cs:28
Defines Position, Rotation and Scale of its Entity.
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
Entity processor, triggered on various EntitySystem events such as Entity and Component additions and...
This processor will take care of adding/removing children of every Entity added/removed in the Entity...
Current timing used for variable-step (real time) or fixed-step (game time) games.
Definition: GameTime.cs:31
object Item
Gets the added or removed item (if dictionary, value only).
NotifyCollectionChangedAction Action
Gets the type of action performed. Allowed values are NotifyCollectionChangedAction.Add and NotifyCollectionChangedAction.Remove.
Updates TransformationComponent.WorldMatrix of entities.
override AssociatedData GenerateAssociatedData(Entity entity)
A class that represents a tag propety.
Definition: PropertyKey.cs:17
TransformationProcessor()
Initializes a new instance of the TransformationProcessor class.
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47