/// <summary> /// Calculate mesh only once ... no worry about animation, no accurate bounding box /// </summary> /// <param name="bones"></param> /// <param name="mesh"></param> /// <returns></returns> /// <remarks> /// https://gamedev.stackexchange.com/questions/46332/mesh-manipulation-on-gpu-vs-cpu /// https://gamedev.stackexchange.com/questions/43986/calculate-an-aabb-for-bone-animated-model /// </remarks> AnimationHittableGeometryComponent ConstructMesh(Matrix4x4[] bones, CMOAnimateMeshComponent mesh) { var pos = new List <Vector3>(); var norms = new List <Vector3>(); var indeces = new List <int>(); for (int indx = 0; indx < mesh.VertexBuffers.Count; indx++) { var vb = mesh.VertexBuffers[indx]; var vertices = new Vertex[vb.Length]; for (var i = 0; i < vb.Length; i++) { // Retrieve skinning information for vertex var skin = new SkinningVertex(); if (mesh.SkinningVertexBuffers.Count > 0) { skin = mesh.SkinningVertexBuffers[indx][i]; } // Create vertex vertices[i] = new Vertex(vb[i].Position, vb[i].Normal, (Vector4)vb[i].Color, vb[i].UV, skin); //the same matrix as in animation.hlsl var skinTransform = Matrix4x4.Transpose( bones[skin.BoneIndex0] * skin.BoneWeight0 + bones[skin.BoneIndex1] * skin.BoneWeight1 + bones[skin.BoneIndex2] * skin.BoneWeight2 + bones[skin.BoneIndex3] * skin.BoneWeight3); pos.Add(Vector3.Transform(vb[i].Position, skinTransform)); norms.Add(Vector3.TransformNormal(vb[i].Normal, skinTransform)); } } var offset = 0; // Initialize index buffers for (var i = 0; i < mesh.IndexBuffers.Count; i++) { var ib = mesh.IndexBuffers[i]; foreach (var ii in ib) { indeces.Add(offset + (int)ii); } offset += mesh.VertexBuffers[i].Length; } var geo = new AnimationHittableGeometryComponent(); geo.Positions = pos.ToImmutableArray(); geo.Indices = indeces.ToImmutableArray(); geo.Normals = norms.ToImmutableArray(); geo.IsModified = true; return(geo); }
void UpdateRenderComponent(Device device, D3DAnimRenderComponent render, CMOAnimateMeshComponent mesh) { render.ClearIndexBuffer(); render.ClearVertexBuffer(); render.TextureViews.Set(new List <ShaderResourceView>()); try { // Initialize vertex buffers for (int indx = 0; indx < mesh.VertexBuffers.Count; indx++) { var vb = mesh.VertexBuffers[indx]; Vertex[] vertices = new Vertex[vb.Length]; for (var i = 0; i < vb.Length; i++) { // Retrieve skinning information for vertex var skin = new SkinningVertex(); if (mesh.SkinningVertexBuffers.Count > 0) { skin = mesh.SkinningVertexBuffers[indx][i]; } // Create vertex vertices[i] = new Vertex(vb[i].Position, vb[i].Normal, (Vector4)vb[i].Color, vb[i].UV, skin); } render .AddVertexBuffer(Buffer.Create(device, BindFlags.VertexBuffer, vertices)) .DebugName = "VertexBuffer_" + indx.ToString(); } // Initialize index buffers for (var i = 0; i < mesh.IndexBuffers.Count; i++) { var ib = mesh.IndexBuffers[i]; render .AddIndexBuffer(Buffer.Create(device, BindFlags.IndexBuffer, ib)) .DebugName = "IndexBuffer_" + i.ToString(); } var tloader = new TextureLoader(device); //Load textures if a material has any. foreach (var mat in mesh.Materials) { for (var i = 0; i < mat.Textures.Length; i++) { if (System.IO.File.Exists(mat.Textures[i])) { render.TextureViews.Get().Add(tloader.LoadShaderResource(new FileInfo(mat.Textures[i]))); } else { render.TextureViews.Get().Add(null); } } } } catch (Exception ex) { ex.ToString(); } render.PerMaterialBuffer.Set(new Buffer(device, Unsafe.SizeOf <ConstantBuffers.PerMaterial>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)); render.PerObjectBuffer.Set(new Buffer(device, Unsafe.SizeOf <ConstantBuffers.PerObject>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)); render.PerArmatureBuffer.Set(new Buffer(device, ConstantBuffers.PerArmature.Size(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)); }