Краткий экскурс. Все кто хочет осваивать XNA должны знать, что, скорее всего (но необязательно) им придется писать на C#, являющимся управляемым (managed) языком (не единственным, но предпочтительным для работы с XNA). Это понятие включает много чего и с этим вы можете ознакомиться при необходимости чуть погуглив, но кроме всего прочего, любая библиотека или исполнимый файл (далее сборка) скомпилированный для работы с XNA (в том числе) содержит самоописательную информацию или по-другому метаданные. Т.е. сборка несет в себе много информации о себе самой – из метаданных можно узнать о классах и их членах этой сборки, а так же о тех классах на которые сборка ссылается. Например, метаданные метода содержат полное описание метода, включая класс (сборку его содержащую), тип возвращаемый методом и всех его параметров. Такое обилие информации не должно пропадать! Я надеюсь, вы с этим тоже согласны. Так вот с помощью метаданных, анализа IL в который компилируется наш код и неугомонных ручек вполне возможно восстановить исходный код сборки. Для этого есть несколько готовых программ (ildasm даже входит в комплект .NET Framework SDK), но мы скачали (я надеюсь, вы последовали моей рекомендации) признанного лидера .NET Reflector от Lutz Roeder.
Итак, устанавливаем и запускаем, в итоге видим, что-то вроде:
Это оно, то, что послужит вам верой и правдой, если вы и дальше будете что-то писать под .NET. Итак, нам нужно добраться до библиотек XNA, щелкаем меню File->Open… и ищем библиотечку под названием Microsoft.Xna.Framework.dll , я ее нашел у себя по пути C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v3.0\References\Windows\x86\Microsoft.Xna.Framework.dll чего и вам желаю. Потом нас заинтересует вот эта кнопка:
В появившемся справа дополнении окна мы запишем BoundingFrustum примерно так:
Потом уверенно щелкаем пару раз на названии в списке и оказываемся на соответствующем классе в дереве, раскроем его:
Обращаю внимание, здесь хорошо видно какой класс и какие интерфейсы наследует наш пациент (сразу запишем в карточку, что его тянет меряться с себе подобными IEquatable). Теперь вызовем у класса контекстное меню:
Здесь нас интересует пункт Disassemble. Из-за всех наших экспериментов рефлектор должен принять примерно такой вид:
Прокрутив вниз скроллер окна Disassembler вы увидите гиперссылку Expand methods. Вот собственно и все волшебство - перед вами текст класса.
Небольшое лирическое отступление: в процессе работы над проектами довольно часто задаешься вопросом “Почему?!!!”, почему .NET или библиотечка от сторонних производителей ведет себя так, а не иначе и здесь рефлектор просто вне конкуренции. Порой копания в нутрах фреймворка заставляют задуматься об индийско-китайском заговоре в рядах майкрософта. Не подумайте что я программнацист, среди коллег из азии есть очень достойные профессионалы, просто поневоле вспоминается анекдот как индийский программист проверял булеву переменную на истинность:
publicvoid SomeMethod(bool isPragMahaghama){if(isPragMahaghama.ToString().Length==4){// что то делаем …}}
Теперь по образу и подобию нам понадобится класс Gjk, методы SupportMapping из BoundingBox и BoundingSphere – потому как очень многое в библиотеках Microsoft sealed и internal. Выкидываем инициализацию по матрице, а тупо прописываем 8 угловых точек (единственно нужно проследить чтобы они шли в нужном порядке – это нужно для того чтобы Plane переменные корректно обрабатывали нахождение объекта по “ту” и по “сю” сторону от себя). Методы можно сделать похожими на эти:
Для инициализации получившегося класса мы будем использовать 8 точек:
Именно в такой последовательности (ааа… 7 и 8 поменяйте местами). Так вот, из них мы получаем 6 плоскостей, которые затем используются в хвост и в гриву для определения пересечений.
Теперь выкидываем матричный конструктор и добавляем свой:
public SimplePryzm(Vector3[] corners){this.planes=new Plane[6];this.cornerArray=new Vector3[8];if(corners.Length!=8)thrownew Exception("Дайте углов!"); corners.CopyTo(cornerArray,0); SetPlanes();}
Здесь самый важный момент это метод SetPlanes, на скорую руку (не взыщите) и с учетом рисунка предыдущего выглядит он так:
Что в сухом остатке, кто не знал – теперь знает, что такое Reflector и чем его следует закусывать, у нас есть обещанный мной в запале BoundingFrustum с произвольной инициализацией. Если у кого созреет хороший алгоритм “обжимки” мешей такой конструкцией feel free to use.
P.S.: В файле кода я указал, но на всякий случай еще раз скажу здесь – если вы хотите использовать этот класс по серьезному советую проверить инициализацию плоскостей. С лучами и другими плоскостями все будет работать нормально, но видимо где-то я напутал с точками и при проверках пересечения с объемами могут быть глюки (не с той стороны плоскости определяется фигура).
928 Прочтений • [SimpleBoundingPryzm, рефлектор и все, все, все…] [08.08.2012] [Комментариев: 0]