@@ -139,6 +139,8 @@ private static void ExtractHull(DecomposedHulls hullDesc, out VertexPosition3[]
139139
140140 internal static unsafe BepuUtilities . Memory . Buffer < Triangle > ExtractBepuMesh ( Model model , IServiceRegistry services , BufferPool pool )
141141 {
142+ var nodeTransforms = ExtractNodeTransforms ( model ) ;
143+
142144 int totalIndices = 0 ;
143145 foreach ( var meshData in model . Meshes )
144146 {
@@ -148,13 +150,24 @@ internal static unsafe BepuUtilities.Memory.Buffer<Triangle> ExtractBepuMesh(Mod
148150 pool . Take < Triangle > ( totalIndices / 3 , out var triangles ) ;
149151 var bepuTriangles = triangles . As < Vector3 > ( ) ;
150152 var spanLeft = new Span < Vector3 > ( bepuTriangles . Memory , bepuTriangles . Length ) ;
151- foreach ( var mesh in model . Meshes )
153+ foreach ( var meshData in model . Meshes )
152154 {
153- mesh . Draw . IndexBuffer . AsReadable ( services , out var indexHelper , out int indexCount ) ;
154- mesh . Draw . VertexBuffers [ 0 ] . AsReadable ( services , out var vertexHelper , out int vertexCount ) ;
155+ meshData . Draw . IndexBuffer . AsReadable ( services , out var indexHelper , out int indexCount ) ;
156+ meshData . Draw . VertexBuffers [ 0 ] . AsReadable ( services , out var vertexHelper , out int vertexCount ) ;
155157
156158 var copyJob = new VertexBufferHelper . CopyAsTriangleList { IndexBufferHelper = indexHelper } ;
157- vertexHelper . Read < PositionSemantic , Vector3 , VertexBufferHelper . CopyAsTriangleList > ( spanLeft [ ..indexCount ] , copyJob ) ;
159+ var vertSlice = spanLeft [ ..indexCount ] ;
160+ vertexHelper . Read < PositionSemantic , Vector3 , VertexBufferHelper . CopyAsTriangleList > ( vertSlice , copyJob ) ;
161+
162+ if ( nodeTransforms != null )
163+ {
164+ for ( int i = 0 ; i < vertSlice . Length ; i ++ )
165+ {
166+ Matrix posMatrix = Matrix . Translation ( vertSlice [ i ] ) ;
167+ Matrix . Multiply ( ref posMatrix , ref nodeTransforms [ meshData . NodeIndex ] , out var finalMatrix ) ;
168+ vertSlice [ i ] = finalMatrix . TranslationVector ;
169+ }
170+ }
158171
159172 spanLeft = spanLeft [ indexCount ..] ;
160173 }
@@ -164,30 +177,87 @@ internal static unsafe BepuUtilities.Memory.Buffer<Triangle> ExtractBepuMesh(Mod
164177
165178 private static void ExtractMeshBuffers ( Model model , IServiceRegistry services , out VertexPosition3 [ ] vertices , out int [ ] indices )
166179 {
167- int totalVertices = 0 , totalIndices = 0 ;
180+ var nodeTransforms = ExtractNodeTransforms ( model ) ;
181+
182+ int totalVerts = 0 , totalIndices = 0 ;
168183 foreach ( var meshData in model . Meshes )
169184 {
170- totalVertices += meshData . Draw . VertexBuffers [ 0 ] . Count ;
185+ totalVerts += meshData . Draw . VertexBuffers [ 0 ] . Count ;
171186 totalIndices += meshData . Draw . IndexBuffer . Count ;
172187 }
173188
174- vertices = new VertexPosition3 [ totalVertices ] ;
175- indices = new int [ totalIndices ] ;
189+ var combinedVerts = new VertexPosition3 [ totalVerts ] ;
190+ var combinedIndices = new int [ totalIndices ] ;
191+ var verticesLeft = MemoryMarshal . Cast < VertexPosition3 , Vector3 > ( combinedVerts . AsSpan ( ) ) ;
192+ var indicesLeft = combinedIndices . AsSpan ( ) ;
176193
177- var verticesLeft = MemoryMarshal . Cast < VertexPosition3 , Vector3 > ( vertices . AsSpan ( ) ) ;
178- var indicesLeft = indices . AsSpan ( ) ;
179-
180- foreach ( var mesh in model . Meshes )
194+ int indexOffset = 0 ;
195+ foreach ( var meshData in model . Meshes )
181196 {
182- mesh . Draw . IndexBuffer . AsReadable ( services , out var indexHelper , out int indexCount ) ;
183- mesh . Draw . VertexBuffers [ 0 ] . AsReadable ( services , out var vertexHelper , out int vertexCount ) ;
197+ meshData . Draw . VertexBuffers [ 0 ] . AsReadable ( services , out var vertexHelper , out var vertexCount ) ;
198+ meshData . Draw . IndexBuffer . AsReadable ( services , out var indexHelper , out var indexCount ) ;
199+
200+ var vertSlice = verticesLeft [ ..vertexCount ] ;
201+ vertexHelper . Copy < PositionSemantic , Vector3 > ( vertSlice ) ;
202+
203+ if ( nodeTransforms != null )
204+ {
205+ for ( int i = 0 ; i < vertSlice . Length ; i ++ )
206+ {
207+ Matrix posMatrix = Matrix . Translation ( vertSlice [ i ] ) ;
208+ Matrix . Multiply ( ref posMatrix , ref nodeTransforms [ meshData . NodeIndex ] , out var finalMatrix ) ;
209+ vertSlice [ i ] = finalMatrix . TranslationVector ;
210+ }
211+ }
184212
185- vertexHelper . Copy < PositionSemantic , Vector3 > ( verticesLeft [ ..vertexCount ] ) ;
186- indexHelper . CopyTo ( indicesLeft [ ..indexCount ] ) ;
213+ var indicesForSlice = indicesLeft [ ..indexCount ] ;
214+ indexHelper . CopyTo ( indicesForSlice ) ;
215+ for ( int i = 0 ; i < indicesForSlice . Length ; i ++ )
216+ indicesForSlice [ i ] += indexOffset ;
217+ indexOffset += vertexCount ;
187218
188219 verticesLeft = verticesLeft [ vertexCount ..] ;
189220 indicesLeft = indicesLeft [ indexCount ..] ;
190221 }
222+
223+ vertices = combinedVerts ;
224+ indices = combinedIndices ;
225+ }
226+
227+ private static Matrix [ ] ? ExtractNodeTransforms ( Model model )
228+ {
229+ Matrix [ ] ? nodeTransforms = null ;
230+ if ( model . Skeleton == null )
231+ return nodeTransforms ;
232+
233+ var nodesLength = model . Skeleton . Nodes . Length ;
234+ nodeTransforms = new Matrix [ nodesLength ] ;
235+ nodeTransforms [ 0 ] = Matrix . Identity ;
236+ for ( var i = 0 ; i < nodesLength ; i ++ )
237+ {
238+ var node = model . Skeleton . Nodes [ i ] ;
239+ Matrix . Transformation ( ref node . Transform . Scale , ref node . Transform . Rotation , ref node . Transform . Position , out var localMatrix ) ;
240+
241+ Matrix worldMatrix ;
242+ if ( node . ParentIndex != - 1 )
243+ {
244+ if ( node . ParentIndex >= i )
245+ throw new InvalidOperationException ( "Skeleton nodes are not sorted" ) ;
246+ var nodeTransform = nodeTransforms [ node . ParentIndex ] ;
247+ Matrix . Multiply ( ref localMatrix , ref nodeTransform , out worldMatrix ) ;
248+ }
249+ else
250+ {
251+ worldMatrix = localMatrix ;
252+ }
253+
254+ if ( i != 0 )
255+ {
256+ nodeTransforms [ i ] = worldMatrix ;
257+ }
258+ }
259+
260+ return nodeTransforms ;
191261 }
192262
193263 /// <summary>
0 commit comments