Я работаю над анимацией целевой морфы.Использование параллельной обработки для Point3D
Я пытаюсь найти способы ускорить некоторые вычисления точек сетки в 3D WPF.
Итак, у меня есть две сетки - «текущая» сетка, которая содержит состояние игры и сетку «морфинга», которые мне нужно рассчитать различия между ними.
Я пытаюсь использовать параллельный цикл, но он продолжает бросать ошибку:
Первый шанс исключение типа «System.InvalidOperationException» произошло в WindowsBase.dll Первый шанс исключение type 'System.InvalidOperationException' произошел в mscorlib.dll В начале случайное исключение типа 'System.AggregateException' произошло в mscorlib.dll Дополнительная информация: Произошла одна или несколько ошибок.
Программа '[7444] HelixTrial.vshost.exe' вышла с кодом -1 (0xffffffff).
Мой код довольно простой. Он делает список, подсчитывает позиции в текущей сетке (которая равна целевой сетке морщин). Затем он пересекает сетки, обнаруживая разницу в позициях через Vector3D. Затем он должен добавить вектор в список.
List<Vector3D> listVectors = new List<Vector3D>();
int i = currentMesh.Positions.Count;
Parallel.For(0, i, thisloop =>
{
Point3D mor = morphMesh.Positions[thisloop];
Point3D cur = currentMesh.Positions[thisloop];
Vector3D foo = mor - cur;
listVectors.Add(foo);
});
Это выглядит хорошо для меня, но не работает. Возможно ли, что Point3D нельзя использовать в параллельном цикле?
Большое спасибо.
EDIT
Это должно показать, как делается «morphMesh» и откуда приходит.
morphMesh берется из группы в мишени для моей модели человека (импортированный формат .OBJ). Я всего лишь анимация частей сетки. Поэтому я получаю группу меша, которую меня интересует, захватывая ребенка целевой модели морфинга.
var lipsmorph = morph.Children[21];
morphgeometry = (GeometryModel3D)lipsmorph;
morphMesh = (MeshGeometry3D)morphgeometry.Geometry;
Так что это делает, получая губы группу целевой модели оборотня, это идентифицируется как группа в индексе ребенка 21. Тогда получается, что в сетке, так что я могу использовать его вычислить координировать различия и манипулировать соответствующей сеткой в живой «текущей» модели. Я также использую весовые коэффициенты, но я попытался свести код примера к минимуму, чтобы сначала получить его работу с различиями в сетке. Веса - это простые математики, поэтому не следует представлять такую большую проблему, как то, что я прошу здесь.
EDIT TWO
Использование кода Скотта и замораживании модели первых - это будет работать. Но для меня это не стоит делать, так как выполнение этого кода происходит в то же время, что и непараллельное решение для всех моих вычислений, таких как веса. Скотт ссылался на это в одном из своих комментариев. Я просто не занимаюсь математикой, чтобы изменить ситуацию.
Но так или иначе, возможно, для ссылки других людей я отправлю код, который, наконец, прекратил бросать ошибки.
i = currentMesh.Positions.Count;
List<Vector3D> listVectors = new List<Vector3D>();
morphMesh.Freeze();
currentMesh.Freeze();
try
{
Parallel.For(0, i,
() => new List<Vector3D>(), //Create a thread local list per thread
(thisloop, loopstate, localList) => //"localList" is the variable we created above or was the list that was returned from a previous loop iteration.
{
Point3D mor = morphMesh.Positions[thisloop];
Point3D cur = currentMesh.Positions[thisloop];
Vector3D foo = mor - cur;
localList.Add(foo);
return localList; //This hands the list off to be the input "localList" variable for the next thread that uses it.
},
localList => //Combine the thread local lists in to the master list in a thread safe way.
{
lock (listVectors)
listVectors.AddRange(localList);
});
}
catch (AggregateException b)
{
data.Text = b.InnerException.ToString();
}
Ещё не ответ на ваш вопрос, но я рекомендую вам забрать бесплатную книгу от Microsoft [«Шаблоны для параллельного программирования»] (http://www.microsoft.com/en-us/download/details.aspx?id=19222) многие примеры кода в ней вращаются вокруг 3D и он даст вам хорошие рекомендации о том, какую работу вы должны выполнять в своем цикле 'Parallel.For'. –