private static void UpdateDecalPositions(InstancingId id, List <MyCubeInstanceData> instanceData, List <MyCubeInstanceDecalData> decals) { m_tmpDecalsUpdate.Clear(); for (int it1 = 0; it1 < decals.Count; it1++) { MyCubeInstanceDecalData decal = decals[it1]; MyCubeInstanceData cubeData = instanceData[decal.InstanceIndex]; if (!cubeData.EnableSkinning) { break; } MyDecalTopoData decalTopo; bool found = MyScreenDecals.GetDecalTopoData(decal.DecalId, out decalTopo); if (!found) { continue; } Matrix localCubeMatrix; Matrix skinningMatrix = cubeData.ConstructDeformedCubeInstanceMatrix(ref decalTopo.BoneIndices, ref decalTopo.BoneWeights, out localCubeMatrix); Matrix localCubeMatrixInv; Matrix.Invert(ref localCubeMatrix, out localCubeMatrixInv); // TODO: Optimization: it would be cool if we keep original cube coordiates local intersection // and avoid matrix inversion here. Refer to MyCubeGrid.GetIntersectionWithLine(), MyCubeGridHitInfo Matrix invBinding = decalTopo.MatrixBinding * localCubeMatrixInv; Matrix transform = invBinding * skinningMatrix; m_tmpDecalsUpdate.Add(new MyDecalPositionUpdate() { ID = decal.DecalId, Transform = transform }); } MyScreenDecals.UpdateDecals(m_tmpDecalsUpdate); }