/// <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); }
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); }