ДР/2011/Л8/Зад. 2
- Forums:
Центриране
Укажете на рендера да ползва сцената "data/hw8/axe_test.retrace".
Една от Mesh геометриите, която се ползва, е axe_lo.obj файл (съдържащ модел на брадва). Ако отворите OBJ файла и му разгледате върховете, ще забележите, че не са центрирани около началото на координатната система (0, 0, 0), а целия обект е преместен някъде с -5 по X и с +20 по Z (т.е. самата триъгълна мрежа не е зададена в "каноничен" вид, а е вече транслирана нанякъде). За съжаление, такива случаи са често срещани, и ще трябва да се справяме с тях. А от транслацията произлизат много проблеми:
- Въпреки, че според трансформацията на брадвата (във axe_test.retrace файла) е указано да стои някъде близо отдясно до сърцето, тя е доста далеч отзад
- Генерира се огромна обхващаща сфера, с радиус поне 20, за обект, чиито радиус не надвишава 3 (и рендера е бавен в следствие на което)
- Ротирането не работи както човек очаква. Тъй като след скалирането, брадвата е вече на 70 единици разстояние от началото на координатната система, то ротирането (например сменете yaw ъгъла на axeNode от -5 на -35) дори с малки ъгли дава големи премествания на обекта (който се движи по кръг с радиус 70)
За да се справим с всички тези проблеми, ще центрираме обекта около (0, 0, 0) директно след като го прочетем от OBJ файла. За целта:
- Трябва да намерим центъра на триъгълната мрежа. Един начин, който не е много прецизен, но върши работа в повечето случаи е да сумираме всички върхове на обекта (vertices) и да разделим на броя им (като пропускаме dummy-то на индекс 0). Т.е. трябва да се намери средноаритметично на vertices масива.
- Обекта трябва да се транслира така, че центъра му да попадне в (0, 0, 0), т.е. от всички върхове трябва да се извади намерения център
В резултат трябва да получите нещо като това: пример. При правилно реализиран алгоритъм, при променяне на ротацията на axe node-а, обекта се върти около центъра си, а не се премества на никъде. Подобно и за скалирането.
Бонус (1т):
Подобно на бонуса за група 0, направете вашия алгоритъм да се пуска само ако укажем изрично в сценовия файл. Добавете bool флагче recenter към Mesh и го инциализирайте с
false в Mesh конструктора. След което го регистрирайте в fillProperties(). След което, алгоритъма ви трябва да сработва само ако имаме ред "recenter true" във блока, дефиниращ axe Mesh-а. Не забравяйте да вземете стойността на това свойство (pb.getBoolProperty...) преди извикването на loadFromOBJ() в fillProperties() метода!
Супер бонус:
Измислете по-интелигентен начин за намиране на центъра на обекта (вижте в wikipedia за център на тежестта).