Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        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));
        }