Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ColliderShapeAssetCompiler.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 SiliconStudio.Assets.Compiler;
5 using SiliconStudio.BuildEngine;
6 using SiliconStudio.Core.IO;
7 using SiliconStudio.Core.Mathematics;
8 using SiliconStudio.Core.Serialization.Assets;
9 using SiliconStudio.Paradox.Effects.Data;
10 using SiliconStudio.Paradox.Engine;
11 using SiliconStudio.Paradox.Graphics.Data;
12 using System;
13 using System.Collections.Generic;
14 using System.Linq;
15 using System.Threading.Tasks;
16 
18 
19 using VHACDSharp;
20 
21 namespace SiliconStudio.Paradox.Assets.Physics
22 {
23  internal class ColliderShapeAssetCompiler : AssetCompilerBase<ColliderShapeAsset>
24  {
25  protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, ColliderShapeAsset asset, AssetCompilerResult result)
26  {
27  result.BuildSteps = new ListBuildStep
28  {
29  new ColliderShapeCombineCommand(urlInStorage, asset),
30  };
31 
32  result.ShouldWaitForPreviousBuilds = asset.Data.ColliderShapes.Any(shape => shape.GetType() == typeof(ConvexHullColliderShapeDesc));
33  }
34 
35  private class ColliderShapeCombineCommand : AssetCommand<ColliderShapeAsset>
36  {
37  public ColliderShapeCombineCommand(string url, ColliderShapeAsset asset)
38  : base(url, asset)
39  {
40  }
41 
42  private ConvexHullMesh convexHullMesh;
43 
44  public override void Cancel()
45  {
46  lock (this)
47  {
48  if (convexHullMesh != null) convexHullMesh.Cancel();
49  }
50  }
51 
52  protected override Task<ResultStatus> DoCommandOverride(ICommandContext commandContext)
53  {
54  var assetManager = new AssetManager();
55 
56  //pre process special types
57  foreach (var shape in asset.Data.ColliderShapes)
58  {
59  var type = shape.GetType();
60  if (type == typeof(ConvexHullColliderShapeDesc))
61  {
62  var convexHullDesc = (ConvexHullColliderShapeDesc)shape;
63 
64  //decompose and fill vertex data
65  if (convexHullDesc.Model != null)
66  {
67  var loadSettings = new AssetManagerLoaderSettings
68  {
69  ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(MeshData))
70  };
71 
72  var modelAsset = assetManager.Load<ModelData>(convexHullDesc.Model.Location, loadSettings);
73  if (modelAsset != null)
74  {
75  convexHullDesc.ConvexHulls = new List<List<List<Vector3>>>();
76  convexHullDesc.ConvexHullsIndices = new List<List<List<uint>>>();
77 
78  commandContext.Logger.Info("Processing convex hull generation, this might take a while!");
79 
80  var nodeTransforms = new List<Matrix>();
81 
82  //pre-compute all node transforms, assuming nodes are ordered... see ModelViewHierarchyUpdater
83  var nodesLength = modelAsset.Hierarchy.Nodes.Length;
84  for (var i = 0; i < nodesLength; i++)
85  {
86  Matrix localMatrix;
87  TransformationComponent.CreateMatrixTRS(
88  ref modelAsset.Hierarchy.Nodes[i].Transform.Translation,
89  ref modelAsset.Hierarchy.Nodes[i].Transform.Rotation,
90  ref modelAsset.Hierarchy.Nodes[i].Transform.Scaling, out localMatrix);
91 
92  Matrix worldMatrix;
93  if (modelAsset.Hierarchy.Nodes[i].ParentIndex != -1)
94  {
95  var nodeTransform = nodeTransforms[modelAsset.Hierarchy.Nodes[i].ParentIndex];
96  Matrix.Multiply(ref localMatrix, ref nodeTransform, out worldMatrix);
97  }
98  else
99  {
100  worldMatrix = localMatrix;
101  }
102 
103  nodeTransforms.Add(worldMatrix);
104  }
105 
106  for (var i = 0; i < nodesLength; i++)
107  {
108  var i1 = i;
109  if (modelAsset.Meshes.All(x => x.NodeIndex != i1)) continue; // no geometry in the node
110 
111  var combinedVerts = new List<float>();
112  var combinedIndices = new List<uint>();
113 
114  var hullsList = new List<List<Vector3>>();
115  convexHullDesc.ConvexHulls.Add(hullsList);
116 
117  var indicesList = new List<List<uint>>();
118  convexHullDesc.ConvexHullsIndices.Add(indicesList);
119 
120  foreach (var meshData in modelAsset.Meshes.Where(x => x.NodeIndex == i1))
121  {
122  var indexOffset = (uint)combinedVerts.Count / 3;
123 
124  var stride = meshData.Draw.VertexBuffers[0].Declaration.VertexStride;
125  var vertexDataAsset = assetManager.Load<BufferData>(meshData.Draw.VertexBuffers[0].Buffer.Location);
126 
127  var vertexData = vertexDataAsset.Content;
128  var vertexIndex = meshData.Draw.VertexBuffers[0].Offset;
129  for (var v = 0; v < meshData.Draw.VertexBuffers[0].Count; v++)
130  {
131  var posMatrix = Matrix.Translation(new Vector3(BitConverter.ToSingle(vertexData, vertexIndex + 0), BitConverter.ToSingle(vertexData, vertexIndex + 4), BitConverter.ToSingle(vertexData, vertexIndex + 8)));
132 
133  Matrix rotatedMatrix;
134  var nodeTransform = nodeTransforms[i];
135  Matrix.Multiply(ref posMatrix, ref nodeTransform, out rotatedMatrix);
136 
137  combinedVerts.Add(rotatedMatrix.TranslationVector.X);
138  combinedVerts.Add(rotatedMatrix.TranslationVector.Y);
139  combinedVerts.Add(rotatedMatrix.TranslationVector.Z);
140 
141  vertexIndex += stride;
142  }
143 
144  var indexDataAsset = assetManager.Load<BufferData>(meshData.Draw.IndexBuffer.Buffer.Location);
145 
146  var indexData = indexDataAsset.Content;
147  var indexIndex = meshData.Draw.IndexBuffer.Offset;
148  for (var v = 0; v < meshData.Draw.IndexBuffer.Count; v++)
149  {
150  if (meshData.Draw.IndexBuffer.Is32Bit)
151  {
152  combinedIndices.Add(BitConverter.ToUInt32(indexData, indexIndex) + indexOffset);
153  indexIndex += 4;
154  }
155  else
156  {
157  combinedIndices.Add(BitConverter.ToUInt16(indexData, indexIndex) + indexOffset);
158  indexIndex += 2;
159  }
160  }
161  }
162 
163  var decompositionDesc = new ConvexHullMesh.DecompositionDesc
164  {
165  VertexCount = (uint)combinedVerts.Count / 3,
166  IndicesCount = (uint)combinedIndices.Count,
167  Vertexes = combinedVerts.ToArray(),
168  Indices = combinedIndices.ToArray(),
169  Depth = convexHullDesc.Depth,
170  PosSampling = convexHullDesc.PosSampling,
171  PosRefine = convexHullDesc.PosRefine,
172  AngleSampling = convexHullDesc.AngleSampling,
173  AngleRefine = convexHullDesc.AngleRefine,
174  Alpha = convexHullDesc.Alpha,
175  Threshold = convexHullDesc.Threshold,
176  SimpleHull = convexHullDesc.SimpleWrap
177  };
178 
179  lock (this)
180  {
181  convexHullMesh = new ConvexHullMesh();
182  }
183 
184  convexHullMesh.Generate(decompositionDesc);
185 
186  var count = convexHullMesh.Count;
187 
188  commandContext.Logger.Info("Node generated " + count + " convex hulls");
189 
190  var vertexCountHull = 0;
191 
192  for (uint h = 0; h < count; h++)
193  {
194  float[] points;
195  convexHullMesh.CopyPoints(h, out points);
196 
197  var pointList = new List<Vector3>();
198 
199  for (var v = 0; v < points.Length; v += 3)
200  {
201  var vert = new Vector3(points[v + 0], points[v + 1], points[v + 2]);
202  pointList.Add(vert);
203 
204  vertexCountHull++;
205  }
206 
207  hullsList.Add(pointList);
208 
209  uint[] indices;
210  convexHullMesh.CopyIndices(h, out indices);
211 
212  //for (var t = 0; t < indices.Length; t += 3)
213  //{
214  // Utilities.Swap(ref indices[t], ref indices[t + 2]);
215  //}
216 
217  var indexList = new List<uint>(indices);
218 
219  indicesList.Add(indexList);
220  }
221 
222  lock (this)
223  {
224  convexHullMesh.Dispose();
225  convexHullMesh = null;
226  }
227 
228  commandContext.Logger.Info("For a total of " + vertexCountHull + " vertexes");
229  }
230  }
231  }
232 
233  //clear up the reference as we don't need this data anymore
234  convexHullDesc.Model = null;
235  }
236  }
237 
238  assetManager.Save(Url, asset.Data);
239 
240  return Task.FromResult(ResultStatus.Successful);
241  }
242  }
243  }
244 }
Result of a compilation of assets when using IAssetCompiler.Compile
A command processing an Asset.
Definition: AssetCommand.cs:11
Specifies settings for AssetManager.Load{T} operations.
The context used when compiling an asset in a Package.
_In_ size_t count
Definition: DirectXTexP.h:174
using VHACDSharp
Data type for SiliconStudio.Paradox.Effects.Mesh.
Definition: EngineData.cs:197
Data type for SiliconStudio.Paradox.Effects.Model.
Definition: EngineData.cs:241
using SiliconStudio.Paradox. Physics
SiliconStudio.Core.Mathematics.Vector3 Vector3
Content of a GPU buffer (vertex buffer, index buffer, etc...).
Definition: BufferData.cs:10
Defines a normalized file path. See UPath for details. This class cannot be inherited.
Definition: UFile.cs:13
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47