Добавяне на нормали към списък от върхове

Използвам DirectX 9 в C#
Съхранявам всичките си върхове в списък (а не масив), защото използвам динамичен LOD алгоритъм, така че всичко се изчислява на кадър, така че моите върхове потенциално могат да бъдат различни за всеки кадър.

Всичко работи добре, докато не се опитах да добавя нормали и осветление.
Разбрах, че не можете да редактирате нормалата, след като добавите връх към списък, защото това е списък от структури, а не от класове. Така че просто дава грешка като "не може да промени върнатата стойност на blablaba, защото не е променлива"
Например, ако се опитам да направя това, няма да работи -

vertices[i].Normal = new Vector3(0, 1, 0);

Нормалите трябва да се добавят, когато върхът е поставен в списъка, но не можете да изчислите нормалите, докато нямате пълна мрежа.

Така че направих нов персонализиран тип връх и вместо да го направя структура, го направих клас. Това също не работи, защото directx няма да го приеме, освен ако не е структура...

Тогава се опитах да го накарам да работи с масиви вместо със списък от върхове. Това доведе до по-малко от един кадър в секунда. Трябваше да използвам Array.Resize, за да променя размера на моя масив няколкостотин пъти на кадър и предполагам, че това не ми хареса.

Вероятно си мислите, че трябва да превърна окончателния списък в масив и след това да изчисля нормалите от там. Това няма да работи, защото върховете не са добавени в определен ред, така че не мога да знам кои върхове са близо до даден връх, за да мога да изчисля нормала.

И така, как мога да съхраня върховете си по начин, по който мога да им дам нормали, след като изградя мрежата си?


person Frobot    schedule 30.01.2012    source източник


Отговори (1)


C# ви пречи да пишете vertices[i].Normal = new Vector3(0, 1, 0), защото този израз няма да направи това, което искате. За разлика от индексатора на масив, индексаторът List<T> връща копие на посочения елемент и тъй като върхът е структура, целият връх се копира, Normal и всички. Ще актуализирате временно копие на върха, а не действителния връх, който е в списъка.

Заобиколното решение е да вземете (копие на) върха от списъка, да го актуализирате и да го поставите (копие на) обратно:

var vertex = vertices[i];
vertex.Normal = new Vector3(0, 1, 0); 
vertices[i] = vertex;

Жалко е, че няма прост начин да се избегне това многократно копиране.

person Michael Liu    schedule 30.01.2012
comment
Изобщо не мислех, че ще ми позволи да го направя по този начин, но работи перфектно. много благодаря - person Frobot; 30.01.2012