예제 #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);
        }
예제 #2
0
        OrientationComponent CreateStickOnComponent(AnimationHittableGeometryComponent geo)
        {
            var box = geo.Box;
            var com = new OrientationComponent();

            com.AxisUpLocal         = -Vector3.UnitZ;                                       //local axis of current anim mesh by default
            com.AttachPointLocal    = box.GetCenter() + com.AxisUpLocal * box.Size().Z / 2; //the bottom point of Box for stick on terrain
            com.FrontDirectionLocal = Vector3.UnitY;

            return(com);
        }